mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
Open source GPL/LGPL release
This commit is contained in:
9
userspace/.gitignore
vendored
Normal file
9
userspace/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
build/
|
||||
|
||||
# The annoying GCC debug files
|
||||
*.gcno
|
||||
*.gcda
|
||||
|
||||
# The HTML, etc, generated by the unit test script.
|
||||
results.html
|
||||
results.json
|
||||
174
userspace/Makefile
Normal file
174
userspace/Makefile
Normal file
@@ -0,0 +1,174 @@
|
||||
# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# TODO:
|
||||
# - Separate rule for nvgpu_unit shared library
|
||||
# - Proper header dependency checking.
|
||||
|
||||
# Turn off suffix rules. They are deprecated.
|
||||
.SUFFIXES:
|
||||
|
||||
# Full paths. Makes submakefiles easier. That said this make file _must_ be run
|
||||
# from <NVGPU>/userspace/.
|
||||
TWD=$(CURDIR)
|
||||
|
||||
# Top level out dir.
|
||||
OUT=$(TWD)/build
|
||||
|
||||
# Core unit test framework.
|
||||
CORE_SRC=$(TWD)/src
|
||||
CORE_OUT=$(OUT)/nvgpu_unit_core
|
||||
|
||||
# Nvgpu driver code.
|
||||
NVGPU_SRC=$(TWD)/../drivers/gpu/nvgpu
|
||||
# Nvgpu-next driver code.
|
||||
NVGPU_NEXT_SRC=$(TWD)/../../nvgpu-next/drivers/gpu/nvgpu
|
||||
NVGPU_OUT=$(OUT)/libnvgpu
|
||||
|
||||
# Unit tests themselves.
|
||||
UNIT_SRC=$(TWD)/units
|
||||
UNIT_OUT=$(OUT)/units
|
||||
|
||||
INCLUDES= \
|
||||
-I$(NVGPU_SRC) \
|
||||
-I$(NVGPU_SRC)/include \
|
||||
-I$(NVGPU_NEXT_SRC) \
|
||||
-I$(NVGPU_NEXT_SRC)/include \
|
||||
-I$(TWD)/../include \
|
||||
-I$(TWD)/../include/uapi \
|
||||
-I$(TWD)/include \
|
||||
|
||||
# This is safety build by default.
|
||||
NV_BUILD_CONFIGURATION_IS_SAFETY=1
|
||||
# This Makefile is only for host POSIX builds
|
||||
NVGPU_POSIX=1
|
||||
# Enable fault injection for unit tests
|
||||
NVGPU_FAULT_INJECTION_ENABLEMENT=1
|
||||
|
||||
# Linux configs. We want these so that we can mirror builds from the actual
|
||||
# Linux kernel.
|
||||
# include Makefile.configs
|
||||
CONFIGS := -D__NVGPU_POSIX__ \
|
||||
-DNVGPU_UNITTEST_FAULT_INJECTION_ENABLEMENT \
|
||||
-D__NVGPU_UNIT_TEST__
|
||||
|
||||
# safety-debug profile is used by default
|
||||
NVGPU_FORCE_SAFETY_PROFILE := 1
|
||||
NVGPU_FORCE_DEBUG_PROFILE := 1
|
||||
include $(NVGPU_SRC)/Makefile.shared.configs
|
||||
CONFIGS+=$(NVGPU_COMMON_CFLAGS)
|
||||
|
||||
# Compiler, c-flags, etc.
|
||||
|
||||
# CC = clang
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -ggdb -Werror -Wno-unused-parameter \
|
||||
-Wno-missing-field-initializers -Wformat -Wchar-subscripts \
|
||||
-Wparentheses -Wtrigraphs -Wpointer-arith -Wmissing-declarations \
|
||||
-Wmissing-prototypes -Wredundant-decls -Wmain -Wreturn-type \
|
||||
-Wmultichar -Wunused -Wmissing-braces -Wstrict-aliasing \
|
||||
-Wsign-compare -Waddress -Wno-unused-local-typedefs -fPIC \
|
||||
-Wno-maybe-uninitialized $(INCLUDES) $(CONFIGS)
|
||||
LIB_PATHS = -L$(OUT) -L$(UNIT_OUT)
|
||||
LIBS = -lpthread -pthread -lgcov -ldl
|
||||
|
||||
# NV_IS_COVERITY is used by violation whitelisting macros which use pragma
|
||||
# directives. Whitelisting is only enabled when a coverity scan is being run.
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_IS_COVERITY),1)
|
||||
CFLAGS += -Wno-unknown-pragmas
|
||||
CONFIGS += -DNV_IS_COVERITY
|
||||
endif
|
||||
|
||||
# Source files. We expect $(OBJS) and $(HEADERS) to get filled in here.
|
||||
include Makefile.sources
|
||||
|
||||
all: $(OUT)/nvgpu_unit $(UNITS)
|
||||
|
||||
# Convenience targets.
|
||||
.PHONY: libnvgpu core units
|
||||
libnvgpu: $(OUT)/libnvgpu-drv-igpu.so
|
||||
core: $(OUT)/nvgpu_unit
|
||||
units: $(UNITS)
|
||||
|
||||
# Note the weird libnvgpu_unit.so file: this is a bit of a hack. It lets the
|
||||
# unit tests link back against the nvgpu_unit executable so that they can call
|
||||
# functions (like unit_info()) directly. This shared library isn't actually
|
||||
# used for anything beyond that.
|
||||
#
|
||||
# Also it really should have its own rule...
|
||||
$(OUT)/nvgpu_unit: $(OUT)/libnvgpu-drv-igpu.so $(CORE_OBJS)
|
||||
$(CC) -shared -o $(OUT)/libnvgpu_unit.so \
|
||||
$(CORE_OBJS) $(LIB_PATHS) $(LIBS)
|
||||
$(CC) --coverage \
|
||||
-o $(OUT)/nvgpu_unit $(CORE_OBJS) $(LIB_PATHS) $(LIBS)
|
||||
|
||||
$(OUT)/libnvgpu-drv-igpu.so: $(OBJS)
|
||||
$(CC) -shared -Wl,--no-undefined -o $(OUT)/libnvgpu-drv-igpu.so $(OBJS) -lgcov -rdynamic -lpthread
|
||||
|
||||
# Default build target for all the nvgpu driver object files we want to build in
|
||||
# userspace. These get bundled into libnvgpu-drv-igpu.so.
|
||||
$(NVGPU_OUT)/%.o : $(NVGPU_SRC)/%.c $(HEADERS)
|
||||
@if [ ! -d $(dir $@) ] ; then \
|
||||
mkdir -p $(dir $@) ; \
|
||||
fi
|
||||
$(CC) --coverage $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# Default build target for all the nvgpu-next driver object files we want to
|
||||
# build in userspace. These too get bundled into libnvgpu-drv-igpu.so.
|
||||
$(NVGPU_OUT)/%.o : $(NVGPU_NEXT_SRC)/%.c $(HEADERS) $(HEADERS_NEXT)
|
||||
@if [ ! -d $(dir $@) ] ; then \
|
||||
mkdir -p $(dir $@) ; \
|
||||
fi
|
||||
$(CC) --coverage $(CFLAGS) $(configs) -c -o $@ $<
|
||||
|
||||
# Build target for unit test files. These are not part of the libnvgpu-drv-igpu.so.
|
||||
# These comprise the unit test framework.
|
||||
$(CORE_OUT)/%.o : $(CORE_SRC)/%.c $(CORE_HEADERS)
|
||||
@if [ ! -d $(dir $@) ] ; then \
|
||||
mkdir -p $(dir $@) ; \
|
||||
fi
|
||||
$(CC) --coverage $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# Certain variables should be exported to the unit test module builds.
|
||||
export TWD INCLUDES CONFIGS UNIT_SRC UNIT_OUT
|
||||
export CC CFLAGS LIB_PATHS LIBS
|
||||
|
||||
.PHONY: $(UNITS)
|
||||
$(UNITS): $(OUT)/libnvgpu-drv-igpu.so
|
||||
@echo "Building unit module: $@"
|
||||
@+$(MAKE) --no-print-directory -C $@
|
||||
|
||||
.PHONY: clean nvgpu_clean core_clean unit_clean
|
||||
|
||||
clean: nvgpu_clean core_clean unit_clean
|
||||
rm -rf $(OUT)
|
||||
|
||||
nvgpu_clean:
|
||||
rm -rf $(OUT)/libnvgpu*
|
||||
|
||||
core_clean:
|
||||
rm -rf $(OUT)/nvgpu_unit*
|
||||
|
||||
unit_clean:
|
||||
@for d in $(UNITS); do \
|
||||
echo Cleaning $$d; \
|
||||
$(MAKE) --no-print-directory -C $$d clean; \
|
||||
done
|
||||
rm -rf $(OUT)/units
|
||||
38
userspace/Makefile.interface.tmk
Normal file
38
userspace/Makefile.interface.tmk
Normal file
@@ -0,0 +1,38 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION
|
||||
NV_INTERFACE_NAME := nvgpu-unit
|
||||
NV_INTERFACE_EXPORTS := libnvgpu-unit
|
||||
NV_INTERFACE_PUBLIC_INCLUDES := include
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
160
userspace/Makefile.sources
Normal file
160
userspace/Makefile.sources
Normal file
@@ -0,0 +1,160 @@
|
||||
# -*- mode: makefile -*-
|
||||
#
|
||||
# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
include $(NVGPU_SRC)/Makefile.sources
|
||||
include $(NVGPU_NEXT_SRC)/Makefile.sources
|
||||
|
||||
OBJS := $(srcs:%.c=$(NVGPU_OUT)/%.o) $(srcs_next:%.c=$(NVGPU_OUT)/%.o)
|
||||
|
||||
HEADERS := \
|
||||
$(NVGPU_SRC)/include/nvgpu/*.h \
|
||||
$(NVGPU_SRC)/include/nvgpu/hw/*/*.h
|
||||
|
||||
CORE_OBJS := \
|
||||
$(CORE_OUT)/unit_main.o \
|
||||
$(CORE_OUT)/nvgpu.o \
|
||||
$(CORE_OUT)/args.o \
|
||||
$(CORE_OUT)/io.o \
|
||||
$(CORE_OUT)/module.o \
|
||||
$(CORE_OUT)/required_tests.o \
|
||||
$(CORE_OUT)/results.o \
|
||||
$(CORE_OUT)/exec.o
|
||||
|
||||
CORE_HEADERS := \
|
||||
$(CORE_SRC)/../include/unit/*.h
|
||||
|
||||
# Each directory under the UNIT_SRC directory should correspond to one module.
|
||||
UNITS := \
|
||||
$(UNIT_SRC)/posix/env \
|
||||
$(UNIT_SRC)/posix/bitops \
|
||||
$(UNIT_SRC)/posix/fault-injection \
|
||||
$(UNIT_SRC)/posix/bug \
|
||||
$(UNIT_SRC)/posix/os_sched \
|
||||
$(UNIT_SRC)/posix/log2 \
|
||||
$(UNIT_SRC)/posix/sizes \
|
||||
$(UNIT_SRC)/posix/thread \
|
||||
$(UNIT_SRC)/posix/cond \
|
||||
$(UNIT_SRC)/posix/timers \
|
||||
$(UNIT_SRC)/posix/kmem \
|
||||
$(UNIT_SRC)/posix/rwsem \
|
||||
$(UNIT_SRC)/posix/queue \
|
||||
$(UNIT_SRC)/posix/utils \
|
||||
$(UNIT_SRC)/posix/circ_buf \
|
||||
$(UNIT_SRC)/bus \
|
||||
$(UNIT_SRC)/pramin \
|
||||
$(UNIT_SRC)/ptimer \
|
||||
$(UNIT_SRC)/priv_ring \
|
||||
$(UNIT_SRC)/init \
|
||||
$(UNIT_SRC)/interface/bit-utils \
|
||||
$(UNIT_SRC)/interface/lock \
|
||||
$(UNIT_SRC)/interface/nvgpu_gk20a \
|
||||
$(UNIT_SRC)/interface/atomic \
|
||||
$(UNIT_SRC)/interface/rbtree \
|
||||
$(UNIT_SRC)/interface/static_analysis \
|
||||
$(UNIT_SRC)/interface/string \
|
||||
$(UNIT_SRC)/interface/worker \
|
||||
$(UNIT_SRC)/interface/kref \
|
||||
$(UNIT_SRC)/interface/list \
|
||||
$(UNIT_SRC)/mc \
|
||||
$(UNIT_SRC)/mm/nvgpu_sgt \
|
||||
$(UNIT_SRC)/mm/allocators/buddy_allocator \
|
||||
$(UNIT_SRC)/mm/allocators/nvgpu_allocator \
|
||||
$(UNIT_SRC)/mm/allocators/bitmap_allocator \
|
||||
$(UNIT_SRC)/mm/allocators/page_allocator \
|
||||
$(UNIT_SRC)/mm/as \
|
||||
$(UNIT_SRC)/mm/dma \
|
||||
$(UNIT_SRC)/mm/gmmu/pd_cache \
|
||||
$(UNIT_SRC)/mm/gmmu/page_table \
|
||||
$(UNIT_SRC)/mm/hal/cache/flush_gk20a_fusa \
|
||||
$(UNIT_SRC)/mm/hal/cache/flush_gv11b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gmmu/gmmu_gk20a_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gmmu/gmmu_gm20b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gmmu/gmmu_gp10b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gmmu/gmmu_gv11b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gp10b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/gv11b_fusa \
|
||||
$(UNIT_SRC)/mm/hal/mmu_fault/gv11b_fusa \
|
||||
$(UNIT_SRC)/mm/mm \
|
||||
$(UNIT_SRC)/mm/page_table_faults \
|
||||
$(UNIT_SRC)/mm/nvgpu_mem \
|
||||
$(UNIT_SRC)/mm/vm \
|
||||
$(UNIT_SRC)/netlist \
|
||||
$(UNIT_SRC)/fb \
|
||||
$(UNIT_SRC)/fbp \
|
||||
$(UNIT_SRC)/fifo \
|
||||
$(UNIT_SRC)/fifo/fifo/gk20a \
|
||||
$(UNIT_SRC)/fifo/fifo/gv11b \
|
||||
$(UNIT_SRC)/fifo/channel \
|
||||
$(UNIT_SRC)/fifo/channel/gk20a \
|
||||
$(UNIT_SRC)/fifo/channel/gm20b \
|
||||
$(UNIT_SRC)/fifo/channel/gv11b \
|
||||
$(UNIT_SRC)/fifo/ctxsw_timeout/gv11b \
|
||||
$(UNIT_SRC)/fifo/engine \
|
||||
$(UNIT_SRC)/fifo/engine/gm20b \
|
||||
$(UNIT_SRC)/fifo/engine/gp10b \
|
||||
$(UNIT_SRC)/fifo/engine/gv100 \
|
||||
$(UNIT_SRC)/fifo/engine/gv11b \
|
||||
$(UNIT_SRC)/fifo/fifo \
|
||||
$(UNIT_SRC)/fifo/pbdma \
|
||||
$(UNIT_SRC)/fifo/pbdma/gm20b \
|
||||
$(UNIT_SRC)/fifo/pbdma/gp10b \
|
||||
$(UNIT_SRC)/fifo/pbdma/gv11b \
|
||||
$(UNIT_SRC)/fifo/preempt \
|
||||
$(UNIT_SRC)/fifo/preempt/gv11b \
|
||||
$(UNIT_SRC)/fifo/ramfc/gp10b \
|
||||
$(UNIT_SRC)/fifo/ramfc/gv11b \
|
||||
$(UNIT_SRC)/fifo/ramin/gk20a \
|
||||
$(UNIT_SRC)/fifo/ramin/gm20b \
|
||||
$(UNIT_SRC)/fifo/ramin/gv11b \
|
||||
$(UNIT_SRC)/fifo/runlist \
|
||||
$(UNIT_SRC)/fifo/runlist/gk20a \
|
||||
$(UNIT_SRC)/fifo/runlist/gv11b \
|
||||
$(UNIT_SRC)/fifo/tsg \
|
||||
$(UNIT_SRC)/fifo/tsg/gv11b \
|
||||
$(UNIT_SRC)/fifo/userd/gk20a \
|
||||
$(UNIT_SRC)/fifo/usermode/gv11b \
|
||||
$(UNIT_SRC)/ltc \
|
||||
$(UNIT_SRC)/enabled \
|
||||
$(UNIT_SRC)/falcon \
|
||||
$(UNIT_SRC)/falcon/falcon_tests \
|
||||
$(UNIT_SRC)/fuse \
|
||||
$(UNIT_SRC)/pmu \
|
||||
$(UNIT_SRC)/therm \
|
||||
$(UNIT_SRC)/top \
|
||||
$(UNIT_SRC)/class \
|
||||
$(UNIT_SRC)/gr \
|
||||
$(UNIT_SRC)/gr/falcon \
|
||||
$(UNIT_SRC)/gr/config \
|
||||
$(UNIT_SRC)/gr/init \
|
||||
$(UNIT_SRC)/gr/fs_state \
|
||||
$(UNIT_SRC)/gr/global_ctx \
|
||||
$(UNIT_SRC)/gr/ctx \
|
||||
$(UNIT_SRC)/gr/obj_ctx \
|
||||
$(UNIT_SRC)/gr/intr \
|
||||
$(UNIT_SRC)/gr/setup \
|
||||
$(UNIT_SRC)/acr \
|
||||
$(UNIT_SRC)/ce \
|
||||
$(UNIT_SRC)/cg \
|
||||
$(UNIT_SRC)/rc \
|
||||
$(UNIT_SRC)/sync \
|
||||
$(UNIT_SRC)/ecc \
|
||||
$(UNIT_SRC)/io
|
||||
134
userspace/Makefile.tmk
Normal file
134
userspace/Makefile.tmk
Normal file
@@ -0,0 +1,134 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_COMMON_SRCS := \
|
||||
src/nvgpu.c \
|
||||
src/args.c \
|
||||
src/io.c \
|
||||
src/module.c \
|
||||
src/required_tests.c \
|
||||
src/results.c \
|
||||
src/exec.c
|
||||
NVGPU_UNIT_COMMON_INCLUDES := \
|
||||
include \
|
||||
../drivers/gpu/nvgpu \
|
||||
../drivers/gpu/nvgpu/include
|
||||
|
||||
ifdef NV_COMPONENT_FLAG_NVTEST_EXECUTABLE_SECTION
|
||||
include $(NV_BUILD_START_COMPONENT)
|
||||
|
||||
NV_COMPONENT_NAME := nvgpu_unit
|
||||
NV_COMPONENT_SOURCES := \
|
||||
src/unit_main.c \
|
||||
$(NVGPU_UNIT_COMMON_SRCS)
|
||||
|
||||
NV_COMPONENT_INCLUDES := \
|
||||
$(NVGPU_UNIT_COMMON_INCLUDES)
|
||||
|
||||
ifndef NVGPU_UNIT_GPU
|
||||
NVGPU_UNIT_GPU := igpu
|
||||
endif
|
||||
|
||||
NV_COMPONENT_NEEDED_INTERFACE_DIRS := ../libs/$(NVGPU_UNIT_GPU)
|
||||
|
||||
ifneq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1)
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += pthread
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += dl
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += gcov
|
||||
endif
|
||||
|
||||
_NV_TOOLCHAIN_CFLAGS += -rdynamic
|
||||
|
||||
NV_UNIT_SH=unit.sh
|
||||
NV_SUBMIT_UNIT_SH=nvgpu_submit_unit.sh
|
||||
NV_TESTLIST_PY=testlist.py
|
||||
NV_REQ_TESTS_INI=required_tests.ini
|
||||
NV_COMPONENT_SYSTEMIMAGE_DIR := $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/nvgpu_unit
|
||||
systemimage:: $(NV_COMPONENT_SYSTEMIMAGE_DIR) $(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_UNIT_SH) \
|
||||
$(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/$(NV_SUBMIT_UNIT_SH) \
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_TESTLIST_PY) \
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_REQ_TESTS_INI)
|
||||
|
||||
#make the output directory
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR) : $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)
|
||||
$(MKDIR_P) $@
|
||||
|
||||
#copy the test script
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_UNIT_SH) : $(NV_COMPONENT_DIR)/$(NV_UNIT_SH) $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(CP) $< $@
|
||||
#the submit script goes in the parent directory
|
||||
$(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/$(NV_SUBMIT_UNIT_SH) : $(NV_COMPONENT_DIR)/$(NV_SUBMIT_UNIT_SH) $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(CP) $< $@
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_TESTLIST_PY) : $(NV_COMPONENT_DIR)/$(NV_TESTLIST_PY) $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(CP) $< $@
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR)/$(NV_REQ_TESTS_INI) : $(NV_COMPONENT_DIR)/$(NV_REQ_TESTS_INI) $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(CP) $< $@
|
||||
|
||||
include $(NV_BUILD_NVTEST_EXECUTABLE)
|
||||
|
||||
endif
|
||||
|
||||
ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION
|
||||
include $(NV_BUILD_START_COMPONENT)
|
||||
|
||||
NV_COMPONENT_NAME := nvgpu_unit-lib
|
||||
NV_COMPONENT_OWN_INTERFACE_DIR := .
|
||||
|
||||
NV_COMPONENT_SOURCES := \
|
||||
$(NVGPU_UNIT_COMMON_SRCS)
|
||||
|
||||
NV_COMPONENT_INCLUDES := \
|
||||
$(NVGPU_UNIT_COMMON_INCLUDES)
|
||||
|
||||
ifneq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1)
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += pthread
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += dl
|
||||
NVGPU_FORCE_SAFETY_PROFILE := 1
|
||||
NVGPU_FORCE_DEBUG_PROFILE := 1
|
||||
endif
|
||||
|
||||
NV_COMPONENT_CFLAGS += \
|
||||
-D__NVGPU_POSIX__ \
|
||||
-DNVGPU_UNITTEST_FAULT_INJECTION_ENABLEMENT
|
||||
|
||||
-include ../drivers/gpu/nvgpu/Makefile.shared.configs
|
||||
NV_COMPONENT_CFLAGS += $(NVGPU_COMMON_CFLAGS)
|
||||
|
||||
NV_COMPONENT_SYSTEMIMAGE_DIR := $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/nvgpu_unit/
|
||||
systemimage:: $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR) : $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)
|
||||
$(MKDIR_P) $@
|
||||
NV_COMPONENT_SYSTEMIMAGE_NAME := libnvgpu-unit.so
|
||||
|
||||
include $(NV_BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
156
userspace/SWUTS.h
Normal file
156
userspace/SWUTS.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @page NVGPU-SWUTS
|
||||
*
|
||||
* NVGPU Software Unit Test Specifications
|
||||
* =======================================
|
||||
*
|
||||
* The following pages cover the various unit test specifications needed
|
||||
* to test the NVGPU driver.
|
||||
*
|
||||
* - @ref SWUTS-enabled
|
||||
* - @ref SWUTS-interface-bit-utils
|
||||
* - @ref SWUTS-interface-lock
|
||||
* - @ref SWUTS-interface-nvgpu-gk20a
|
||||
* - @ref SWUTS-interface-rbtree
|
||||
* - @ref SWUTS-interface-static_analysis
|
||||
* - @ref SWUTS-interface-string
|
||||
* - @ref SWUTS-interface-worker
|
||||
* - @ref SWUTS-interface-kref
|
||||
* - @ref SWUTS-interface-list
|
||||
* - @ref SWUTS-bus
|
||||
* - @ref SWUTS-falcon
|
||||
* - @ref SWUTS-netlist
|
||||
* - @ref SWUTS-fifo
|
||||
* - @ref SWUTS-fifo-channel
|
||||
* - @ref SWUTS-fifo-channel-gk20a
|
||||
* - @ref SWUTS-fifo-channel-gm20b
|
||||
* - @ref SWUTS-fifo-channel-gv11b
|
||||
* - @ref SWUTS-fifo-ctxsw_timeout-gv11b
|
||||
* - @ref SWUTS-fifo-engine
|
||||
* - @ref SWUTS-fifo-engine-gm20b
|
||||
* - @ref SWUTS-fifo-engine-gp10b
|
||||
* - @ref SWUTS-fifo-engine-gv100
|
||||
* - @ref SWUTS-fifo-engine-gv11b
|
||||
* - @ref SWUTS-fifo-fifo
|
||||
* - @ref SWUTS-fifo-fifo-gk20a
|
||||
* - @ref SWUTS-fifo-fifo-gv11b
|
||||
* - @ref SWUTS-fifo-pbdma
|
||||
* - @ref SWUTS-fifo-pbdma-gm20b
|
||||
* - @ref SWUTS-fifo-pbdma-gp10b
|
||||
* - @ref SWUTS-fifo-pbdma-gv11b
|
||||
* - @ref SWUTS-fifo-preempt
|
||||
* - @ref SWUTS-fifo-preempt-gv11b
|
||||
* - @ref SWUTS-fifo-ramfc-gp10b
|
||||
* - @ref SWUTS-fifo-ramfc-gv11b
|
||||
* - @ref SWUTS-fifo-ramin-gk20a
|
||||
* - @ref SWUTS-fifo-ramin-gm20b
|
||||
* - @ref SWUTS-fifo-ramin-gp10b
|
||||
* - @ref SWUTS-fifo-ramin-gv11b
|
||||
* - @ref SWUTS-fifo-runlist
|
||||
* - @ref SWUTS-fifo-runlist-gk20a
|
||||
* - @ref SWUTS-fifo-runlist-gv11b
|
||||
* - @ref SWUTS-fifo-tsg
|
||||
* - @ref SWUTS-fifo-tsg-gv11b
|
||||
* - @ref SWUTS-fifo-userd-gk20a
|
||||
* - @ref SWUTS-fifo-usermode-gv11b
|
||||
* - @ref SWUTS-nvgpu-sync
|
||||
* - @ref SWUTS-init
|
||||
* - @ref SWUTS-intr
|
||||
* - @ref SWUTS-interface-atomic
|
||||
* - @ref SWUTS-ltc
|
||||
* - @ref SWUTS-nvgpu-rc
|
||||
* - @ref SWUTS-mc
|
||||
* - @ref SWUTS-mm-allocators-bitmap-allocator
|
||||
* - @ref SWUTS-mm-allocators-buddy-allocator
|
||||
* - @ref SWUTS-mm-allocators-nvgpu-allocator
|
||||
* - @ref SWUTS-mm-as
|
||||
* - @ref SWUTS-mm-dma
|
||||
* - @ref SWUTS-mm-gmmu-page_table
|
||||
* - @ref SWUTS-mm-gmmu-pd_cache
|
||||
* - @ref SWUTS-mm-hal-cache-flush-gk20a-fusa
|
||||
* - @ref SWUTS-mm-hal-cache-flush-gv11b-fusa
|
||||
* - @ref SWUTS-mm-hal-gmmu-gmmu_gk20a_fusa
|
||||
* - @ref SWUTS-mm-hal-gmmu-gmmu_gm20b_fusa
|
||||
* - @ref SWUTS-mm-hal-gmmu-gmmu_gp10b_fusa
|
||||
* - @ref SWUTS-mm-hal-gmmu-gmmu_gv11b_fusa
|
||||
* - @ref SWUTS-mm-hal-gp10b_fusa
|
||||
* - @ref SWUTS-mm-hal-gv11b-fusa
|
||||
* - @ref SWUTS-mm-hal-mmu_fault-gv11b_fusa
|
||||
* - @ref SWUTS-mm-nvgpu-mem
|
||||
* - @ref SWUTS-mm-nvgpu-sgt
|
||||
* - @ref SWUTS-mm-page_table_faults
|
||||
* - @ref SWUTS-mm-mm
|
||||
* - @ref SWUTS-mm-vm
|
||||
* - @ref SWUTS-nvgpu-sync
|
||||
* - @ref SWUTS-fb
|
||||
* - @ref SWUTS-fbp
|
||||
* - @ref SWUTS-fuse
|
||||
* - @ref SWUTS-posix-bitops
|
||||
* - @ref SWUTS-posix-cond
|
||||
* - @ref SWUTS-posix-log2
|
||||
* - @ref SWUTS-posix-fault-injection
|
||||
* - @ref SWUTS-posix-sizes
|
||||
* - @ref SWUTS-posix-thread
|
||||
* - @ref SWUTS-posix-timers
|
||||
* - @ref SWUTS-posix-queue
|
||||
* - @ref SWUTS-posix-bug
|
||||
* - @ref SWUTS-posix-ossched
|
||||
* - @ref SWUTS-posix-rwsem
|
||||
* - @ref SWUTS-posix-utils
|
||||
* - @ref SWUTS-posix-circbuf
|
||||
* - @ref SWUTS-posix-kmem
|
||||
* - @ref SWUTS-priv_ring
|
||||
* - @ref SWUTS-ptimer
|
||||
* - @ref SWUTS-sdl
|
||||
* - @ref SWUTS-therm
|
||||
* - @ref SWUTS-acr
|
||||
* - @ref SWUTS-ce
|
||||
* - @ref SWUTS-cg
|
||||
* - @ref SWUTS-init_test
|
||||
* - @ref SWUTS-power_mgmt
|
||||
* - @ref SWUTS-qnx-fuse
|
||||
* - @ref SWUTS-nvrm_dev_os
|
||||
* - @ref SWUTS-devctl_ctrl
|
||||
* - @ref SWUTS-channel_os
|
||||
* - @ref SWUTS-top
|
||||
* - @ref SWUTS-class
|
||||
* - @ref SWUTS-gr
|
||||
* - @ref SWUTS-gr-setup
|
||||
* - @ref SWUTS-gr-intr
|
||||
* - @ref SWUTS-gr-init-hal-gv11b
|
||||
* - @ref SWUTS-gr-falcon
|
||||
* - @ref SWUTS-gr-falcon-gm20b
|
||||
* - @ref SWUTS-gr-fs-state
|
||||
* - @ref SWUTS-gr-global-ctx
|
||||
* - @ref SWUTS-gr-ctx
|
||||
* - @ref SWUTS-gr-obj-ctx
|
||||
* - @ref SWUTS-gr-config
|
||||
* - @ref SWUTS-ecc
|
||||
* - @ref SWUTS-pmu
|
||||
* - @ref SWUTS-io
|
||||
*
|
||||
*/
|
||||
|
||||
124
userspace/SWUTS.sources
Normal file
124
userspace/SWUTS.sources
Normal file
@@ -0,0 +1,124 @@
|
||||
INPUT += ../../../userspace/SWUTS.h
|
||||
INPUT += ../../../userspace/units/ce/nvgpu-ce.h
|
||||
INPUT += ../../../userspace/units/cg/nvgpu-cg.h
|
||||
INPUT += ../../../userspace/units/enabled/nvgpu-enabled.h
|
||||
INPUT += ../../../userspace/units/interface/bit-utils/bit-utils.h
|
||||
INPUT += ../../../userspace/units/interface/lock/lock.h
|
||||
INPUT += ../../../userspace/units/interface/nvgpu_gk20a/nvgpu_gk20a.h
|
||||
INPUT += ../../../userspace/units/interface/rbtree/rbtree.h
|
||||
INPUT += ../../../userspace/units/interface/static_analysis/static_analysis.h
|
||||
INPUT += ../../../userspace/units/interface/string/nvgpu-string.h
|
||||
INPUT += ../../../userspace/units/interface/worker/worker.h
|
||||
INPUT += ../../../userspace/units/interface/kref/kref.h
|
||||
INPUT += ../../../userspace/units/interface/list/list.h
|
||||
INPUT += ../../../userspace/units/bus/nvgpu-bus.h
|
||||
INPUT += ../../../userspace/units/falcon/falcon_tests/nvgpu-falcon.h
|
||||
INPUT += ../../../userspace/units/netlist/nvgpu-netlist.h
|
||||
INPUT += ../../../userspace/units/fbp/nvgpu-fbp.h
|
||||
INPUT += ../../../userspace/units/fb/fb_fusa.h
|
||||
INPUT += ../../../userspace/units/fifo/nvgpu-fifo-common.h
|
||||
INPUT += ../../../userspace/units/fifo/channel/nvgpu-channel.h
|
||||
INPUT += ../../../userspace/units/fifo/channel/gk20a/nvgpu-channel-gk20a.h
|
||||
INPUT += ../../../userspace/units/fifo/channel/gm20b/nvgpu-channel-gm20b.h
|
||||
INPUT += ../../../userspace/units/fifo/channel/gv11b/nvgpu-channel-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/ctxsw_timeout/gv11b/nvgpu-ctxsw-timeout-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/nvgpu-engine.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/nvgpu-engine-status.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/gm20b/nvgpu-engine-gm20b.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/gp10b/nvgpu-engine-gp10b.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/gv100/nvgpu-engine-gv100.h
|
||||
INPUT += ../../../userspace/units/fifo/engine/gv11b/nvgpu-engine-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/fifo/nvgpu-fifo.h
|
||||
INPUT += ../../../userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.h
|
||||
INPUT += ../../../userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.h
|
||||
INPUT += ../../../userspace/units/fifo/fifo/gv11b/nvgpu-fifo-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/fifo/gv11b/nvgpu-fifo-intr-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/pbdma/nvgpu-pbdma.h
|
||||
INPUT += ../../../userspace/units/fifo/pbdma/gm20b/nvgpu-pbdma-gm20b.h
|
||||
INPUT += ../../../userspace/units/fifo/pbdma/gm20b/nvgpu-pbdma-status-gm20b.h
|
||||
INPUT += ../../../userspace/units/fifo/pbdma/gp10b/nvgpu-pbdma-gp10b.h
|
||||
INPUT += ../../../userspace/units/fifo/pbdma/gv11b/nvgpu-pbdma-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/preempt/nvgpu-preempt.h
|
||||
INPUT += ../../../userspace/units/fifo/preempt/gv11b/nvgpu-preempt-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/ramfc/gp10b/nvgpu-ramfc-gp10b.h
|
||||
INPUT += ../../../userspace/units/fifo/ramfc/gv11b/nvgpu-ramfc-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/ramin/gk20a/ramin-gk20a-fusa.h
|
||||
INPUT += ../../../userspace/units/fifo/ramin/gm20b/ramin-gm20b-fusa.h
|
||||
INPUT += ../../../userspace/units/fifo/ramin/gv11b/ramin-gv11b-fusa.h
|
||||
INPUT += ../../../userspace/units/fifo/runlist/nvgpu-runlist.h
|
||||
INPUT += ../../../userspace/units/fifo/runlist/gk20a/nvgpu-runlist-gk20a.h
|
||||
INPUT += ../../../userspace/units/fifo/runlist/gv11b/nvgpu-runlist-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/tsg/nvgpu-tsg.h
|
||||
INPUT += ../../../userspace/units/fifo/tsg/gv11b/nvgpu-tsg-gv11b.h
|
||||
INPUT += ../../../userspace/units/rc/nvgpu-rc.h
|
||||
INPUT += ../../../userspace/units/rc/nvgpu-rc.c
|
||||
INPUT += ../../../userspace/units/fifo/userd/gk20a/nvgpu-userd-gk20a.h
|
||||
INPUT += ../../../userspace/units/fifo/userd/gv11b/nvgpu-usermode-gv11b.h
|
||||
INPUT += ../../../userspace/units/fifo/usermode/gv11b/nvgpu-usermode-gv11b.h
|
||||
INPUT += ../../../userspace/units/sync/nvgpu-sync.c
|
||||
INPUT += ../../../userspace/units/sync/nvgpu-sync.h
|
||||
INPUT += ../../../userspace/units/fuse/nvgpu-fuse.h
|
||||
INPUT += ../../../userspace/units/fuse/nvgpu-fuse-gm20b.h
|
||||
INPUT += ../../../userspace/units/fuse/nvgpu-fuse-gp10b.h
|
||||
INPUT += ../../../userspace/units/init/nvgpu-init.h
|
||||
INPUT += ../../../userspace/units/interface/atomic/atomic.h
|
||||
INPUT += ../../../userspace/units/ltc/nvgpu-ltc.h
|
||||
INPUT += ../../../userspace/units/mc/nvgpu-mc.h
|
||||
INPUT += ../../../userspace/units/mm/allocators/bitmap_allocator/bitmap_allocator.h
|
||||
INPUT += ../../../userspace/units/mm/allocators/buddy_allocator/buddy_allocator.h
|
||||
INPUT += ../../../userspace/units/mm/allocators/nvgpu_allocator/nvgpu_allocator.h
|
||||
INPUT += ../../../userspace/units/mm/as/as.h
|
||||
INPUT += ../../../userspace/units/mm/dma/dma.h
|
||||
INPUT += ../../../userspace/units/mm/gmmu/page_table/page_table.h
|
||||
INPUT += ../../../userspace/units/mm/gmmu/pd_cache/pd_cache.h
|
||||
INPUT += ../../../userspace/units/mm/hal/cache/flush_gk20a_fusa/flush-gk20a-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/cache/flush_gv11b_fusa/flush-gv11b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gmmu/gmmu_gk20a_fusa/gmmu-gk20a-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gmmu/gmmu_gm20b_fusa/gmmu-gm20b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gmmu/gmmu_gp10b_fusa/gmmu-gp10b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gmmu/gmmu_gv11b_fusa/gmmu-gv11b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gp10b_fusa/mm-gp10b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/gv11b_fusa/mm-gv11b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/hal/mmu_fault/gv11b_fusa/mmu-fault-gv11b-fusa.h
|
||||
INPUT += ../../../userspace/units/mm/nvgpu_mem/nvgpu_mem.h
|
||||
INPUT += ../../../userspace/units/mm/nvgpu_sgt/nvgpu_sgt.h
|
||||
INPUT += ../../../userspace/units/mm/page_table_faults/page_table_faults.h
|
||||
INPUT += ../../../userspace/units/mm/mm/mm.h
|
||||
INPUT += ../../../userspace/units/mm/vm/vm.h
|
||||
INPUT += ../../../userspace/units/sync/nvgpu-sync.h
|
||||
INPUT += ../../../userspace/units/posix/bitops/posix-bitops.h
|
||||
INPUT += ../../../userspace/units/posix/bug/posix-bug.h
|
||||
INPUT += ../../../userspace/units/posix/cond/posix-cond.h
|
||||
INPUT += ../../../userspace/units/posix/log2/posix-log2.h
|
||||
INPUT += ../../../userspace/units/posix/queue/posix-queue.h
|
||||
INPUT += ../../../userspace/units/posix/fault-injection/posix-fault-injection.h
|
||||
INPUT += ../../../userspace/units/posix/fault-injection/posix-fault-injection-kmem.h
|
||||
INPUT += ../../../userspace/units/posix/fault-injection/posix-fault-injection-dma-alloc.h
|
||||
INPUT += ../../../userspace/units/posix/sizes/posix-sizes.h
|
||||
INPUT += ../../../userspace/units/posix/thread/posix-thread.h
|
||||
INPUT += ../../../userspace/units/posix/timers/posix-timers.h
|
||||
INPUT += ../../../userspace/units/posix/os_sched/posix-ossched.h
|
||||
INPUT += ../../../userspace/units/posix/rwsem/posix-rwsem.h
|
||||
INPUT += ../../../userspace/units/posix/utils/posix-utils.h
|
||||
INPUT += ../../../userspace/units/posix/circ_buf/posix-circbuf.h
|
||||
INPUT += ../../../userspace/units/posix/kmem/posix-kmem.h
|
||||
INPUT += ../../../userspace/units/priv_ring/nvgpu-priv_ring.h
|
||||
INPUT += ../../../userspace/units/ptimer/nvgpu-ptimer.h
|
||||
INPUT += ../../../userspace/units/therm/nvgpu-therm.h
|
||||
INPUT += ../../../userspace/units/acr/nvgpu-acr.h
|
||||
INPUT += ../../../userspace/units/top/nvgpu-top.h
|
||||
INPUT += ../../../userspace/units/class/nvgpu-class.h
|
||||
INPUT += ../../../userspace/units/gr/nvgpu-gr.h
|
||||
INPUT += ../../../userspace/units/gr/setup/nvgpu-gr-setup.h
|
||||
INPUT += ../../../userspace/units/gr/intr/nvgpu-gr-intr.h
|
||||
INPUT += ../../../userspace/units/gr/init/nvgpu-gr-init-hal-gv11b.h
|
||||
INPUT += ../../../userspace/units/gr/falcon/nvgpu-gr-falcon.h
|
||||
INPUT += ../../../userspace/units/gr/falcon/nvgpu-gr-falcon-gm20b.h
|
||||
INPUT += ../../../userspace/units/gr/fs_state/nvgpu-gr-fs-state.h
|
||||
INPUT += ../../../userspace/units/gr/global_ctx/nvgpu-gr-global-ctx.h
|
||||
INPUT += ../../../userspace/units/gr/ctx/nvgpu-gr-ctx.h
|
||||
INPUT += ../../../userspace/units/gr/obj_ctx/nvgpu-gr-obj-ctx.h
|
||||
INPUT += ../../../userspace/units/gr/config/nvgpu-gr-config.h
|
||||
INPUT += ../../../userspace/units/ecc/nvgpu-ecc.h
|
||||
INPUT += ../../../userspace/units/pmu/nvgpu-pmu.h
|
||||
INPUT += ../../../userspace/units/io/common_io.h
|
||||
103
userspace/gcov.sh
Executable file
103
userspace/gcov.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# Script to run NVGPU unit tests and collect GCOV coverage.
|
||||
|
||||
|
||||
# First check dependencies and install them if needed
|
||||
if [ -z $(which gcc) ] || [ -z "$(pip show gcovr)" ]
|
||||
then
|
||||
echo "Some dependencies are missing, installing the now..."
|
||||
sudo apt install gcc python-pip -y
|
||||
#pip may have a more recent version of gcovr than apt.
|
||||
pip install gcovr
|
||||
fi
|
||||
|
||||
SCRIPT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
|
||||
pushd $SCRIPT_ROOT
|
||||
|
||||
#Libraries are in a different folder on host and target
|
||||
LIB_FOLDER="."
|
||||
if [ -d "./build" ]; then
|
||||
LIB_FOLDER="./build"
|
||||
fi
|
||||
|
||||
#Extract the root path of the source code
|
||||
NVGPU_SRC_ROOT=$(readelf -p .debug_line $LIB_FOLDER/libnvgpu-drv-igpu.so | \
|
||||
grep drivers/gpu/nvgpu/os/posix | sed 's/\s*\[.*\]\s*//g' | \
|
||||
sed 's/drivers\/gpu\/nvgpu\/os\/posix//g' | head -n 1)
|
||||
NVGPU_SRC_ROOT=$(realpath $NVGPU_SRC_ROOT)
|
||||
|
||||
#Make sure the source code is accessible (for on target testing)
|
||||
if [ -d "$NVGPU_SRC_ROOT/drivers/gpu/nvgpu" ]; then
|
||||
echo "Root folder for sources: $NVGPU_SRC_ROOT"
|
||||
else
|
||||
echo "FATAL: Source code folder not found: $NVGPU_SRC_ROOT"
|
||||
exit
|
||||
fi
|
||||
|
||||
#Clean existing GCOV files to avoid getting a cumulative result
|
||||
find . -name "*.gcda" -exec rm {} +
|
||||
find $NVGPU_SRC_ROOT -name "*.gcda" -exec rm {} +
|
||||
|
||||
#Run unit tests
|
||||
./unit.sh
|
||||
OUT=$?
|
||||
if [ ! $OUT -eq 0 ]; then
|
||||
echo "ERROR: Unit test run failed."
|
||||
read -p "Press ENTER to run GCOV anyway" -n 1 -r
|
||||
fi
|
||||
|
||||
#Run GCOV
|
||||
cd ..
|
||||
if [ -d report ]; then
|
||||
rm -rf report/
|
||||
fi
|
||||
mkdir report
|
||||
echo "Generating GCOV report..."
|
||||
python -m gcovr -v -s -e '.+posix/.+' -e '.*userspace/.+' \
|
||||
-r $NVGPU_SRC_ROOT --html-details --output report/index.html &> gcov.log
|
||||
|
||||
#Patch the paths to match output from automative runs so that hashes are identical
|
||||
sed -i 's/Value\">drivers\//Value\">kernel\/nvgpu\/drivers\//g' report/*.c.html
|
||||
|
||||
#Present the results
|
||||
if [ "$(uname -m)" = "aarch64" ]; then
|
||||
echo "Running on target, starting a webserver..."
|
||||
HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
||||
if [[ "$HOST_IP" =~ ^[0-9\.]+$ ]]; then
|
||||
echo -e "\n\nOpen http://$HOST_IP:8000/ to see the results"
|
||||
else
|
||||
echo "ERROR: Network is down: $HOST_IP"
|
||||
exit 1
|
||||
fi
|
||||
cd report/
|
||||
python -m SimpleHTTPServer &> /dev/null &
|
||||
PYTHON_PID=$!
|
||||
cd ..
|
||||
read -p "Press ENTER to stop the webserver. " -n 1 -r
|
||||
kill $PYTHON_PID
|
||||
else
|
||||
echo "Running on host, opening default browser..."
|
||||
xdg-open $SCRIPT_ROOT/../report/index.html
|
||||
fi
|
||||
popd
|
||||
78
userspace/include/unit/args.h
Normal file
78
userspace/include/unit/args.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_ARGS_H__
|
||||
#define __UNIT_ARGS_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* Allow defaults to be changed at compile time.
|
||||
*/
|
||||
#define __stringify(x) #x
|
||||
#define stringify(x) __stringify(x)
|
||||
|
||||
#ifndef __DEFAULT_ARG_DRIVER_LOAD_PATH
|
||||
#if defined(__NVGPU_POSIX__)
|
||||
#define __DEFAULT_ARG_DRIVER_LOAD_PATH ./build/libnvgpu-drv-igpu.so
|
||||
#else
|
||||
#define __DEFAULT_ARG_DRIVER_LOAD_PATH ./libnvgpu-drv-igpu.so
|
||||
#endif
|
||||
#endif
|
||||
#define DEFAULT_ARG_DRIVER_LOAD_PATH stringify(__DEFAULT_ARG_DRIVER_LOAD_PATH)
|
||||
|
||||
#ifndef __DEFAULT_ARG_UNIT_LOAD_PATH
|
||||
#define __DEFAULT_ARG_UNIT_LOAD_PATH build/units
|
||||
#endif
|
||||
#define DEFAULT_ARG_UNIT_LOAD_PATH stringify(__DEFAULT_ARG_UNIT_LOAD_PATH)
|
||||
#define TEST_PLAN_MAX 1
|
||||
|
||||
struct unit_fw;
|
||||
|
||||
struct unit_fw_args {
|
||||
bool help;
|
||||
int verbose_lvl;
|
||||
bool no_color;
|
||||
int thread_count;
|
||||
bool nvtest;
|
||||
bool is_qnx;
|
||||
unsigned int test_lvl;
|
||||
bool debug;
|
||||
const char *binary_name;
|
||||
|
||||
const char *driver_load_path;
|
||||
|
||||
const char *unit_name;
|
||||
const char *unit_load_path;
|
||||
const char *unit_to_run;
|
||||
const char *required_tests_file;
|
||||
};
|
||||
|
||||
int core_parse_args(struct unit_fw *fw, int argc, char **argv);
|
||||
void core_print_help(struct unit_fw *fw);
|
||||
|
||||
/*
|
||||
* Convenience for getting the args struct pointer.
|
||||
*/
|
||||
#define args(fw) ((fw)->args)
|
||||
|
||||
#endif
|
||||
69
userspace/include/unit/core.h
Normal file
69
userspace/include/unit/core.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_CORE_H__
|
||||
#define __UNIT_CORE_H__
|
||||
|
||||
struct unit_fw_args;
|
||||
struct unit_modules;
|
||||
struct unit_results;
|
||||
|
||||
struct gk20a;
|
||||
struct nvgpu_posix_fault_inj_container;
|
||||
|
||||
/*
|
||||
* The core unit testing framework data structure. Keeps track of global state
|
||||
* for the unit test app.
|
||||
*/
|
||||
struct unit_fw {
|
||||
struct unit_fw_args *args;
|
||||
|
||||
struct unit_module **modules;
|
||||
|
||||
struct unit_results *results;
|
||||
|
||||
/*
|
||||
* driver library interface. Currently the only two directly referenced
|
||||
* functions are:
|
||||
*
|
||||
* nvgpu_posix_probe()
|
||||
* nvgpu_posix_cleanup()
|
||||
*
|
||||
* There will get populated so that we can call them before/after each
|
||||
* module.
|
||||
*/
|
||||
void *nvgpu_so;
|
||||
struct {
|
||||
struct gk20a *(*nvgpu_posix_probe)(void);
|
||||
void (*nvgpu_posix_cleanup)(struct gk20a *g);
|
||||
void (*nvgpu_posix_init_fault_injection)
|
||||
(struct nvgpu_posix_fault_inj_container *c);
|
||||
void (*nvgpu_posix_init_fault_injection_qnx)
|
||||
(struct nvgpu_posix_fault_inj_container *c);
|
||||
} nvgpu;
|
||||
void *nvgpu_qnx_ut;
|
||||
};
|
||||
|
||||
int core_load_nvgpu(struct unit_fw *fw);
|
||||
int core_exec(struct unit_fw *fw);
|
||||
int verbose_lvl(struct unit_module *module);
|
||||
#endif
|
||||
103
userspace/include/unit/io.h
Normal file
103
userspace/include/unit/io.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_IO_H__
|
||||
#define __UNIT_IO_H__
|
||||
|
||||
struct unit_fw;
|
||||
struct unit_module;
|
||||
|
||||
/*
|
||||
* necessary for args(fw) macro. IO will always, in general, depend on args
|
||||
* since the args will specify where IO should be directed to.
|
||||
*/
|
||||
#include <unit/args.h>
|
||||
|
||||
#define core_msg(fw, msg, ...) \
|
||||
core_vbs(fw, 0, msg, ##__VA_ARGS__)
|
||||
#define core_msg_color(fw, color, msg, ...) \
|
||||
core_vbs_color(fw, color, 0, msg, ##__VA_ARGS__)
|
||||
|
||||
#define core_vbs_color(fw, color, lvl, msg, ...) \
|
||||
do { \
|
||||
if ((lvl) > args(fw)->verbose_lvl) \
|
||||
continue; \
|
||||
\
|
||||
/* Print if verbosity level is high enough. */ \
|
||||
__core_print_stdout(fw, color, msg, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define core_vbs(fw, lvl, msg, ...) \
|
||||
core_vbs_color(fw, NULL, lvl, msg, ##__VA_ARGS__)
|
||||
|
||||
#define core_err(fw, msg, ...) \
|
||||
__core_print_stderr(fw, "(%s:%d) " msg, \
|
||||
__func__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Output macro for unit tests to use.
|
||||
*/
|
||||
#define unit_info(unit, msg, ...) \
|
||||
__unit_info_color(unit, NULL, msg, ##__VA_ARGS__)
|
||||
#define unit_err(unit, msg, ...) \
|
||||
__unit_info_color(unit, C_RED, msg, ##__VA_ARGS__)
|
||||
|
||||
|
||||
/*
|
||||
* helper to check a condition, output and error if condition is false
|
||||
* and execute bail_out_code
|
||||
*/
|
||||
#define unit_assert(cond, bail_out_code) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
unit_err(m, "%s:%d (" #cond ") is false\n", \
|
||||
__func__, __LINE__); \
|
||||
bail_out_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Don't go overboard with these!!!
|
||||
*/
|
||||
#define C_RED "\x1B[31m"
|
||||
#define C_GREEN "\x1B[32m"
|
||||
#define C_YELLOW "\x1B[33m"
|
||||
#define C_BLUE "\x1B[34m"
|
||||
#define C_MAGENTA "\x1B[35m"
|
||||
#define C_CYAN "\x1B[36m"
|
||||
#define C_WHITE "\x1B[37m"
|
||||
#define C_RESET "\x1B[0m"
|
||||
|
||||
/*
|
||||
* Printing functions. Do not use these directly. Instead use the provided
|
||||
* macros.
|
||||
*/
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
void __core_print_stdout(struct unit_fw *fw, const char *color,
|
||||
const char *fmt, ...);
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...);
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
void __unit_info_color(struct unit_module *unit, const char *color,
|
||||
const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
31
userspace/include/unit/module.h
Normal file
31
userspace/include/unit/module.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_MODULE_H__
|
||||
#define __UNIT_MODULE_H__
|
||||
|
||||
struct unit_fw;
|
||||
struct unit_module;
|
||||
|
||||
struct unit_module **core_load_modules(struct unit_fw *fw);
|
||||
|
||||
#endif
|
||||
31
userspace/include/unit/required_tests.h
Normal file
31
userspace/include/unit/required_tests.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __REQUIRED_TESTS_H__
|
||||
#define __REQUIRED_TESTS_H__
|
||||
|
||||
#define MAX_LINE_SIZE 256
|
||||
|
||||
int parse_req_file(struct unit_fw *fw, const char *ini_file);
|
||||
int check_executed_tests(struct unit_fw *fw);
|
||||
|
||||
#endif
|
||||
78
userspace/include/unit/results.h
Normal file
78
userspace/include/unit/results.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_RESULTS_H__
|
||||
#define __UNIT_RESULTS_H__
|
||||
|
||||
/*
|
||||
* Keep track of the the results of a set of unit tests. This is effectively
|
||||
* just a single linked list of records for each test.
|
||||
*/
|
||||
|
||||
struct unit_test_record {
|
||||
/*
|
||||
* Let's us determine the name of the test.
|
||||
*/
|
||||
struct unit_module *mod;
|
||||
struct unit_module_test *test;
|
||||
|
||||
/*
|
||||
* True for pass, false for fail.
|
||||
*/
|
||||
bool status;
|
||||
|
||||
struct unit_test_record *next;
|
||||
};
|
||||
|
||||
struct unit_test_list {
|
||||
struct unit_test_record *head;
|
||||
struct unit_test_record *last;
|
||||
};
|
||||
|
||||
enum result_enum {
|
||||
PASSED,
|
||||
FAILED,
|
||||
SKIPPED,
|
||||
};
|
||||
|
||||
struct unit_results {
|
||||
struct unit_test_list passing;
|
||||
struct unit_test_list failing;
|
||||
struct unit_test_list skipped;
|
||||
|
||||
int nr_tests;
|
||||
int nr_passing;
|
||||
int nr_skipped;
|
||||
};
|
||||
|
||||
#define for_record_in_test_list(__test_list, __test) \
|
||||
for ((__test) = (__test_list)->head; \
|
||||
(__test) != NULL; \
|
||||
(__test) = (__test)->next)
|
||||
|
||||
int core_add_test_record(struct unit_fw *fw,
|
||||
struct unit_module *mod,
|
||||
struct unit_module_test *test,
|
||||
enum result_enum result);
|
||||
void core_print_test_status(struct unit_fw *fw);
|
||||
|
||||
#endif
|
||||
42
userspace/include/unit/unit-requirement-ids.h
Normal file
42
userspace/include/unit/unit-requirement-ids.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_UNIT_REQUIREMENT_IDS_H__
|
||||
#define __UNIT_UNIT_REQUIREMENT_IDS_H__
|
||||
|
||||
/*
|
||||
* Unit requirement test specification unique IDs.
|
||||
*/
|
||||
#define PD_CACHE_REQ1_UID "6439202"
|
||||
#define PD_CACHE_REQ2_UID "6898078"
|
||||
#define PD_CACHE_REQ3_UID "6957786"
|
||||
#define PD_CACHE_REQ4_UID "6962424"
|
||||
#define PD_CACHE_REQ5_UID "6963067"
|
||||
#define PD_CACHE_REQ6_UID "6962548"
|
||||
#define PD_CACHE_REQ7_UID "7138651"
|
||||
#define PD_CACHE_REQ8_UID "6962610"
|
||||
|
||||
#define PAGE_TABLE_REQ1_UID "6439094"
|
||||
|
||||
#define VM_REQ1_UID "6434840"
|
||||
|
||||
#endif
|
||||
192
userspace/include/unit/unit.h
Normal file
192
userspace/include/unit/unit.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UNIT_UNIT_H__
|
||||
#define __UNIT_UNIT_H__
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
struct gk20a;
|
||||
|
||||
struct unit_module;
|
||||
typedef int (*module_test_fn)(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
#define UNIT_SUCCESS 0
|
||||
#define UNIT_FAIL -1
|
||||
|
||||
struct unit_module_test {
|
||||
|
||||
/*
|
||||
* Function to call to execute the test.
|
||||
*/
|
||||
module_test_fn fn;
|
||||
|
||||
/*
|
||||
* Name of the test function. It will be used to match the test
|
||||
* results with its SWUTS.
|
||||
*/
|
||||
const char *fn_name;
|
||||
|
||||
/*
|
||||
* Name of the test. It can be used to describe a subcase when the
|
||||
* same test function is used several times.
|
||||
*/
|
||||
const char *case_name;
|
||||
|
||||
/*
|
||||
* Minimum test plan level (L0, L1) to execute the test.
|
||||
*/
|
||||
unsigned int test_lvl;
|
||||
|
||||
/*
|
||||
* A void pointer to arbitrary arguments. Lets the same unit test
|
||||
* function perform multiple tests. This gets passed into the
|
||||
* module_test_fn as @args.
|
||||
*/
|
||||
void *args;
|
||||
|
||||
/*
|
||||
* Linkage to JAMA test specification. An example would be:
|
||||
*
|
||||
* .requirement = "NVGPU-RQCD-68"
|
||||
* .verification_criteria = "C1"
|
||||
*
|
||||
* This would link to C1 verification criteria of the pd_cache
|
||||
* requirement NVGPU-RQCD-68.
|
||||
*
|
||||
* This is an optional field for any given unit test. But a unit
|
||||
* test module must satisfy the necessary VC for all requirements
|
||||
* within that unit.
|
||||
*/
|
||||
struct {
|
||||
/*
|
||||
* Requirement linkage: this should point to the unique ID
|
||||
* of the test specification.
|
||||
*/
|
||||
const char *unique_id;
|
||||
|
||||
/*
|
||||
* The particular verification criteria that this is
|
||||
* satisfying.
|
||||
*/
|
||||
const char *verification_criteria;
|
||||
|
||||
/*
|
||||
* Specific requirement this test provides coverage for.
|
||||
*/
|
||||
const char *requirement;
|
||||
} jama;
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface to the unit test framework module loader. Each unit test module
|
||||
* will have exactly one of these.
|
||||
*/
|
||||
struct unit_module {
|
||||
/*
|
||||
* Name of the module.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/*
|
||||
* NULL terminated list of tests within the module.
|
||||
*/
|
||||
struct unit_module_test *tests;
|
||||
unsigned long nr_tests;
|
||||
|
||||
/*
|
||||
* Run priority. Currently 3 defined:
|
||||
*
|
||||
* UNIT_PRIO_SELF_TEST
|
||||
* UNIT_PRIO_POSIX_TEST
|
||||
* UNIT_PRIO_NVGPU_TEST
|
||||
*
|
||||
* These let us run environment and POSIX API wrapper tests before the
|
||||
* rest of the unit tests run.
|
||||
*/
|
||||
unsigned int prio;
|
||||
|
||||
/*
|
||||
* For the core FW to use. Not for modules!!!
|
||||
*/
|
||||
void *lib_handle;
|
||||
struct unit_fw *fw;
|
||||
|
||||
pthread_t thread;
|
||||
};
|
||||
|
||||
/*
|
||||
* Zero is the higest priority. Increasing the prio value decreases priority to
|
||||
* run.
|
||||
*/
|
||||
#define UNIT_PRIO_SELF_TEST 0U
|
||||
#define UNIT_PRIO_POSIX_TEST 50U
|
||||
#define UNIT_PRIO_NVGPU_TEST 100U
|
||||
|
||||
#define UNIT_MODULE(__name, __tests, __prio) \
|
||||
struct unit_module __unit_module__ = { \
|
||||
.name = #__name, \
|
||||
.tests = __tests, \
|
||||
.nr_tests = (sizeof(__tests) / \
|
||||
sizeof(struct unit_module_test)), \
|
||||
.prio = __prio, \
|
||||
.lib_handle = NULL, \
|
||||
.fw = NULL, \
|
||||
}
|
||||
|
||||
#define UNIT_TEST(__name, __fn, __args, __test_lvl) \
|
||||
{ \
|
||||
.fn_name = #__fn, \
|
||||
.case_name = #__name, \
|
||||
.fn = __fn, \
|
||||
.args = __args, \
|
||||
.test_lvl = __test_lvl, \
|
||||
.jama.requirement = "", \
|
||||
.jama.unique_id = "", \
|
||||
.jama.verification_criteria = "", \
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this for a unit test that satisfies or contributes to satisfying a
|
||||
* verification criteria for a given requirement.
|
||||
*/
|
||||
#define UNIT_TEST_REQ(__req, __uid, __vc, __name, __fn, __args, __test_lvl) \
|
||||
{ \
|
||||
.fn_name = #__fn, \
|
||||
.case_name = #__name, \
|
||||
.fn = __fn, \
|
||||
.args = __args, \
|
||||
.test_lvl = __test_lvl, \
|
||||
.jama.requirement = __req, \
|
||||
.jama.unique_id = __uid, \
|
||||
.jama.verification_criteria = __vc, \
|
||||
}
|
||||
|
||||
#define unit_return_fail(m, msg, ...) \
|
||||
do { \
|
||||
unit_err(m, "%s():%d " msg, \
|
||||
__func__, __LINE__, ##__VA_ARGS__); \
|
||||
return UNIT_FAIL; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
136
userspace/install-unit.sh
Executable file
136
userspace/install-unit.sh
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#
|
||||
# Install the unit test binaries, build by tmake, onto a jetson running
|
||||
# L4T. The only argument is the IP address of the jetson.
|
||||
#
|
||||
|
||||
usage() {
|
||||
echo "Usage:"
|
||||
echo ""
|
||||
echo " $ $1 [-hs] [--help] [--install-sshkey] <jetson-ip>"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Copy to target jetson. Takes a local path and a remote path relative
|
||||
# to ubuntu's $HOME.
|
||||
#
|
||||
# It helps a lot of you set up an authorized key on the target! Otherwise
|
||||
# you may have a lot of typing to do...
|
||||
jcp() {
|
||||
cmd="rsync -qur $1 $target:$2"
|
||||
echo "> $cmd"
|
||||
$cmd
|
||||
}
|
||||
|
||||
# Add our public key to the authorized key list on the target host.
|
||||
install_ssh_key() {
|
||||
ssh-copy-id -f $target
|
||||
return $?
|
||||
}
|
||||
|
||||
# Variables which may be set by CLI arguments.
|
||||
install_sshkey=
|
||||
|
||||
# To start with filter out any non-target arguments. Right now that's only -h
|
||||
# and -s.
|
||||
positionals=()
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
arg="$1"
|
||||
|
||||
case $arg in
|
||||
-h|--help)
|
||||
usage $0
|
||||
exit 1
|
||||
;;
|
||||
-s|--install-sshkey)
|
||||
install_sshkey=yes
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
positionals+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
set -- "${positionals[@]}"
|
||||
|
||||
if [ "x$1" == "x" ]
|
||||
then
|
||||
echo "Missing IP address!"
|
||||
usage $0
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "x$TOP" == "x" ]
|
||||
then
|
||||
echo "\$TOP must be set!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
target="ubuntu@$1"
|
||||
nvgpu_bins=$TOP/out/*/nvidia/kernel/nvgpu
|
||||
|
||||
# Install the ssh key if needed.
|
||||
if [ "$install_sshkey" == "yes" ]
|
||||
then
|
||||
echo "Installing our SSH key"
|
||||
install_ssh_key $target || exit 1
|
||||
fi
|
||||
|
||||
# Building the necessary directory structure. It may not be present
|
||||
# first time this is run.
|
||||
ssh $target mkdir -p nvgpu_unit/units/igpu
|
||||
ssh $target mkdir -p nvgpu_unit/firmware/gv11b
|
||||
ssh $target mkdir -p $TOP/kernel
|
||||
if [ $? != 0 ]; then
|
||||
echo
|
||||
echo "!! Unable to make $TOP on the target jetson! This directory needs"
|
||||
echo "!! to be present and writable by this script in order for coverage"
|
||||
echo "!! tracking to work."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# And copy...
|
||||
jcp $nvgpu_bins/userspace-l4t_64/nvgpu_unit nvgpu_unit/nvgpu_unit
|
||||
jcp $nvgpu_bins/userspace-l4t_64/libnvgpu_unit-lib.so nvgpu_unit/libnvgpu-unit.so
|
||||
jcp $nvgpu_bins/libs/igpu-l4t_64/libnvgpu-drv-igpu.so nvgpu_unit/libnvgpu-drv-igpu.so
|
||||
jcp $TOP/kernel/nvgpu/userspace/unit.sh nvgpu_unit/unit.sh
|
||||
jcp $TOP/kernel/nvgpu/userspace/gcov.sh nvgpu_unit/gcov.sh
|
||||
jcp $TOP/kernel/nvgpu/userspace/testlist.py nvgpu_unit/testlist.py
|
||||
|
||||
find $nvgpu_bins/userspace/units -name "*.so" -not -path "*unit.so" \
|
||||
-not -path "*drv.so" -exec du -b {} \; | sort -n | while read size unit_so ; do
|
||||
jcp $unit_so nvgpu_unit/units/igpu
|
||||
done
|
||||
|
||||
# Set up the necessary coverage files. Basically what we do is recreate just
|
||||
# enough of the source/build output here on the local machine over on the
|
||||
# target jetson. This means you may
|
||||
jcp $nvgpu_bins nvgpu_unit
|
||||
jcp $TOP/kernel/nvgpu $TOP/kernel
|
||||
if [ -d TOP/kernel/nvgpu-next ]; then
|
||||
jcp $TOP/kernel/nvgpu-next $TOP/kernel
|
||||
fi
|
||||
26
userspace/libnvgpu-unit.export
Normal file
26
userspace/libnvgpu-unit.export
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__core_print_stdout
|
||||
__core_print_stderr
|
||||
__unit_info_color
|
||||
verbose_lvl
|
||||
34
userspace/nvgpu_submit_unit.sh
Executable file
34
userspace/nvgpu_submit_unit.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#
|
||||
# Execute the unit test. Args to this script are passed on to the unit test
|
||||
# core. This just serves to set the LD_LIBRARY_PATH environment variable such
|
||||
# that unit tests are found and nvgpu-drv-igpu is found.
|
||||
#
|
||||
|
||||
this_script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
|
||||
pushd $this_script_dir/nvgpu_unit
|
||||
./unit.sh $*
|
||||
rc=$?
|
||||
popd
|
||||
exit $rc
|
||||
1072
userspace/required_tests.ini
Normal file
1072
userspace/required_tests.ini
Normal file
File diff suppressed because it is too large
Load Diff
201
userspace/src/args.c
Normal file
201
userspace/src/args.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unit/core.h>
|
||||
#include <unit/args.h>
|
||||
#include <unit/io.h>
|
||||
|
||||
static struct option core_opts[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "no-color", 0, NULL, 'C' },
|
||||
{ "nvtest", 0, NULL, 'n' },
|
||||
{ "is-qnx", 0, NULL, 'Q' },
|
||||
{ "unit-load-path", 1, NULL, 'L' },
|
||||
{ "driver-load-path", 1, NULL, 'K' },
|
||||
{ "num-threads", 1, NULL, 'j' },
|
||||
{ "test-level", 1, NULL, 't' },
|
||||
{ "debug", 0, NULL, 'd' },
|
||||
{ "required", 0, NULL, 'r' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
static const char *core_opts_str = "hvqCnQL:K:j:t:dr:";
|
||||
|
||||
void core_print_help(struct unit_fw *fw)
|
||||
{
|
||||
const char **line, *help_msg[] = {
|
||||
"NvGpu Unit Testing FW. Basic usage\n",
|
||||
"\n",
|
||||
" $ nvgpu_unit [options] <unit>\n",
|
||||
"\n",
|
||||
"Basic usage consists of one or more options and a particular unit test to\n",
|
||||
"execute.\n",
|
||||
"\n",
|
||||
"Available options are as follows:\n",
|
||||
"\n",
|
||||
" -h, --help Print this help message and exit.\n",
|
||||
" -v, --verbose Increment the verbosity level. Can be specified\n",
|
||||
" multiple times.\n",
|
||||
" -q, --quiet Set the verbose level back to 0.\n",
|
||||
" -C, --no-color Disable color printing; for example, if writing\n",
|
||||
" output to a file the color escape sequences will\n",
|
||||
" corrupt that file.\n",
|
||||
" -n, --nvtest Enable nvtest-formatted output results\n",
|
||||
" -Q, --is-qnx QNX specific tests\n",
|
||||
" -L, --unit-load-path <PATH>\n",
|
||||
" Path to where the unit test libraries reside.\n",
|
||||
" -K, --driver-load-path <PATH>\n",
|
||||
" Path to driver library.\n",
|
||||
" -j, --num-threads <COUNT>\n",
|
||||
" Number of threads to use while running all tests.\n",
|
||||
" -t, --test-level <LEVEL>\n",
|
||||
" Test plan level. 0=L0, 1=L1. default: 1\n",
|
||||
" -d, --debug Disable signal handling to facilitate debug of",
|
||||
" crashes.\n",
|
||||
" -r, --required <FILE> Path to a file with a list of required tests to\n"
|
||||
" check if all were executed.\n",
|
||||
"\n",
|
||||
"Note: mandatory arguments to long arguments are mandatory for short\n",
|
||||
"arguments as well.\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
line = help_msg;
|
||||
while (*line != NULL) {
|
||||
core_msg(fw, "%s", *line);
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_arg_defaults(struct unit_fw_args *args)
|
||||
{
|
||||
args->driver_load_path = DEFAULT_ARG_DRIVER_LOAD_PATH;
|
||||
args->unit_load_path = DEFAULT_ARG_UNIT_LOAD_PATH;
|
||||
args->thread_count = 1;
|
||||
args->test_lvl = TEST_PLAN_MAX;
|
||||
args->required_tests_file = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse command line arguments.
|
||||
*/
|
||||
int core_parse_args(struct unit_fw *fw, int argc, char **argv)
|
||||
{
|
||||
int c, opt_index;
|
||||
struct unit_fw_args *args;
|
||||
|
||||
args = malloc(sizeof(*args));
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
set_arg_defaults(args);
|
||||
|
||||
args->binary_name = strrchr(argv[0], '/');
|
||||
if (args->binary_name == NULL) {
|
||||
/* no slash, so use the whole name */
|
||||
args->binary_name = argv[0];
|
||||
} else {
|
||||
/* move past the slash */
|
||||
args->binary_name++;
|
||||
}
|
||||
|
||||
fw->args = args;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv,
|
||||
core_opts_str, core_opts, &opt_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
args->help = true;
|
||||
break;
|
||||
case 'v':
|
||||
args->verbose_lvl += 1;
|
||||
break;
|
||||
case 'q':
|
||||
args->verbose_lvl = 0;
|
||||
break;
|
||||
case 'C':
|
||||
args->no_color = true;
|
||||
break;
|
||||
case 'n':
|
||||
args->nvtest = true;
|
||||
break;
|
||||
case 'L':
|
||||
args->unit_load_path = optarg;
|
||||
break;
|
||||
case 'K':
|
||||
args->driver_load_path = optarg;
|
||||
break;
|
||||
case 'j':
|
||||
args->thread_count = strtol(optarg, NULL, 10);
|
||||
if (args->thread_count == 0) {
|
||||
core_err(fw, "Invalid number of threads\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'Q':
|
||||
args->is_qnx = true;
|
||||
break;
|
||||
case 't':
|
||||
args->test_lvl = strtol(optarg, NULL, 10);
|
||||
if (args->test_lvl > TEST_PLAN_MAX) {
|
||||
core_err(fw, "Invalid test plan level\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
args->debug = true;
|
||||
break;
|
||||
case 'r':
|
||||
args->required_tests_file = optarg;
|
||||
break;
|
||||
case '?':
|
||||
args->help = true;
|
||||
return -1;
|
||||
default:
|
||||
core_err(fw, "bug?!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is an extra argument after the command-line options, then
|
||||
* it is a unit test name that need to be specifically run.
|
||||
*/
|
||||
if (optind < argc) {
|
||||
args->unit_to_run = argv[optind];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
275
userspace/src/exec.c
Normal file
275
userspace/src/exec.c
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <unit/io.h>
|
||||
#include <unit/core.h>
|
||||
#include <unit/args.h>
|
||||
#include <unit/unit.h>
|
||||
#include <unit/module.h>
|
||||
#include <unit/results.h>
|
||||
|
||||
#include <nvgpu/posix/probe.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
/*
|
||||
* Sempaphore to limit the number of threads
|
||||
*/
|
||||
sem_t unit_thread_semaphore;
|
||||
|
||||
/*
|
||||
* C11 thread local storage, used to access test context when a signal is
|
||||
* received (ex: SIGSEGV) in a thread.
|
||||
*/
|
||||
_Thread_local struct unit_module *thread_local_module;
|
||||
_Thread_local struct unit_module_test *thread_local_test;
|
||||
|
||||
/*
|
||||
* Execute a module and all its subtests. This function builds a gk20a for the
|
||||
* test to use by executing nvgpu_posix_probe() and nvgpu_posix_cleanup();
|
||||
*/
|
||||
static void *core_exec_module(void *module_param)
|
||||
{
|
||||
unsigned int i;
|
||||
struct unit_module *module = (struct unit_module *) module_param;
|
||||
struct gk20a *g;
|
||||
struct nvgpu_posix_fault_inj_container *fi_container = NULL;
|
||||
clock_t begin;
|
||||
double time_spent;
|
||||
|
||||
/*
|
||||
* Setup fault injection first so that faults can be injected in
|
||||
* nvgpu_posix_probe().
|
||||
*/
|
||||
fi_container = (struct nvgpu_posix_fault_inj_container *)
|
||||
malloc(sizeof(struct nvgpu_posix_fault_inj_container));
|
||||
if (fi_container == NULL) {
|
||||
core_msg_color(module->fw, C_RED,
|
||||
" failed to allocate fault inj: Module %s\n",
|
||||
module->name);
|
||||
goto thread_exit;
|
||||
}
|
||||
memset(fi_container, 0, sizeof(struct nvgpu_posix_fault_inj_container));
|
||||
module->fw->nvgpu.nvgpu_posix_init_fault_injection(fi_container);
|
||||
if (module->fw->nvgpu.nvgpu_posix_init_fault_injection_qnx != NULL) {
|
||||
module->fw->nvgpu.nvgpu_posix_init_fault_injection_qnx(fi_container);
|
||||
}
|
||||
|
||||
g = module->fw->nvgpu.nvgpu_posix_probe();
|
||||
|
||||
if (!g) {
|
||||
core_msg_color(module->fw, C_RED,
|
||||
" nvgpu_posix_probe failed: Module %s\n",
|
||||
module->name);
|
||||
goto thread_exit;
|
||||
}
|
||||
|
||||
core_vbs(module->fw, 1, "Execing module: %s\n", module->name);
|
||||
begin = clock();
|
||||
|
||||
thread_local_module = module;
|
||||
|
||||
/*
|
||||
* Execute each test within the module. No reinit is done between tests.
|
||||
* Thats up to the module itself to handle. Any setup/teardown between
|
||||
* unit tests must be handled within the module.
|
||||
*/
|
||||
for (i = 0; i < module->nr_tests; i++) {
|
||||
struct unit_module_test *t = module->tests + i;
|
||||
int test_status;
|
||||
thread_local_test = t;
|
||||
|
||||
if (t->test_lvl > module->fw->args->test_lvl) {
|
||||
core_add_test_record(module->fw, module, t, SKIPPED);
|
||||
core_vbs(module->fw, 1, "Skipping L%d test %s.%s\n",
|
||||
t->test_lvl, module->name, t->fn_name);
|
||||
continue;
|
||||
}
|
||||
core_msg(module->fw, "Running %s.%s(%s)\n", module->name,
|
||||
t->fn_name, t->case_name);
|
||||
|
||||
test_status = t->fn(module, g, t->args);
|
||||
|
||||
if (test_status != UNIT_SUCCESS)
|
||||
core_msg_color(module->fw, C_RED,
|
||||
" Unit error! Test %s.%s(%s) FAILED!\n",
|
||||
module->name, t->fn_name, t->case_name);
|
||||
|
||||
core_add_test_record(module->fw, module, t,
|
||||
test_status == UNIT_SUCCESS ? PASSED : FAILED);
|
||||
}
|
||||
|
||||
module->fw->nvgpu.nvgpu_posix_cleanup(g);
|
||||
|
||||
time_spent = (double)(clock() - begin) / CLOCKS_PER_SEC;
|
||||
core_vbs(module->fw, 1, "Module completed: %s (execution time: %f)\n",
|
||||
module->name, time_spent);
|
||||
thread_exit:
|
||||
if (fi_container != NULL) {
|
||||
free(fi_container);
|
||||
}
|
||||
sem_post(&unit_thread_semaphore);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go over all the modules and run them one by one.
|
||||
*/
|
||||
static void run_modules(struct unit_fw *fw)
|
||||
{
|
||||
struct unit_module **modules;
|
||||
|
||||
for (modules = fw->modules; *modules != NULL; modules++) {
|
||||
if (fw->args->thread_count == 1) {
|
||||
core_exec_module(*modules);
|
||||
} else {
|
||||
sem_wait(&unit_thread_semaphore);
|
||||
pthread_create(&((*modules)->thread), NULL,
|
||||
core_exec_module, (void *) *modules);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* According to POSIX, "Signals which are generated by some action attributable
|
||||
* to a particular thread, such as a hardware fault, shall be generated for the
|
||||
* thread that caused the signal to be generated."
|
||||
* This custom signal handler will be run from within the thread that caused the
|
||||
* exception. Thanks to the context being saved in local thread storage, it is
|
||||
* then trivial to report which test case failed, and then terminate the thread.
|
||||
*/
|
||||
static void thread_error_handler(int sig, siginfo_t *siginfo, void *context)
|
||||
{
|
||||
core_msg_color(thread_local_module->fw, C_RED,
|
||||
" Signal %d in Test: %s.%s(%s)!\n", sig,
|
||||
thread_local_module->name, thread_local_test->fn_name,
|
||||
thread_local_test->case_name);
|
||||
core_add_test_record(thread_local_module->fw, thread_local_module,
|
||||
thread_local_test, FAILED);
|
||||
sem_post(&unit_thread_semaphore);
|
||||
|
||||
/*
|
||||
* If single threaded, the signal will cause the process to end, so
|
||||
* exit gracefully while printing test results.
|
||||
*/
|
||||
if (thread_local_module->fw->args->thread_count == 1) {
|
||||
core_print_test_status(thread_local_module->fw);
|
||||
exit(-1);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Install a custom signal handler for several signals to be used when running
|
||||
* in multithreaded environment.
|
||||
*/
|
||||
static int install_thread_error_handler(void)
|
||||
{
|
||||
struct sigaction action;
|
||||
int err;
|
||||
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_sigaction = &thread_error_handler;
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
|
||||
/* SIGSEGV: Invalid memory reference */
|
||||
err = sigaction(SIGSEGV, &action, NULL);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
/* SIGILL: Illegal Instruction */
|
||||
err = sigaction(SIGILL, &action, NULL);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
/* SIGFPE: Floating-point exception */
|
||||
err = sigaction(SIGFPE, &action, NULL);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
/* SIGBUS: Bus error */
|
||||
err = sigaction(SIGBUS, &action, NULL);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
/* SIGSYS: Bad system call */
|
||||
err = sigaction(SIGSYS, &action, NULL);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute all modules loaded by the unit test framework.
|
||||
*/
|
||||
int core_exec(struct unit_fw *fw)
|
||||
{
|
||||
struct unit_module **modules;
|
||||
int err = 0;
|
||||
|
||||
if (args(fw)->nvtest) {
|
||||
/* special prints for NVTEST fw in GVS */
|
||||
printf("[start: %s]\n", args(fw)->binary_name);
|
||||
}
|
||||
core_vbs(fw, 1, "Using %d threads\n", fw->args->thread_count);
|
||||
sem_init(&unit_thread_semaphore, 0, fw->args->thread_count);
|
||||
|
||||
/*
|
||||
* By default, use a custom signal hanlder to catch faults such as
|
||||
* SIGSEGV. This can be disabled with the -d argument to make it
|
||||
* easier to investigate with a debugger.
|
||||
*/
|
||||
if (!fw->args->debug) {
|
||||
err = install_thread_error_handler();
|
||||
if (err != 0) {
|
||||
core_msg_color(fw, C_RED,
|
||||
" Failed to install signal handler!\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
run_modules(fw);
|
||||
|
||||
if (fw->args->thread_count > 1) {
|
||||
for (modules = fw->modules; *modules != NULL; modules++) {
|
||||
pthread_join((*modules)->thread, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (args(fw)->nvtest) {
|
||||
/* special prints for NVTEST fw in GVS */
|
||||
printf("[%s: %s]\n",
|
||||
((fw->results->nr_tests - fw->results->nr_passing -
|
||||
fw->results->nr_skipped) == 0) ?
|
||||
"pass" : "fail",
|
||||
args(fw)->binary_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
110
userspace/src/io.c
Normal file
110
userspace/src/io.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unit/io.h>
|
||||
#include <unit/args.h>
|
||||
#include <unit/core.h>
|
||||
#include <unit/unit.h>
|
||||
|
||||
#define MAX_LOG_LINE_LENGTH 4096
|
||||
|
||||
static void __core_print_file(struct unit_fw *fw, FILE *filp,
|
||||
const char *prefix, const char *msg,
|
||||
const char *color)
|
||||
{
|
||||
const char *reset = C_RESET;
|
||||
|
||||
if (color == NULL || args(fw)->no_color) {
|
||||
color = "";
|
||||
reset = "";
|
||||
}
|
||||
|
||||
fprintf(filp, "[%s%s%s] %s%s%s",
|
||||
color, prefix, reset,
|
||||
color, msg, reset);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
void __core_print_stdout(struct unit_fw *fw, const char *color,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[MAX_LOG_LINE_LENGTH];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
buf[MAX_LOG_LINE_LENGTH - 1] = 0;
|
||||
|
||||
__core_print_file(fw, stdout, "C", buf, color);
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[MAX_LOG_LINE_LENGTH];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
buf[MAX_LOG_LINE_LENGTH - 1] = 0;
|
||||
|
||||
__core_print_file(fw, stdout, "E", buf, C_RED);
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
void __unit_info_color(struct unit_module *unit, const char *color,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[MAX_LOG_LINE_LENGTH];
|
||||
char *msg_start;
|
||||
int written;
|
||||
|
||||
/*
|
||||
* Default color for module prints is blue. Users can still turn this
|
||||
* off with '-C'.
|
||||
*/
|
||||
if (color == NULL)
|
||||
color = C_BLUE;
|
||||
|
||||
/*
|
||||
* First prepend the unit name to the print.
|
||||
*/
|
||||
written = snprintf(buf, MAX_LOG_LINE_LENGTH, " [%s] ", unit->name);
|
||||
|
||||
msg_start = buf + written;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(msg_start, MAX_LOG_LINE_LENGTH - written, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
__core_print_file(unit->fw, stdout, "T", buf, color);
|
||||
}
|
||||
221
userspace/src/module.c
Normal file
221
userspace/src/module.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unit/core.h>
|
||||
#include <unit/io.h>
|
||||
#include <unit/args.h>
|
||||
#include <unit/unit.h>
|
||||
#include <unit/module.h>
|
||||
|
||||
static int check_module(struct unit_fw *fw, struct unit_module *mod)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Make sure this module has reasonable data.
|
||||
*/
|
||||
if (mod->name == NULL) {
|
||||
core_err(fw, "Unnamed module!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mod->tests == NULL || mod->nr_tests == 0) {
|
||||
core_err(fw, "%s: Empty module!\n", mod->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < mod->nr_tests; i++) {
|
||||
struct unit_module_test *test = &mod->tests[i];
|
||||
|
||||
if (test->fn_name == NULL) {
|
||||
core_err(fw, "%s: Unnamed test\n", mod->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (test->fn == NULL) {
|
||||
core_err(fw, "%s: Test %s missing function\n",
|
||||
mod->name, test->fn_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct unit_module *load_one_module(struct unit_fw *fw,
|
||||
struct dirent *dent)
|
||||
{
|
||||
void *lib_handle;
|
||||
struct unit_module *mod;
|
||||
|
||||
core_vbs(fw, 1, "Loading: %s\n", dent->d_name);
|
||||
|
||||
if (fw->args->unit_to_run != NULL) {
|
||||
if (strstr(dent->d_name, fw->args->unit_to_run) == NULL) {
|
||||
core_vbs(fw, 1, " Skipping unit (not *%s*)\n",
|
||||
fw->args->unit_to_run);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lib_handle = dlopen(dent->d_name, RTLD_NOW);
|
||||
if (lib_handle == NULL) {
|
||||
core_err(fw, "Failed to load %s: %s\n",
|
||||
dent->d_name, dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mod = dlsym(lib_handle, "__unit_module__");
|
||||
if (mod == NULL) {
|
||||
core_vbs(fw, 1,
|
||||
"Failed to resolve __unit_module__ in %s: %s\n",
|
||||
dent->d_name, dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mod->lib_handle = lib_handle;
|
||||
mod->fw = fw;
|
||||
|
||||
core_vbs(fw, 1, " '%s' contains %lu tests\n", mod->name, mod->nr_tests);
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
static int cmp_module_prio(const void *__mod_a, const void *__mod_b)
|
||||
{
|
||||
const struct unit_module * const *mod_a = __mod_a;
|
||||
const struct unit_module * const *mod_b = __mod_b;
|
||||
|
||||
return (*mod_a)->prio > (*mod_b)->prio;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort the module list according to prio.
|
||||
*/
|
||||
static void sort_modules_by_prio(struct unit_module **modules, int nr)
|
||||
{
|
||||
qsort(modules, (size_t)nr, sizeof(struct unit_module *),
|
||||
cmp_module_prio);
|
||||
}
|
||||
|
||||
static bool is_shared_obj_filename(char *name)
|
||||
{
|
||||
size_t len = strlen(name);
|
||||
|
||||
if ((len > 3) && (strcmp(&name[len-3], ".so") == 0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Load all the modules we can from the module load path. Return the list of
|
||||
* loaded module as an array of pointers to modules. The returned list of
|
||||
* modules is NULL terminated.
|
||||
*/
|
||||
struct unit_module **core_load_modules(struct unit_fw *fw)
|
||||
{
|
||||
int nr_modules = 0, i;
|
||||
DIR *load_dir;
|
||||
struct dirent *ent;
|
||||
const char *load_path = args(fw)->unit_load_path;
|
||||
struct unit_module **modules, *mod;
|
||||
|
||||
core_vbs(fw, 1, "Loading modules from %s\n", load_path);
|
||||
|
||||
/*
|
||||
* Open and count the number of files in the dir.
|
||||
*/
|
||||
load_dir = opendir(load_path);
|
||||
if (!load_dir) {
|
||||
core_err(fw, "%s: Unable to open dir (%s)\n",
|
||||
load_path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ent = readdir(load_dir);
|
||||
while (ent != NULL) {
|
||||
if (is_shared_obj_filename(ent->d_name)) {
|
||||
nr_modules += 1;
|
||||
} else {
|
||||
core_vbs(fw, 1,
|
||||
"Skipping load of file %s (not a .so)\n",
|
||||
ent->d_name);
|
||||
}
|
||||
ent = readdir(load_dir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate necessary space for storing pointers to the modules and
|
||||
* load the modules. +1 for the last NULL entry.
|
||||
*/
|
||||
modules = malloc(sizeof(*modules) * (nr_modules + 1));
|
||||
if (!modules) {
|
||||
core_err(fw, "Out of mem! (huh?)\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
rewinddir(load_dir);
|
||||
i = 0;
|
||||
while ((ent = readdir(load_dir)) != NULL) {
|
||||
if (strcmp(".", ent->d_name) == 0 ||
|
||||
strcmp("..", ent->d_name) == 0 ||
|
||||
!is_shared_obj_filename(ent->d_name))
|
||||
continue;
|
||||
|
||||
mod = load_one_module(fw, ent);
|
||||
if (mod == NULL)
|
||||
continue;
|
||||
|
||||
if (check_module(fw, mod) != 0)
|
||||
continue;
|
||||
|
||||
modules[i] = mod;
|
||||
i++;
|
||||
}
|
||||
|
||||
modules[i] = NULL;
|
||||
|
||||
sort_modules_by_prio(modules, i);
|
||||
|
||||
closedir(load_dir);
|
||||
return modules;
|
||||
|
||||
err:
|
||||
closedir(load_dir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the current verbosity level */
|
||||
int verbose_lvl(struct unit_module *module)
|
||||
{
|
||||
return module->fw->args->verbose_lvl;
|
||||
}
|
||||
115
userspace/src/nvgpu.c
Normal file
115
userspace/src/nvgpu.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unit/io.h>
|
||||
#include <unit/core.h>
|
||||
|
||||
/*
|
||||
* Load driver library. This is done with dlopen() since this will make
|
||||
* resolving addresses into symbols easier in the future.
|
||||
*
|
||||
* Also, this makes people think carefully about what functions to call in
|
||||
* nvgpu-drv-igpu from the unit test FW. The interaction should really be limited
|
||||
* and doing explicit name lookups is a good way to prevent too much coupling.
|
||||
*/
|
||||
int core_load_nvgpu(struct unit_fw *fw)
|
||||
{
|
||||
const char *msg;
|
||||
int flag = RTLD_NOW;
|
||||
const char *load_path = args(fw)->driver_load_path;
|
||||
|
||||
if (fw->args->is_qnx == 0) {
|
||||
/*
|
||||
* Specify a GLOBAL binding so that subsequently loaded
|
||||
* unit tests see the nvgpu-drv-igpu library. They will of course
|
||||
* need it (and will access it directly). I.e they will link
|
||||
* against nvgpu-drv-igpu and this should satisfy that linkage.
|
||||
*/
|
||||
flag |= RTLD_GLOBAL;
|
||||
}
|
||||
|
||||
/* TODO: WAR: remove this dependency of libnvgpu-drv-igpu.so for qnx unit
|
||||
* test, refer NVGPU-1935 for more detail */
|
||||
fw->nvgpu_so = dlopen(load_path, flag);
|
||||
|
||||
if (fw->nvgpu_so == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to load %s: %s\n", load_path, msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We directly check the value of the returned symbol for these
|
||||
* functions against NULL because if it is NULL then something is
|
||||
* terribly wrong.
|
||||
*/
|
||||
|
||||
fw->nvgpu.nvgpu_posix_probe = dlsym(fw->nvgpu_so,
|
||||
"nvgpu_posix_probe");
|
||||
if (fw->nvgpu.nvgpu_posix_probe == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to resolve nvgpu_posix_probe: %s\n", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fw->nvgpu.nvgpu_posix_cleanup = dlsym(fw->nvgpu_so,
|
||||
"nvgpu_posix_cleanup");
|
||||
if (fw->nvgpu.nvgpu_posix_cleanup == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to resolve nvgpu_posix_cleanup: %s\n", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fw->nvgpu.nvgpu_posix_init_fault_injection = dlsym(fw->nvgpu_so,
|
||||
"nvgpu_posix_init_fault_injection");
|
||||
if (fw->nvgpu.nvgpu_posix_init_fault_injection == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to resolve nvgpu_posix_init_fault_injection: %s\n",
|
||||
msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fw->args->is_qnx != 0) {
|
||||
fw->nvgpu_qnx_ut = dlopen("libnvgpu_ut_igpu.so", flag);
|
||||
if (fw->nvgpu_qnx_ut == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to load nvgpu_ut_igpu: %s\n", msg);
|
||||
return -1;
|
||||
}
|
||||
fw->nvgpu.nvgpu_posix_init_fault_injection_qnx =
|
||||
dlsym(fw->nvgpu_qnx_ut,
|
||||
"nvgpu_posix_init_fault_injection");
|
||||
if (fw->nvgpu.nvgpu_posix_init_fault_injection_qnx == NULL) {
|
||||
msg = dlerror();
|
||||
core_err(fw, "Failed to resolve nvgpu_posix_init_fault_injection: %s\n",
|
||||
msg);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fw->nvgpu.nvgpu_posix_init_fault_injection_qnx = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
333
userspace/src/required_tests.c
Normal file
333
userspace/src/required_tests.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unit/io.h>
|
||||
#include <unit/core.h>
|
||||
#include <unit/unit.h>
|
||||
#include <unit/required_tests.h>
|
||||
#include <unit/results.h>
|
||||
#include <nvgpu/list.h>
|
||||
|
||||
struct test_list_node {
|
||||
char *test_subtest_name;
|
||||
long test_level;
|
||||
struct nvgpu_list_node list;
|
||||
};
|
||||
struct unit_list_node {
|
||||
char *unit_name;
|
||||
struct nvgpu_list_node test_list_head;
|
||||
struct nvgpu_list_node list;
|
||||
};
|
||||
|
||||
static struct nvgpu_list_node unit_list_head;
|
||||
|
||||
static inline struct test_list_node *
|
||||
test_list_node_from_list(struct nvgpu_list_node *node)
|
||||
{
|
||||
return (struct test_list_node *)
|
||||
((uintptr_t)node - offsetof(struct test_list_node, list));
|
||||
};
|
||||
static inline struct unit_list_node *
|
||||
unit_list_node_from_list(struct nvgpu_list_node *node)
|
||||
{
|
||||
return (struct unit_list_node *)
|
||||
((uintptr_t)node - offsetof(struct unit_list_node, list));
|
||||
};
|
||||
|
||||
/*
|
||||
* Add a unit in the list of units. The node will hold the name of the unit and
|
||||
* another list of tests.
|
||||
*/
|
||||
static struct unit_list_node *add_unit(struct nvgpu_list_node *head,
|
||||
const char *unit_name)
|
||||
{
|
||||
struct unit_list_node *node = malloc(sizeof(struct unit_list_node));
|
||||
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->unit_name = malloc(strlen(unit_name)+1);
|
||||
if (node->unit_name == NULL) {
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(node->unit_name, unit_name);
|
||||
nvgpu_init_list_node(&node->test_list_head);
|
||||
nvgpu_list_add(&node->list, head);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* From a unit list node, add a test_subtest string along with its test level.
|
||||
*/
|
||||
static struct test_list_node *add_test_subtest_level(
|
||||
struct unit_list_node *unit, const char *test_subtest_name, long level)
|
||||
{
|
||||
struct test_list_node *node = malloc(sizeof(struct test_list_node));
|
||||
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->test_level = level;
|
||||
node->test_subtest_name = malloc(strlen(test_subtest_name)+1);
|
||||
if (node->test_subtest_name == NULL) {
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(node->test_subtest_name, test_subtest_name);
|
||||
|
||||
nvgpu_list_add(&node->list, &unit->test_list_head);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple helper to sanitize the input and remove un-needed characters.
|
||||
*/
|
||||
static void sanitize(char *dest, const char *src)
|
||||
{
|
||||
char *dest_start = dest;
|
||||
|
||||
if (dest == NULL || src == NULL)
|
||||
return;
|
||||
|
||||
/* Trim leading spaces */
|
||||
while (*src == ' ' || *src == '\t')
|
||||
src++;
|
||||
|
||||
/* Copy the rest of the string */
|
||||
while (*src != '\0') {
|
||||
if (*src == '#') {
|
||||
/* Rest of the line is a comment, discard it */
|
||||
break;
|
||||
}
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = '\0';
|
||||
|
||||
/* Backtrack to remove line returns and trim spaces at the end */
|
||||
while (dest_start <= dest) {
|
||||
if ((*dest == '\0') || (*dest == '\r') || (*dest == '\n')
|
||||
|| (*dest == ' ')) {
|
||||
*dest = '\0';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
dest--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse a sting looking for a long number, along with error handling. */
|
||||
static bool parse_long(const char *str, long *val)
|
||||
{
|
||||
char *tmp;
|
||||
bool result = true;
|
||||
errno = 0;
|
||||
*val = strtol(str, &tmp, 10);
|
||||
|
||||
if (tmp == str || *tmp != '\0' ||
|
||||
((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the INI file that contains the list of required tests. This manages a
|
||||
* list of units, and each unit node has a list of test cases.
|
||||
*/
|
||||
int parse_req_file(struct unit_fw *fw, const char *ini_file)
|
||||
{
|
||||
char rawline[MAX_LINE_SIZE];
|
||||
char line[MAX_LINE_SIZE];
|
||||
char tmp[MAX_LINE_SIZE];
|
||||
char *open_bracket, *close_bracket, *equal;
|
||||
long value, len;
|
||||
struct unit_list_node *current_unit = NULL;
|
||||
FILE *file = fopen(ini_file, "r");
|
||||
|
||||
if (file == NULL) {
|
||||
perror("Error reading INI file: ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nvgpu_init_list_node(&unit_list_head);
|
||||
|
||||
while (fgets(rawline, sizeof(rawline), file)) {
|
||||
line[0] = '\0';
|
||||
tmp[0] = '\0';
|
||||
sanitize(line, rawline);
|
||||
if (strlen(line) == 0) {
|
||||
continue;
|
||||
}
|
||||
open_bracket = strchr(line, '[');
|
||||
close_bracket = strchr(line, ']');
|
||||
equal = strchr(line, '=');
|
||||
|
||||
if (equal != NULL) {
|
||||
/* This is a key/value pair */
|
||||
if (current_unit == NULL) {
|
||||
continue;
|
||||
}
|
||||
strncpy(tmp, line, (equal-line));
|
||||
tmp[equal-line] = '\0';
|
||||
if (!parse_long(equal+1, &value)) {
|
||||
core_err(fw, "Conversion error:\n%s\n",
|
||||
rawline);
|
||||
return -1;
|
||||
}
|
||||
if (add_test_subtest_level(current_unit, tmp, value)
|
||||
== NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else if ((open_bracket != NULL) && (close_bracket != NULL)) {
|
||||
/* This is a section */
|
||||
if (open_bracket++ > close_bracket) {
|
||||
continue;
|
||||
}
|
||||
len = close_bracket-open_bracket;
|
||||
strncpy(tmp, open_bracket, len);
|
||||
tmp[len] = '\0';
|
||||
current_unit = add_unit(&unit_list_head, tmp);
|
||||
if (current_unit == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
/* Unknown line or syntax error */
|
||||
core_err(fw, "Syntax error parsing:\n%s\n", rawline);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper that takes a test function name and a subcase name, combines them to
|
||||
* be in the same format as the INI file, and compare the result to a given
|
||||
* string. Returns true if it matches.
|
||||
*/
|
||||
static bool cmp_test_name(const char *exec_fn_name, const char* exec_case_name,
|
||||
const char *ini_test_subtest_name)
|
||||
{
|
||||
char exec_test_subtest_name[MAX_LINE_SIZE];
|
||||
|
||||
exec_test_subtest_name[0] = '\0';
|
||||
strcat(exec_test_subtest_name, exec_fn_name);
|
||||
strcat(exec_test_subtest_name, ".");
|
||||
strcat(exec_test_subtest_name, exec_case_name);
|
||||
|
||||
if (strcmp(ini_test_subtest_name, exec_test_subtest_name) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the tests that were executed and compare them to the list of tests
|
||||
* from the INI file. This only check passing tests; if there are failed tests,
|
||||
* the failure will be handled somewhere else, and skipped tests are handled by
|
||||
* the test level in the INI file.
|
||||
* Returns the number of required tests that were not executed.
|
||||
*/
|
||||
int check_executed_tests(struct unit_fw *fw)
|
||||
{
|
||||
struct unit_test_record *rec;
|
||||
struct unit_list_node *unit_node, *found_unit_node = NULL;
|
||||
struct test_list_node *test_node, *found_test_node = NULL;
|
||||
struct unit_test_list *passing_tests = &fw->results->passing;
|
||||
int missing_count = 0;
|
||||
|
||||
for_record_in_test_list(passing_tests, rec) {
|
||||
found_unit_node = NULL;
|
||||
found_test_node = NULL;
|
||||
/* Search for the unit name */
|
||||
nvgpu_list_for_each_entry(unit_node, &unit_list_head,
|
||||
unit_list_node, list) {
|
||||
if (strcmp(unit_node->unit_name, rec->mod->name) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
found_unit_node = unit_node;
|
||||
/* Search for the fn_name.case_name */
|
||||
nvgpu_list_for_each_entry(test_node,
|
||||
&unit_node->test_list_head,
|
||||
test_list_node, list) {
|
||||
if (cmp_test_name(rec->test->fn_name,
|
||||
rec->test->case_name,
|
||||
test_node->test_subtest_name)) {
|
||||
found_test_node = test_node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (found_test_node == NULL) {
|
||||
/* Test should be added to the INI file */
|
||||
core_err(fw,
|
||||
"Test not in required tests: [%s] %s.%s\n",
|
||||
rec->mod->name, rec->test->fn_name,
|
||||
rec->test->case_name);
|
||||
} else {
|
||||
/* Found it, remove it from the list. */
|
||||
nvgpu_list_del(&found_test_node->list);
|
||||
if (nvgpu_list_empty(
|
||||
&found_unit_node->test_list_head)) {
|
||||
/* No more tests, remove the unit itself */
|
||||
nvgpu_list_del(&found_unit_node->list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that all the executed tests were removed from the list, any test
|
||||
* that is leftover is a required test that was not executed.
|
||||
*/
|
||||
nvgpu_list_for_each_entry(unit_node, &unit_list_head, unit_list_node,
|
||||
list) {
|
||||
nvgpu_list_for_each_entry(test_node, &unit_node->test_list_head,
|
||||
test_list_node, list) {
|
||||
if (test_node->test_level <= fw->args->test_lvl) {
|
||||
core_err(fw, "Required test not run: [%s] %s\n",
|
||||
unit_node->unit_name,
|
||||
test_node->test_subtest_name);
|
||||
missing_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return missing_count;
|
||||
}
|
||||
|
||||
201
userspace/src/results.c
Normal file
201
userspace/src/results.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unit/io.h>
|
||||
#include <unit/core.h>
|
||||
#include <unit/unit.h>
|
||||
#include <unit/results.h>
|
||||
|
||||
/*
|
||||
* Mutex to ensure core_add_test_record() is thread safe.
|
||||
*/
|
||||
pthread_mutex_t mutex_results = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int __init_results(struct unit_fw *fw)
|
||||
{
|
||||
struct unit_results *results;
|
||||
|
||||
if (fw->results != NULL)
|
||||
return 0;
|
||||
|
||||
results = malloc(sizeof(*results));
|
||||
if (results == NULL)
|
||||
return -1;
|
||||
|
||||
memset(results, 0, sizeof(*results));
|
||||
|
||||
fw->results = results;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_record(struct unit_test_list *list,
|
||||
struct unit_test_record *tr)
|
||||
{
|
||||
/*
|
||||
* First entry.
|
||||
*/
|
||||
if (list->head == NULL) {
|
||||
list->head = tr;
|
||||
list->last = tr;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add to the end of the list and update the pointer to the last entry
|
||||
* in the list. This gives us O(1) add time.
|
||||
*/
|
||||
list->last->next = tr;
|
||||
list->last = tr;
|
||||
}
|
||||
|
||||
int core_add_test_record(struct unit_fw *fw,
|
||||
struct unit_module *mod,
|
||||
struct unit_module_test *test,
|
||||
enum result_enum result)
|
||||
{
|
||||
struct unit_test_record *tr;
|
||||
int err = 0;
|
||||
|
||||
pthread_mutex_lock(&mutex_results);
|
||||
/*
|
||||
* Does nothing if results are already inited.
|
||||
*/
|
||||
if (__init_results(fw) != 0) {
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tr = malloc(sizeof(*tr));
|
||||
if (tr == NULL) {
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tr->mod = mod;
|
||||
tr->test = test;
|
||||
tr->status = (result == PASSED);
|
||||
tr->next = NULL;
|
||||
|
||||
fw->results->nr_tests += 1;
|
||||
switch (result) {
|
||||
case PASSED:
|
||||
add_record(&fw->results->passing, tr);
|
||||
fw->results->nr_passing += 1;
|
||||
break;
|
||||
case FAILED:
|
||||
add_record(&fw->results->failing, tr);
|
||||
break;
|
||||
case SKIPPED:
|
||||
add_record(&fw->results->skipped, tr);
|
||||
fw->results->nr_skipped += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
pthread_mutex_unlock(&mutex_results);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void dump_test_record(FILE *logfile, struct unit_test_record *rec,
|
||||
bool status, bool first)
|
||||
{
|
||||
first ? fprintf(logfile, "\t{") : fprintf(logfile, ",\n\t{");
|
||||
fprintf(logfile, "\"unit\": \"%s\", ", rec->mod->name);
|
||||
fprintf(logfile, "\"test\": \"%s\", ", rec->test->fn_name);
|
||||
fprintf(logfile, "\"case\": \"%s\", ", rec->test->case_name);
|
||||
fprintf(logfile, "\"status\": %s, ", status ? "true":"false");
|
||||
fprintf(logfile, "\"uid\": \"%s\", ", rec->test->jama.unique_id);
|
||||
fprintf(logfile, "\"vc\": \"%s\", ",
|
||||
rec->test->jama.verification_criteria);
|
||||
fprintf(logfile, "\"req\": \"%s\", ", rec->test->jama.requirement);
|
||||
fprintf(logfile, "\"test_level\": %d", rec->test->test_lvl);
|
||||
fprintf(logfile, "}");
|
||||
}
|
||||
|
||||
static void dump_test_log(struct unit_fw *fw, struct unit_test_list
|
||||
*passing_tests, struct unit_test_list *failing_tests)
|
||||
{
|
||||
struct unit_test_record *rec;
|
||||
int count = 0;
|
||||
FILE *logfile = fopen("results.json", "w+");
|
||||
|
||||
fprintf(logfile, "[\n");
|
||||
for_record_in_test_list(passing_tests, rec) {
|
||||
dump_test_record(logfile, rec, true, count == 0);
|
||||
count++;
|
||||
}
|
||||
for_record_in_test_list(failing_tests, rec) {
|
||||
dump_test_record(logfile, rec, false, count == 0);
|
||||
count++;
|
||||
}
|
||||
fprintf(logfile, "\n]\n");
|
||||
fclose(logfile);
|
||||
}
|
||||
|
||||
void core_print_test_status(struct unit_fw *fw)
|
||||
{
|
||||
struct unit_test_list *failing_tests = &fw->results->failing;
|
||||
struct unit_test_list *skipped_tests = &fw->results->skipped;
|
||||
struct unit_test_record *rec;
|
||||
|
||||
/*
|
||||
* Print stats for the tests.
|
||||
*/
|
||||
core_msg(fw, "\n");
|
||||
core_msg(fw, "Test results:\n");
|
||||
core_msg(fw, "-------------\n");
|
||||
core_msg(fw, "\n");
|
||||
core_msg(fw, " Skipped: %d\n", fw->results->nr_skipped);
|
||||
core_msg(fw, " Passing: %d\n", fw->results->nr_passing);
|
||||
core_msg(fw, " Failing: %d\n",
|
||||
fw->results->nr_tests - fw->results->nr_passing -
|
||||
fw->results->nr_skipped);
|
||||
core_msg(fw, " Total: %d\n", fw->results->nr_tests);
|
||||
core_msg(fw, "\n");
|
||||
core_msg(fw, "Skipped tests:\n");
|
||||
core_msg(fw, "\n");
|
||||
for_record_in_test_list(skipped_tests, rec) {
|
||||
core_msg(fw, " %s.%s(%s)\n",
|
||||
rec->mod->name,
|
||||
rec->test->fn_name,
|
||||
rec->test->case_name);
|
||||
}
|
||||
|
||||
core_msg(fw, "\n");
|
||||
core_msg(fw, "Failing tests:\n");
|
||||
core_msg(fw, "\n");
|
||||
|
||||
for_record_in_test_list(failing_tests, rec) {
|
||||
core_msg(fw, " %s.%s(%s)\n",
|
||||
rec->mod->name,
|
||||
rec->test->fn_name,
|
||||
rec->test->case_name);
|
||||
}
|
||||
|
||||
dump_test_log(fw, &fw->results->passing, &fw->results->failing);
|
||||
}
|
||||
113
userspace/src/unit_main.c
Normal file
113
userspace/src/unit_main.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NvGpu unit testing framework!
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unit/io.h>
|
||||
#include <unit/core.h>
|
||||
#include <unit/args.h>
|
||||
#include <unit/module.h>
|
||||
#include <unit/results.h>
|
||||
#include <unit/required_tests.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct unit_fw *fw;
|
||||
int ret;
|
||||
|
||||
fw = malloc(sizeof(*fw));
|
||||
if (!fw)
|
||||
return 1;
|
||||
|
||||
memset(fw, 0, sizeof(*fw));
|
||||
|
||||
ret = core_parse_args(fw, argc, argv);
|
||||
if (ret) {
|
||||
core_err(fw, "Unable to parse args.\n");
|
||||
core_err(fw, "Exiting!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
core_vbs(fw, 1, "Welcome to the nvgpu unit testing framework!\n");
|
||||
|
||||
if (args(fw)->help) {
|
||||
core_print_help(fw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = core_load_nvgpu(fw);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
fw->modules = core_load_modules(fw);
|
||||
if (fw->modules == NULL)
|
||||
return -1;
|
||||
|
||||
ret = core_exec(fw);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (fw->results == NULL) {
|
||||
core_msg(fw, "No tests were run!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
core_print_test_status(fw);
|
||||
|
||||
if ((fw->results->nr_tests - fw->results->nr_passing -
|
||||
fw->results->nr_skipped) != 0) {
|
||||
/* Some tests failed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fw->args->unit_to_run != NULL) {
|
||||
/*
|
||||
* Just in case (especially when running in automation), return
|
||||
* a failure if only executed a subset of the units
|
||||
*/
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (fw->args->required_tests_file != NULL) {
|
||||
ret = parse_req_file(fw, fw->args->required_tests_file);
|
||||
if (ret != 0) {
|
||||
core_err(fw,
|
||||
"Failed to load the required tests file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = check_executed_tests(fw);
|
||||
if (ret != 0) {
|
||||
core_err(fw,
|
||||
"Found %d required tests that were not run!\n",
|
||||
ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
235
userspace/testlist.py
Executable file
235
userspace/testlist.py
Executable file
@@ -0,0 +1,235 @@
|
||||
#!/usr/bin/python2
|
||||
#
|
||||
# Copyright (c) 2019-2021, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import argparse, os
|
||||
import json, md5
|
||||
|
||||
RESULTS_FILE = 'results.json'
|
||||
HTML_FILE = 'results.html'
|
||||
REQ_FILE = 'required_tests.json'
|
||||
|
||||
HTML_HEAD='''
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Verdana;
|
||||
}
|
||||
.res-table {
|
||||
border: solid 1px #DDD;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0; font-size: 12px;
|
||||
}
|
||||
.res-table thead th {
|
||||
background-color: #76B900;
|
||||
border: solid 1px #DDD;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.res-table tbody td {
|
||||
border: solid 1px #DDD;
|
||||
padding: 10px;
|
||||
}
|
||||
h2 {
|
||||
color: #76B900;
|
||||
text-transfer: uppercase;
|
||||
}
|
||||
a[href*="jamacloud.com/"] {
|
||||
background:url(https://nvidia.jamacloud.com/img/favicon-16x16.png) no-repeat left center;
|
||||
padding-left:19px;
|
||||
}
|
||||
</style>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#uid-toggle").click(function() {
|
||||
$(".invalid-uid").parent().toggle();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<body>
|
||||
<h2>Results</h2>
|
||||
'''
|
||||
|
||||
#Build a dictionary-based structure to easily access tests by unit and name.
|
||||
def build_results_dict(results):
|
||||
test_dict = {}
|
||||
#Iterate through the results and group them by unit name
|
||||
for result in results:
|
||||
unit = result['unit']
|
||||
test = result['case']
|
||||
if unit not in test_dict:
|
||||
test_dict[unit] = {}
|
||||
if test in test_dict[unit]:
|
||||
print("WARNING: %s - %s already exists." % (unit, test))
|
||||
test_dict[unit][test] = result
|
||||
return test_dict
|
||||
|
||||
def regen():
|
||||
output_list = []
|
||||
if not os.path.exists(RESULTS_FILE):
|
||||
print("File 'results.json' not found. Run unit.sh first.")
|
||||
exit(1)
|
||||
with open(RESULTS_FILE) as infile:
|
||||
results = json.loads(infile.read())
|
||||
|
||||
test_dict = build_results_dict(results)
|
||||
|
||||
#Generate the output by alphabetical order
|
||||
test_count = 0
|
||||
for unit, tests in sorted(test_dict.items(), key=lambda kv: kv[0], reverse=False):
|
||||
for test in sorted(tests.items()):
|
||||
entry = {"unit": unit, "test": test[1]['test'], 'case': test[1]['case'], 'test_level': test[1]['test_level']}
|
||||
if test[1]['uid'] != "":
|
||||
entry['uid'] = test[1]['uid']
|
||||
entry['vc'] = test[1]['vc']
|
||||
entry['req'] = test[1]['req']
|
||||
output_list.append(entry)
|
||||
test_count += 1
|
||||
with open(REQ_FILE, "w+") as outfile:
|
||||
json_text = json.dumps(output_list, indent=4).replace(" \n", "\n")
|
||||
outfile.write(json_text+"\n")
|
||||
print("Generated updated version of \"%s\" based on tests in \"%s\"." % (REQ_FILE, RESULTS_FILE))
|
||||
print("Required tests: %d" % test_count)
|
||||
|
||||
def get_RGB(s):
|
||||
hash = md5.md5(s).hexdigest()
|
||||
rgb = '#' + hash[0:2] + hash[2:4] + hash[4:6]
|
||||
return rgb
|
||||
|
||||
def format_html_test(unit, test, status, error, uid, req, vc):
|
||||
if status:
|
||||
status = "green"
|
||||
else:
|
||||
status = "red"
|
||||
color = get_RGB(unit)
|
||||
ret = "<tr><td bgcolor='%s'></td><td>%s</td><td>%s</td><td bgcolor=%s>%s</td>" % (color, unit, test, status, error)
|
||||
jamalink = ""
|
||||
class_name = "invalid-uid"
|
||||
if uid != "":
|
||||
jamalink = "https://nvidia.jamacloud.com/perspective.req#/items/%s?projectId=20460" % uid
|
||||
jamalink = "<a class=\"jama\" href=\"%s\" target=\"_blank\">%s</a>" % (jamalink, uid)
|
||||
class_name = "valid-uid"
|
||||
ret += "<td class='uid %s'>%s</td>\n" % (class_name, jamalink)
|
||||
ret += "<td>%s</td><td>%s</td>\n" % (req, vc)
|
||||
ret += "</tr>\n"
|
||||
return ret
|
||||
|
||||
def check(test_level, html = False):
|
||||
#Check that tests in results.json cover required_tests.json
|
||||
with open(RESULTS_FILE) as results_file:
|
||||
results = json.loads(results_file.read())
|
||||
with open(REQ_FILE) as req_file:
|
||||
reqd_tests = json.loads(req_file.read())
|
||||
|
||||
test_dict = build_results_dict(results)
|
||||
req_dict = build_results_dict(reqd_tests)
|
||||
|
||||
errors = 0
|
||||
test_count = 0
|
||||
log = ""
|
||||
html = ""
|
||||
|
||||
#First make sure that all required tests were run and PASSED.
|
||||
for reqd_test in reqd_tests:
|
||||
unit = reqd_test['unit']
|
||||
test = reqd_test['case']
|
||||
error = ""
|
||||
status = False
|
||||
skipped = False
|
||||
if unit not in test_dict:
|
||||
error = ("ERROR: Required unit %s is not in test results.\n" % unit)
|
||||
log += error
|
||||
errors += 1
|
||||
elif test not in test_dict[unit]:
|
||||
if req_dict[unit][test]['test_level'] <= test_level:
|
||||
error = ("ERROR: Required test %s - %s is not in test results.\n" % (unit, test))
|
||||
log += error
|
||||
errors += 1
|
||||
else:
|
||||
skipped = True
|
||||
elif test_dict[unit][test]['status'] is False:
|
||||
log += ("ERROR: Required test %s - %s FAILED.\n" % (unit, test))
|
||||
error = "FAILED"
|
||||
errors += 1
|
||||
else:
|
||||
status = True
|
||||
error = "PASS"
|
||||
if not skipped:
|
||||
html += format_html_test(unit, test, status, error, reqd_test.get('uid', ''), reqd_test.get('req', ''), reqd_test.get('vc', ''))
|
||||
test_count += 1
|
||||
|
||||
#As a helpful hint, check to see if any tests were run without being in the list of required
|
||||
#tests. This should not cause a failure, but just a warning for the developer to add the
|
||||
#test to the required list.
|
||||
for result in results:
|
||||
unit = result['unit']
|
||||
test = result['case']
|
||||
if unit not in req_dict:
|
||||
log += ("WARNING: Tested unit %s is not in required tests. Use testlist.py --regen\n" % unit)
|
||||
elif test not in req_dict[unit]:
|
||||
log +=("WARNING: Test %s - %s is not in required tests. Use testlist.py --regen\n" % (unit, test))
|
||||
|
||||
if log != "":
|
||||
print(log)
|
||||
|
||||
if html:
|
||||
with open(HTML_FILE, "w+") as outfile:
|
||||
outfile.write(HTML_HEAD)
|
||||
outfile.write("<table class=\"res-table\" width=\"100%\">\n")
|
||||
outfile.write("<thead><tr><th width=20 colspan=2>Unit</th><th>Test</th><th>Result</th>\n")
|
||||
outfile.write("<th>JAMA UID <a href=\"#\" id=\"uid-toggle\">[Toggle]</a></th><th>Requirement</th><th>VC</th></tr></thead>\n")
|
||||
outfile.write("<tbody>\n")
|
||||
outfile.write(html)
|
||||
outfile.write("</tbody></table>\n")
|
||||
outfile.write("</body></html>")
|
||||
print("Wrote %s" % HTML_FILE)
|
||||
|
||||
if errors > 0:
|
||||
return 1
|
||||
else:
|
||||
print("PASS: All %d tests found in result log." % test_count)
|
||||
return 0
|
||||
|
||||
def html(test_level):
|
||||
return check(test_level, html = True)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--regen", help="Regenerate list of expected test cases.", action="store_true")
|
||||
parser.add_argument("--check", help="Make sure all expected test cases were run.", action="store_true")
|
||||
parser.add_argument("--test-level", "-t", help="Test level used for checking results. Default=0", type=int, default=0)
|
||||
parser.add_argument("--html", help="Perform --check and export results in an HTML file.", action="store_true")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.regen:
|
||||
regen()
|
||||
exit(0)
|
||||
if args.check:
|
||||
exit(check(args.test_level))
|
||||
if args.html:
|
||||
exit(html(args.test_level))
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
118
userspace/unit.sh
Executable file
118
userspace/unit.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#
|
||||
# Execute the unit test. Args to this script are passed on to the unit test
|
||||
# core. This just serves to set the LD_LIBRARY_PATH environment variable such
|
||||
# that unit tests are found and nvgpu-drv-igpu is found.
|
||||
#
|
||||
|
||||
options=$(getopt -o t: --long test-level: -- "$@")
|
||||
|
||||
this_script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
|
||||
pushd $this_script_dir
|
||||
|
||||
FIRMWARES=("/gpu-firmware-private/t19x/gr/net/safety/NETD_img.bin"
|
||||
"/gpu-firmware-private/t19x/gr/net/safety/fecs_sig.bin"
|
||||
"/gpu-firmware-private/t19x/gr/net/safety/gpccs_sig.bin"
|
||||
"/gpu-firmware-private/t19x/gr/fecs/safety/fecs.bin"
|
||||
"/gpu-firmware-private/t19x/gr/gpccs/safety/gpccs.bin"
|
||||
"/gpu-firmware-private/t19x/gr/pmu/safety/acr_ucode_prod.bin"
|
||||
"/gpu-firmware-private/t19x/gr/pmu/safety/acr_ucode_dbg.bin")
|
||||
|
||||
FIRMWARE_TARGET_PATH="/lib/firmware/gv11b/"
|
||||
|
||||
CUR_DIR=`pwd`
|
||||
DEST_DIR=${CUR_DIR}/firmware/gv11b/
|
||||
mkdir -p ${DEST_DIR}
|
||||
|
||||
if [ -f nvgpu_unit ]; then
|
||||
if [ -d ${FIRMWARE_TARGET_PATH} ]
|
||||
then
|
||||
cp -rf ${FIRMWARE_TARGET_PATH}/* ${DEST_DIR}
|
||||
else
|
||||
echo "${FIRMWARE_TARGET_PATH} doesn't exist\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# if the executable is in the current directory, we are running on
|
||||
# target, so use that dir structure
|
||||
LD_LIBRARY_PATH=".:units/igpu"
|
||||
cores=$(cat /proc/cpuinfo |grep processor |wc -l)
|
||||
|
||||
# Ignore number of cores for now; it seems that the parallel unit
|
||||
# tests are just too buggy and that they really don't save much
|
||||
# actual computing time.
|
||||
NVGPU_UNIT="./nvgpu_unit --nvtest --unit-load-path units/igpu --no-color \
|
||||
--num-threads 1"
|
||||
|
||||
else
|
||||
# running on host
|
||||
if [ "x$TEGRA_TOP" == "x" ]
|
||||
then
|
||||
echo "\$TEGRA_TOP must be set!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i in "${FIRMWARES[@]}"
|
||||
do
|
||||
if [ -f ${TEGRA_TOP}/${i} ]
|
||||
then
|
||||
cp -f ${TEGRA_TOP}/${i} ${DEST_DIR}
|
||||
else
|
||||
echo "firmware file \"${TEGRA_TOP}/${i}\" doesn't exist\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
LD_LIBRARY_PATH="build:build/units"
|
||||
# On host, must run single-threaded to avoid high VAs
|
||||
NVGPU_UNIT="./build/nvgpu_unit --num-threads 1"
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
echo "$ $NVGPU_UNIT $*"
|
||||
|
||||
$NVGPU_UNIT $*
|
||||
rc=$?
|
||||
if [ $rc -eq "0" ]; then
|
||||
#get the test level, if passed into this script
|
||||
eval set -- $options
|
||||
while true; do
|
||||
case "$1" in
|
||||
-t|--test-level)
|
||||
shift;
|
||||
testlevelparam="-t $1"
|
||||
;;
|
||||
--)
|
||||
shift;
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
fi
|
||||
|
||||
rm -rf ${CUR_DIR}/firmware
|
||||
popd
|
||||
exit $rc
|
||||
45
userspace/units/Makefile.units
Normal file
45
userspace/units/Makefile.units
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- mode: makefile -*-
|
||||
#
|
||||
# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#
|
||||
# Inlcude this in unit test makefiles to get useful rules.
|
||||
#
|
||||
|
||||
LOCAL_HEADERS = (shell ls *.h)
|
||||
|
||||
.PHONY: all clean
|
||||
all: lib$(MODULE).so
|
||||
@true
|
||||
|
||||
#
|
||||
# Inherits from the top level makefile. As such the unit test make files cannot
|
||||
# be invoked by themselves.
|
||||
%.o : %.c # $(LOCAL_HEADERS)
|
||||
$(CC) --coverage $(CFLAGS) -c -o $@ $<
|
||||
|
||||
lib$(MODULE).so: $(OBJS)
|
||||
$(CC) -shared -o $@ $(OBJS) $(LIB_PATHS) -lnvgpu_unit -lgcov
|
||||
@mkdir -p $(UNIT_OUT)/
|
||||
@cp $@ $(UNIT_OUT)/
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.so
|
||||
37
userspace/units/Makefile.units.common.interface.tmk
Normal file
37
userspace/units/Makefile.units.common.interface.tmk
Normal file
@@ -0,0 +1,37 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION
|
||||
NV_INTERFACE_NAME := $(NVGPU_UNIT_NAME)
|
||||
NV_INTERFACE_EXPORTS := $(NV_SOURCE)/kernel/nvgpu/userspace/units/nvgpu_unit.common
|
||||
NV_INTERFACE_PUBLIC_INCLUDES := . include
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
110
userspace/units/Makefile.units.common.tmk
Normal file
110
userspace/units/Makefile.units.common.tmk
Normal file
@@ -0,0 +1,110 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION
|
||||
include $(NV_BUILD_START_COMPONENT)
|
||||
|
||||
NV_COMPONENT_NAME := $(NVGPU_UNIT_NAME)
|
||||
NV_COMPONENT_OWN_INTERFACE_DIR := .
|
||||
|
||||
#For the simple case, if there's only one source file with the same name as the
|
||||
#component, the unit test can let this makefile add it.
|
||||
#But if the unit test has > 1 file, they can define NVGPU_UNIT_SRCS
|
||||
ifdef NVGPU_UNIT_SRCS
|
||||
NV_COMPONENT_SOURCES := \
|
||||
$(NVGPU_UNIT_SRCS)
|
||||
else
|
||||
NV_COMPONENT_SOURCES := \
|
||||
$(NVGPU_UNIT_NAME).c
|
||||
endif
|
||||
|
||||
ifdef NVGPU_UNIT_INCLUDES
|
||||
NV_COMPONENT_INCLUDES := \
|
||||
$(NVGPU_UNIT_INCLUDES)
|
||||
endif
|
||||
NV_COMPONENT_INCLUDES += \
|
||||
$(NV_SOURCE)/kernel/nvgpu/userspace/units/mock-iospace/include \
|
||||
$(NV_SOURCE)/kernel/nvgpu/drivers/gpu/nvgpu/include \
|
||||
$(NV_SOURCE)/kernel/nvgpu/drivers/gpu/nvgpu \
|
||||
$(NV_SOURCE)/kernel/nvgpu-next/drivers/gpu/nvgpu/include \
|
||||
$(NV_SOURCE)/kernel/nvgpu-next/drivers/gpu/nvgpu
|
||||
|
||||
ifdef NVGPU_CFLAGS
|
||||
NV_COMPONENT_CFLAGS := \
|
||||
$(NVGPU_CFLAGS)
|
||||
else
|
||||
NV_COMPONENT_CFLAGS += -D__NVGPU_POSIX__
|
||||
endif
|
||||
NV_COMPONENT_CFLAGS += -D__NVGPU_UNIT_TEST__
|
||||
NV_COMPONENT_CFLAGS += -DNVGPU_UNITTEST_FAULT_INJECTION_ENABLEMENT
|
||||
|
||||
ifneq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1)
|
||||
NVGPU_FORCE_SAFETY_PROFILE := 1
|
||||
NVGPU_FORCE_DEBUG_PROFILE := 1
|
||||
endif
|
||||
|
||||
-include $(NV_SOURCE)/kernel/nvgpu/drivers/gpu/nvgpu/Makefile.shared.configs
|
||||
NV_COMPONENT_CFLAGS += $(NVGPU_COMMON_CFLAGS)
|
||||
|
||||
NV_COMPONENT_NEEDED_INTERFACE_DIRS := \
|
||||
$(NV_SOURCE)/kernel/nvgpu/userspace
|
||||
|
||||
ifdef NVGPU_UNIT_SHARED_LIBRARIES
|
||||
NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += $(NVGPU_UNIT_SHARED_LIBRARIES)
|
||||
endif
|
||||
|
||||
ifdef NVGPU_UNIT_INTERFACE_DIRS
|
||||
NV_COMPONENT_NEEDED_INTERFACE_DIRS += $(NVGPU_UNIT_INTERFACE_DIRS)
|
||||
endif
|
||||
ifdef CONFIG_NVGPU_DGPU
|
||||
NV_COMPONENT_NEEDED_INTERFACE_DIRS += $(NV_SOURCE)/kernel/nvgpu/libs/dgpu
|
||||
else
|
||||
NV_COMPONENT_NEEDED_INTERFACE_DIRS += $(NV_SOURCE)/kernel/nvgpu/libs/igpu
|
||||
endif
|
||||
|
||||
ifdef NVGPU_SYSTEMIMAGE_DIR
|
||||
NV_COMPONENT_SYSTEMIMAGE_DIR := $(NVGPU_SYSTEMIMAGE_DIR)
|
||||
else
|
||||
ifdef CONFIG_NVGPU_DGPU
|
||||
NV_COMPONENT_SYSTEMIMAGE_DIR := $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/nvgpu_unit/units/dgpu
|
||||
else
|
||||
NV_COMPONENT_SYSTEMIMAGE_DIR := $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)/nvgpu_unit/units/igpu
|
||||
endif
|
||||
endif
|
||||
|
||||
systemimage:: $(NV_COMPONENT_SYSTEMIMAGE_DIR)
|
||||
$(NV_COMPONENT_SYSTEMIMAGE_DIR) : $(NV_SYSTEMIMAGE_TEST_EXECUTABLE_DIR)
|
||||
$(MKDIR_P) $@
|
||||
|
||||
include $(NV_BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
38
userspace/units/acr/Makefile
Normal file
38
userspace/units/acr/Makefile
Normal file
@@ -0,0 +1,38 @@
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-acr.o
|
||||
MODULE = nvgpu-acr
|
||||
|
||||
LIB_PATHS += -lfalcon_utf \
|
||||
-lnvgpu-gr
|
||||
|
||||
include ../Makefile.units
|
||||
|
||||
lib$(MODULE).so: falcon_utf \
|
||||
nvgpu-gr
|
||||
|
||||
falcon_utf:
|
||||
$(MAKE) -C ../falcon
|
||||
|
||||
nvgpu-gr:
|
||||
$(MAKE) -C ../gr
|
||||
35
userspace/units/acr/Makefile.interface.tmk
Normal file
35
userspace/units/acr/Makefile.interface.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-acr
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
40
userspace/units/acr/Makefile.tmk
Normal file
40
userspace/units/acr/Makefile.tmk
Normal file
@@ -0,0 +1,40 @@
|
||||
################################## tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-acr
|
||||
NVGPU_UNIT_SRCS=nvgpu-acr.c
|
||||
|
||||
NVGPU_UNIT_INTERFACE_DIRS := \
|
||||
$(NV_COMPONENT_DIR)/../falcon \
|
||||
$(NV_COMPONENT_DIR)/../gr
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
1018
userspace/units/acr/nvgpu-acr.c
Normal file
1018
userspace/units/acr/nvgpu-acr.c
Normal file
File diff suppressed because it is too large
Load Diff
188
userspace/units/acr/nvgpu-acr.h
Normal file
188
userspace/units/acr/nvgpu-acr.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-acr
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for acr
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_acr_init
|
||||
*
|
||||
* Description: The test_acr_init shall test the initialization of
|
||||
* the ACR unit
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_acr_init
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the falcon test environment
|
||||
* - Initialize the ECC support
|
||||
* - Initialize the PMU
|
||||
* - Inject memory allocation fault to test the fail scenario 1
|
||||
* - Give incorrect chip version to test the fail scenario 2
|
||||
* - Give correct chip id and set the register to enable debug mode
|
||||
* to have branch coverage
|
||||
* - Give correct chip id and test the pass scenario
|
||||
* - Uninitialize the PMU support
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_acr_init(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_acr_prepare_ucode_blob
|
||||
*
|
||||
* Description: The test_acr_prepare_ucode_blob shall test the blob creation of
|
||||
* the ACR unit
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: g->acr->prepare_ucode_blob
|
||||
*
|
||||
* Input: None
|
||||
* Steps:
|
||||
* - Initialize the test env and register space needed for the test
|
||||
* - Prepare HW and SW setup needed for the test
|
||||
* - Inject memmory allocation failure to test fai scneario for
|
||||
* g->acr->prepare_ucode_blob(g)
|
||||
* - Give incorrect chip version number to test second fail scenario
|
||||
* - NVGPU_SEC_SECUREGPCCS flag is set to false to get the branch coverage
|
||||
* - NVGPU_SEC_SECUREGPCCS flag is set to true to test the pass scenario
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
int test_acr_prepare_ucode_blob(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
/**
|
||||
* Test specification for: test_acr_is_lsf_lazy_bootstrap
|
||||
*
|
||||
* Description: The test_acr_is_lsf_lazy_bootstrap shall test the
|
||||
* lazy bootstrap of the ACR unit
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_acr_is_lsf_lazy_bootstrap
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the test env and register space needed for the test
|
||||
* - Prepare HW and SW setup needed for the test
|
||||
* - Pass scenario: lsf lazy bootstrap the ACR for following falcon ids:
|
||||
* FALCON_ID_FECS, FALCON_ID_PMU and FALCON_ID_GPCCS
|
||||
* - Pass invalid falcon id to fail the function
|
||||
* - Pass acr as NULL to fail nvgpu_acr_is_lsf_lazy_bootstrap()
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
int test_acr_is_lsf_lazy_bootstrap(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
/**
|
||||
* Test specification for: test_acr_construct_execute
|
||||
*
|
||||
* Description: The test_acr_construct_execute shall test the two main tasks of
|
||||
* the ACR unit:
|
||||
* 1. Blob construct of LS ucode in non-wpr memory
|
||||
* 2. ACR HS ucode load & bootstrap
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_acr_construct_execute
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the test env and register space needed for the test
|
||||
* - Prepare HW and SW setup needed for the test
|
||||
* - Set the falcon_falcon_cpuctl_halt_intr_m bit for the
|
||||
* register falcon_falcon_cpuctl_r
|
||||
* - Inject memory allocation failure in g->acr->prepare_ucode_blob so that
|
||||
* acr_construct_execute() fails
|
||||
* - Cover fail scenario when "is_falcon_supported"
|
||||
* is set to false. This fails nvgpu_acr_bootstrap_hs_acr()
|
||||
* - Set is_falcon_supported to true to test the pass scenario
|
||||
* - Pass g->acr as NULL to create fail scenario.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
int test_acr_construct_execute(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
/**
|
||||
* Test specification for: test_acr_bootstrap_hs_acr
|
||||
*
|
||||
* Description: The test_acr_bootstrap_hs_acr shall test the ACR HS ucode load
|
||||
* & bootstrap functionality of the ACR unit
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_acr_bootstrap_hs_acr, nvgpu_pmu_report_bar0_pri_err_status,
|
||||
* gops_pmu.validate_mem_integrity, gv11b_pmu_validate_mem_integrity,
|
||||
* gops_pmu.is_debug_mode_enabled, gv11b_pmu_is_debug_mode_en,
|
||||
* gops_acr.pmu_clear_bar0_host_err_status,
|
||||
* gv11b_clear_pmu_bar0_host_err_status, gops_pmu.bar0_error_status,
|
||||
* gv11b_pmu_bar0_error_status
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the test env and register space needed for the test
|
||||
* - Prepare HW and SW setup needed for the test
|
||||
* - Call prepare_ucode_blob without setting halt bit so that
|
||||
* timeout error occurs in acr bootstrap
|
||||
* - Set the falcon_falcon_cpuctl_halt_intr_m bit for the
|
||||
* register falcon_falcon_cpuctl_r
|
||||
* - Prepare the ucode blob
|
||||
* - Set mailbox_error = true to create read failure for mailbox 0 register
|
||||
* - Inject memory allocation failure to fail nvgpu_acr_bootstrap_hs_acr()
|
||||
* - Call nvgpu_acr_bootstrap_hs_acr() twice to cover recovery branch.
|
||||
* - Cover branch for fail scenario when "is_falcon_supported" is set to false
|
||||
* - Cover branch by setting g->acr->acr.acr_engine_bus_err_status = NULL
|
||||
* - Cover branch when "acr_engine_bus_err_status" ops fails
|
||||
* - Cover all scenarios to test gv11b_pmu_bar0_error_status() by wriring
|
||||
* different values to pwr_pmu_bar0_error_status_r() register
|
||||
* - Set g->acr->acr.acr_validate_mem_integrity = NULL to cover branch
|
||||
* - Set g->acr->acr.report_acr_engine_bus_err_status = NULL to cover branch
|
||||
* - Set ->ops.pmu.is_debug_mode_enabled = true to get branch coverage
|
||||
* - Cover branch by setting p->is_silicon = true
|
||||
* - Pass g->acr = NULL to fail nvgpu_acr_bootstrap_hs_acr()
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
int test_acr_bootstrap_hs_acr(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
26
userspace/units/bus/Makefile
Normal file
26
userspace/units/bus/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-bus.o
|
||||
MODULE = bus
|
||||
|
||||
include ../Makefile.units
|
||||
23
userspace/units/bus/Makefile.interface.tmk
Normal file
23
userspace/units/bus/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=bus
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
24
userspace/units/bus/Makefile.tmk
Normal file
24
userspace/units/bus/Makefile.tmk
Normal file
@@ -0,0 +1,24 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=bus
|
||||
NVGPU_UNIT_SRCS=nvgpu-bus.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
357
userspace/units/bus/nvgpu-bus.c
Normal file
357
userspace/units/bus/nvgpu-bus.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <unit/core.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/cic.h>
|
||||
#include <os/posix/os_posix.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <hal/mc/mc_gp10b.h>
|
||||
#include <hal/ptimer/ptimer_gk20a.h>
|
||||
#include <hal/bus/bus_gk20a.h>
|
||||
#include <hal/bus/bus_gm20b.h>
|
||||
#include <hal/bus/bus_gp10b.h>
|
||||
#include <hal/bus/bus_gv11b.h>
|
||||
#include <hal/cic/cic_gv11b.h>
|
||||
|
||||
#include <nvgpu/hw/gv11b/hw_mc_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_bus_gv11b.h>
|
||||
|
||||
#include "nvgpu-bus.h"
|
||||
|
||||
#define assert(cond) unit_assert(cond, goto done)
|
||||
u32 read_bind_status_reg = 0U;
|
||||
/*
|
||||
* Write callback.
|
||||
*/
|
||||
static void writel_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read callback.
|
||||
*/
|
||||
static void readl_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
/* BAR_1 bind status is indicated by value of
|
||||
* bus_bind_status_bar1_pending = empty(0x0U) and
|
||||
* bus_bind_status_bar1_outstanding = false(0x0U).
|
||||
*
|
||||
* Similarly, for BAR_2 bind status, we check
|
||||
* bus_bind_status_bar2_pending = empty (0x0U)
|
||||
* and bus_bind_status_bar2_outstanding = false(0x0U).
|
||||
*
|
||||
* During bar1/2_bind HAL, the bus_bind_status_r() register is polled to
|
||||
* check if its value changed as described above.
|
||||
* To get complete branch coverage in bus.bar1/2_bind(), after
|
||||
* "read_bind_status_reg" read attempts, the value of
|
||||
* bus_bind_status_r() is read as pending field = empty and
|
||||
* outstanding field = false.
|
||||
* This maps to bind_status = done after "read_cmd_reg" polling
|
||||
* attempts.
|
||||
*/
|
||||
if (access->addr == bus_bind_status_r()) {
|
||||
if (read_bind_status_reg == 3U) {
|
||||
access->value =
|
||||
(bus_bind_status_bar1_pending_empty_f() |
|
||||
bus_bind_status_bar1_outstanding_false_f() |
|
||||
bus_bind_status_bar2_pending_empty_f() |
|
||||
bus_bind_status_bar2_outstanding_false_f());
|
||||
read_bind_status_reg = nvgpu_safe_add_u32(
|
||||
read_bind_status_reg, 1U);
|
||||
return;
|
||||
}
|
||||
read_bind_status_reg = nvgpu_safe_add_u32(read_bind_status_reg,
|
||||
1U);
|
||||
}
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
|
||||
static struct nvgpu_posix_io_callbacks test_reg_callbacks = {
|
||||
/* Write APIs all can use the same accessor. */
|
||||
.writel = writel_access_reg_fn,
|
||||
.writel_check = writel_access_reg_fn,
|
||||
.bar1_writel = writel_access_reg_fn,
|
||||
.usermode_writel = writel_access_reg_fn,
|
||||
|
||||
/* Likewise for the read APIs. */
|
||||
.__readl = readl_access_reg_fn,
|
||||
.readl = readl_access_reg_fn,
|
||||
.bar1_readl = readl_access_reg_fn,
|
||||
};
|
||||
|
||||
/* NV_PBUS register space */
|
||||
#define NV_PBUS_START 0x00001000U
|
||||
#define NV_PBUS_SIZE 0x00000FFFU
|
||||
|
||||
/* NV_PRIV_GPC register space */
|
||||
#define NV_PMC_START 0x00000000U
|
||||
#define NV_PMC_SIZE 0x00000FFFU
|
||||
|
||||
/* NV_PTIMER register space */
|
||||
#define NV_PTIMER_START 0x00009000U
|
||||
#define NV_PTIMER_SIZE 0x00000FFFU
|
||||
|
||||
int test_bus_setup(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Init HAL */
|
||||
g->ops.bus.init_hw = gk20a_bus_init_hw;
|
||||
g->ops.bus.isr = gk20a_bus_isr;
|
||||
g->ops.bus.bar1_bind = gm20b_bus_bar1_bind;
|
||||
g->ops.bus.bar2_bind = gp10b_bus_bar2_bind;
|
||||
g->ops.bus.configure_debug_bus = gv11b_bus_configure_debug_bus;
|
||||
g->ops.mc.intr_nonstall_unit_config =
|
||||
mc_gp10b_intr_nonstall_unit_config;
|
||||
g->ops.ptimer.isr = gk20a_ptimer_isr;
|
||||
g->ops.cic.init = gv11b_cic_init;
|
||||
g->ops.cic.report_err = nvgpu_cic_report_err_safety_services;
|
||||
|
||||
/* Map register space NV_PRIV_MASTER */
|
||||
if (nvgpu_posix_io_add_reg_space(g, NV_PBUS_START, NV_PBUS_SIZE) != 0) {
|
||||
unit_err(m, "%s: failed to register space: NV_PBUS\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Map register space NV_PMC */
|
||||
if (nvgpu_posix_io_add_reg_space(g, NV_PMC_START,
|
||||
NV_PMC_SIZE) != 0) {
|
||||
unit_err(m, "%s: failed to register space: NV_PMC\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Map register space NV_PTIMER */
|
||||
if (nvgpu_posix_io_add_reg_space(g, NV_PTIMER_START,
|
||||
NV_PTIMER_SIZE) != 0) {
|
||||
unit_err(m, "%s: failed to register space: NV_PTIMER\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
(void)nvgpu_posix_register_io(g, &test_reg_callbacks);
|
||||
|
||||
if (nvgpu_cic_init_common(g) != 0) {
|
||||
unit_err(m, "%s: Failed to initialize CIC\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_bus_free_reg_space(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Free register space */
|
||||
nvgpu_posix_io_delete_reg_space(g, NV_PBUS_START);
|
||||
nvgpu_posix_io_delete_reg_space(g, NV_PMC_START);
|
||||
nvgpu_posix_io_delete_reg_space(g, NV_PTIMER_START);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_init_hw(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_FAIL;
|
||||
struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g);
|
||||
|
||||
nvgpu_writel(g, bus_debug_sel_0_r(), 0xFU);
|
||||
nvgpu_writel(g, bus_debug_sel_1_r(), 0xFU);
|
||||
nvgpu_writel(g, bus_debug_sel_2_r(), 0xFU);
|
||||
nvgpu_writel(g, bus_debug_sel_3_r(), 0xFU);
|
||||
|
||||
p->is_fpga = false;
|
||||
p->is_silicon = false;
|
||||
g->ops.bus.configure_debug_bus = NULL;
|
||||
ret = g->ops.bus.init_hw(g);
|
||||
assert(nvgpu_readl(g, bus_intr_en_1_r()) == 0U);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_0_r()) == 0xFU);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_1_r()) == 0xFU);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_2_r()) == 0xFU);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_3_r()) == 0xFU);
|
||||
|
||||
p->is_silicon = true;
|
||||
g->ops.bus.configure_debug_bus = gv11b_bus_configure_debug_bus;
|
||||
ret = g->ops.bus.init_hw(g);
|
||||
assert(nvgpu_readl(g, bus_intr_en_1_r()) == 0xEU);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_0_r()) == 0x0U);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_1_r()) == 0x0U);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_2_r()) == 0x0U);
|
||||
assert(nvgpu_readl(g, bus_debug_sel_3_r()) == 0x0U);
|
||||
|
||||
p->is_fpga = true;
|
||||
p->is_silicon = false;
|
||||
ret = g->ops.bus.init_hw(g);
|
||||
assert(nvgpu_readl(g, bus_intr_en_1_r()) == 0xEU);
|
||||
ret = UNIT_SUCCESS;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_bar_bind(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_FAIL;
|
||||
struct nvgpu_mem bar_inst = {0};
|
||||
struct nvgpu_posix_fault_inj *timer_fi =
|
||||
nvgpu_timers_get_fault_injection();
|
||||
|
||||
/* Initialize cpu_va to a known value */
|
||||
bar_inst.cpu_va = (void *) 0xCE418000U;
|
||||
bar_inst.aperture = APERTURE_VIDMEM;
|
||||
/* Set bus_bind_status_r to 0xF that is both bar1 and bar2 status
|
||||
* pending and outstanding.
|
||||
*/
|
||||
nvgpu_posix_io_writel_reg_space(g, bus_bind_status_r(), 0xFU);
|
||||
|
||||
/* Call bus.bar1_bind() HAL */
|
||||
ret = g->ops.bus.bar1_bind(g, &bar_inst);
|
||||
|
||||
/* Make sure HAL returns success as bind_status is marked as done in
|
||||
* third polling attempt.
|
||||
*/
|
||||
if (ret != 0U) {
|
||||
unit_err(m, "bus.bar1_bind HAL failed.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Send error if bar1_block register is not set as expected:
|
||||
* Bit 27:0 - 4k aligned block pointer = bar_inst.cpu_va >> 12 = 0xCE418
|
||||
* Bit 29:28- Target = Vidmem = (00)b
|
||||
* Bit 30 - Debug CYA = (0)b
|
||||
* Bit 31 - Mode = virtual = (1)b
|
||||
*/
|
||||
assert(nvgpu_readl(g, bus_bar1_block_r()) == 0x800CE418U);
|
||||
|
||||
/* Call bus.bar1_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain outstanding during this call.
|
||||
*/
|
||||
nvgpu_posix_io_writel_reg_space(g, bus_bind_status_r(), 0x5U);
|
||||
ret = g->ops.bus.bar1_bind(g, &bar_inst);
|
||||
/* The HAL should return error this time as timeout is expected to
|
||||
* expire.
|
||||
*/
|
||||
if (ret != -EINVAL) {
|
||||
unit_err(m, "bus.bar1_bind did not fail as expected.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Call bus.bar1_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain pending during this call.
|
||||
*/
|
||||
nvgpu_posix_io_writel_reg_space(g, bus_bind_status_r(), 0xAU);
|
||||
ret = g->ops.bus.bar1_bind(g, &bar_inst);
|
||||
/* The HAL should return error this time as timeout is expected to
|
||||
* expire.
|
||||
*/
|
||||
if (ret != -EINVAL) {
|
||||
unit_err(m, "bus.bar1_bind did not fail as expected.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Enable fault injection for the timer init call for branch coverage */
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 0);
|
||||
ret = g->ops.bus.bar1_bind(g, &bar_inst);
|
||||
if (ret == 0U) {
|
||||
unit_err(m, "Error injection for timeout init failed.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
|
||||
bar_inst.cpu_va = (void *) 0x2670C000U;
|
||||
read_bind_status_reg = 0U;
|
||||
ret = g->ops.bus.bar2_bind(g, &bar_inst);
|
||||
if (ret != 0U) {
|
||||
unit_err(m, "bus.bar2_bind HAL failed.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
assert(nvgpu_readl(g, bus_bar2_block_r()) == 0x8002670CU);
|
||||
|
||||
/* Call bus.bar2_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain outstanding during this call.
|
||||
*/
|
||||
nvgpu_posix_io_writel_reg_space(g, bus_bind_status_r(), 0x5U);
|
||||
ret = g->ops.bus.bar2_bind(g, &bar_inst);
|
||||
if (ret != -EINVAL) {
|
||||
unit_err(m, "bus.bar2_bind did not fail as expected.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Call bus.bar2_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain pending during this call.
|
||||
*/
|
||||
nvgpu_posix_io_writel_reg_space(g, bus_bind_status_r(), 0xAU);
|
||||
ret = g->ops.bus.bar2_bind(g, &bar_inst);
|
||||
if (ret != -EINVAL) {
|
||||
unit_err(m, "bus.bar2_bind did not fail as expected.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Enable fault injection for the timer init call for branch coverage */
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 0);
|
||||
ret = g->ops.bus.bar2_bind(g, &bar_inst);
|
||||
if (ret == 0U) {
|
||||
unit_err(m, "Error injection for timeout init failed.\n");
|
||||
ret = UNIT_FAIL;
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
|
||||
ret = UNIT_SUCCESS;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_bus_isr(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
|
||||
nvgpu_writel(g, bus_intr_0_r(), bus_intr_0_pri_squash_m());
|
||||
g->ops.bus.isr(g);
|
||||
|
||||
nvgpu_writel(g, bus_intr_0_r(), bus_intr_0_pri_fecserr_m());
|
||||
g->ops.bus.isr(g);
|
||||
|
||||
nvgpu_writel(g, bus_intr_0_r(), bus_intr_0_pri_timeout_m());
|
||||
g->ops.bus.isr(g);
|
||||
|
||||
nvgpu_writel(g, bus_intr_0_r(), 0x10U);
|
||||
g->ops.bus.isr(g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct unit_module_test bus_tests[] = {
|
||||
UNIT_TEST(bus_setup, test_bus_setup, NULL, 0),
|
||||
UNIT_TEST(bus_init_hw, test_init_hw, NULL, 0),
|
||||
UNIT_TEST(bus_bar_bind, test_bar_bind, NULL, 0),
|
||||
UNIT_TEST(bus_isr, test_bus_isr, NULL, 0),
|
||||
UNIT_TEST(bus_free_reg_space, test_bus_free_reg_space, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(bus, bus_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
178
userspace/units/bus/nvgpu-bus.h
Normal file
178
userspace/units/bus/nvgpu-bus.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_BUS_H
|
||||
#define UNIT_NVGPU_BUS_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-bus
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for nvgpu.common.bus
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_bus_setup
|
||||
*
|
||||
* Description: Setup prerequisites for tests.
|
||||
*
|
||||
* Test Type: Other (setup)
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize common.bus and few other necessary HAL function pointers.
|
||||
* - Map the register space for NV_PBUS, NV_PMC and NV_PTIMER.
|
||||
* - Register read/write callback functions.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if encounters an error creating reg space
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_bus_setup(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_bus_free_reg_space
|
||||
*
|
||||
* Description: Free resources from test_bus_setup()
|
||||
*
|
||||
* Test Type: Other (cleanup)
|
||||
*
|
||||
* Input: test_bus_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Free up NV_PBUS, NV_PMC and NV_PTIMER register space.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_SUCCESS
|
||||
*/
|
||||
int test_bus_free_reg_space(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_init_hw
|
||||
*
|
||||
* Description: Verify the bus.init_hw and bus.configure_debug_bus HAL.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_bus.init_hw, gk20a_bus_init_hw,
|
||||
* gops_bus.configure_debug_bus, gv11b_bus_configure_debug_bus
|
||||
*
|
||||
* Input: test_bus_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the Debug bus related registers to non-zero value.
|
||||
* - Set is_silicon and is_fpga flag to false to get branch coverage.
|
||||
* - Set configure_debug_bus HAL to NULL for branch coverage.
|
||||
* - Call init_hw() HAL.
|
||||
* - Read back the interrupt enable register and check if it is equal to 0.
|
||||
* - Read back the debug bus registers to make sure they are NOT zeroed out.
|
||||
*
|
||||
* - For more branch coverage, set is_silicon flag to true.
|
||||
* - Initialize the configure_debug_bus HAL to gv11b_bus_configure_debug_bus.
|
||||
* - Call init_hw() HAL.
|
||||
* - Read back the interrupt enable register and check if it is equal to 0xEU.
|
||||
* - PRI_SQUASH = Bit 1:1
|
||||
* - PRI_FECSERR = Bit 2:2
|
||||
* - PRI_TIMEOUT = Bit 3:3
|
||||
* - Read back the debug bus registers to make sure they are zeroed out.
|
||||
*
|
||||
* - For better branch coverage, set is_silicon to false and is_fpga to true
|
||||
* - Call init_hw() HAL.
|
||||
* - Read back the interrupt enable register and check if it is equal to 0xEU.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if above HAL fails to enable interrupts.
|
||||
* - UNIT_SUCCESS otherwise.
|
||||
*/
|
||||
int test_init_hw(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_bar_bind
|
||||
*
|
||||
* Description: Verify the bus.bar1_bind and bus.bar2_bind HAL.
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Targets: gops_bus.bar1_bind, gm20b_bus_bar1_bind,
|
||||
* gops_bus.bar2_bind, gp10b_bus_bar2_bind
|
||||
*
|
||||
* Input: test_bus_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize cpu_va to a known value (say 0xCE418000U).
|
||||
* - Set bus_bind_status_r to 0xF that is both bar1 and bar2 status
|
||||
* pending and outstanding.
|
||||
* - Call bus.bar1_bind() HAL.
|
||||
* - Make sure HAL returns success as bind_status is marked as done in
|
||||
* third polling attempt.
|
||||
* - Send error if bar1_block register is not set as expected:
|
||||
* - Bit 27:0 - 4k aligned block pointer = bar_inst.cpu_va >> 12 = 0xCE418
|
||||
* - Bit 29:28- Target = (11)b
|
||||
* - Bit 30 - Debug CYA = (0)b
|
||||
* - Bit 31 - Mode = virtual = (1)b
|
||||
* - Set bus_bind_status_r to 0x5U that is both bar1 and bar2 status
|
||||
* is set as outstanding.
|
||||
* - Call bus.bar1_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain outstanding during this call.
|
||||
* - Set bus_bind_status_r to 0xAU that is both bar1 and bar2 status
|
||||
* is set as pending.
|
||||
* - Call bus.bar1_bind HAL again and except ret != 0 as the bind status
|
||||
* will remain pending during this call.
|
||||
* - The HAL should return error this time as timeout is expected to expire.
|
||||
* - Enable fault injection for the timer init call for branch coverage.
|
||||
* - Repeat the above steps for BAR2 but with different cpu_va = 0x2670C000U.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if above HAL fails to bind BAR1/2
|
||||
* - UNIT_SUCCESS otherwise.
|
||||
*/
|
||||
int test_bar_bind(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_bus_isr
|
||||
*
|
||||
* Description: Verify the bus.isr HAL.
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Targets: gops_bus.isr, gk20a_bus_isr
|
||||
*
|
||||
* Input: test_bus_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize interrupt register bus_intr_0_r() to 0x2(pri_squash)
|
||||
* - Call isr HAL.
|
||||
* - Initialize interrupt register bus_intr_0_r() to 0x4(pri_fecserr)
|
||||
* - Call isr HAL.
|
||||
* - Initialize interrupt register bus_intr_0_r() to 0x8(pri_timeout)
|
||||
* - Call isr HAL.
|
||||
* - Initialize interrupt register bus_intr_0_r() to 0x10(fb_req_timeout)
|
||||
* - Call isr HAL.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_SUCCESS.
|
||||
*/
|
||||
int test_bus_isr(struct unit_module *m, struct gk20a *g, void *args);
|
||||
#endif /* UNIT_NVGPU_BUS_H */
|
||||
26
userspace/units/ce/Makefile
Normal file
26
userspace/units/ce/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-ce.o
|
||||
MODULE = ce
|
||||
|
||||
include ../Makefile.units
|
||||
23
userspace/units/ce/Makefile.interface.tmk
Normal file
23
userspace/units/ce/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=ce
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
24
userspace/units/ce/Makefile.tmk
Normal file
24
userspace/units/ce/Makefile.tmk
Normal file
@@ -0,0 +1,24 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=ce
|
||||
NVGPU_UNIT_SRCS=nvgpu-ce.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
388
userspace/units/ce/nvgpu-ce.c
Normal file
388
userspace/units/ce/nvgpu-ce.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/device.h>
|
||||
#include <nvgpu/ce.h>
|
||||
#include <nvgpu/cic.h>
|
||||
#include <hal/ce/ce_gp10b.h>
|
||||
#include <hal/ce/ce_gv11b.h>
|
||||
#include <hal/cic/cic_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_ce_gv11b.h>
|
||||
|
||||
#include "nvgpu-ce.h"
|
||||
|
||||
#define assert(cond) unit_assert(cond, goto fail)
|
||||
|
||||
#define CE_ADDR_SPACE_START 0x00104000
|
||||
#define CE_ADDR_SPACE_SIZE 0xfff
|
||||
#define NUM_INST 2
|
||||
|
||||
/*
|
||||
* Mock I/O
|
||||
*/
|
||||
|
||||
/*
|
||||
* Write callback. Forward the write access to the mock IO framework.
|
||||
*/
|
||||
static u32 intr_status_written[NUM_INST];
|
||||
static void writel_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
if (access->addr == ce_intr_status_r(0)) {
|
||||
intr_status_written[0] |= access->value;
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr,
|
||||
nvgpu_posix_io_readl_reg_space(g, access->addr) &
|
||||
~access->value);
|
||||
} else if (access->addr == ce_intr_status_r(1)) {
|
||||
intr_status_written[1] |= access->value;
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr,
|
||||
nvgpu_posix_io_readl_reg_space(g, access->addr) &
|
||||
~access->value);
|
||||
} else {
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read callback. Get the register value from the mock IO framework.
|
||||
*/
|
||||
static void readl_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
|
||||
static struct nvgpu_posix_io_callbacks test_reg_callbacks = {
|
||||
/* Write APIs all can use the same accessor. */
|
||||
.writel = writel_access_reg_fn,
|
||||
.writel_check = writel_access_reg_fn,
|
||||
.bar1_writel = writel_access_reg_fn,
|
||||
.usermode_writel = writel_access_reg_fn,
|
||||
|
||||
/* Likewise for the read APIs. */
|
||||
.__readl = readl_access_reg_fn,
|
||||
.readl = readl_access_reg_fn,
|
||||
.bar1_readl = readl_access_reg_fn,
|
||||
};
|
||||
|
||||
/*
|
||||
* Replacement functions that can be assigned to function pointers
|
||||
*/
|
||||
static void mock_void_return(struct gk20a *g)
|
||||
{
|
||||
/* noop */
|
||||
}
|
||||
|
||||
static int mock_mc_enable_units(struct gk20a *g, u32 units, bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int mock_mc_enable_dev(struct gk20a *g, const struct nvgpu_device *dev,
|
||||
bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mock_intr_unit_config(struct gk20a *g, u32 unit, bool enable)
|
||||
{
|
||||
/* noop */
|
||||
}
|
||||
|
||||
int test_ce_setup_env(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
/* Create mc register space */
|
||||
if (nvgpu_posix_io_add_reg_space(g, CE_ADDR_SPACE_START,
|
||||
CE_ADDR_SPACE_SIZE) != 0) {
|
||||
unit_err(m, "%s: failed to create register space\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
(void)nvgpu_posix_register_io(g, &test_reg_callbacks);
|
||||
|
||||
nvgpu_mutex_init(&g->cg_pg_lock);
|
||||
g->blcg_enabled = false;
|
||||
nvgpu_spinlock_init(&g->mc.intr_lock);
|
||||
|
||||
g->ops.cic.init = gv11b_cic_init;
|
||||
g->ops.cic.report_err = nvgpu_cic_report_err_safety_services;
|
||||
|
||||
if (nvgpu_cic_init_common(g) != 0) {
|
||||
unit_err(m, "%s: failed to initialize CIC\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_ce_free_env(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Free mc register space */
|
||||
nvgpu_posix_io_delete_reg_space(g, CE_ADDR_SPACE_START);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_ce_init_support(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
int err;
|
||||
|
||||
nvgpu_device_init(g);
|
||||
|
||||
g->fifo.num_engines = 0;
|
||||
g->ops.ce.set_pce2lce_mapping = mock_void_return;
|
||||
g->ops.ce.init_prod_values = mock_void_return;
|
||||
g->ops.mc.enable_units = mock_mc_enable_units;
|
||||
g->ops.mc.enable_dev = mock_mc_enable_dev;
|
||||
g->ops.mc.intr_nonstall_unit_config = mock_intr_unit_config;
|
||||
g->ops.mc.intr_stall_unit_config = mock_intr_unit_config;
|
||||
|
||||
/* test default case where all HALs are defined */
|
||||
err = nvgpu_ce_init_support(g);
|
||||
if (err != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "failed to init ce\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* test with this HAL set to NULL for branch coverage */
|
||||
g->ops.ce.set_pce2lce_mapping = NULL;
|
||||
err = nvgpu_ce_init_support(g);
|
||||
if (err != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "failed to init ce\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* test with this HAL set to NULL for branch coverage */
|
||||
g->ops.ce.init_prod_values = NULL;
|
||||
err = nvgpu_ce_init_support(g);
|
||||
if (err != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "failed to init ce\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_ce_stall_isr(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
int inst_id;
|
||||
u32 intr_val;
|
||||
|
||||
g->ops.ce.isr_stall = gv11b_ce_stall_isr;
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
intr_status_written[inst_id] = 0;
|
||||
intr_val = 0x1f; /* all intr sources */
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
g->ops.ce.isr_stall(g, inst_id, 0);
|
||||
if (intr_status_written[inst_id] != (intr_val &
|
||||
~ce_intr_status_nonblockpipe_pending_f())) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
intr_status_written[inst_id] = 0;
|
||||
intr_val = 0x0;
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
g->ops.ce.isr_stall(g, inst_id, 0);
|
||||
if (intr_status_written[inst_id] != intr_val) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_ce_nonstall_isr(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
int inst_id;
|
||||
u32 intr_val;
|
||||
u32 val;
|
||||
|
||||
g->ops.ce.isr_nonstall = gp10b_ce_nonstall_isr;
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
intr_status_written[inst_id] = 0;
|
||||
intr_val = 0x1f; /* all intr sources */
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
val = g->ops.ce.isr_nonstall(g, inst_id, 0);
|
||||
if (val != (NVGPU_CIC_NONSTALL_OPS_WAKEUP_SEMAPHORE |
|
||||
NVGPU_CIC_NONSTALL_OPS_POST_EVENTS)) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "incorrect ops returned 0x%08x\n", val);
|
||||
goto done;
|
||||
}
|
||||
if (intr_status_written[inst_id] !=
|
||||
ce_intr_status_nonblockpipe_pending_f()) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared properly, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
intr_status_written[inst_id] = 0;
|
||||
intr_val = 0x0;
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
val = g->ops.ce.isr_nonstall(g, inst_id, 0);
|
||||
if (val != 0U) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "incorrect ops returned 0x%08x\n", val);
|
||||
goto done;
|
||||
}
|
||||
if (intr_status_written[inst_id] != intr_val) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 mock_get_num_lce(struct gk20a *g)
|
||||
{
|
||||
return NUM_INST;
|
||||
}
|
||||
|
||||
int test_mthd_buffer_fault_in_bar2_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
int inst_id;
|
||||
u32 intr_val;
|
||||
|
||||
g->ops.ce.mthd_buffer_fault_in_bar2_fault =
|
||||
gv11b_ce_mthd_buffer_fault_in_bar2_fault;
|
||||
g->ops.top.get_num_lce = mock_get_num_lce;
|
||||
|
||||
intr_val = 0x1f; /* all intr sources */
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
intr_status_written[inst_id] = 0;
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
}
|
||||
g->ops.ce.mthd_buffer_fault_in_bar2_fault(g);
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
if (intr_status_written[inst_id] !=
|
||||
ce_intr_status_mthd_buffer_fault_pending_f()) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared properly, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
intr_val = 0x0;
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
intr_status_written[inst_id] = 0;
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_intr_status_r(inst_id),
|
||||
intr_val);
|
||||
}
|
||||
g->ops.ce.mthd_buffer_fault_in_bar2_fault(g);
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
if (intr_status_written[inst_id] != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
unit_err(m, "intr_status not cleared properly, only 0x%08x\n",
|
||||
intr_status_written[inst_id]);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_get_num_pce(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
u32 pce_map_val; /* 16 bit bitmap */
|
||||
u32 val;
|
||||
|
||||
g->ops.ce.get_num_pce = gv11b_ce_get_num_pce;
|
||||
for (pce_map_val = 0; pce_map_val <= U16_MAX; pce_map_val++) {
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_pce_map_r(),
|
||||
pce_map_val);
|
||||
val = g->ops.ce.get_num_pce(g);
|
||||
if (val != hweight32(pce_map_val)) {
|
||||
unit_return_fail(m, "incorrect value %u\n", val);
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_init_prod_values(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int inst_id;
|
||||
u32 val;
|
||||
|
||||
g->ops.ce.init_prod_values = gv11b_ce_init_prod_values;
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
/* init reg to known state */
|
||||
nvgpu_posix_io_writel_reg_space(g, ce_lce_opt_r(inst_id), 0U);
|
||||
}
|
||||
g->ops.ce.init_prod_values(g);
|
||||
for (inst_id = 0; inst_id < NUM_INST; inst_id++) {
|
||||
/* verify written correctly */
|
||||
val = nvgpu_posix_io_readl_reg_space(g, ce_lce_opt_r(inst_id));
|
||||
if (val != ce_lce_opt_force_barriers_npl__prod_f()) {
|
||||
unit_return_fail(m, "value incorrect 0x%08x\n", val);
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct unit_module_test ce_tests[] = {
|
||||
UNIT_TEST(ce_setup_env, test_ce_setup_env, NULL, 0),
|
||||
UNIT_TEST(ce_init_support, test_ce_init_support, NULL, 0),
|
||||
UNIT_TEST(ce_stall_isr, test_ce_stall_isr, NULL, 0),
|
||||
UNIT_TEST(ce_nonstall_isr, test_ce_nonstall_isr, NULL, 0),
|
||||
UNIT_TEST(mthd_buffer_fault_in_bar2_fault, test_mthd_buffer_fault_in_bar2_fault, NULL, 0),
|
||||
UNIT_TEST(ce_get_num_pce, test_get_num_pce, NULL, 0),
|
||||
UNIT_TEST(ce_init_prod_values, test_init_prod_values, NULL, 0),
|
||||
UNIT_TEST(ce_free_env, test_ce_free_env, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(ce, ce_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
212
userspace/units/ce/nvgpu-ce.h
Normal file
212
userspace/units/ce/nvgpu-ce.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_CE_H
|
||||
#define UNIT_NVGPU_CE_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-ce
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for CE
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_ce_setup_env
|
||||
*
|
||||
* Description: Do basic setup before starting other tests.
|
||||
*
|
||||
* Test Type: Other (setup)
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize reg spaces used by tests.
|
||||
* - Initialize required data for cg, mc modules.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if encounters an error creating reg space
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_ce_setup_env(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ce_free_env
|
||||
*
|
||||
* Description: Do basic setup before starting other tests.
|
||||
*
|
||||
* Test Type: Other (setup)
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Free reg spaces
|
||||
*
|
||||
* Output: UNIT_SUCCESS always.
|
||||
*/
|
||||
int test_ce_free_env(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ce_init_support
|
||||
*
|
||||
* Description: Validate CE init functionality.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.ce_init_support, nvgpu_ce_init_support
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Setup necessary mock HALs to do nothing and return success as appropriate.
|
||||
* - Call nvgpu_ce_init_support and verify success is returned.
|
||||
* - Set set_pce2lce_mapping and init_prod_values HAL function pointers to NULL
|
||||
* for branch coverage.
|
||||
* - Call nvgpu_ce_init_support and verify success is returned.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_ce_init_support(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ce_stall_isr
|
||||
*
|
||||
* Description: Validate stall interrupt handler functionality.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.isr_stall, gv11b_ce_stall_isr, gp10b_ce_stall_isr
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Set all CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.isr_stall.
|
||||
* - Verify all (and only) the stall interrupts are cleared.
|
||||
* - Set no CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.isr_stall.
|
||||
* - Verify no interrupts are cleared.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_ce_stall_isr(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ce_nonstall_isr
|
||||
*
|
||||
* Description: Validate nonstall interrupt handler functionality.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.isr_nonstall, gp10b_ce_nonstall_isr
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Set all CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.isr_nonstall.
|
||||
* - Verify only the nonstall interrupt is cleared and the expected ops are
|
||||
* returned.
|
||||
* - Set no CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.isr_nonstall.
|
||||
* - Verify no interrupts are cleared and no ops are returned.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_ce_nonstall_isr(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_mthd_buffer_fault_in_bar2_fault
|
||||
*
|
||||
* Description: Validate method buffer interrupt functionality.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.mthd_buffer_fault_in_bar2_fault,
|
||||
* gv11b_ce_mthd_buffer_fault_in_bar2_fault
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Set all CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.mthd_buffer_fault_in_bar2_fault.
|
||||
* - Verify only the correct interrupt is cleared.
|
||||
* - Set no CE interrupt sources pending in the interrupt status reg for each
|
||||
* instance.
|
||||
* - Call gops_ce.mthd_buffer_fault_in_bar2_fault.
|
||||
* - Verify no interrupts are cleared.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_mthd_buffer_fault_in_bar2_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_get_num_pce
|
||||
*
|
||||
* Description: Validate function to get number of PCEs.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.get_num_pce, gv11b_ce_get_num_pce
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Loop through all possible 16 bit values for the PCE Map register.
|
||||
* - For each value, write to the PCE Map register.
|
||||
* - Call gops_ce.get_num_pce and verify the correct number of PCEs is
|
||||
* returned.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_get_num_pce(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_init_prod_values
|
||||
*
|
||||
* Description: Validate prod value init functionality.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: gops_ce.init_prod_values, gv11b_ce_init_prod_values
|
||||
*
|
||||
* Input: test_ce_setup_env must have been run.
|
||||
*
|
||||
* Steps:
|
||||
* - Clear the LCE Options register for all instances.
|
||||
* - Call gops_ce.init_prod_values.
|
||||
* - Verify all instances of the LCE Options register are set properly.
|
||||
*
|
||||
* Output: Returns PASS if expected result is met, FAIL otherwise.
|
||||
*/
|
||||
int test_init_prod_values(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
#endif /* UNIT_NVGPU_CE_H */
|
||||
32
userspace/units/cg/Makefile
Normal file
32
userspace/units/cg/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-cg.o
|
||||
MODULE = nvgpu-cg
|
||||
|
||||
LIB_PATHS += -lnvgpu-fifo-common
|
||||
include ../Makefile.units
|
||||
|
||||
lib$(MODULE).so: fifo
|
||||
|
||||
fifo:
|
||||
$(MAKE) -C ../fifo
|
||||
34
userspace/units/cg/Makefile.interface.tmk
Normal file
34
userspace/units/cg/Makefile.interface.tmk
Normal file
@@ -0,0 +1,34 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-cg
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
39
userspace/units/cg/Makefile.tmk
Normal file
39
userspace/units/cg/Makefile.tmk
Normal file
@@ -0,0 +1,39 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-cg
|
||||
NVGPU_UNIT_SRCS=nvgpu-cg.c
|
||||
|
||||
NVGPU_UNIT_INTERFACE_DIRS := \
|
||||
$(NV_COMPONENT_DIR)/../fifo
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
710
userspace/units/cg/nvgpu-cg.c
Normal file
710
userspace/units/cg/nvgpu-cg.c
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/enabled.h>
|
||||
#include <nvgpu/power_features/cg.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/device.h>
|
||||
#include <nvgpu/hw/gp10b/hw_fuse_gp10b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_gr_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_therm_gv11b.h>
|
||||
|
||||
#include "hal/init/hal_gv11b.h"
|
||||
#include "hal/power_features/cg/gating_reglist.h"
|
||||
#include "hal/power_features/cg/gv11b_gating_reglist.h"
|
||||
#include "../fifo/nvgpu-fifo-common.h"
|
||||
|
||||
#include "nvgpu-cg.h"
|
||||
|
||||
struct cg_test_data {
|
||||
u32 cg_type;
|
||||
void (*load_enable)(struct gk20a *g);
|
||||
u32 domain_count;
|
||||
const struct gating_desc *domain_descs[16];
|
||||
void (*gating_funcs[16])(struct gk20a *g, bool prod);
|
||||
u32 domain_desc_sizes[16];
|
||||
};
|
||||
|
||||
static struct cg_test_data blcg_fb_ltc = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_blcg_fb_ltc_load_enable,
|
||||
.domain_count = 2,
|
||||
};
|
||||
|
||||
static struct cg_test_data blcg_fifo = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_blcg_fifo_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
static struct cg_test_data blcg_pmu = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_blcg_pmu_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
static struct cg_test_data blcg_ce = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_blcg_ce_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
static struct cg_test_data blcg_gr = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_blcg_gr_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
static struct cg_test_data slcg_fb_ltc = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_fb_ltc_load_enable,
|
||||
.domain_count = 2,
|
||||
};
|
||||
|
||||
static struct cg_test_data slcg_priring = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_priring_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
static struct cg_test_data slcg_fifo = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_fifo_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
struct cg_test_data slcg_pmu = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_pmu_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
struct cg_test_data slcg_therm = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_therm_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
struct cg_test_data slcg_ce2 = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_slcg_ce2_load_enable,
|
||||
.domain_count = 1,
|
||||
};
|
||||
|
||||
struct cg_test_data slcg_gr_load_gating_prod = {
|
||||
.cg_type = NVGPU_GPU_CAN_SLCG,
|
||||
.load_enable = nvgpu_cg_init_gr_load_gating_prod,
|
||||
.domain_count = 6,
|
||||
};
|
||||
|
||||
struct cg_test_data blcg_gr_load_gating_prod = {
|
||||
.cg_type = NVGPU_GPU_CAN_BLCG,
|
||||
.load_enable = nvgpu_cg_init_gr_load_gating_prod,
|
||||
.domain_count = 4,
|
||||
};
|
||||
|
||||
#define INIT_BLCG_DOMAIN_TEST_DATA(param) ({\
|
||||
struct cg_test_data *tmp = &blcg_##param; \
|
||||
tmp->domain_descs[0] = gv11b_blcg_##param##_get_gating_prod(); \
|
||||
tmp->gating_funcs[0] = g->ops.cg.blcg_##param##_load_gating_prod; \
|
||||
tmp->domain_desc_sizes[0] = gv11b_blcg_##param##_gating_prod_size(); \
|
||||
})
|
||||
|
||||
static void init_blcg_fb_ltc_data(struct gk20a *g)
|
||||
{
|
||||
blcg_fb_ltc.domain_descs[0] = gv11b_blcg_fb_get_gating_prod();
|
||||
blcg_fb_ltc.gating_funcs[0] = g->ops.cg.blcg_fb_load_gating_prod;
|
||||
blcg_fb_ltc.domain_desc_sizes[0] = gv11b_blcg_fb_gating_prod_size();
|
||||
blcg_fb_ltc.domain_descs[1] = gv11b_blcg_ltc_get_gating_prod();
|
||||
blcg_fb_ltc.gating_funcs[1] = g->ops.cg.blcg_ltc_load_gating_prod;
|
||||
blcg_fb_ltc.domain_desc_sizes[1] = gv11b_blcg_ltc_gating_prod_size();
|
||||
}
|
||||
|
||||
static void init_blcg_fifo_data(struct gk20a *g)
|
||||
{
|
||||
INIT_BLCG_DOMAIN_TEST_DATA(fifo);
|
||||
}
|
||||
|
||||
static void init_blcg_pmu_data(struct gk20a *g)
|
||||
{
|
||||
INIT_BLCG_DOMAIN_TEST_DATA(pmu);
|
||||
}
|
||||
|
||||
static void init_blcg_ce_data(struct gk20a *g)
|
||||
{
|
||||
INIT_BLCG_DOMAIN_TEST_DATA(ce);
|
||||
}
|
||||
|
||||
static void init_blcg_gr_data(struct gk20a *g)
|
||||
{
|
||||
INIT_BLCG_DOMAIN_TEST_DATA(gr);
|
||||
}
|
||||
|
||||
static void init_blcg_gr_load_gating_data(struct gk20a *g)
|
||||
{
|
||||
blcg_gr_load_gating_prod.domain_descs[0] =
|
||||
gv11b_blcg_bus_get_gating_prod();
|
||||
blcg_gr_load_gating_prod.gating_funcs[0] =
|
||||
g->ops.cg.blcg_bus_load_gating_prod;
|
||||
blcg_gr_load_gating_prod.domain_desc_sizes[0] =
|
||||
gv11b_blcg_bus_gating_prod_size();
|
||||
blcg_gr_load_gating_prod.domain_descs[1] =
|
||||
gv11b_blcg_gr_get_gating_prod();
|
||||
blcg_gr_load_gating_prod.gating_funcs[1] =
|
||||
g->ops.cg.blcg_gr_load_gating_prod;
|
||||
blcg_gr_load_gating_prod.domain_desc_sizes[1] =
|
||||
gv11b_blcg_gr_gating_prod_size();
|
||||
blcg_gr_load_gating_prod.domain_descs[2] =
|
||||
gv11b_blcg_xbar_get_gating_prod();
|
||||
blcg_gr_load_gating_prod.gating_funcs[2] =
|
||||
g->ops.cg.blcg_xbar_load_gating_prod;
|
||||
blcg_gr_load_gating_prod.domain_desc_sizes[2] =
|
||||
gv11b_blcg_xbar_gating_prod_size();
|
||||
blcg_gr_load_gating_prod.domain_descs[3] =
|
||||
gv11b_blcg_hshub_get_gating_prod();
|
||||
blcg_gr_load_gating_prod.gating_funcs[3] =
|
||||
g->ops.cg.blcg_hshub_load_gating_prod;
|
||||
blcg_gr_load_gating_prod.domain_desc_sizes[3] =
|
||||
gv11b_blcg_hshub_gating_prod_size();
|
||||
}
|
||||
|
||||
#define INIT_SLCG_DOMAIN_TEST_DATA(param) ({\
|
||||
struct cg_test_data *tmp = &slcg_##param; \
|
||||
tmp->domain_descs[0] = gv11b_slcg_##param##_get_gating_prod(); \
|
||||
tmp->gating_funcs[0] = g->ops.cg.slcg_##param##_load_gating_prod; \
|
||||
tmp->domain_desc_sizes[0] = gv11b_slcg_##param##_gating_prod_size(); \
|
||||
})
|
||||
|
||||
static void init_slcg_fb_ltc_data(struct gk20a *g)
|
||||
{
|
||||
slcg_fb_ltc.domain_descs[0] = gv11b_slcg_fb_get_gating_prod();
|
||||
slcg_fb_ltc.gating_funcs[0] = g->ops.cg.slcg_fb_load_gating_prod;
|
||||
slcg_fb_ltc.domain_desc_sizes[0] = gv11b_slcg_fb_gating_prod_size();
|
||||
slcg_fb_ltc.domain_descs[1] = gv11b_slcg_ltc_get_gating_prod();
|
||||
slcg_fb_ltc.gating_funcs[1] = g->ops.cg.slcg_ltc_load_gating_prod;
|
||||
slcg_fb_ltc.domain_desc_sizes[1] = gv11b_slcg_ltc_gating_prod_size();
|
||||
}
|
||||
|
||||
static void init_slcg_priring_data(struct gk20a *g)
|
||||
{
|
||||
INIT_SLCG_DOMAIN_TEST_DATA(priring);
|
||||
}
|
||||
|
||||
static void init_slcg_fifo_data(struct gk20a *g)
|
||||
{
|
||||
INIT_SLCG_DOMAIN_TEST_DATA(fifo);
|
||||
}
|
||||
|
||||
static void init_slcg_pmu_data(struct gk20a *g)
|
||||
{
|
||||
INIT_SLCG_DOMAIN_TEST_DATA(pmu);
|
||||
}
|
||||
|
||||
static void init_slcg_therm_data(struct gk20a *g)
|
||||
{
|
||||
INIT_SLCG_DOMAIN_TEST_DATA(therm);
|
||||
}
|
||||
|
||||
static void init_slcg_ce2_data(struct gk20a *g)
|
||||
{
|
||||
INIT_SLCG_DOMAIN_TEST_DATA(ce2);
|
||||
}
|
||||
|
||||
static void init_slcg_gr_load_gating_data(struct gk20a *g)
|
||||
{
|
||||
slcg_gr_load_gating_prod.domain_descs[0] =
|
||||
gv11b_slcg_bus_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[0] =
|
||||
g->ops.cg.slcg_bus_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[0] =
|
||||
gv11b_slcg_bus_gating_prod_size();
|
||||
slcg_gr_load_gating_prod.domain_descs[1] =
|
||||
gv11b_slcg_chiplet_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[1] =
|
||||
g->ops.cg.slcg_chiplet_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[1] =
|
||||
gv11b_slcg_chiplet_gating_prod_size();
|
||||
slcg_gr_load_gating_prod.domain_descs[2] =
|
||||
gv11b_slcg_gr_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[2] =
|
||||
g->ops.cg.slcg_gr_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[2] =
|
||||
gv11b_slcg_gr_gating_prod_size();
|
||||
slcg_gr_load_gating_prod.domain_descs[3] =
|
||||
gv11b_slcg_perf_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[3] =
|
||||
g->ops.cg.slcg_perf_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[3] =
|
||||
gv11b_slcg_perf_gating_prod_size();
|
||||
slcg_gr_load_gating_prod.domain_descs[4] =
|
||||
gv11b_slcg_xbar_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[4] =
|
||||
g->ops.cg.slcg_xbar_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[4] =
|
||||
gv11b_slcg_xbar_gating_prod_size();
|
||||
slcg_gr_load_gating_prod.domain_descs[5] =
|
||||
gv11b_slcg_hshub_get_gating_prod();
|
||||
slcg_gr_load_gating_prod.gating_funcs[5] =
|
||||
g->ops.cg.slcg_hshub_load_gating_prod;
|
||||
slcg_gr_load_gating_prod.domain_desc_sizes[5] =
|
||||
gv11b_slcg_hshub_gating_prod_size();
|
||||
}
|
||||
|
||||
static void writel_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
nvgpu_posix_io_record_access(g, access);
|
||||
}
|
||||
|
||||
static void readl_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
|
||||
|
||||
static struct nvgpu_posix_io_callbacks cg_callbacks = {
|
||||
/* Write APIs all can use the same accessor. */
|
||||
.writel = writel_access_reg_fn,
|
||||
.writel_check = writel_access_reg_fn,
|
||||
.bar1_writel = writel_access_reg_fn,
|
||||
.usermode_writel = writel_access_reg_fn,
|
||||
|
||||
/* Likewise for the read APIs. */
|
||||
.__readl = readl_access_reg_fn,
|
||||
.readl = readl_access_reg_fn,
|
||||
.bar1_readl = readl_access_reg_fn,
|
||||
};
|
||||
|
||||
static int init_test_env(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
nvgpu_posix_register_io(g, &cg_callbacks);
|
||||
|
||||
/*
|
||||
* Fuse register fuse_opt_priv_sec_en_r() is read during init_hal hence
|
||||
* add it to reg space
|
||||
*/
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
fuse_opt_priv_sec_en_r(), 0x4) != 0) {
|
||||
unit_err(m, "Add reg space failed!\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
fuse_opt_ecc_en_r(), 0x4) != 0) {
|
||||
unit_err(m, "Add reg space failed!\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
fuse_opt_feature_fuses_override_disable_r(), 0x4) != 0) {
|
||||
unit_err(m, "Add reg space failed!\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
gr_fecs_feature_override_ecc_r(), 0x4) != 0) {
|
||||
unit_err(m, "Add reg space failed!\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
gr_fecs_feature_override_ecc_1_r(), 0x4) != 0) {
|
||||
unit_err(m, "Add reg space failed!\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
gv11b_init_hal(g);
|
||||
|
||||
init_blcg_fb_ltc_data(g);
|
||||
init_blcg_fifo_data(g);
|
||||
init_blcg_pmu_data(g);
|
||||
init_blcg_ce_data(g);
|
||||
init_blcg_gr_data(g);
|
||||
init_blcg_gr_load_gating_data(g);
|
||||
|
||||
init_slcg_fb_ltc_data(g);
|
||||
init_slcg_priring_data(g);
|
||||
init_slcg_fifo_data(g);
|
||||
init_slcg_pmu_data(g);
|
||||
init_slcg_therm_data(g);
|
||||
init_slcg_ce2_data(g);
|
||||
init_slcg_gr_load_gating_data(g);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int add_domain_gating_regs(struct gk20a *g,
|
||||
const struct gating_desc *desc, u32 size)
|
||||
{
|
||||
int err = 0;
|
||||
u32 i, j;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (nvgpu_posix_io_add_reg_space(g, desc[i].addr, 0x4) != 0) {
|
||||
err = -ENOMEM;
|
||||
goto clean_regs;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
clean_regs:
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
nvgpu_posix_io_delete_reg_space(g, desc[j].addr);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void delete_domain_gating_regs(struct gk20a *g,
|
||||
const struct gating_desc *desc, u32 size)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
nvgpu_posix_io_delete_reg_space(g, desc[i].addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void invalid_load_enabled(struct gk20a *g,
|
||||
struct cg_test_data *test_data)
|
||||
{
|
||||
u32 i, j;
|
||||
|
||||
for (i = 0; i < test_data->domain_count; i++) {
|
||||
for (j = 0; j < test_data->domain_desc_sizes[i]; j++) {
|
||||
nvgpu_writel(g, test_data->domain_descs[i][j].addr,
|
||||
0xdeadbeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int verify_load_enabled(struct gk20a *g, struct cg_test_data *test_data,
|
||||
bool prod)
|
||||
{
|
||||
u32 i, j, value;
|
||||
int mismatch = 0;
|
||||
|
||||
for (i = 0; i < test_data->domain_count; i++) {
|
||||
for (j = 0; j < test_data->domain_desc_sizes[i]; j++) {
|
||||
value =
|
||||
nvgpu_readl(g, test_data->domain_descs[i][j].addr);
|
||||
if (prod == true &&
|
||||
value != test_data->domain_descs[i][j].prod) {
|
||||
mismatch = 1;
|
||||
goto out;
|
||||
} else if (prod == false &&
|
||||
value != test_data->domain_descs[i][j].disable) {
|
||||
mismatch = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return mismatch;
|
||||
}
|
||||
|
||||
static void load_test_data_non_prod(struct gk20a *g,
|
||||
struct cg_test_data *test_data)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < test_data->domain_count; i++) {
|
||||
test_data->gating_funcs[i](g, false);
|
||||
}
|
||||
}
|
||||
|
||||
int test_cg(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
struct cg_test_data *test_data = (struct cg_test_data *) args;
|
||||
struct gpu_ops gops_temp;
|
||||
u32 i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < test_data->domain_count; i++) {
|
||||
err = add_domain_gating_regs(g, test_data->domain_descs[i],
|
||||
test_data->domain_desc_sizes[i]);
|
||||
if (err != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
invalid_load_enabled(g, test_data);
|
||||
|
||||
/**
|
||||
* Test scenario where enabled flag and platform capability are
|
||||
* not set.
|
||||
*/
|
||||
test_data->load_enable(g);
|
||||
err = verify_load_enabled(g, test_data, true);
|
||||
if (err == 0) {
|
||||
unit_err(m, "enabled flag and platform capability "
|
||||
"not yet set\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/** Tests if platform capability is checked setting enabled flag. */
|
||||
nvgpu_set_enabled(g, test_data->cg_type, true);
|
||||
test_data->load_enable(g);
|
||||
err = verify_load_enabled(g, test_data, true);
|
||||
if (err == 0) {
|
||||
unit_err(m, "platform capability not yet set\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/** Tests if enabled flag is checked setting platform capability. */
|
||||
nvgpu_set_enabled(g, test_data->cg_type, false);
|
||||
if (test_data->cg_type == NVGPU_GPU_CAN_BLCG) {
|
||||
g->blcg_enabled = true;
|
||||
} else if (test_data->cg_type == NVGPU_GPU_CAN_SLCG) {
|
||||
g->slcg_enabled = true;
|
||||
}
|
||||
test_data->load_enable(g);
|
||||
err = verify_load_enabled(g, test_data, true);
|
||||
if (err == 0) {
|
||||
unit_err(m, "enabled flag not yet set\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/** Tests if gating registers are setup as expected. */
|
||||
nvgpu_set_enabled(g, test_data->cg_type, true);
|
||||
test_data->load_enable(g);
|
||||
err = verify_load_enabled(g, test_data, true);
|
||||
if (err != 0) {
|
||||
unit_err(m, "gating registers prod mismatch\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
load_test_data_non_prod(g, test_data);
|
||||
err = verify_load_enabled(g, test_data, false);
|
||||
if (err != 0) {
|
||||
unit_err(m, "gating registers disable mismatch\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Tests if CG hals are checked for NULL before invoking. */
|
||||
memcpy((u8 *)&gops_temp, (u8 *)&g->ops, sizeof(struct gpu_ops));
|
||||
memset(&g->ops, 0, sizeof(struct gpu_ops));
|
||||
|
||||
invalid_load_enabled(g, test_data);
|
||||
|
||||
test_data->load_enable(g);
|
||||
err = verify_load_enabled(g, test_data, true);
|
||||
if (err == 0) {
|
||||
unit_err(m, "CG hals not initialized\n");
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
memcpy((u8 *)&g->ops, (u8 *)&gops_temp, sizeof(struct gpu_ops));
|
||||
|
||||
/** Cleanup */
|
||||
for (i = 0; i < test_data->domain_count; i++) {
|
||||
delete_domain_gating_regs(g, test_data->domain_descs[i],
|
||||
test_data->domain_desc_sizes[i]);
|
||||
}
|
||||
|
||||
nvgpu_set_enabled(g, test_data->cg_type, false);
|
||||
|
||||
g->blcg_enabled = false;
|
||||
g->slcg_enabled = false;
|
||||
|
||||
/* Check that no invalid register access occurred */
|
||||
if (nvgpu_posix_io_get_error_code(g) != 0) {
|
||||
unit_return_fail(m, "Invalid register accessed\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int elcg_add_engine_therm_regs(struct gk20a *g)
|
||||
{
|
||||
u32 i;
|
||||
const struct nvgpu_device *dev;
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
|
||||
for (i = 0U; i < f->num_engines; i++) {
|
||||
dev = f->active_engines[i];
|
||||
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
therm_gate_ctrl_r(dev->engine_id), 0x4) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void elcg_delete_engine_therm_regs(struct gk20a *g)
|
||||
{
|
||||
u32 i;
|
||||
const struct nvgpu_device *dev;
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
|
||||
for (i = 0U; i < f->num_engines; i++) {
|
||||
dev = f->active_engines[i];
|
||||
|
||||
nvgpu_posix_io_delete_reg_space(g,
|
||||
therm_gate_ctrl_r(dev->engine_id));
|
||||
}
|
||||
}
|
||||
|
||||
static int verify_elcg_status(struct gk20a *g, u32 cg_mode)
|
||||
{
|
||||
u32 i;
|
||||
const struct nvgpu_device *dev;
|
||||
struct nvgpu_fifo *f = &g->fifo;
|
||||
int err = UNIT_SUCCESS;
|
||||
u32 gate_r;
|
||||
|
||||
for (i = 0; i < f->num_engines; i++) {
|
||||
dev = f->active_engines[i];
|
||||
gate_r = nvgpu_readl(g, therm_gate_ctrl_r(dev->engine_id));
|
||||
|
||||
if (cg_mode == ELCG_RUN) {
|
||||
if (get_field(gate_r,
|
||||
therm_gate_ctrl_eng_clk_m()) !=
|
||||
therm_gate_ctrl_eng_clk_run_f()) {
|
||||
err = UNIT_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_field(gate_r,
|
||||
therm_gate_ctrl_idle_holdoff_m()) !=
|
||||
therm_gate_ctrl_idle_holdoff_on_f()) {
|
||||
err = UNIT_FAIL;
|
||||
break;
|
||||
}
|
||||
} else if (cg_mode == ELCG_AUTO) {
|
||||
if (get_field(gate_r,
|
||||
therm_gate_ctrl_eng_clk_m()) !=
|
||||
therm_gate_ctrl_eng_clk_auto_f()) {
|
||||
err = UNIT_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int test_elcg_api(struct gk20a *g, int exp_err)
|
||||
{
|
||||
int err;
|
||||
|
||||
nvgpu_cg_elcg_enable_no_wait(g);
|
||||
err = verify_elcg_status(g, ELCG_AUTO);
|
||||
if (err != exp_err) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
nvgpu_cg_elcg_disable_no_wait(g);
|
||||
err = verify_elcg_status(g, ELCG_RUN);
|
||||
if (err != exp_err) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_elcg(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = test_fifo_init_support(m, g, NULL);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "failed to init fifo support\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = elcg_add_engine_therm_regs(g);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "failed to add engine therm registers\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (test_elcg_api(g, UNIT_FAIL) != UNIT_SUCCESS) {
|
||||
unit_return_fail(m, "enabled flag not yet set\n");
|
||||
}
|
||||
|
||||
nvgpu_set_enabled(g, NVGPU_GPU_CAN_ELCG, true);
|
||||
|
||||
if (test_elcg_api(g, UNIT_FAIL) != UNIT_SUCCESS) {
|
||||
unit_return_fail(m, "platform capability not yet set\n");
|
||||
}
|
||||
|
||||
g->elcg_enabled = true;
|
||||
|
||||
if (test_elcg_api(g, UNIT_SUCCESS) != UNIT_SUCCESS) {
|
||||
unit_return_fail(m,
|
||||
"elcg enable disable not setup correctly\n");
|
||||
}
|
||||
|
||||
/* Check that no invalid register access occurred */
|
||||
if (nvgpu_posix_io_get_error_code(g) != 0) {
|
||||
unit_return_fail(m, "Invalid register accessed\n");
|
||||
}
|
||||
|
||||
elcg_delete_engine_therm_regs(g);
|
||||
|
||||
err = test_fifo_remove_support(m, g, NULL);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "failed to remove fifo support\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct unit_module_test cg_tests[] = {
|
||||
UNIT_TEST(init, init_test_env, NULL, 0),
|
||||
|
||||
UNIT_TEST(blcg_fb_ltc, test_cg, &blcg_fb_ltc, 0),
|
||||
UNIT_TEST(blcg_fifo, test_cg, &blcg_fifo, 0),
|
||||
UNIT_TEST(blcg_ce, test_cg, &blcg_ce, 0),
|
||||
UNIT_TEST(blcg_pmu, test_cg, &blcg_pmu, 0),
|
||||
UNIT_TEST(blcg_gr, test_cg, &blcg_gr, 0),
|
||||
|
||||
UNIT_TEST(slcg_fb_ltc, test_cg, &slcg_fb_ltc, 0),
|
||||
UNIT_TEST(slcg_priring, test_cg, &slcg_priring, 0),
|
||||
UNIT_TEST(slcg_fifo, test_cg, &slcg_fifo, 0),
|
||||
UNIT_TEST(slcg_pmu, test_cg, &slcg_pmu, 0),
|
||||
UNIT_TEST(slcg_therm, test_cg, &slcg_therm, 0),
|
||||
UNIT_TEST(slcg_ce2, test_cg, &slcg_ce2, 0),
|
||||
|
||||
UNIT_TEST(slcg_gr_load_gating_prod, test_cg,
|
||||
&slcg_gr_load_gating_prod, 0),
|
||||
UNIT_TEST(blcg_gr_load_gating_prod, test_cg,
|
||||
&blcg_gr_load_gating_prod, 0),
|
||||
|
||||
UNIT_TEST(elcg, test_elcg, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(cg, cg_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
122
userspace/units/cg/nvgpu-cg.h
Normal file
122
userspace/units/cg/nvgpu-cg.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-cg
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for cg
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_cg
|
||||
*
|
||||
* Description: The cg unit shall be able to setup the clock gating register
|
||||
* values as specified in the hal reglist structures for BLCG/SLCG.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_cg_blcg_fb_ltc_load_enable, nvgpu_cg_blcg_fifo_load_enable,
|
||||
* nvgpu_cg_blcg_ce_load_enable, nvgpu_cg_blcg_pmu_load_enable,
|
||||
* nvgpu_cg_blcg_gr_load_enable, nvgpu_cg_slcg_fb_ltc_load_enable,
|
||||
* nvgpu_cg_slcg_priring_load_enable, nvgpu_cg_slcg_fifo_load_enable,
|
||||
* nvgpu_cg_slcg_pmu_load_enable, nvgpu_cg_slcg_therm_load_enable,
|
||||
* nvgpu_cg_slcg_ce2_load_enable, nvgpu_cg_init_gr_load_gating_prod
|
||||
*
|
||||
* Input: The struct specifying type of clock gating, target nvgpu routine
|
||||
* that handles the setup, clock gating domain descriptors.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the test environment:
|
||||
* - Register read/write IO callbacks.
|
||||
* - Add relevant fuse registers to the register space.
|
||||
* - Initialize hal to setup the hal functions.
|
||||
* - Initialize slcg and blcg gating register data by querying through
|
||||
* nvgpu exported functions.
|
||||
* - Add the domain gating registers to the register space.
|
||||
* - Load invalid values in the gating registers.
|
||||
* - Invoke the nvgpu function to load the clock gating values.
|
||||
* - Verify that load is not enabled as BLCG/SLCG enabled flag isn't set.
|
||||
* - Enable BLCG/SLCG enabled flag.
|
||||
* - Invoke the nvgpu function to load the clock gating values.
|
||||
* - Verify that load is not enabled as platform capability isn't set.
|
||||
* - Disable BLCG/SLCG enabled flag.
|
||||
* - Set the platform capability.
|
||||
* - Invoke the nvgpu function to load the clock gating values.
|
||||
* - Verify that load is not enabled as enabled flag isn't set.
|
||||
* - Enable BLCG/SLCG enabled flag.
|
||||
* - Invoke the nvgpu function to load the clock gating values.
|
||||
* - Verify that load is enabled.
|
||||
* - Invoke the nvgpu functions to load the non-prod clock gating values.
|
||||
* - Verify that load is not enabled.
|
||||
* - Set all CG gpu_ops to NULL.
|
||||
* - Invoke the nvgpu function to load the clock gating values.
|
||||
* - Verify that load is not enabled as HALs are not set.
|
||||
* - Restore the CG gpu_ops.
|
||||
* - Any invalid accesses by nvgpu will be caught through ABORTs and
|
||||
* test fails if ABORTs are encountered.
|
||||
* - Delete domain gating registers from the registere space.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_cg(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_elcg
|
||||
*
|
||||
* Description: The cg unit shall be able to setup the engine therm register
|
||||
* values to enable/disable ELCG.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_cg_elcg_enable_no_wait, nvgpu_cg_elcg_disable_no_wait
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the test environment:
|
||||
* - Register read/write IO callbacks.
|
||||
* - Add relevant fuse registers to the register space.
|
||||
* - Initialize hal to setup the hal functions.
|
||||
* - Initialize fifo support to configure ELCG at engine level.
|
||||
* - Add the engine therm registers to the register space.
|
||||
* - Invoke the nvgpu function to enable/disable ELCG.
|
||||
* - Verify that cg mode isn't set in therm registers as ELCG enabled flag
|
||||
* isn't set.
|
||||
* - Enable ELCG enabled flag.
|
||||
* - Invoke the nvgpu function to enable/disable ELCG.
|
||||
* - Verify that cg mode isn't set in therm registers as ELCG platform
|
||||
* capability isn't set.
|
||||
* - Set the platform capability.
|
||||
* - Invoke the nvgpu function to enable/disable ELCG.
|
||||
* - Verify that cg mode is set in therm registers.
|
||||
* - Any invalid accesses by nvgpu will be caught through ABORTs and
|
||||
* test fails if ABORTs are encountered.
|
||||
* - Delete engine therm registers from the registere space.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_elcg(struct unit_module *m, struct gk20a *g, void *args);
|
||||
26
userspace/units/class/Makefile
Normal file
26
userspace/units/class/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-class.o
|
||||
MODULE = class
|
||||
|
||||
include ../Makefile.units
|
||||
23
userspace/units/class/Makefile.interface.tmk
Normal file
23
userspace/units/class/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=class
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
24
userspace/units/class/Makefile.tmk
Normal file
24
userspace/units/class/Makefile.tmk
Normal file
@@ -0,0 +1,24 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=class
|
||||
NVGPU_UNIT_SRCS=nvgpu-class.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
155
userspace/units/class/nvgpu-class.c
Normal file
155
userspace/units/class/nvgpu-class.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/class.h>
|
||||
|
||||
#include "hal/class/class_gv11b.h"
|
||||
|
||||
#include "nvgpu-class.h"
|
||||
|
||||
u32 valid_compute_classes[] = {
|
||||
0xC3C0U, /* VOLTA_COMPUTE_A */
|
||||
};
|
||||
|
||||
u32 invalid_compute_classes[] = {
|
||||
0xC397U, /* VOLTA_A */
|
||||
0xC3B5U, /* VOLTA_DMA_COPY_A */
|
||||
0xC36FU, /* VOLTA_CHANNEL_GPFIFO_A */
|
||||
0xC0B5U, /* PASCAL_DMA_COPY_A */
|
||||
0xC06FU, /* PASCAL_CHANNEL_GPFIFO_A */
|
||||
0xB06FU, /* MAXWELL_CHANNEL_GPFIFO_A */
|
||||
0xB0B5U, /* MAXWELL_DMA_COPY_A */
|
||||
0xA140U, /* KEPLER_INLINE_TO_MEMORY_B */
|
||||
0xA0B5U, /* KEPLER_DMA_COPY_A */
|
||||
0xC097U, /* PASCAL_A */
|
||||
0xC0C0U, /* PASCAL_COMPUTE_A */
|
||||
0xB1C0U, /* MAXWELL_COMPUTE_B */
|
||||
0xB197U, /* MAXWELL_B */
|
||||
0x902DU, /* FERMI_TWOD_A */
|
||||
0x1234U, /* random value */
|
||||
0x76543210U, /* random value */
|
||||
0x0000U, /* BVEC test value */
|
||||
0xB000U, /* BVEC test value */
|
||||
0xC3BFU, /* BVEC test value */
|
||||
0xC3C1U, /* BVEC test value */
|
||||
0xD000U, /* BVEC test value */
|
||||
0xFFFFFFFFU, /* BVEC test value */
|
||||
};
|
||||
|
||||
u32 valid_classes[] = {
|
||||
0xC36FU, /* VOLTA_CHANNEL_GPFIFO_A */
|
||||
0xC397U, /* VOLTA_A */
|
||||
0xC3B5U, /* VOLTA_DMA_COPY_A */
|
||||
0xC3C0U, /* VOLTA_COMPUTE_A */
|
||||
};
|
||||
|
||||
u32 invalid_classes[] = {
|
||||
0x1234U, /* random value */
|
||||
0xC097U, /* PASCAL_A */
|
||||
0xC0C0U, /* PASCAL_COMPUTE_A */
|
||||
0xB1C0U, /* MAXWELL_COMPUTE_B */
|
||||
0xB197U, /* MAXWELL_B */
|
||||
0x902DU, /* FERMI_TWOD_A */
|
||||
0xC0B5U, /* PASCAL_DMA_COPY_A */
|
||||
0xC06FU, /* PASCAL_CHANNEL_GPFIFO_A */
|
||||
0xB06FU, /* MAXWELL_CHANNEL_GPFIFO_A */
|
||||
0xB0B5U, /* MAXWELL_DMA_COPY_A */
|
||||
0xA140U, /* KEPLER_INLINE_TO_MEMORY_B */
|
||||
0xA0B5U, /* KEPLER_DMA_COPY_A */
|
||||
0x76543210U, /* random value */
|
||||
0x0000U, /* BVEC test value */
|
||||
0xB000U, /* BVEC test value */
|
||||
0xC36EU, /* BVEC test value */
|
||||
0xC370U, /* BVEC test value */
|
||||
0xC396U, /* BVEC test value */
|
||||
0xC398U, /* BVEC test value */
|
||||
0xC3B4U, /* BVEC test value */
|
||||
0xC3B6U, /* BVEC test value */
|
||||
0xC3BFU, /* BVEC test value */
|
||||
0xC3C1U, /* BVEC test value */
|
||||
0xD000U, /* BVEC test value */
|
||||
0xFFFFFFFFU, /* BVEC test value */
|
||||
};
|
||||
|
||||
int class_validate_setup(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
bool valid = false;
|
||||
u32 i;
|
||||
|
||||
/* Init HAL */
|
||||
g->ops.gpu_class.is_valid_compute = gv11b_class_is_valid_compute;
|
||||
g->ops.gpu_class.is_valid = gv11b_class_is_valid;
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(valid_compute_classes)/sizeof(u32);
|
||||
i++) {
|
||||
valid = g->ops.gpu_class.is_valid_compute(
|
||||
valid_compute_classes[i]);
|
||||
if (!valid) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(invalid_compute_classes)/sizeof(u32);
|
||||
i++) {
|
||||
valid = g->ops.gpu_class.is_valid_compute(
|
||||
invalid_compute_classes[i]);
|
||||
if (valid) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(valid_classes)/sizeof(u32);
|
||||
i++) {
|
||||
valid = g->ops.gpu_class.is_valid(valid_classes[i]);
|
||||
if (!valid) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof(invalid_classes)/sizeof(u32);
|
||||
i++) {
|
||||
valid = g->ops.gpu_class.is_valid(invalid_classes[i]);
|
||||
if (valid) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
|
||||
fail:
|
||||
unit_err(m, "%s: failed to validate class API\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
struct unit_module_test class_tests[] = {
|
||||
UNIT_TEST(class_validate, class_validate_setup, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(class, class_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
82
userspace/units/class/nvgpu-class.h
Normal file
82
userspace/units/class/nvgpu-class.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_CLASS_H
|
||||
#define UNIT_NVGPU_CLASS_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-class
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for nvgpu.common.class
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: class_validate
|
||||
*
|
||||
* Description: Validate common.class unit API.
|
||||
*
|
||||
* Test Type: Feature, Boundary Values
|
||||
*
|
||||
* Targets: gops_class.is_valid, gv11b_class_is_valid
|
||||
* Equivalence classes:
|
||||
* Variable: class_num
|
||||
* - Valid : { 0xC3C0U }, { 0xC3B5U }, { 0xC36FU }, { 0xC397U }
|
||||
*
|
||||
* Targets: gops_class.is_valid_compute, gv11b_class_is_valid_compute,
|
||||
* Equivalence classes:
|
||||
* Variable: class_num
|
||||
* - Valid : { 0xC3C0U }
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize common.class HAL function pointers.
|
||||
* - Validate common.class unit API with below positive/negative data
|
||||
* sets.
|
||||
*
|
||||
* - g->ops.gpu_class.is_valid_compute()
|
||||
* Pass data set of supported compute classes and ensure API
|
||||
* returns success in each case.
|
||||
*
|
||||
* - g->ops.gpu_class.is_valid_compute()
|
||||
* Pass data set of unsupported compute classes and ensure API
|
||||
* returns failure in each case.
|
||||
*
|
||||
* - g->ops.gpu_class.is_valid()
|
||||
* Pass data set of all supported classes and ensure API
|
||||
* returns success in each case.
|
||||
*
|
||||
* - g->ops.gpu_class.is_valid()
|
||||
* Pass data set of unsupported classes and ensure API
|
||||
* returns failure in each case.
|
||||
*
|
||||
* Output:
|
||||
* Returns PASS if above validation was performed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int class_validate_setup(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
|
||||
#endif /* UNIT_NVGPU_CLASS_H */
|
||||
26
userspace/units/ecc/Makefile
Normal file
26
userspace/units/ecc/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-ecc.o
|
||||
MODULE = ecc
|
||||
|
||||
include ../Makefile.units
|
||||
35
userspace/units/ecc/Makefile.interface.tmk
Normal file
35
userspace/units/ecc/Makefile.interface.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-ecc
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
35
userspace/units/ecc/Makefile.tmk
Normal file
35
userspace/units/ecc/Makefile.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-ecc
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
253
userspace/units/ecc/nvgpu-ecc.c
Normal file
253
userspace/units/ecc/nvgpu-ecc.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/ecc.h>
|
||||
#include <nvgpu/ltc.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
#include <common/gr/gr_priv.h>
|
||||
|
||||
#include "nvgpu-ecc.h"
|
||||
|
||||
static void mock_ecc_free(struct gk20a *g) {
|
||||
|
||||
}
|
||||
|
||||
int test_ecc_init_support(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
/*
|
||||
* Case #1:
|
||||
* - First time ecc intialization.
|
||||
* - "nvgpu_ecc_init_support" should perform init and return 0.
|
||||
*/
|
||||
g->ecc.initialized = false;
|
||||
if (nvgpu_ecc_init_support(g) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case #2:
|
||||
* - Second time ecc intialization.
|
||||
* - "nvgpu_ecc_init_support" should skip init but return 0.
|
||||
*/
|
||||
g->ecc.initialized = true;
|
||||
if (nvgpu_ecc_init_support(g) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_ecc_finalize_support(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
/*
|
||||
* Case #1:
|
||||
* - First time ecc intialization.
|
||||
* - "nvgpu_ecc_finalize_support" should perform init and return 0.
|
||||
*/
|
||||
g->ecc.initialized = false;
|
||||
if (nvgpu_ecc_finalize_support(g) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case #2:
|
||||
* - Second time ecc intialization.
|
||||
* - "nvgpu_ecc_finalize_support" should skip init but return 0.
|
||||
*/
|
||||
g->ecc.initialized = true;
|
||||
if (nvgpu_ecc_finalize_support(g) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_ecc_counter_init(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
struct nvgpu_ecc_stat *stat = NULL;
|
||||
char *name;
|
||||
struct nvgpu_posix_fault_inj *kmem_fi =
|
||||
nvgpu_kmem_get_fault_injection();
|
||||
|
||||
/*
|
||||
* Test setup:
|
||||
* - Allocate memory for ecc counter name.
|
||||
* - Initialize ecc support.
|
||||
*/
|
||||
name = nvgpu_kzalloc(g, NVGPU_ECC_STAT_NAME_MAX_SIZE + 1);
|
||||
if (name == NULL) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
if (nvgpu_ecc_init_support(g) != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case #1:
|
||||
* - Initialize "name" with valid length string.
|
||||
* - "nvgpu_ecc_counter_init" should return 0.
|
||||
*/
|
||||
strcpy(name, "test_counter");
|
||||
if (nvgpu_ecc_counter_init(g, &stat, name) != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
nvgpu_ecc_counter_deinit(g, &stat);
|
||||
|
||||
/*
|
||||
* Case #2:
|
||||
* - Inject SW fault to cause "nvgpu_kzalloc" failure.
|
||||
* - "nvgpu_ecc_counter_init" should return -ENOMEM.
|
||||
*/
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, true, 0);
|
||||
if (nvgpu_ecc_counter_init(g, &stat, name) != -ENOMEM) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, false, 0);
|
||||
|
||||
/*
|
||||
* Case #3:
|
||||
* - Intialize "name" with string of length greater than
|
||||
* NVGPU_ECC_STAT_NAME_MAX_SIZE.
|
||||
* - "nvgpu_ecc_counter_init" should return 0, with a truncated
|
||||
* counter name.
|
||||
*/
|
||||
memset(name, NVGPU_ECC_STAT_NAME_MAX_SIZE, 'a');
|
||||
if (nvgpu_ecc_counter_init(g, &stat, name) != 0) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nvgpu_ecc_counter_deinit(g, &stat);
|
||||
|
||||
if (!nvgpu_list_empty(&g->ecc.stats_list)) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (stat != NULL) {
|
||||
nvgpu_ecc_counter_deinit(g, &stat);
|
||||
}
|
||||
nvgpu_kfree(g, name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_ecc_free(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
|
||||
if (nvgpu_ecc_init_support(g) != 0) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup:
|
||||
* - allocate memory for gr and clear it to zero.
|
||||
* - set gr->config to NULL to return immediately from
|
||||
* nvgpu_gr_ecc_free.
|
||||
* - Allocate memory for ltc and clear it to zero, this should set
|
||||
* the ltc_Count and slice_per_ltc to 0.
|
||||
*/
|
||||
g->gr = nvgpu_kzalloc(g, sizeof(*g->gr));
|
||||
if (g->gr == NULL) {
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
g->ltc = nvgpu_kzalloc(g, sizeof(*g->ltc));
|
||||
if (g->ltc == NULL) {
|
||||
nvgpu_kfree(g, g->gr);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Case #1:
|
||||
* - fb, fpba and pmu ecc HALs have ecc free handles set to NULL.
|
||||
* - "nvgpu_ecc_free" should skip freeing ecc counters for fb, fpba,
|
||||
* pmu and return without faulting.
|
||||
*/
|
||||
g->ops.fb.ecc.free = NULL;
|
||||
g->ops.pmu.ecc_free = NULL;
|
||||
g->ecc.ltc.ecc_sec_count = nvgpu_kzalloc(g,
|
||||
sizeof(*g->ecc.ltc.ecc_sec_count));
|
||||
g->ecc.ltc.ecc_ded_count = nvgpu_kzalloc(g,
|
||||
sizeof(*g->ecc.ltc.ecc_ded_count));
|
||||
if (g->ecc.ltc.ecc_sec_count == NULL
|
||||
|| g->ecc.ltc.ecc_ded_count == NULL) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
nvgpu_ecc_free(g);
|
||||
|
||||
/*
|
||||
* Case #2:
|
||||
* - fb and pmu ecc HALs have ecc free handles are set.
|
||||
* - "nvgpu_ecc_free" should return without faulting.
|
||||
*/
|
||||
g->ops.fb.ecc.free = mock_ecc_free;
|
||||
g->ops.pmu.ecc_free = mock_ecc_free;
|
||||
g->ecc.ltc.ecc_sec_count = nvgpu_kzalloc(g,
|
||||
sizeof(*g->ecc.ltc.ecc_sec_count));
|
||||
g->ecc.ltc.ecc_ded_count = nvgpu_kzalloc(g,
|
||||
sizeof(*g->ecc.ltc.ecc_ded_count));
|
||||
if (g->ecc.ltc.ecc_sec_count == NULL
|
||||
|| g->ecc.ltc.ecc_ded_count == NULL) {
|
||||
ret = UNIT_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
nvgpu_ecc_free(g);
|
||||
g->ecc.ltc.ecc_sec_count = NULL;
|
||||
g->ecc.ltc.ecc_ded_count = NULL;
|
||||
|
||||
cleanup:
|
||||
if (g->ecc.ltc.ecc_sec_count != NULL) {
|
||||
nvgpu_kfree(g, g->ecc.ltc.ecc_sec_count);
|
||||
}
|
||||
if (g->ecc.ltc.ecc_ded_count != NULL) {
|
||||
nvgpu_kfree(g, g->ecc.ltc.ecc_ded_count);
|
||||
}
|
||||
nvgpu_kfree(g, g->gr);
|
||||
nvgpu_kfree(g, g->ltc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct unit_module_test ecc_tests[] = {
|
||||
UNIT_TEST(ecc_init_support, test_ecc_init_support, NULL, 0),
|
||||
UNIT_TEST(ecc_finalize_support, test_ecc_finalize_support, NULL, 0),
|
||||
UNIT_TEST(ecc_counter_init, test_ecc_counter_init, NULL, 0),
|
||||
UNIT_TEST(ecc_free, test_ecc_free, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(ecc, ecc_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
161
userspace/units/ecc/nvgpu-ecc.h
Normal file
161
userspace/units/ecc/nvgpu-ecc.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_ECC_H
|
||||
#define UNIT_NVGPU_ECC_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-ecc
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for nvgpu.common.ecc
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Test specification for: test_ecc_init_support
|
||||
*
|
||||
* Description: Verify the "nvgpu_ecc_init_support" API.
|
||||
*
|
||||
* Test Type: Feature Based
|
||||
*
|
||||
* Targets: nvgpu_ecc_init_support, gops_ecc.ecc_init_support
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Test case #1
|
||||
* - Fresh initalization, ecc.initialized = false.
|
||||
* - "nvgpu_ecc_init_support" should succeed and return 0.
|
||||
* - Test case #2
|
||||
* - Re-initialization, ecc.initailiziation = true.
|
||||
* - "nvgpu_ecc_init_support" will succeed but skip init and return 0.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if "nvgpu_ecc_init_support" fails with non-zero return value.
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_ecc_init_support(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ecc_finalize_support
|
||||
*
|
||||
* Description: Verify the "nvgpu_ecc_finalize_support" API.
|
||||
*
|
||||
* Test Type: Feature Based
|
||||
*
|
||||
* Targets: nvgpu_ecc_finalize_support, gops_ecc.ecc_finalize_support
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Test case #1
|
||||
* - Fresh initalization, ecc.initialized = false.
|
||||
* - "nvgpu_ecc_finalize_support" should succeed and return 0.
|
||||
* - Test case #2
|
||||
* - Re-initialization, ecc.initailiziation = true.
|
||||
* - "nvgpu_ecc_finalize_support" will succeed but skip init and return 0.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if "nvgpu_ecc_finalize_support" fails with non-zero return value.
|
||||
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_ecc_finalize_support(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ecc_counter_init
|
||||
*
|
||||
* Description: Verify "nvgpu_ecc_counter_init" API.
|
||||
*
|
||||
* Test Type: Feature Based
|
||||
*
|
||||
* Targets: nvgpu_ecc_counter_init, nvgpu_ecc_stat_add
|
||||
*
|
||||
* Input: nvgpu_ecc_init_support
|
||||
*
|
||||
* Steps:
|
||||
* - Invokes "nvgpu_ecc_init_support".
|
||||
* - Allocate memory for counter name string.
|
||||
* - Test case #1
|
||||
* - Invokes "nvgpu_ecc_counter_init" with valid counter name("test_counter")
|
||||
* - "nvgpu_ecc_counter_init" should succeed and return 0.
|
||||
* - Test case #2
|
||||
* - Inject memory allocation fault
|
||||
* - "nvgpu_ecc_counter_init" should return -ENOMEM
|
||||
* - Test Case #3
|
||||
* - Set counter name to string with invalid length equal to
|
||||
* NVGPU_ECC_STAT_NAME_MAX_SIZE.
|
||||
* - "nvgpu_ecc_counter_init" will truncate the counter name and return 0.
|
||||
* - Test case #4
|
||||
* - Verify that the g->ecc.stats_list is empty.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL under the following conditions:
|
||||
* - Counter name memory allocation failed.
|
||||
* - "nvgpu_ecc_init_support" failed.
|
||||
* - "nvgpu_ecc_counter_init" failed.
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_ecc_counter_init(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_ecc_free
|
||||
*
|
||||
* Description: Verify "nvgpu_ecc_free" API.
|
||||
*
|
||||
* Test Type: Feature Based
|
||||
*
|
||||
* Targets: nvgpu_ecc_free
|
||||
*
|
||||
* Input: nvgpu_ecc_init_support
|
||||
*
|
||||
* Steps:
|
||||
* - Do the following setup
|
||||
* - "nvgpu_ecc_init_support".
|
||||
* - assign respective HALs and allocate memory for g->ltc and g->gr.
|
||||
* - Test case #1
|
||||
* - Invokes "nvgpu_ecc_free" with unassigned fb_ecc_free, fbpa_ecc_free
|
||||
* and pmu.ecc_free HALs.
|
||||
* - "nvgpu_ecc_free" should succeed without faulting.
|
||||
* - Test case #2
|
||||
* - Invokes "nvgpu_ecc_free" with uassigned fb_ecc_free, fbpa_ecc_free
|
||||
* and pmu.ecc_free HALs.
|
||||
* - "nvgpu_ecc_free" should succeed without faulting.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL under the following conditions:
|
||||
* - "nvgpu_ecc_init_support" failed.
|
||||
* - Memory allocation failed for either g->gr or g->ltc.
|
||||
* - Memory allocation failed for either ltc.ecc_sec/ded_count.
|
||||
*
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_ecc_free(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
#endif /* UNIT_NVGPU_ECC_H */
|
||||
26
userspace/units/enabled/Makefile
Normal file
26
userspace/units/enabled/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-enabled.o
|
||||
MODULE = nvgpu-enabled
|
||||
|
||||
include ../Makefile.units
|
||||
35
userspace/units/enabled/Makefile.interface.tmk
Normal file
35
userspace/units/enabled/Makefile.interface.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-enabled
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
35
userspace/units/enabled/Makefile.tmk
Normal file
35
userspace/units/enabled/Makefile.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-enabled
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
131
userspace/units/enabled/nvgpu-enabled.c
Normal file
131
userspace/units/enabled/nvgpu-enabled.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unit/io.h>
|
||||
#include <unit/unit.h>
|
||||
#include <nvgpu/enabled.h>
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include "nvgpu-enabled.h"
|
||||
|
||||
static unsigned long *original_enabled_flags;
|
||||
|
||||
int test_nvgpu_init_enabled_flags(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
int err;
|
||||
struct nvgpu_posix_fault_inj *kmem_fi =
|
||||
nvgpu_kmem_get_fault_injection();
|
||||
original_enabled_flags = g->enabled_flags;
|
||||
|
||||
/*
|
||||
* Test 1 - Enable SW fault injection and check that init function
|
||||
* fails with -ENOMEM.
|
||||
*/
|
||||
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, true, 0);
|
||||
err = nvgpu_init_enabled_flags(g);
|
||||
if (err != -ENOMEM) {
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
unit_return_fail(m,
|
||||
"enabled_flags init didn't fail as expected\n");
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, false, 0);
|
||||
|
||||
/*
|
||||
* Test 2 - Check that enabled_flags are inited successfully
|
||||
* Use these flags (allocated memory) for next tests in module.
|
||||
*/
|
||||
|
||||
err = nvgpu_init_enabled_flags(g);
|
||||
if (err != 0) {
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
unit_return_fail(m, "enabled_flags init failed\n");
|
||||
}
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_nvgpu_enabled_flags_false_check(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
u32 i;
|
||||
u32 n = NVGPU_MAX_ENABLED_BITS;
|
||||
|
||||
for (i = 1U; i < n; i++) { /* First flag is index 1 */
|
||||
if (nvgpu_is_enabled(g, i)) {
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
unit_return_fail(m,
|
||||
"enabled_flag %u inited to non-zero value\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_nvgpu_set_enabled(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
u32 i;
|
||||
u32 n = NVGPU_MAX_ENABLED_BITS;
|
||||
|
||||
for (i = 1U; i < n; i++) { /* First flag is index 1 */
|
||||
nvgpu_set_enabled(g, i, true);
|
||||
if (!nvgpu_is_enabled(g, i)) {
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
unit_return_fail(m,
|
||||
"enabled_flag %u could not be enabled\n", i);
|
||||
}
|
||||
|
||||
nvgpu_set_enabled(g, i, false);
|
||||
if (nvgpu_is_enabled(g, i)) {
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
unit_return_fail(m,
|
||||
"enabled_flag %u could not be disabled\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_nvgpu_free_enabled_flags(struct unit_module *m,
|
||||
struct gk20a *g, void *args)
|
||||
{
|
||||
nvgpu_free_enabled_flags(g);
|
||||
g->enabled_flags = original_enabled_flags;
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct unit_module_test enabled_tests[] = {
|
||||
/*
|
||||
* Init test should run first in order to use newly allocated memory.
|
||||
*/
|
||||
UNIT_TEST(init, test_nvgpu_init_enabled_flags, NULL, 0),
|
||||
|
||||
UNIT_TEST(enabled_flags_false_check, test_nvgpu_enabled_flags_false_check, NULL, 0),
|
||||
UNIT_TEST(set_enabled, test_nvgpu_set_enabled, NULL, 0),
|
||||
|
||||
UNIT_TEST(free, test_nvgpu_free_enabled_flags, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(enabled, enabled_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
125
userspace/units/enabled/nvgpu-enabled.h
Normal file
125
userspace/units/enabled/nvgpu-enabled.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_ENABLED_H
|
||||
#define UNIT_NVGPU_ENABLED_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-enabled
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for enabled
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_nvgpu_init_enabled_flags
|
||||
*
|
||||
* Description: Initialize GPU enabled_flags
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_init_enabled_flags
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - GPU structure contains enabled_flags initialized at boot
|
||||
* - Store already created enabled_flags pointer in a global variable
|
||||
* - Initialize enabled_flags for this unit test
|
||||
* - New created enabled_flags are set to false
|
||||
* - Check if return value indicates success
|
||||
*
|
||||
* Output: Returns SUCCESS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_nvgpu_init_enabled_flags(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_nvgpu_enabled_flags_false_check
|
||||
*
|
||||
* Description: Check if enabled_flags are set to false.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_is_enabled
|
||||
*
|
||||
* Input: test_nvgpu_init_enabled_flags
|
||||
*
|
||||
* Steps:
|
||||
* - Check flag value
|
||||
* - As flags are allocated for unit test, flag value is expected to be false
|
||||
* - Iterate over each flag and check if flag value is false
|
||||
*
|
||||
* Output: Returns SUCCESS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_nvgpu_enabled_flags_false_check(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_nvgpu_set_enabled
|
||||
*
|
||||
* Description: Set and reset enabled_flags
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_is_enabled, nvgpu_set_enabled
|
||||
*
|
||||
* Input: test_nvgpu_init_enabled_flags
|
||||
*
|
||||
* Steps:
|
||||
* - Set and reset each flag
|
||||
* - Iterate over a flag 'i' and set it to true
|
||||
* - Check if flag 'i' value is true
|
||||
* - Reset value of flag 'i' to false
|
||||
* - Check if flag 'i' value is false
|
||||
*
|
||||
* Output: Returns SUCCESS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_nvgpu_set_enabled(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_nvgpu_free_enabled_flags
|
||||
*
|
||||
* Description: Free enabled_flags
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_free_enabled_flags
|
||||
*
|
||||
* Input: test_nvgpu_init_enabled_flags
|
||||
*
|
||||
* Steps:
|
||||
* - Free enabled_flag memory
|
||||
* - Free enabled_flags allocated for this unit test
|
||||
* - Restore originally created enabled_flags pointer
|
||||
*
|
||||
* Output: Returns SUCCESS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_nvgpu_free_enabled_flags(struct unit_module *m,
|
||||
struct gk20a *g, void *args);
|
||||
#endif /* UNIT_NVGPU_ENABLED_H */
|
||||
27
userspace/units/falcon/Makefile
Normal file
27
userspace/units/falcon/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = falcon_utf.o
|
||||
|
||||
MODULE = falcon_utf
|
||||
|
||||
include ../Makefile.units
|
||||
29
userspace/units/falcon/Makefile.interface.tmk
Normal file
29
userspace/units/falcon/Makefile.interface.tmk
Normal file
@@ -0,0 +1,29 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
# libfalcon_utf interface makefile fragment
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION
|
||||
|
||||
NV_INTERFACE_NAME := falcon_utf
|
||||
NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME)
|
||||
NV_INTERFACE_SONAME := lib$(NV_INTERFACE_NAME).so
|
||||
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
26
userspace/units/falcon/Makefile.tmk
Normal file
26
userspace/units/falcon/Makefile.tmk
Normal file
@@ -0,0 +1,26 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019 NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
# Component makefile for compiling falcon_utf common tests.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME = falcon_utf
|
||||
NVGPU_UNIT_SRCS = falcon_utf.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
33
userspace/units/falcon/falcon_tests/Makefile
Normal file
33
userspace/units/falcon/falcon_tests/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = falcon.o
|
||||
MODULE = falcon
|
||||
|
||||
LIB_PATHS += -lfalcon_utf
|
||||
|
||||
include ../../Makefile.units
|
||||
|
||||
lib$(MODULE).so: falcon_utf
|
||||
|
||||
falcon_utf:
|
||||
$(MAKE) -C ..
|
||||
23
userspace/units/falcon/falcon_tests/Makefile.interface.tmk
Normal file
23
userspace/units/falcon/falcon_tests/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=falcon
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
27
userspace/units/falcon/falcon_tests/Makefile.tmk
Normal file
27
userspace/units/falcon/falcon_tests/Makefile.tmk
Normal file
@@ -0,0 +1,27 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019-2020 NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=falcon
|
||||
NVGPU_UNIT_SRCS=falcon.c
|
||||
|
||||
NVGPU_UNIT_INTERFACE_DIRS := \
|
||||
$(NV_COMPONENT_DIR)/..
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
1409
userspace/units/falcon/falcon_tests/falcon.c
Normal file
1409
userspace/units/falcon/falcon_tests/falcon.c
Normal file
File diff suppressed because it is too large
Load Diff
514
userspace/units/falcon/falcon_tests/nvgpu-falcon.h
Normal file
514
userspace/units/falcon/falcon_tests/nvgpu-falcon.h
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-falcon
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for falcon
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_sw_init_free
|
||||
*
|
||||
* Description: The falcon unit shall be able to initialize the falcon's
|
||||
* base register address, required software setup for valid falcon ID.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_get_instance, nvgpu_falcon_sw_init,
|
||||
* nvgpu_falcon_sw_free, gops_pmu.falcon_base_addr,
|
||||
* gv11b_pmu_falcon_base_addr, gops_pmu.setup_apertures,
|
||||
* gv11b_setup_apertures, gops_pmu.flcn_setup_boot_config,
|
||||
* gv11b_pmu_flcn_setup_boot_config
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_sw_init with valid falcon ID before initializing HAL.
|
||||
* - Verify that falcon initialization fails since valid gpu_arch|impl
|
||||
* are not initialized.
|
||||
* - Invoke nvgpu_falcon_sw_free with above falcon ID.
|
||||
* - Initialize the test environment:
|
||||
* - Register read/write IO callbacks that handle falcon IO as well.
|
||||
* - Add relevant fuse registers to the register space.
|
||||
* - Initialize hal to setup the hal functions.
|
||||
* - Initialize UTF (Unit Test Framework) falcon structures for PMU and
|
||||
* GPCCS falcons.
|
||||
* - Create and initialize test buffer with random data.
|
||||
* - Invoke nvgpu_falcon_sw_init with invalid falcon ID.
|
||||
* - Verify that falcon initialization fails.
|
||||
* - Invoke nvgpu_falcon_sw_free with above falcon ID.
|
||||
* - Invoke nvgpu_falcon_sw_init with valid falcon ID.
|
||||
* - Verify that falcon initialization succeeds.
|
||||
* - Invoke nvgpu_falcon_sw_free with above falcon ID.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_sw_init_free(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_get_id
|
||||
*
|
||||
* Description: The falcon unit shall be able to return the falcon ID
|
||||
* for the falcon.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_falcon_get_id
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_get_id with the gpccs falcon struct.
|
||||
* - Verify that return falcon ID is #FALCON_ID_GPCCS.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_get_id(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_reset
|
||||
*
|
||||
* Description: The falcon unit shall be able to reset the falcon CPU or trigger
|
||||
* engine specific reset for valid falcon ID.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_reset, gops_falcon.reset, gk20a_falcon_reset
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_reset with NULL falcon pointer.
|
||||
* - Verify that reset fails with -EINVAL return value.
|
||||
* - Invoke nvgpu_falcon_reset with uninitialized falcon struct.
|
||||
* - Verify that reset fails with -EINVAL return value.
|
||||
* - Invoke nvgpu_falcon_reset with valid falcon ID.
|
||||
* - Verify that falcon initialization succeeds and check that bit
|
||||
* falcon_cpuctl_hreset_f is set in falcon_cpuctl register.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_reset(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_scrub
|
||||
*
|
||||
* Description: The falcon unit shall be able to check and return the falcon
|
||||
* memory scrub status.
|
||||
*
|
||||
* Test Type: Feature, Error guessing, Error injection
|
||||
*
|
||||
* Targets: nvgpu_falcon_mem_scrub_wait, gops_falcon.is_falcon_scrubbing_done,
|
||||
* gk20a_is_falcon_scrubbing_done
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_mem_scrub_wait with uninitialized falcon struct.
|
||||
* - Verify that wait fails with -EINVAL return value.
|
||||
* - Invoke nvgpu_falcon_mem_scrub_wait with initialized falcon struct where
|
||||
* underlying falcon's memory scrub is completed.
|
||||
* - Verify that wait succeeds with 0 return value.
|
||||
* - Invoke nvgpu_falcon_mem_scrub_wait with initialized falcon struct where
|
||||
* underlying falcon's memory scrub is yet to complete.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
* - Enable fault injection for the timer init call for branch coverage.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_scrub(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_idle
|
||||
*
|
||||
* Description: The falcon unit shall be able to check and return the falcon
|
||||
* idle status.
|
||||
*
|
||||
* Test Type: Feature, Error guessing, Error injection
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Targets: nvgpu_falcon_wait_idle, gops_falcon.is_falcon_idle,
|
||||
* gk20a_is_falcon_idle
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_wait_idle with uninitialized falcon struct.
|
||||
* - Verify that wait fails with -EINVAL return value.
|
||||
* - Invoke nvgpu_falcon_wait_idle with initialized falcon struct where
|
||||
* underlying falcon is idle.
|
||||
* - Verify that wait succeeds with 0 return value.
|
||||
* - Invoke nvgpu_falcon_wait_idle with initialized falcon struct where
|
||||
* underlying falcon's ext units are busy but falcon CPU is idle.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
* - Invoke nvgpu_falcon_wait_idle with initialized falcon struct where
|
||||
* underlying falcon is not idle.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
* - Enable fault injection for the timer init call for branch coverage.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_idle(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_halt
|
||||
*
|
||||
* Description: The falcon unit shall be able to check and return the falcon
|
||||
* halt status.
|
||||
*
|
||||
* Test Type: Feature, Error guessing, Error injection
|
||||
*
|
||||
* Targets: nvgpu_falcon_wait_for_halt, gops_falcon.is_falcon_cpu_halted,
|
||||
* gk20a_is_falcon_cpu_halted
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_wait_for_halt with uninitialized falcon struct.
|
||||
* - Verify that wait fails with -EINVAL return value.
|
||||
* - Invoke nvgpu_falcon_wait_for_halt with initialized falcon struct where
|
||||
* underlying falcon is halted.
|
||||
* - Verify that wait succeeds with 0 return value.
|
||||
* - Invoke nvgpu_falcon_wait_for_halt with initialized falcon struct where
|
||||
* underlying falcon is not halted.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
* - Enable fault injection for the timer init call for branch coverage.
|
||||
* - Verify that wait fails with -ETIMEDOUT return value.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_halt(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_init
|
||||
*
|
||||
* Description: The falcon unit shall be able to write to falcon's IMEM and
|
||||
* DMEM.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, nvgpu_falcon_copy_to_dmem,
|
||||
* gops_falcon.copy_to_imem, gops_falcon.copy_to_dmem,
|
||||
* gk20a_falcon_copy_to_imem, gk20a_falcon_copy_to_dmem
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* uninitialized falcon struct with sample random data.
|
||||
* - Verify that writes fail with -EINVAL return value in both cases.
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data.
|
||||
* - Verify that writes succeed with 0 return value in both cases.
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data of size that is
|
||||
* not multiple of words.
|
||||
* - Verify that writes succeed with 0 return value in both cases.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_init(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_range
|
||||
*
|
||||
* Description: The falcon unit shall be able to write to falcon's IMEM and
|
||||
* DMEM in accessible range.
|
||||
*
|
||||
* Test Type: Feature, Boundary values
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, nvgpu_falcon_copy_to_dmem,
|
||||
* gops_falcon.copy_to_imem, gops_falcon.copy_to_dmem,
|
||||
* gops_falcon.get_mem_size, gk20a_falcon_copy_to_imem,
|
||||
* gk20a_falcon_copy_to_dmem, gk20a_falcon_get_mem_size
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data and valid range.
|
||||
* - Verify that writes succeed with 0 return value in both cases.
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data and invalid range
|
||||
* with valid and invalid offset.
|
||||
* - Verify that writes fail with -EINVAL return value in both cases.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_range(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_fault
|
||||
*
|
||||
* Description: The falcon unit shall fail the call to copy to DMEM when
|
||||
* DMEMC reads return invalid value due to HW fault.
|
||||
*
|
||||
* Test Type: Error injection
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_dmem, gops_falcon.copy_to_dmem,
|
||||
* gk20a_falcon_copy_to_dmem
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Enable the falcon DMEMC read fault.
|
||||
* - Invoke nvgpu_falcon_copy_to_dmem with initialized falcon struct with
|
||||
* sample random data and valid range.
|
||||
* - Disable the falcon DMEMC read fault.
|
||||
* - Verify that writes failed.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_aligned
|
||||
*
|
||||
* Description: The falcon unit shall be able to write to falcon's IMEM and
|
||||
* DMEM only at aligned offsets.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, nvgpu_falcon_copy_to_dmem,
|
||||
* gops_falcon.copy_to_imem, gops_falcon.copy_to_dmem,
|
||||
* gk20a_falcon_copy_to_imem, gk20a_falcon_copy_to_dmem
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data and 4-byte aligned
|
||||
* offset.
|
||||
* - Verify that writes succeed with 0 return value in both cases.
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data and non 4-byte
|
||||
* aligned offset.
|
||||
* - Verify that writes fail with -EINVAL return value in both cases.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_aligned(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_zero
|
||||
*
|
||||
* Description: The falcon unit shall fail the API call to write zero
|
||||
* bytes to falcon memory.
|
||||
*
|
||||
* Test Type: Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, nvgpu_falcon_copy_to_dmem,
|
||||
* gops_falcon.copy_to_imem, gops_falcon.copy_to_dmem,
|
||||
* gk20a_falcon_copy_to_imem, gk20a_falcon_copy_to_dmem
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with sample random data and zero bytes.
|
||||
* - Verify that writes fail with -EINVAL return value in both cases.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_zero(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mailbox
|
||||
*
|
||||
* Description: The falcon unit shall read and write value of falcon's mailbox
|
||||
* registers.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_mailbox_read, nvgpu_falcon_mailbox_write,
|
||||
* gops_falcon.mailbox_read, gops_falcon.mailbox_write,
|
||||
* gk20a_falcon_mailbox_read, gk20a_falcon_mailbox_write
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_mailbox_read and nvgpu_falcon_mailbox_write with
|
||||
* uninitialized falcon struct.
|
||||
* - Verify that read returns zero.
|
||||
* - Write a sample value to mailbox registers and read using the nvgpu APIs.
|
||||
* - Verify the value by reading the registers through IO accessor.
|
||||
* - Read/Write value from invalid mailbox register of initialized falcon.
|
||||
* - Verify that read returns zero.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mailbox(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_bootstrap
|
||||
*
|
||||
* Description: The falcon unit shall configure the bootstrap parameters into
|
||||
* falcon memory and registers.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_hs_ucode_load_bootstrap, gops_falcon.bootstrap,
|
||||
* gk20a_falcon_bootstrap
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with uninitialized
|
||||
* falcon struct.
|
||||
* - Verify that call fails with -EINVAL return value.
|
||||
* - Fetch the ACR firmware from filesystem.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* Fail the falcon reset by failing mem scrub wait.
|
||||
* - Verify that bootstrap fails.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* Fail the imem copy for non-secure code by setting invalid size in ucode
|
||||
* header.
|
||||
* - Verify that bootstrap fails.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* Fail the imem copy for secure code by setting invalid size in ucode header.
|
||||
* - Verify that bootstrap fails.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* Fail the imem copy for secure code by setting invalid size in ucode header.
|
||||
* - Verify that bootstrap fails.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* Fail the dmem copy setting invalid dmem size in ucode header.
|
||||
* - Verify that bootstrap fails.
|
||||
* - Invoke nvgpu_falcon_hs_ucode_load_bootstrap with initialized falcon struct.
|
||||
* - Verify that bootstrap succeeds and verify the expected state of registers
|
||||
* falcon_dmactl_r, falcon_falcon_bootvec_r, falcon_falcon_cpuctl_r.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_bootstrap(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_unaligned_cpu_buffer
|
||||
*
|
||||
* Description: The falcon unit shall be able to read/write from/to falcon's
|
||||
* IMEM and DMEM from memory buffer that is unaligned.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, nvgpu_falcon_copy_to_dmem,
|
||||
* gops_falcon.copy_to_imem, gops_falcon.copy_to_dmem,
|
||||
* gk20a_falcon_copy_to_imem, gk20a_falcon_copy_to_dmem
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize unaligned random data memory buffer and set size.
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_to_dmem with
|
||||
* initialized falcon struct with above initialized sample random data
|
||||
* and valid range.
|
||||
* - Verify that writes succeed with 0 return value in both cases.
|
||||
* - Write data of size 1K to valid range in imem/dmem from unaligned data
|
||||
* to verify the buffering logic and cover branches in
|
||||
* falcon_copy_to_dmem|imem_unaligned_src.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_unaligned_cpu_buffer(struct unit_module *m,
|
||||
struct gk20a *g, void *__args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_falcon_mem_rw_inval_port
|
||||
*
|
||||
* Description: The falcon unit shall not be able to read/write from/to falcon's
|
||||
* memory from invalid port.
|
||||
*
|
||||
* Test Type: Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_copy_to_imem, gops_falcon.copy_to_imem,
|
||||
* gops_falcon.get_ports_count, gk20a_falcon_copy_to_imem,
|
||||
* gk20a_falcon_get_ports_count
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_copy_to_imem and nvgpu_falcon_copy_from_imem with
|
||||
* initialized falcon struct with initialized sample random data, valid
|
||||
* range but invalid port.
|
||||
* - Verify that return value is -EINVAL.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_mem_rw_inval_port(struct unit_module *m, struct gk20a *g,
|
||||
void *__args);
|
||||
/**
|
||||
* Test specification for: test_falcon_irq
|
||||
*
|
||||
* Description: The falcon unit shall be able to set or clear the falcon irq
|
||||
* mask and destination registers for supported falcons.
|
||||
*
|
||||
* Test Type: Feature, Error guessing
|
||||
*
|
||||
* Targets: nvgpu_falcon_set_irq, gops_falcon.set_irq,
|
||||
* gk20a_falcon_set_irq
|
||||
*
|
||||
* Input: None.
|
||||
*
|
||||
* Steps:
|
||||
* - Invoke nvgpu_falcon_set_irq with uninitialized falcon struct.
|
||||
* - Invoke nvgpu_falcon_set_irq with initialized falcon struct where
|
||||
* underlying falcon has interrupt support disabled.
|
||||
* - Invoke nvgpu_falcon_set_irq to enable the interrupts with
|
||||
* initialized falcon struct and sample interrupt mask and
|
||||
* destination values and the underlying falcon has
|
||||
* interrupt support enabled.
|
||||
* - Verify that falcon_irqmset_r and falcon_irqdest_r are set as
|
||||
* expected.
|
||||
* - Invoke nvgpu_falcon_set_irq to disable the interrupts with
|
||||
* initialized falcon struct and the underlying falcon has
|
||||
* interrupt support enabled.
|
||||
* - Verify that falcon_irqmclr_r is set to 0xffffffff.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int test_falcon_irq(struct unit_module *m, struct gk20a *g, void *__args);
|
||||
255
userspace/units/falcon/falcon_utf.c
Normal file
255
userspace/units/falcon/falcon_utf.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/io.h>
|
||||
|
||||
#include <nvgpu/falcon.h>
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/kmem.h>
|
||||
#include <nvgpu/hw/gm20b/hw_falcon_gm20b.h>
|
||||
|
||||
#include "falcon_utf.h"
|
||||
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
struct nvgpu_posix_fault_inj *nvgpu_utf_falcon_memcpy_get_fault_injection(void)
|
||||
{
|
||||
struct nvgpu_posix_fault_inj_container *c =
|
||||
nvgpu_posix_fault_injection_get_container();
|
||||
|
||||
return &c->falcon_memcpy_fi;
|
||||
}
|
||||
|
||||
void nvgpu_utf_falcon_writel_access_reg_fn(struct gk20a *g,
|
||||
struct utf_falcon *flcn,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
u32 addr_mask = falcon_falcon_dmemc_offs_m() |
|
||||
falcon_falcon_dmemc_blk_m();
|
||||
u32 flcn_base;
|
||||
u32 ctrl_r;
|
||||
u32 offset;
|
||||
|
||||
flcn_base = flcn->flcn->flcn_base;
|
||||
|
||||
if (access->addr == (flcn_base + falcon_falcon_imemd_r(0))) {
|
||||
ctrl_r = nvgpu_posix_io_readl_reg_space(g,
|
||||
flcn_base + falcon_falcon_imemc_r(0));
|
||||
|
||||
if (ctrl_r & falcon_falcon_imemc_aincw_f(1)) {
|
||||
offset = ctrl_r & addr_mask;
|
||||
|
||||
*((u32 *) ((u8 *)flcn->imem + offset)) = access->value;
|
||||
offset += 4U;
|
||||
|
||||
ctrl_r &= ~(addr_mask);
|
||||
ctrl_r |= offset;
|
||||
nvgpu_posix_io_writel_reg_space(g,
|
||||
flcn_base + falcon_falcon_imemc_r(0), ctrl_r);
|
||||
}
|
||||
} else if (access->addr == (flcn_base + falcon_falcon_dmemd_r(0))) {
|
||||
ctrl_r = nvgpu_posix_io_readl_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmemc_r(0));
|
||||
|
||||
if (ctrl_r & falcon_falcon_dmemc_aincw_f(1)) {
|
||||
offset = ctrl_r & addr_mask;
|
||||
|
||||
*((u32 *) ((u8 *)flcn->dmem + offset)) = access->value;
|
||||
offset += 4U;
|
||||
|
||||
ctrl_r &= ~(addr_mask);
|
||||
ctrl_r |= offset;
|
||||
nvgpu_posix_io_writel_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmemc_r(0), ctrl_r);
|
||||
}
|
||||
} else if (access->addr == (flcn_base + falcon_falcon_cpuctl_r())) {
|
||||
|
||||
if (access->value == falcon_falcon_cpuctl_halt_intr_m()) {
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g,
|
||||
access->addr);
|
||||
access->value |= falcon_falcon_cpuctl_halt_intr_m();
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr,
|
||||
access->value);
|
||||
} else if (access->value == falcon_falcon_cpuctl_startcpu_f(1)) {
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g,
|
||||
access->addr);
|
||||
access->value |= falcon_falcon_cpuctl_startcpu_f(1);
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr,
|
||||
access->value);
|
||||
/* set falcon mailbox0 to value 0 */
|
||||
nvgpu_posix_io_writel_reg_space(g, flcn_base +
|
||||
falcon_falcon_mailbox0_r(), 0);
|
||||
}
|
||||
}
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
}
|
||||
|
||||
void nvgpu_utf_falcon_readl_access_reg_fn(struct gk20a *g,
|
||||
struct utf_falcon *flcn,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
u32 addr_mask = falcon_falcon_dmemc_offs_m() |
|
||||
falcon_falcon_dmemc_blk_m();
|
||||
u32 flcn_base;
|
||||
u32 ctrl_r;
|
||||
u32 offset;
|
||||
|
||||
flcn_base = flcn->flcn->flcn_base;
|
||||
|
||||
if (access->addr == (flcn_base + falcon_falcon_imemd_r(0))) {
|
||||
ctrl_r = nvgpu_posix_io_readl_reg_space(g,
|
||||
flcn_base + falcon_falcon_imemc_r(0));
|
||||
|
||||
if (ctrl_r & falcon_falcon_dmemc_aincr_f(1)) {
|
||||
offset = ctrl_r & addr_mask;
|
||||
|
||||
access->value = *((u32 *) ((u8 *)flcn->imem + offset));
|
||||
offset += 4U;
|
||||
|
||||
ctrl_r &= ~(addr_mask);
|
||||
ctrl_r |= offset;
|
||||
nvgpu_posix_io_writel_reg_space(g,
|
||||
flcn_base + falcon_falcon_imemc_r(0), ctrl_r);
|
||||
}
|
||||
} else if (access->addr == (flcn_base + falcon_falcon_dmemd_r(0))) {
|
||||
ctrl_r = nvgpu_posix_io_readl_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmemc_r(0));
|
||||
|
||||
if (ctrl_r & falcon_falcon_dmemc_aincr_f(1)) {
|
||||
offset = ctrl_r & addr_mask;
|
||||
|
||||
access->value = *((u32 *) ((u8 *)flcn->dmem + offset));
|
||||
offset += 4U;
|
||||
|
||||
ctrl_r &= ~(addr_mask);
|
||||
ctrl_r |= offset;
|
||||
nvgpu_posix_io_writel_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmemc_r(0), ctrl_r);
|
||||
}
|
||||
} else if (access->addr == (flcn_base + falcon_falcon_dmemc_r(0))) {
|
||||
ctrl_r = nvgpu_posix_io_readl_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmemc_r(0));
|
||||
|
||||
if (nvgpu_posix_fault_injection_handle_call(
|
||||
nvgpu_utf_falcon_memcpy_get_fault_injection())) {
|
||||
access->value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
access->value = ctrl_r & addr_mask;
|
||||
} else {
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
}
|
||||
|
||||
struct utf_falcon *nvgpu_utf_falcon_init(struct unit_module *m,
|
||||
struct gk20a *g, u32 flcn_id)
|
||||
{
|
||||
struct utf_falcon *utf_flcn;
|
||||
struct nvgpu_falcon *flcn;
|
||||
u32 flcn_size;
|
||||
u32 flcn_base;
|
||||
u32 hwcfg_r, hwcfg1_r, ports;
|
||||
|
||||
if (nvgpu_falcon_sw_init(g, flcn_id) != 0) {
|
||||
unit_err(m, "nvgpu Falcon init failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flcn = nvgpu_falcon_get_instance(g, flcn_id);
|
||||
|
||||
utf_flcn = (struct utf_falcon *) malloc(sizeof(struct utf_falcon));
|
||||
if (!utf_flcn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utf_flcn->flcn = flcn;
|
||||
|
||||
flcn_base = flcn->flcn_base;
|
||||
if (nvgpu_posix_io_add_reg_space(g,
|
||||
flcn_base,
|
||||
UTF_FALCON_MAX_REG_OFFSET) != 0) {
|
||||
unit_err(m, "Falcon add reg space failed!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize IMEM & DMEM size that will be needed by NvGPU for
|
||||
* bounds check.
|
||||
*/
|
||||
hwcfg_r = flcn_base + falcon_falcon_hwcfg_r();
|
||||
flcn_size = UTF_FALCON_IMEM_DMEM_SIZE / FALCON_BLOCK_SIZE;
|
||||
flcn_size = (flcn_size << 9) | flcn_size;
|
||||
nvgpu_posix_io_writel_reg_space(g, hwcfg_r, flcn_size);
|
||||
|
||||
/* set imem and dmem ports count. */
|
||||
hwcfg1_r = flcn_base + falcon_falcon_hwcfg1_r();
|
||||
ports = (1 << 8) | (1 << 12);
|
||||
nvgpu_posix_io_writel_reg_space(g, hwcfg1_r, ports);
|
||||
|
||||
utf_flcn->imem = (u32 *) nvgpu_kzalloc(g, UTF_FALCON_IMEM_DMEM_SIZE);
|
||||
if (utf_flcn->imem == NULL) {
|
||||
unit_err(m, "Falcon imem alloc failed!\n");
|
||||
goto out_reg_space;
|
||||
}
|
||||
|
||||
utf_flcn->dmem = (u32 *) nvgpu_kzalloc(g, UTF_FALCON_IMEM_DMEM_SIZE);
|
||||
if (utf_flcn->dmem == NULL) {
|
||||
unit_err(m, "Falcon dmem alloc failed!\n");
|
||||
goto free_imem;
|
||||
}
|
||||
|
||||
return utf_flcn;
|
||||
|
||||
free_imem:
|
||||
nvgpu_kfree(g, utf_flcn->imem);
|
||||
out_reg_space:
|
||||
nvgpu_posix_io_delete_reg_space(g, flcn_base);
|
||||
out:
|
||||
nvgpu_falcon_sw_free(g, flcn_id);
|
||||
free(utf_flcn);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nvgpu_utf_falcon_free(struct gk20a *g, struct utf_falcon *utf_flcn)
|
||||
{
|
||||
if (utf_flcn == NULL || utf_flcn->flcn == NULL)
|
||||
return;
|
||||
|
||||
nvgpu_kfree(g, utf_flcn->dmem);
|
||||
nvgpu_kfree(g, utf_flcn->imem);
|
||||
nvgpu_posix_io_delete_reg_space(g, utf_flcn->flcn->flcn_base);
|
||||
nvgpu_falcon_sw_free(g, utf_flcn->flcn->flcn_id);
|
||||
free(utf_flcn);
|
||||
}
|
||||
|
||||
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, struct utf_falcon *utf_flcn,
|
||||
u32 reg_data)
|
||||
{
|
||||
u32 flcn_base;
|
||||
|
||||
flcn_base = utf_flcn->flcn->flcn_base;
|
||||
|
||||
nvgpu_posix_io_writel_reg_space(g,
|
||||
flcn_base + falcon_falcon_dmactl_r(), reg_data);
|
||||
}
|
||||
55
userspace/units/falcon/falcon_utf.h
Normal file
55
userspace/units/falcon/falcon_utf.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __FALCON_UTF_H__
|
||||
#define __FALCON_UTF_H__
|
||||
|
||||
#include <nvgpu/posix/types.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
|
||||
#define UTF_FALCON_MAX_REG_OFFSET 0x400
|
||||
#define UTF_FALCON_IMEM_DMEM_SIZE (127 * 1024)
|
||||
|
||||
struct gk20a;
|
||||
struct nvgpu_falcon;
|
||||
|
||||
struct utf_falcon {
|
||||
struct nvgpu_falcon *flcn;
|
||||
u32 *imem;
|
||||
u32 *dmem;
|
||||
};
|
||||
|
||||
struct nvgpu_posix_fault_inj *nvgpu_utf_falcon_memcpy_get_fault_injection(void);
|
||||
|
||||
void nvgpu_utf_falcon_writel_access_reg_fn(struct gk20a *g,
|
||||
struct utf_falcon *flcn,
|
||||
struct nvgpu_reg_access *access);
|
||||
void nvgpu_utf_falcon_readl_access_reg_fn(struct gk20a *g,
|
||||
struct utf_falcon *flcn,
|
||||
struct nvgpu_reg_access *access);
|
||||
struct utf_falcon *nvgpu_utf_falcon_init(struct unit_module *m,
|
||||
struct gk20a *g, u32 flcn_id);
|
||||
void nvgpu_utf_falcon_free(struct gk20a *g, struct utf_falcon *utf_flcn);
|
||||
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, struct utf_falcon *utf_flcn,
|
||||
u32 reg_data);
|
||||
|
||||
#endif
|
||||
28
userspace/units/falcon/libfalcon_utf.export
Normal file
28
userspace/units/falcon/libfalcon_utf.export
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
nvgpu_utf_falcon_free
|
||||
nvgpu_utf_falcon_init
|
||||
nvgpu_utf_falcon_readl_access_reg_fn
|
||||
nvgpu_utf_falcon_set_dmactl
|
||||
nvgpu_utf_falcon_writel_access_reg_fn
|
||||
nvgpu_utf_falcon_memcpy_get_fault_injection
|
||||
27
userspace/units/fb/Makefile
Normal file
27
userspace/units/fb/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = fb_fusa.o fb_gv11b_fusa.o fb_gm20b_fusa.o fb_mmu_fault_gv11b_fusa.o \
|
||||
fb_intr_gv11b_fusa.o
|
||||
MODULE = fb
|
||||
|
||||
include ../Makefile.units
|
||||
23
userspace/units/fb/Makefile.interface.tmk
Normal file
23
userspace/units/fb/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=fb
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
25
userspace/units/fb/Makefile.tmk
Normal file
25
userspace/units/fb/Makefile.tmk
Normal file
@@ -0,0 +1,25 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=fb
|
||||
NVGPU_UNIT_SRCS=fb_fusa.c fb_gv11b_fusa.c fb_gm20b_fusa.c \
|
||||
fb_mmu_fault_gv11b_fusa.c fb_intr_gv11b_fusa.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
159
userspace/units/fb/fb_fusa.c
Normal file
159
userspace/units/fb/fb_fusa.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include "hal/fb/intr/fb_intr_gv11b.h"
|
||||
#include <nvgpu/hw/gv11b/hw_fb_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_mc_gv11b.h>
|
||||
|
||||
#include "fb_fusa.h"
|
||||
|
||||
static bool intercept_mmu_invalidate;
|
||||
static u32 intercept_fb_mmu_ctrl_r;
|
||||
|
||||
void helper_intercept_mmu_write(u32 val)
|
||||
{
|
||||
intercept_fb_mmu_ctrl_r = val;
|
||||
intercept_mmu_invalidate = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write callback (for all nvgpu_writel calls).
|
||||
*/
|
||||
static void writel_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
if (intercept_mmu_invalidate &&
|
||||
(access->addr == fb_mmu_invalidate_pdb_r())) {
|
||||
intercept_mmu_invalidate = false;
|
||||
nvgpu_writel(g, fb_mmu_ctrl_r(), intercept_fb_mmu_ctrl_r);
|
||||
}
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
nvgpu_posix_io_record_access(g, access);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read callback, similar to the write callback above.
|
||||
*/
|
||||
static void readl_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Define all the callbacks to be used during the test. Typically all
|
||||
* write operations use the same callback, likewise for all read operations.
|
||||
*/
|
||||
static struct nvgpu_posix_io_callbacks fb_callbacks = {
|
||||
/* Write APIs all can use the same accessor. */
|
||||
.writel = writel_access_reg_fn,
|
||||
.writel_check = writel_access_reg_fn,
|
||||
.bar1_writel = writel_access_reg_fn,
|
||||
.usermode_writel = writel_access_reg_fn,
|
||||
|
||||
/* Likewise for the read APIs. */
|
||||
.__readl = readl_access_reg_fn,
|
||||
.readl = readl_access_reg_fn,
|
||||
.bar1_readl = readl_access_reg_fn,
|
||||
};
|
||||
|
||||
static int fb_gv11b_init(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
nvgpu_posix_register_io(g, &fb_callbacks);
|
||||
|
||||
/* Register space: FB */
|
||||
if (nvgpu_posix_io_add_reg_space(g, fb_niso_intr_r(), SZ_4K) != 0) {
|
||||
unit_return_fail(m, "nvgpu_posix_io_add_reg_space failed FB\n");
|
||||
}
|
||||
|
||||
/* Register space: MC_INTR */
|
||||
if (nvgpu_posix_io_add_reg_space(g, mc_intr_r(0), SZ_1K) != 0) {
|
||||
unit_return_fail(m, "nvgpu_posix_io_add_reg_space failed MC\n");
|
||||
}
|
||||
|
||||
/* Register space: HSHUB */
|
||||
if (nvgpu_posix_io_add_reg_space(g, fb_hshub_num_active_ltcs_r(),
|
||||
SZ_256) != 0) {
|
||||
|
||||
unit_return_fail(m,
|
||||
"nvgpu_posix_io_add_reg_space failed HSHUB\n");
|
||||
}
|
||||
|
||||
/* Register space: FBHUB */
|
||||
if (nvgpu_posix_io_add_reg_space(g, fb_fbhub_num_active_ltcs_r(),
|
||||
SZ_256) != 0) {
|
||||
|
||||
unit_return_fail(m,
|
||||
"nvgpu_posix_io_add_reg_space failed FBHUB\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int fb_gv11b_cleanup(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Unregister space: FB */
|
||||
nvgpu_posix_io_delete_reg_space(g, fb_niso_intr_r());
|
||||
nvgpu_posix_io_delete_reg_space(g, mc_intr_r(0));
|
||||
nvgpu_posix_io_delete_reg_space(g, fb_hshub_num_active_ltcs_r());
|
||||
nvgpu_posix_io_delete_reg_space(g, fb_fbhub_num_active_ltcs_r());
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct unit_module_test fb_tests[] = {
|
||||
UNIT_TEST(fb_gv11b_init, fb_gv11b_init, NULL, 0),
|
||||
UNIT_TEST(fb_gv11b_init_test, fb_gv11b_init_test, NULL, 0),
|
||||
UNIT_TEST(fb_gm20b_tlb_invalidate_test, fb_gm20b_tlb_invalidate_test,
|
||||
NULL, 0),
|
||||
UNIT_TEST(fb_gm20b_mmu_ctrl_test, fb_gm20b_mmu_ctrl_test, NULL, 0),
|
||||
UNIT_TEST(fb_mmu_fault_gv11b_init_test, fb_mmu_fault_gv11b_init_test,
|
||||
NULL, 0),
|
||||
UNIT_TEST(fb_mmu_fault_gv11b_buffer_test,
|
||||
fb_mmu_fault_gv11b_buffer_test, NULL, 0),
|
||||
UNIT_TEST(fb_mmu_fault_gv11b_snap_reg, fb_mmu_fault_gv11b_snap_reg,
|
||||
NULL, 0),
|
||||
UNIT_TEST(fb_mmu_fault_gv11b_handle_fault,
|
||||
fb_mmu_fault_gv11b_handle_fault, NULL, 0),
|
||||
UNIT_TEST(fb_mmu_fault_gv11b_handle_bar2_fault,
|
||||
fb_mmu_fault_gv11b_handle_bar2_fault, NULL, 2),
|
||||
UNIT_TEST(fb_intr_gv11b_init_test, fb_intr_gv11b_init_test, NULL, 0),
|
||||
UNIT_TEST(fb_intr_gv11b_isr_test, fb_intr_gv11b_isr_test, NULL, 0),
|
||||
|
||||
UNIT_TEST(fb_intr_gv11b_ecc_test_L2TLB, fb_intr_gv11b_ecc_test,
|
||||
(void *) TEST_ECC_L2TLB, 0),
|
||||
UNIT_TEST(fb_intr_gv11b_ecc_test_HUBTLB, fb_intr_gv11b_ecc_test,
|
||||
(void *) TEST_ECC_HUBTLB, 0),
|
||||
UNIT_TEST(fb_intr_gv11b_ecc_test_FILLUNIT, fb_intr_gv11b_ecc_test,
|
||||
(void *) TEST_ECC_FILLUNIT, 0),
|
||||
|
||||
UNIT_TEST(fb_gv11b_cleanup, fb_gv11b_cleanup, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(fb, fb_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
406
userspace/units/fb/fb_fusa.h
Normal file
406
userspace/units/fb/fb_fusa.h
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_FB_H
|
||||
#define UNIT_NVGPU_FB_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-fb
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for nvgpu.hal.fb
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: fb_gv11b_init_test
|
||||
*
|
||||
* Description: Tests the init HALs for GV11B.
|
||||
*
|
||||
* Targets: nvgpu_ecc_init_support, gv11b_fb_init_hw, gv11b_fb_init_fs_state,
|
||||
* gv11b_fb_ecc_init, gv11b_fb_ecc_free, gops_fb.fb_ecc_free,
|
||||
* gops_fb.fb_ecc_init, gops_ecc.ecc_init_support, gops_fb.init_hw,
|
||||
* gops_fb.init_fs_state, gm20b_fb_init_hw
|
||||
*
|
||||
* Test Type: Feature, Other (setup), Error injection
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Set up the ops function pointer for all the HALs under test.
|
||||
* - Initialize the g->mm structure with arbitrary addresses.
|
||||
* - Call the ecc_init_support HAL to initialize ECC support.
|
||||
* - Call the init_hw HAL and ensure the FB_NISO mask was set.
|
||||
* - Call the init_fs_state HAL and ensure atomic mode was set in the MMU
|
||||
* control register.
|
||||
* - Perform dynamic memory error injection on the fb_ecc_init HAL to ensure
|
||||
* it fails as expected.
|
||||
* - Call the fb_ecc_init HAL and ensure it succeeds.
|
||||
* - Call the fb_ecc_free HAL to free dynamic memory.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_gv11b_init_test(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_gm20b_tlb_invalidate_test
|
||||
*
|
||||
* Description: .
|
||||
*
|
||||
* Targets: gm20b_fb_tlb_invalidate, gops_fb.tlb_invalidate
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize ops.fb.tlb_invalidate pointer to gm20b_fb_tlb_invalidate HAL.
|
||||
* - Create a test nvgpu_mem PDB with SYSMEM aperture.
|
||||
* - While the NVGPU is powered off, call gm20b_fb_tlb_invalidate and ensure
|
||||
* it returned success.
|
||||
* - The power on state of NVGPU.
|
||||
* - Enable timer error injection (1st occurnce), call gm20b_fb_tlb_invalidate
|
||||
* and ensure it failed.
|
||||
* - Call gm20b_fb_tlb_invalidate again and check that it still failed (because
|
||||
* the fb_mmu_ctrl_r register is not set properly)
|
||||
* - Set the fb_mmu_ctrl_pri_fifo_space_v bit in fb_mmu_ctrl_r register.
|
||||
* - Enable timer error injection (2nd occurnce), call gm20b_fb_tlb_invalidate
|
||||
* and ensure it failed.
|
||||
* - Using an helper during register writes, intercept writes to fb_mmu_ctrl_r
|
||||
* to cause a timeout after the MMU invalidate. Ensure that
|
||||
* gm20b_fb_tlb_invalidate returns a failure.
|
||||
* - Set the fb_mmu_ctrl_pri_fifo_space_v bit again, and set the intercept
|
||||
* helper to write the fb_mmu_ctrl_pri_fifo_empty_v bit upon a write to
|
||||
* fb_mmu_ctrl_r. Ensure that gm20b_fb_tlb_invalidate succeeds.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_gm20b_tlb_invalidate_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_gm20b_mmu_ctrl_test
|
||||
*
|
||||
* Description: Test GM20B HALs targeting MMU features.
|
||||
*
|
||||
* Targets: gm20b_fb_mmu_ctrl, gm20b_fb_mmu_debug_ctrl, gm20b_fb_mmu_debug_wr,
|
||||
* gm20b_fb_mmu_debug_rd, gm20b_fb_vpr_info_fetch, gm20b_fb_dump_vpr_info,
|
||||
* gm20b_fb_dump_wpr_info, gm20b_fb_read_wpr_info, gops_fb.mmu_ctrl,
|
||||
* gops_fb.mmu_debug_wr, gops_fb.mmu_debug_ctrl, gops_fb.mmu_debug_rd,
|
||||
* gops_fb.vpr_info_fetch, gops_fb.dump_wpr_info, gops_fb.dump_vpr_info,
|
||||
* gops_fb.read_wpr_info
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Set up the ops function pointer for all the HALs under test.
|
||||
* - Program an arbitrary value in the fb_mmu_ctrl_r register and ensure the
|
||||
* gm20b_fb_mmu_ctrl HAL returns the same value.
|
||||
* - Program an arbitrary value in the fb_mmu_debug_ctrl_r register and ensure
|
||||
* the gm20b_fb_mmu_debug_ctrl HAL returns the same value.
|
||||
* - Program an arbitrary value in the fb_mmu_debug_wr_r register and ensure the
|
||||
* gm20b_fb_mmu_debug_wr HAL returns the same value.
|
||||
* - Program an arbitrary value in the fb_mmu_debug_rd_r register and ensure the
|
||||
* gm20b_fb_mmu_debug_rd HAL returns the same value.
|
||||
* - Call the VPR/WPR dump operations for code coverage. Ensure that none of
|
||||
* those operations cause a crash.
|
||||
* - Enable timer error injection (1st occurnce), call gm20b_fb_vpr_info_fetch
|
||||
* and ensure it failed.
|
||||
* - Write in the fb_mmu_vpr_info register so that calling
|
||||
* gm20b_fb_vpr_info_fetch triggers timeout in the
|
||||
* gm20b_fb_vpr_info_fetch_wait function. Ensure the return values reflects
|
||||
* a timeout.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_gm20b_mmu_ctrl_test(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_mmu_fault_gv11b_init_test
|
||||
*
|
||||
* Description: Init test to setup HAL pointers for FB_MMU fault testing.
|
||||
*
|
||||
* Targets: gv11b_fb_read_mmu_fault_buffer_size,
|
||||
* gv11b_fb_read_mmu_fault_buffer_put, gv11b_fb_write_mmu_fault_status,
|
||||
* gv11b_fb_read_mmu_fault_buffer_get
|
||||
*
|
||||
* Test Type: Init
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Set up the ops function pointer for all the HALs under test.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_mmu_fault_gv11b_init_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_mmu_fault_gv11b_buffer_test
|
||||
*
|
||||
* Description: Ensure all HAL functions work without causing an ABORT.
|
||||
*
|
||||
* Targets: gv11b_fb_is_fault_buf_enabled, gv11b_fb_fault_buffer_get_ptr_update,
|
||||
* gv11b_fb_write_mmu_fault_buffer_size, gv11b_fb_fault_buf_set_state_hw,
|
||||
* gv11b_fb_read_mmu_fault_status, gv11b_fb_fault_buf_configure_hw,
|
||||
* gv11b_fb_is_fault_buffer_empty, gv11b_fb_read_mmu_fault_addr_lo_hi,
|
||||
* gops_fb.fault_buf_configure_hw, gops_fb.fault_buf_set_state_hw,
|
||||
* gv11b_fb_fault_buffer_size_val, gv11b_fb_read_mmu_fault_inst_lo_hi,
|
||||
* gv11b_fb_read_mmu_fault_info
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Input: fb_mmu_fault_gv11b_init_test
|
||||
*
|
||||
* Steps:
|
||||
* - Call gv11b_fb_fault_buffer_get_ptr_update.
|
||||
* - Set the overflow bit in the fb_mmu_fault_buffer_get_r(0) register, and call
|
||||
* gv11b_fb_fault_buffer_get_ptr_update.
|
||||
* - Call gv11b_fb_fault_buffer_size_val and check that the fault buffer is
|
||||
* empty.
|
||||
* - Call the gv11b_fb_fault_buf_configure_hw HAL and enable fault buffer.
|
||||
* - Enable fault buffer again which shouldn't cause any crash.
|
||||
* - While trying to disable the fault buffer, trigger a failure of
|
||||
* nvgpu_timeout_init.
|
||||
* - Disable the fault buffer.
|
||||
* - Enable fault buffer, set the busy bit in fb_mmu_fault_status_r register,
|
||||
* disable the fault buffer which should cause an internal timeout. Ensure
|
||||
* that the fault buffer is disabled anyway.
|
||||
* - Write test values in the fb_mmu_fault_addr_lo_r / fb_mmu_fault_addr_hi_r
|
||||
* registers, call gv11b_fb_read_mmu_fault_addr_lo_hi and ensure the
|
||||
* returned values match the test values.
|
||||
* - Write test values in the fb_mmu_fault_inst_lo_r / fb_mmu_fault_inst_hi_r
|
||||
* registers, call gv11b_fb_read_mmu_fault_inst_lo_hi and ensure the
|
||||
* returned values match the test values.
|
||||
* - Call the gv11b_fb_read_mmu_fault_info HAL and ensure it returns the same
|
||||
* value as in the fb_mmu_fault_info_r register.
|
||||
* - Call the gv11b_fb_write_mmu_fault_status HAL to write a test value, then
|
||||
* read the fb_mmu_fault_status_r register to ensure it is the same value.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_mmu_fault_gv11b_buffer_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_mmu_fault_gv11b_snap_reg
|
||||
*
|
||||
* Description: Test that gv11b_mm_copy_from_fault_snap_reg behaves correctly
|
||||
* if the reported fault is valid/invalid.
|
||||
*
|
||||
* Targets: gv11b_mm_copy_from_fault_snap_reg
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Input: fb_mmu_fault_gv11b_init_test
|
||||
*
|
||||
* Steps:
|
||||
* - Create a test mmu_fault_info instance.
|
||||
* - Call gv11b_mm_copy_from_fault_snap_reg with an invalid fault bit and
|
||||
* ensure the chid of the mmu_fault_info was just set to a default value of 0.
|
||||
* - Call gv11b_mm_copy_from_fault_snap_reg again with a valid fault bit and
|
||||
* ensure the chid of the mmu_fault_info is now set to
|
||||
* NVGPU_INVALID_CHANNEL_ID.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_mmu_fault_gv11b_snap_reg(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_mmu_fault_gv11b_handle_fault
|
||||
*
|
||||
* Description: Test the gv11b_fb_handle_mmu_fault HAL for all supported
|
||||
* interrupt statuses.
|
||||
*
|
||||
* Targets: gv11b_fb_handle_mmu_fault, gv11b_fb_fault_buf_set_state_hw
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Input: fb_mmu_fault_gv11b_init_test
|
||||
*
|
||||
* Steps:
|
||||
* - Call gv11b_fb_handle_mmu_fault with an interrupt source set to "other"
|
||||
* and ensure it was handled by checking the "valid_clear" bit of the
|
||||
* fb_mmu_fault_status_r register.
|
||||
* - Enable the fault buffer.
|
||||
* - Set interrupt source as dropped and ensure it is handled by
|
||||
* gv11b_fb_handle_mmu_fault.
|
||||
* - Repeat with a source as non-replayable.
|
||||
* - Repeat with a source as non-replayable and overflow.
|
||||
* - Repeat with a source as overflow and corrupted getptr.
|
||||
* - Disable the fault buffer.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_mmu_fault_gv11b_handle_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_mmu_fault_gv11b_handle_bar2_fault
|
||||
*
|
||||
* Description: Test the gv11b_fb_handle_bar2_fault HAL for all supported
|
||||
* interrupt statuses.
|
||||
*
|
||||
* Targets: gv11b_fb_handle_bar2_fault, gv11b_fb_mmu_fault_info_dump,
|
||||
* gv11b_fb_fault_buf_set_state_hw
|
||||
*
|
||||
* Test Type: Feature, Error injection
|
||||
*
|
||||
* Input: fb_mmu_fault_gv11b_init_test
|
||||
*
|
||||
* Steps:
|
||||
* - Create zero'ed test instances of mmu_fault_info and nvgpu_channel.
|
||||
* - Call gv11b_fb_handle_bar2_fault with a fault_status of 0.
|
||||
* - Ensure the gv11b_fb_mmu_fault_info_dump HAL does not cause a crash when
|
||||
* called with a NULL pointer or a zero'ed out mmu_fault_info structure.
|
||||
* - Set the minimum set of properties in the mmu_fault_info structure (valid
|
||||
* and a pointer to the channel)
|
||||
* - Call the gv11b_fb_mmu_fault_info_dump and ensure it doesn't cause a crash.
|
||||
* - Set the fault_status to non-replayable and call gv11b_fb_handle_bar2_fault.
|
||||
* - Set the g->ops.bus.bar2_bind HAL to report a failure and call
|
||||
* gv11b_fb_handle_bar2_fault again.
|
||||
* - Repeat with the fault buffer disabled.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_mmu_fault_gv11b_handle_bar2_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_intr_gv11b_init_test
|
||||
*
|
||||
* Description: Init test to setup HAL pointers for FB_INTR testing.
|
||||
*
|
||||
* Targets: None
|
||||
*
|
||||
* Test Type: Init
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Set up the ops function pointer for all the HALs under test.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_intr_gv11b_init_test(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_intr_gv11b_isr_test
|
||||
*
|
||||
* Description: Test ISR handling with all supported types of interrupts.
|
||||
*
|
||||
* Targets: gv11b_fb_intr_enable, gv11b_fb_intr_disable, gv11b_fb_intr_isr,
|
||||
* gv11b_fb_intr_is_mmu_fault_pending, gops_fb_intr.is_mmu_fault_pending,
|
||||
* gops_fb_intr.enable, gops_fb_intr.disable, gops_fb_intr.isr
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Input: fb_intr_gv11b_init_test
|
||||
*
|
||||
* Steps:
|
||||
* - Mask all interrupts in the fb_niso_intr_en_set_r register.
|
||||
* - Call the gv11b_fb_intr_enable HAL and ensure several interrupts are
|
||||
* unmasked.
|
||||
* - Set the fb_niso_intr_r register to 0 (no interrupt), and ensure that
|
||||
* gv11b_fb_intr_is_mmu_fault_pending indicates that no fault is pending.
|
||||
* - Call the gv11b_fb_intr_isr HAL.
|
||||
* - Set interrupt source as "access counter notify/error" and call the
|
||||
* gv11b_fb_intr_isr HAL (this will only cause a nvgpu_info call)
|
||||
* - Set interrupt source as "MMU fault" and ensure that
|
||||
* gv11b_fb_intr_is_mmu_fault_pending indicates that a fault is pending.
|
||||
* - Set interrupt source as "ECC fault" and call the gv11b_fb_intr_isr HAL
|
||||
* (further ECC testing is done in other tests).
|
||||
* - Use the gv11b_fb_intr_disable HAL to disable interrupts.
|
||||
* - Ensure that what was written in the clear register matches the interrupts
|
||||
* that were enabled at the beginning of this test.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_intr_gv11b_isr_test(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: fb_intr_gv11b_ecc_test
|
||||
*
|
||||
* Description: Tests handling of ECC errors.
|
||||
*
|
||||
* Targets: gv11b_fb_ecc_init, gv11b_fb_intr_isr, gv11b_fb_intr_handle_ecc,
|
||||
* gv11b_fb_ecc_free
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Input: fb_intr_gv11b_init_test, args as a subcase with one of these values:
|
||||
* - TEST_ECC_L2TLB
|
||||
* - TEST_ECC_HUBTLB
|
||||
* - TEST_ECC_FILLUNIT
|
||||
*
|
||||
* Steps:
|
||||
* - Based on the subcase passed as an argument to this test, select the
|
||||
* appropriate values for each HW unit:
|
||||
* - Address of the status register
|
||||
* - Address of the corrected error count register
|
||||
* - Address of the uncorrected error count register
|
||||
* - Expected status mask for corrected errors
|
||||
* - Expected status mask for uncorrected errors
|
||||
* - Expected status mask for corrected errors overflow
|
||||
* - Expected status mask for uncorrected errors overflow
|
||||
* - Call the gv11b_fb_ecc_init HAL.
|
||||
* - Test the hanlding of ISRs in the following cases:
|
||||
* - Corrected error
|
||||
* - Uncorrected error
|
||||
* - Corrected error and overflow (with >0 number of errors)
|
||||
* - Uncorrected error and overflow (with >0 number of errors)
|
||||
* - Corrected and uncorrected with overflow and 0 errors.
|
||||
* - In the case of FILLUNIT, also test the case of corrected and uncorrected
|
||||
* PDE0 errors.
|
||||
* - Clear the interrupt status register.
|
||||
* - Call the gv11b_fb_ecc_free HAL.
|
||||
*
|
||||
* Output: Returns PASS if the steps above were executed successfully. FAIL
|
||||
* otherwise.
|
||||
*/
|
||||
int fb_intr_gv11b_ecc_test(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/* Values below are used by the fb_intr_gv11b_ecc_test test. */
|
||||
#define TEST_ECC_L2TLB 1U
|
||||
#define TEST_ECC_HUBTLB 2U
|
||||
#define TEST_ECC_FILLUNIT 3U
|
||||
|
||||
/* Helper function to intercept writes to the MMU status register. */
|
||||
void helper_intercept_mmu_write(u32 val);
|
||||
|
||||
/** @} */
|
||||
#endif /* UNIT_NVGPU_FB_H */
|
||||
192
userspace/units/fb/fb_gm20b_fusa.c
Normal file
192
userspace/units/fb/fb_gm20b_fusa.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include "hal/mc/mc_gp10b.h"
|
||||
#include "hal/fb/fb_gm20b.h"
|
||||
#include "hal/fb/fb_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_gv11b.h"
|
||||
#include <nvgpu/hw/gv11b/hw_fb_gv11b.h>
|
||||
|
||||
#include "fb_fusa.h"
|
||||
|
||||
#define TEST_REG_VALUE 0x8080A0A0
|
||||
|
||||
int fb_gm20b_tlb_invalidate_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
int err;
|
||||
struct nvgpu_mem pdb = {0};
|
||||
struct nvgpu_posix_fault_inj *timer_fi =
|
||||
nvgpu_timers_get_fault_injection();
|
||||
|
||||
/* Define the operations being tested in this unit test */
|
||||
g->ops.fb.tlb_invalidate = gm20b_fb_tlb_invalidate;
|
||||
|
||||
/* Setup PDB */
|
||||
pdb.aperture = APERTURE_SYSMEM;
|
||||
|
||||
/* First NVGPU is powered off */
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "tlb_invalidate failed (1)\n");
|
||||
}
|
||||
|
||||
/* Set NVGPU as powered on */
|
||||
g->power_on_state = NVGPU_STATE_POWERED_ON;
|
||||
|
||||
/* Timeout init fault injection (MMU FIFO space) */
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 0);
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"tlb_invalidate did not fail as expected (1)\n");
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
|
||||
/* Timeout fail on fb_mmu_ctrl_r() read */
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"tlb_invalidate did not fail as expected (2)\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent timeout on fb_mmu_ctrl_r() by setting a non-zero value in
|
||||
* the fb_mmu_ctrl_pri_fifo_space_v field.
|
||||
*/
|
||||
nvgpu_writel(g, fb_mmu_ctrl_r(), 1 << 16U);
|
||||
|
||||
/* Timeout init fault injection (MMU invalidate) */
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 1);
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"tlb_invalidate did not fail as expected (3)\n");
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
|
||||
/*
|
||||
* Timeout on fb_mmu_ctrl_r read after MMU invalidate (does not return
|
||||
* a failure)
|
||||
*/
|
||||
helper_intercept_mmu_write(0);
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "tlb_invalidate failed (2)\n");
|
||||
}
|
||||
|
||||
/* Success */
|
||||
nvgpu_writel(g, fb_mmu_ctrl_r(), 1 << 16U);
|
||||
helper_intercept_mmu_write(1 << 15U);
|
||||
err = g->ops.fb.tlb_invalidate(g, &pdb);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "tlb_invalidate failed (3)\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int fb_gm20b_mmu_ctrl_test(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int err;
|
||||
u64 wpr_base, wpr_size;
|
||||
struct nvgpu_posix_fault_inj *timer_fi =
|
||||
nvgpu_timers_get_fault_injection();
|
||||
|
||||
/* Define the operations being tested in this unit test */
|
||||
g->ops.fb.mmu_ctrl = gm20b_fb_mmu_ctrl;
|
||||
g->ops.fb.mmu_debug_ctrl = gm20b_fb_mmu_debug_ctrl;
|
||||
g->ops.fb.mmu_debug_wr = gm20b_fb_mmu_debug_wr;
|
||||
g->ops.fb.mmu_debug_rd = gm20b_fb_mmu_debug_rd;
|
||||
g->ops.fb.vpr_info_fetch = gm20b_fb_vpr_info_fetch;
|
||||
g->ops.fb.dump_vpr_info = gm20b_fb_dump_vpr_info;
|
||||
g->ops.fb.dump_wpr_info = gm20b_fb_dump_wpr_info;
|
||||
g->ops.fb.read_wpr_info = gm20b_fb_read_wpr_info;
|
||||
|
||||
/* g->ops.mmu_ctrl must return the value in fb_mmu_ctrl_r */
|
||||
nvgpu_writel(g, fb_mmu_ctrl_r(), TEST_REG_VALUE);
|
||||
if (g->ops.fb.mmu_ctrl(g) != TEST_REG_VALUE) {
|
||||
unit_return_fail(m, "ops.mmu_ctrl: incorrect value\n");
|
||||
}
|
||||
|
||||
/* g->ops.mmu_debug_ctrl must return the value in fb_mmu_debug_ctrl_r */
|
||||
nvgpu_writel(g, fb_mmu_debug_ctrl_r(), TEST_REG_VALUE);
|
||||
if (g->ops.fb.mmu_debug_ctrl(g) != TEST_REG_VALUE) {
|
||||
unit_return_fail(m, "ops.mmu_debug_ctrl: incorrect value\n");
|
||||
}
|
||||
|
||||
/* g->ops.mmu_debug_wr must return the value in fb_mmu_debug_wr_r */
|
||||
nvgpu_writel(g, fb_mmu_debug_wr_r(), TEST_REG_VALUE);
|
||||
if (g->ops.fb.mmu_debug_wr(g) != TEST_REG_VALUE) {
|
||||
unit_return_fail(m, "ops.mmu_debug_wr: incorrect value\n");
|
||||
}
|
||||
|
||||
/* g->ops.mmu_debug_rd must return the value in fb_mmu_debug_rd_r */
|
||||
nvgpu_writel(g, fb_mmu_debug_rd_r(), TEST_REG_VALUE);
|
||||
if (g->ops.fb.mmu_debug_rd(g) != TEST_REG_VALUE) {
|
||||
unit_return_fail(m, "ops.mmu_debug_rd: incorrect value\n");
|
||||
}
|
||||
|
||||
/* For code coverage, run the VPR/WPR dump ops */
|
||||
g->ops.fb.dump_vpr_info(g);
|
||||
g->ops.fb.dump_wpr_info(g);
|
||||
g->ops.fb.read_wpr_info(g, &wpr_base, &wpr_size);
|
||||
g->ops.fb.vpr_info_fetch(g);
|
||||
|
||||
/* Error injection for g->ops.fb.vpr_info_fetch */
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 0);
|
||||
err = g->ops.fb.vpr_info_fetch(g);
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"vpr_info_fetch did not fail as expected (1)\n");
|
||||
}
|
||||
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, true, 1);
|
||||
err = g->ops.fb.vpr_info_fetch(g);
|
||||
nvgpu_posix_enable_fault_injection(timer_fi, false, 0);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"vpr_info_fetch did not fail as expected (2)\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Trigger timeout in the gm20b_fb_vpr_info_fetch_wait function on
|
||||
* fb_mmu_vpr_info_fetch_v(val) == fb_mmu_vpr_info_fetch_false_v()
|
||||
*/
|
||||
nvgpu_writel(g, fb_mmu_vpr_info_r(), 1 << 2U);
|
||||
err = g->ops.fb.vpr_info_fetch(g);
|
||||
if (err != -ETIMEDOUT) {
|
||||
unit_return_fail(m,
|
||||
"vpr_info_fetch did not fail as expected (3)\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
131
userspace/units/fb/fb_gv11b_fusa.c
Normal file
131
userspace/units/fb/fb_gv11b_fusa.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/cic.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include "hal/mc/mc_gp10b.h"
|
||||
#include "hal/fb/fb_gm20b.h"
|
||||
#include "hal/fb/fb_gv11b.h"
|
||||
#include "hal/fb/ecc/fb_ecc_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_ecc_gv11b.h"
|
||||
#include "hal/cic/cic_gv11b.h"
|
||||
#include <nvgpu/hw/gv11b/hw_fb_gv11b.h>
|
||||
|
||||
#include "fb_fusa.h"
|
||||
|
||||
int fb_gv11b_init_test(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int err;
|
||||
struct nvgpu_posix_fault_inj *kmem_fi =
|
||||
nvgpu_kmem_get_fault_injection();
|
||||
|
||||
/* Define the operations being targeted in this unit test */
|
||||
g->ops.ecc.ecc_init_support = nvgpu_ecc_init_support;
|
||||
g->ops.fb.init_hw = gv11b_fb_init_hw;
|
||||
g->ops.fb.init_fs_state = gv11b_fb_init_fs_state;
|
||||
g->ops.fb.set_atomic_mode = gv11b_fb_set_atomic_mode;
|
||||
g->ops.fb.ecc.init = gv11b_fb_ecc_init;
|
||||
g->ops.fb.ecc.free = gv11b_fb_ecc_free;
|
||||
g->ops.fb.ecc.l2tlb_error_mask = gv11b_fb_ecc_l2tlb_error_mask;
|
||||
g->ops.fb.intr.handle_ecc = gv11b_fb_intr_handle_ecc,
|
||||
g->ops.fb.intr.handle_ecc_l2tlb = gv11b_fb_intr_handle_ecc_l2tlb,
|
||||
g->ops.fb.intr.handle_ecc_hubtlb = gv11b_fb_intr_handle_ecc_hubtlb,
|
||||
g->ops.fb.intr.handle_ecc_fillunit = gv11b_fb_intr_handle_ecc_fillunit,
|
||||
|
||||
/* Other HALs */
|
||||
g->ops.mc.intr_stall_unit_config = mc_gp10b_intr_stall_unit_config;
|
||||
g->ops.mc.intr_nonstall_unit_config =
|
||||
mc_gp10b_intr_nonstall_unit_config;
|
||||
g->ops.fb.intr.enable = gv11b_fb_intr_enable;
|
||||
g->ops.cic.init = gv11b_cic_init;
|
||||
g->ops.cic.report_err = nvgpu_cic_report_err_safety_services;
|
||||
|
||||
/*
|
||||
* Define some arbitrary addresses for test purposes.
|
||||
* Note: no need to malloc any memory as this unit only needs to trigger
|
||||
* MMU faults via register mocking. No other memory accesses are done.
|
||||
*/
|
||||
g->mm.sysmem_flush.cpu_va = (void *) 0x10000000;
|
||||
g->mm.mmu_wr_mem.cpu_va = (void *) 0x20000000;
|
||||
g->mm.mmu_wr_mem.aperture = APERTURE_SYSMEM;
|
||||
g->mm.mmu_rd_mem.cpu_va = (void *) 0x30000000;
|
||||
g->mm.mmu_rd_mem.aperture = APERTURE_SYSMEM;
|
||||
|
||||
if (nvgpu_cic_init_common(g) != 0) {
|
||||
unit_return_fail(m, "CIC init failed\n");
|
||||
}
|
||||
|
||||
g->ops.ecc.ecc_init_support(g);
|
||||
|
||||
nvgpu_writel(g, fb_niso_intr_en_set_r(0), 0);
|
||||
g->ops.fb.init_hw(g);
|
||||
/* Ensure that g->ops.fb.intr.enable set up a mask */
|
||||
if (nvgpu_readl(g, fb_niso_intr_en_set_r(0)) == 0) {
|
||||
unit_return_fail(m, "FB_NISO mask not set\n");
|
||||
}
|
||||
|
||||
g->ops.fb.init_fs_state(g);
|
||||
g->ops.fb.set_atomic_mode(g);
|
||||
/* Ensure atomic mode was enabled */
|
||||
if ((nvgpu_readl(g, fb_mmu_ctrl_r()) &
|
||||
fb_mmu_ctrl_atomic_capability_mode_m()) == 0) {
|
||||
|
||||
unit_return_fail(m, "Atomic mode not set\n");
|
||||
}
|
||||
|
||||
/* For branch coverage */
|
||||
nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true);
|
||||
g->ops.fb.init_fs_state(g);
|
||||
nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false);
|
||||
|
||||
/*
|
||||
* gv11b_fb_ecc_init initializes 5 structures via kmem. Test the failure
|
||||
* of all of them.
|
||||
*/
|
||||
for (int i = 0; i < 5; i++) {
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, true, i);
|
||||
err = g->ops.fb.ecc.init(g);
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, false, 0);
|
||||
if (err != -ENOMEM) {
|
||||
unit_return_fail(m, "gv11b_fb_ecc_init did not fail as expected (%d)\n", i);
|
||||
}
|
||||
|
||||
g->ops.ecc.ecc_init_support(g);
|
||||
}
|
||||
|
||||
err = g->ops.fb.ecc.init(g);
|
||||
if (err != 0) {
|
||||
unit_return_fail(m, "gv11b_fb_ecc_init failed\n");
|
||||
}
|
||||
|
||||
g->ops.fb.ecc.free(g);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
218
userspace/units/fb/fb_intr_gv11b_fusa.c
Normal file
218
userspace/units/fb/fb_intr_gv11b_fusa.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/sizes.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include "hal/mc/mc_gp10b.h"
|
||||
#include "hal/fb/fb_gm20b.h"
|
||||
#include "hal/fb/fb_gv11b.h"
|
||||
#include "hal/fb/fb_mmu_fault_gv11b.h"
|
||||
#include "hal/fb/ecc/fb_ecc_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_ecc_gv11b.h"
|
||||
#include <nvgpu/hw/gv11b/hw_fb_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_mc_gv11b.h>
|
||||
|
||||
#include "fb_fusa.h"
|
||||
|
||||
/* Arbitrary number of errors */
|
||||
#define ECC_ERRORS 15U
|
||||
|
||||
int fb_intr_gv11b_init_test(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* HALs under test */
|
||||
g->ops.fb.ecc.init = gv11b_fb_ecc_init;
|
||||
g->ops.fb.ecc.free = gv11b_fb_ecc_free;
|
||||
g->ops.fb.ecc.l2tlb_error_mask = gv11b_fb_ecc_l2tlb_error_mask;
|
||||
g->ops.fb.intr.handle_ecc = gv11b_fb_intr_handle_ecc;
|
||||
g->ops.fb.intr.handle_ecc_l2tlb = gv11b_fb_intr_handle_ecc_l2tlb;
|
||||
g->ops.fb.intr.handle_ecc_hubtlb = gv11b_fb_intr_handle_ecc_hubtlb;
|
||||
g->ops.fb.intr.handle_ecc_fillunit = gv11b_fb_intr_handle_ecc_fillunit;
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int fb_intr_gv11b_isr_test(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Mask all interrupts */
|
||||
nvgpu_writel(g, fb_niso_intr_en_set_r(0), 0);
|
||||
/* Enable interrupts */
|
||||
gv11b_fb_intr_enable(g);
|
||||
if (nvgpu_readl(g, fb_niso_intr_en_set_r(0)) == 0) {
|
||||
unit_return_fail(m, "FB_INTR not unmasked\n");
|
||||
}
|
||||
|
||||
/* Set INTR status register to 0, i.e. no interrupt */
|
||||
nvgpu_writel(g, fb_niso_intr_r(), 0);
|
||||
if (gv11b_fb_intr_is_mmu_fault_pending(g)) {
|
||||
unit_return_fail(m, "MMU fault should NOT be pending\n");
|
||||
}
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* Hub access counter notify/error: just causes a nvgpu_info call */
|
||||
nvgpu_writel(g, fb_niso_intr_r(),
|
||||
fb_niso_intr_hub_access_counter_notify_m());
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* MMU fault: testing of MMU fault handling is done in other tests */
|
||||
nvgpu_writel(g, fb_niso_intr_r(),
|
||||
fb_niso_intr_mmu_other_fault_notify_m());
|
||||
if (!gv11b_fb_intr_is_mmu_fault_pending(g)) {
|
||||
unit_return_fail(m, "MMU fault should be pending\n");
|
||||
}
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* ECC fault: testing of ECC fault handling is done in other tests */
|
||||
nvgpu_writel(g, fb_niso_intr_r(),
|
||||
fb_niso_intr_mmu_ecc_uncorrected_error_notify_pending_f());
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* Disable interrupts */
|
||||
gv11b_fb_intr_disable(g);
|
||||
/*
|
||||
* In real HW it may not be possible to read the set/clear registers but
|
||||
* here we can, and what was programmed in the set register should be
|
||||
* the same as what was programmed in the clear register.
|
||||
*/
|
||||
if (nvgpu_readl(g, fb_niso_intr_en_set_r(0)) !=
|
||||
nvgpu_readl(g, fb_niso_intr_en_clr_r(0))) {
|
||||
|
||||
unit_return_fail(m, "FB_INTR set/clear mismatch\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
struct gv11b_ecc_test_parameters {
|
||||
u32 status_reg;
|
||||
u32 corrected_err_reg;
|
||||
u32 uncorrected_err_reg;
|
||||
u32 corrected_status, uncorrected_status;
|
||||
u32 corrected_overflow, uncorrected_overflow;
|
||||
};
|
||||
|
||||
static struct gv11b_ecc_test_parameters l2tlb_parameters = {
|
||||
.status_reg = fb_mmu_l2tlb_ecc_status_r(),
|
||||
.corrected_err_reg = fb_mmu_l2tlb_ecc_corrected_err_count_r(),
|
||||
.uncorrected_err_reg = fb_mmu_l2tlb_ecc_uncorrected_err_count_r(),
|
||||
.corrected_status = fb_mmu_l2tlb_ecc_status_corrected_err_l2tlb_sa_data_m(),
|
||||
.uncorrected_status = fb_mmu_l2tlb_ecc_status_uncorrected_err_l2tlb_sa_data_m(),
|
||||
.corrected_overflow = fb_mmu_l2tlb_ecc_status_corrected_err_total_counter_overflow_m(),
|
||||
.uncorrected_overflow = fb_mmu_l2tlb_ecc_status_uncorrected_err_total_counter_overflow_m(),
|
||||
};
|
||||
|
||||
static struct gv11b_ecc_test_parameters hubtlb_parameters = {
|
||||
.status_reg = fb_mmu_hubtlb_ecc_status_r(),
|
||||
.corrected_err_reg = fb_mmu_hubtlb_ecc_corrected_err_count_r(),
|
||||
.uncorrected_err_reg = fb_mmu_hubtlb_ecc_uncorrected_err_count_r(),
|
||||
.corrected_status = fb_mmu_hubtlb_ecc_status_corrected_err_sa_data_m(),
|
||||
.uncorrected_status = fb_mmu_hubtlb_ecc_status_uncorrected_err_sa_data_m(),
|
||||
.corrected_overflow = fb_mmu_hubtlb_ecc_status_corrected_err_total_counter_overflow_m(),
|
||||
.uncorrected_overflow = fb_mmu_hubtlb_ecc_status_uncorrected_err_total_counter_overflow_m(),
|
||||
};
|
||||
|
||||
static struct gv11b_ecc_test_parameters fillunit_parameters = {
|
||||
.status_reg = fb_mmu_fillunit_ecc_status_r(),
|
||||
.corrected_err_reg = fb_mmu_fillunit_ecc_corrected_err_count_r(),
|
||||
.uncorrected_err_reg = fb_mmu_fillunit_ecc_uncorrected_err_count_r(),
|
||||
.corrected_status = fb_mmu_fillunit_ecc_status_corrected_err_pte_data_m(),
|
||||
.uncorrected_status = fb_mmu_fillunit_ecc_status_uncorrected_err_pte_data_m(),
|
||||
.corrected_overflow = fb_mmu_fillunit_ecc_status_corrected_err_total_counter_overflow_m(),
|
||||
.uncorrected_overflow = fb_mmu_fillunit_ecc_status_uncorrected_err_total_counter_overflow_m(),
|
||||
};
|
||||
|
||||
int fb_intr_gv11b_ecc_test(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
struct gv11b_ecc_test_parameters *p;
|
||||
u64 subcase = (u64) args;
|
||||
|
||||
switch (subcase) {
|
||||
case TEST_ECC_L2TLB:
|
||||
p = &l2tlb_parameters;
|
||||
break;
|
||||
case TEST_ECC_HUBTLB:
|
||||
p = &hubtlb_parameters;
|
||||
break;
|
||||
case TEST_ECC_FILLUNIT:
|
||||
p = &fillunit_parameters;
|
||||
break;
|
||||
default:
|
||||
unit_return_fail(m, "Invalid subcase\n");
|
||||
}
|
||||
|
||||
g->ops.fb.ecc.init(g);
|
||||
|
||||
/* Set the interrupt status as corrected */
|
||||
nvgpu_writel(g, p->status_reg, p->corrected_status);
|
||||
EXPECT_BUG(gv11b_fb_intr_isr(g, 0U));
|
||||
|
||||
/* Set the interrupt status as uncorrected */
|
||||
nvgpu_writel(g, p->status_reg, p->uncorrected_status);
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* Set arbitrary number of corrected and uncorrected errors */
|
||||
nvgpu_writel(g, p->corrected_err_reg, ECC_ERRORS);
|
||||
nvgpu_writel(g, p->uncorrected_err_reg, ECC_ERRORS);
|
||||
gv11b_fb_intr_isr(g, 0U);
|
||||
|
||||
/* Same but with corrected overflow bit set */
|
||||
nvgpu_writel(g, p->status_reg, 1 | p->corrected_overflow);
|
||||
nvgpu_writel(g, p->corrected_err_reg, ECC_ERRORS);
|
||||
nvgpu_writel(g, p->uncorrected_err_reg, ECC_ERRORS);
|
||||
EXPECT_BUG(gv11b_fb_intr_isr(g, 0U));
|
||||
|
||||
/* Same but with uncorrected overflow bit set */
|
||||
nvgpu_writel(g, p->status_reg, 1 | p->uncorrected_overflow);
|
||||
nvgpu_writel(g, p->corrected_err_reg, ECC_ERRORS);
|
||||
nvgpu_writel(g, p->uncorrected_err_reg, ECC_ERRORS);
|
||||
EXPECT_BUG(gv11b_fb_intr_isr(g, 0U));
|
||||
|
||||
/* Both overflow but error counts at 0 */
|
||||
nvgpu_writel(g, p->status_reg, 1 | p->corrected_overflow |
|
||||
p->uncorrected_overflow);
|
||||
nvgpu_writel(g, p->corrected_err_reg, 0);
|
||||
nvgpu_writel(g, p->uncorrected_err_reg, 0);
|
||||
EXPECT_BUG(gv11b_fb_intr_isr(g, 0U));
|
||||
|
||||
/* Extra case for fillunit */
|
||||
if (subcase == TEST_ECC_FILLUNIT) {
|
||||
/* PDE0 */
|
||||
nvgpu_writel(g, p->status_reg,
|
||||
fb_mmu_fillunit_ecc_status_corrected_err_pde0_data_m() |
|
||||
fb_mmu_fillunit_ecc_status_uncorrected_err_pde0_data_m());
|
||||
EXPECT_BUG(gv11b_fb_intr_isr(g, 0U));
|
||||
}
|
||||
|
||||
/* Clear interrupt status */
|
||||
nvgpu_writel(g, p->status_reg, 0);
|
||||
|
||||
g->ops.fb.ecc.free(g);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
325
userspace/units/fb/fb_mmu_fault_gv11b_fusa.c
Normal file
325
userspace/units/fb/fb_mmu_fault_gv11b_fusa.c
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/nvgpu_init.h>
|
||||
#include "hal/mc/mc_gp10b.h"
|
||||
#include "hal/fb/fb_gm20b.h"
|
||||
#include "hal/fb/fb_gv11b.h"
|
||||
#include "hal/fb/fb_mmu_fault_gv11b.h"
|
||||
#include "hal/fb/intr/fb_intr_gv11b.h"
|
||||
#include "hal/mm/mmu_fault/mmu_fault_gv11b.h"
|
||||
#include <nvgpu/hw/gv11b/hw_fb_gv11b.h>
|
||||
|
||||
#include "fb_fusa.h"
|
||||
|
||||
#define FAULT_STATUS_TEST_VAL 0x101U
|
||||
#define TEST_VALUE_1 0x80801234
|
||||
#define TEST_VALUE_2 0xABCD4567
|
||||
|
||||
static u32 hal_channel_count(struct gk20a *g)
|
||||
{
|
||||
/* Reasonable channel count for the purpose of this test */
|
||||
return 0x00000200U;
|
||||
}
|
||||
|
||||
static void hal_bar2_fault_nop(struct gk20a *g)
|
||||
{
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
static int hal_bar2_bind_nop(struct gk20a *g, struct nvgpu_mem *bar2_inst)
|
||||
{
|
||||
/* no-op */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hal_bar2_bind_fail(struct gk20a *g, struct nvgpu_mem *bar2_inst)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u32 hal_fifo_mmu_fault_id_to_pbdma_id(struct gk20a *g, u32 mmu_fault_id)
|
||||
{
|
||||
return INVAL_ID;
|
||||
}
|
||||
|
||||
int fb_mmu_fault_gv11b_init_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
/* HALs under test */
|
||||
g->ops.fb.read_mmu_fault_buffer_size =
|
||||
gv11b_fb_read_mmu_fault_buffer_size;
|
||||
g->ops.fb.read_mmu_fault_buffer_get =
|
||||
gv11b_fb_read_mmu_fault_buffer_get;
|
||||
g->ops.fb.read_mmu_fault_buffer_put =
|
||||
gv11b_fb_read_mmu_fault_buffer_put;
|
||||
g->ops.fb.write_mmu_fault_buffer_get =
|
||||
fb_gv11b_write_mmu_fault_buffer_get;
|
||||
g->ops.fb.is_fault_buf_enabled = gv11b_fb_is_fault_buf_enabled;
|
||||
g->ops.fb.fault_buf_set_state_hw = gv11b_fb_fault_buf_set_state_hw;
|
||||
g->ops.fb.write_mmu_fault_buffer_size =
|
||||
gv11b_fb_write_mmu_fault_buffer_size;
|
||||
g->ops.fb.read_mmu_fault_status = gv11b_fb_read_mmu_fault_status;
|
||||
g->ops.fb.fault_buf_configure_hw = gv11b_fb_fault_buf_configure_hw;
|
||||
g->ops.fb.write_mmu_fault_buffer_lo_hi =
|
||||
gv11b_fb_write_mmu_fault_buffer_lo_hi;
|
||||
g->ops.fb.read_mmu_fault_addr_lo_hi =
|
||||
gv11b_fb_read_mmu_fault_addr_lo_hi;
|
||||
g->ops.fb.read_mmu_fault_inst_lo_hi =
|
||||
gv11b_fb_read_mmu_fault_inst_lo_hi;
|
||||
g->ops.fb.read_mmu_fault_info = gv11b_fb_read_mmu_fault_info;
|
||||
g->ops.fb.write_mmu_fault_status = gv11b_fb_write_mmu_fault_status;
|
||||
|
||||
/* Other HALs that are needed */
|
||||
g->ops.channel.count = hal_channel_count;
|
||||
g->ops.ce.mthd_buffer_fault_in_bar2_fault = hal_bar2_fault_nop;
|
||||
g->ops.bus.bar2_bind = hal_bar2_bind_nop;
|
||||
g->ops.fifo.mmu_fault_id_to_pbdma_id =
|
||||
hal_fifo_mmu_fault_id_to_pbdma_id;
|
||||
g->ops.mm.mmu_fault.parse_mmu_fault_info =
|
||||
gv11b_mm_mmu_fault_parse_mmu_fault_info;
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int fb_mmu_fault_gv11b_buffer_test(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
u32 get_idx;
|
||||
u32 val;
|
||||
u32 lo, hi;
|
||||
struct nvgpu_posix_fault_inj *timers_fi =
|
||||
nvgpu_timers_get_fault_injection();
|
||||
|
||||
if (g->ops.fb.is_fault_buf_enabled(g, 0)) {
|
||||
unit_return_fail(m, "fault buffer not disabled as expected\n");
|
||||
}
|
||||
|
||||
/* Standard case */
|
||||
gv11b_fb_fault_buffer_get_ptr_update(g, 0, 0);
|
||||
|
||||
/* Overflow situation */
|
||||
nvgpu_writel(g, fb_mmu_fault_buffer_get_r(0),
|
||||
fb_mmu_fault_buffer_get_overflow_m());
|
||||
gv11b_fb_fault_buffer_get_ptr_update(g, 0, 0);
|
||||
|
||||
gv11b_fb_fault_buffer_size_val(g, 0);
|
||||
if (!gv11b_fb_is_fault_buffer_empty(g, 0, &get_idx)) {
|
||||
unit_return_fail(m, "fault buffer not empty as expected\n");
|
||||
}
|
||||
|
||||
/* Fault buffer hw setup */
|
||||
g->ops.fb.fault_buf_configure_hw(g, 0);
|
||||
|
||||
/* Enable fault buffer */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
|
||||
/* Enabling again shouldn't cause an issue */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
|
||||
/* Make nvgpu_timeout_init fail during disable operation */
|
||||
nvgpu_posix_enable_fault_injection(timers_fi, true, 0);
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_DISABLED);
|
||||
nvgpu_posix_enable_fault_injection(timers_fi, false, 0);
|
||||
|
||||
/* Disable */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_DISABLED);
|
||||
|
||||
/* Try to disable again, but cause a timeout as fault status is set */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(),
|
||||
fb_mmu_fault_status_busy_true_f());
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_DISABLED);
|
||||
if (g->ops.fb.is_fault_buf_enabled(g, 0)) {
|
||||
unit_return_fail(m, "fault buffer not disabled as expected\n");
|
||||
}
|
||||
|
||||
nvgpu_writel(g, fb_mmu_fault_addr_lo_r(), TEST_VALUE_1);
|
||||
nvgpu_writel(g, fb_mmu_fault_addr_hi_r(), TEST_VALUE_2);
|
||||
g->ops.fb.read_mmu_fault_addr_lo_hi(g, &lo, &hi);
|
||||
if ((lo != TEST_VALUE_1) || (hi != TEST_VALUE_2)) {
|
||||
unit_return_fail(m, "Invalid MMU fault address\n");
|
||||
}
|
||||
|
||||
nvgpu_writel(g, fb_mmu_fault_inst_lo_r(), TEST_VALUE_1);
|
||||
nvgpu_writel(g, fb_mmu_fault_inst_hi_r(), TEST_VALUE_2);
|
||||
g->ops.fb.read_mmu_fault_inst_lo_hi(g, &lo, &hi);
|
||||
if ((lo != TEST_VALUE_1) || (hi != TEST_VALUE_2)) {
|
||||
unit_return_fail(m, "Invalid MMU fault inst\n");
|
||||
}
|
||||
|
||||
val = g->ops.fb.read_mmu_fault_info(g);
|
||||
if (val != nvgpu_readl(g, fb_mmu_fault_info_r())) {
|
||||
unit_return_fail(m, "invalid fb_mmu_fault_info_r value\n");
|
||||
}
|
||||
|
||||
g->ops.fb.write_mmu_fault_status(g, FAULT_STATUS_TEST_VAL);
|
||||
if (nvgpu_readl(g, fb_mmu_fault_status_r()) != FAULT_STATUS_TEST_VAL) {
|
||||
unit_return_fail(m, "invalid fb_mmu_fault_status_r value\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int fb_mmu_fault_gv11b_snap_reg(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
struct mmu_fault_info mmufault;
|
||||
|
||||
/* Not a valid fault, chid should just be zero'ed out by memset */
|
||||
gv11b_mm_copy_from_fault_snap_reg(g, 0, &mmufault);
|
||||
if (mmufault.chid != 0) {
|
||||
unit_return_fail(m, "chid updated for invalid fault\n");
|
||||
}
|
||||
|
||||
/* Valid fault */
|
||||
gv11b_mm_copy_from_fault_snap_reg(g, fb_mmu_fault_status_valid_set_f(),
|
||||
&mmufault);
|
||||
if (mmufault.chid != NVGPU_INVALID_CHANNEL_ID) {
|
||||
unit_return_fail(m, "chid NOT updated for valid fault\n");
|
||||
}
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
static bool helper_is_intr_cleared(struct gk20a *g)
|
||||
{
|
||||
return (nvgpu_readl(g, fb_mmu_fault_status_r()) ==
|
||||
fb_mmu_fault_status_valid_clear_f());
|
||||
}
|
||||
|
||||
int fb_mmu_fault_gv11b_handle_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
u32 niso_intr;
|
||||
|
||||
/* Set interrupt source as "other" and handle it */
|
||||
niso_intr = fb_niso_intr_mmu_other_fault_notify_m();
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(), 0);
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (1)\n");
|
||||
}
|
||||
|
||||
/* Enable fault buffer */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
|
||||
/* Handle again for branch coverage */
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
|
||||
/* Set a valid dropped status and handle again */
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(),
|
||||
fb_mmu_fault_status_dropped_bar1_phys_set_f());
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (2)\n");
|
||||
}
|
||||
|
||||
/* Now set interrupt source as a non-replayable fault and handle it */
|
||||
niso_intr = fb_niso_intr_mmu_nonreplayable_fault_notify_m();
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(), 0);
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (3)\n");
|
||||
}
|
||||
|
||||
/* Now set source as non-replayable and overflow then handle it */
|
||||
niso_intr = fb_niso_intr_mmu_nonreplayable_fault_notify_m() |
|
||||
fb_niso_intr_mmu_nonreplayable_fault_overflow_m();
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(), 0);
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (4)\n");
|
||||
}
|
||||
|
||||
/* Same case but ensure fault status register is also set properly */
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(),
|
||||
fb_mmu_fault_status_non_replayable_overflow_m());
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (5)\n");
|
||||
}
|
||||
|
||||
/* Case where getptr is reported as corrupted */
|
||||
nvgpu_writel(g, fb_mmu_fault_status_r(),
|
||||
fb_mmu_fault_status_non_replayable_overflow_m() |
|
||||
fb_mmu_fault_status_non_replayable_getptr_corrupted_m());
|
||||
gv11b_fb_handle_mmu_fault(g, niso_intr);
|
||||
if (!helper_is_intr_cleared(g)) {
|
||||
unit_return_fail(m, "unhandled interrupt (6)\n");
|
||||
}
|
||||
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_DISABLED);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int fb_mmu_fault_gv11b_handle_bar2_fault(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
struct mmu_fault_info mmufault;
|
||||
struct nvgpu_channel refch;
|
||||
u32 fault_status = 0;
|
||||
static const char *const error_str = "test error";
|
||||
|
||||
(void) memset(&mmufault, 0, sizeof(mmufault));
|
||||
(void) memset(&refch, 0, sizeof(refch));
|
||||
|
||||
gv11b_fb_handle_bar2_fault(g, &mmufault, fault_status);
|
||||
|
||||
/* Set the minimum mmufault struct to handle the fault */
|
||||
/* First cover some error cases */
|
||||
gv11b_fb_mmu_fault_info_dump(g, NULL);
|
||||
gv11b_fb_mmu_fault_info_dump(g, &mmufault);
|
||||
|
||||
/* Now set it up properly */
|
||||
mmufault.valid = true;
|
||||
mmufault.refch = &refch;
|
||||
mmufault.fault_type_desc = error_str;
|
||||
mmufault.client_type_desc = error_str;
|
||||
mmufault.client_id_desc = error_str;
|
||||
|
||||
gv11b_fb_mmu_fault_info_dump(g, &mmufault);
|
||||
fault_status = fb_mmu_fault_status_non_replayable_error_m();
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
gv11b_fb_handle_bar2_fault(g, &mmufault, fault_status);
|
||||
|
||||
/* Case where g->ops.bus.bar2_bind fails */
|
||||
g->ops.bus.bar2_bind = hal_bar2_bind_fail;
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_ENABLED);
|
||||
gv11b_fb_handle_bar2_fault(g, &mmufault, fault_status);
|
||||
g->ops.bus.bar2_bind = hal_bar2_bind_nop;
|
||||
|
||||
/* Case where fault buffer is not enabled */
|
||||
g->ops.fb.fault_buf_set_state_hw(g, 0, NVGPU_MMU_FAULT_BUF_DISABLED);
|
||||
gv11b_fb_handle_bar2_fault(g, &mmufault, fault_status);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
26
userspace/units/fbp/Makefile
Normal file
26
userspace/units/fbp/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-fbp.o
|
||||
MODULE = fbp
|
||||
|
||||
include ../Makefile.units
|
||||
23
userspace/units/fbp/Makefile.interface.tmk
Normal file
23
userspace/units/fbp/Makefile.interface.tmk
Normal file
@@ -0,0 +1,23 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=fbp
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
24
userspace/units/fbp/Makefile.tmk
Normal file
24
userspace/units/fbp/Makefile.tmk
Normal file
@@ -0,0 +1,24 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=fbp
|
||||
NVGPU_UNIT_SRCS=nvgpu-fbp.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
222
userspace/units/fbp/nvgpu-fbp.c
Normal file
222
userspace/units/fbp/nvgpu-fbp.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unit/unit.h>
|
||||
#include <unit/io.h>
|
||||
#include <nvgpu/posix/io.h>
|
||||
#include <nvgpu/posix/posix-fault-injection.h>
|
||||
|
||||
#include <nvgpu/gk20a.h>
|
||||
#include <nvgpu/fbp.h>
|
||||
|
||||
#include <hal/top/top_gm20b.h>
|
||||
#include <hal/fuse/fuse_gm20b.h>
|
||||
|
||||
#include <nvgpu/hw/gv11b/hw_top_gv11b.h>
|
||||
#include <nvgpu/hw/gv11b/hw_fuse_gv11b.h>
|
||||
#include "nvgpu-fbp.h"
|
||||
|
||||
/*
|
||||
* Write callback.
|
||||
*/
|
||||
static void writel_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read callback.
|
||||
*/
|
||||
static void readl_access_reg_fn(struct gk20a *g,
|
||||
struct nvgpu_reg_access *access)
|
||||
{
|
||||
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
|
||||
}
|
||||
|
||||
static struct nvgpu_posix_io_callbacks test_reg_callbacks = {
|
||||
/* Write APIs all can use the same accessor. */
|
||||
.writel = writel_access_reg_fn,
|
||||
.writel_check = writel_access_reg_fn,
|
||||
.bar1_writel = writel_access_reg_fn,
|
||||
.usermode_writel = writel_access_reg_fn,
|
||||
|
||||
/* Likewise for the read APIs. */
|
||||
.__readl = readl_access_reg_fn,
|
||||
.readl = readl_access_reg_fn,
|
||||
.bar1_readl = readl_access_reg_fn,
|
||||
};
|
||||
|
||||
int test_fbp_setup(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Init HAL */
|
||||
g->ops.top.get_max_fbps_count = gm20b_top_get_max_fbps_count;
|
||||
g->ops.fuse.fuse_status_opt_fbp = gm20b_fuse_status_opt_fbp;
|
||||
|
||||
/* Map register space for FUSE_STATUS_OPT_FBP */
|
||||
if (nvgpu_posix_io_add_reg_space(g, fuse_status_opt_fbp_r(), 0x4)
|
||||
!= 0) {
|
||||
unit_err(m, "%s: failed to register NV_FUSE space\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Map register space for TOP_SCAL_NUM_FBPS */
|
||||
if (nvgpu_posix_io_add_reg_space(g, top_num_fbps_r(), 0x4) != 0) {
|
||||
unit_err(m, "%s: failed to register NV_TOP space\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
(void)nvgpu_posix_register_io(g, &test_reg_callbacks);
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_fbp_free_reg_space(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
/* Free register space */
|
||||
nvgpu_posix_io_delete_reg_space(g, fuse_status_opt_fbp_r());
|
||||
nvgpu_posix_io_delete_reg_space(g, top_num_fbps_r());
|
||||
|
||||
return UNIT_SUCCESS;
|
||||
}
|
||||
|
||||
int test_fbp_init_and_query(struct unit_module *m, struct gk20a *g,
|
||||
void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
int val = 0;
|
||||
u32 fbp_en_mask;
|
||||
u32 max_fbps_count;
|
||||
struct nvgpu_fbp *fbp = g->fbp;
|
||||
struct nvgpu_posix_fault_inj *kmem_fi =
|
||||
nvgpu_kmem_get_fault_injection();
|
||||
|
||||
/* First, cover the memory allocation failure path. */
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, true, 0);
|
||||
|
||||
/* Call fbp_init_support and confirm it returns -ENOMEM. */
|
||||
val = nvgpu_fbp_init_support(g);
|
||||
if (val != -ENOMEM) {
|
||||
unit_err(m,
|
||||
"%s: fbp_init_support did not fail due to memory allocation.\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
nvgpu_posix_enable_fault_injection(kmem_fi, false, 0);
|
||||
|
||||
/* Initialize the FBP floorsweeping status in fuse to 0xE1. */
|
||||
fbp_en_mask = 0xE1U;
|
||||
nvgpu_posix_io_writel_reg_space(g, fuse_status_opt_fbp_r(),
|
||||
fbp_en_mask);
|
||||
|
||||
/* Initialize the maximum number of FBPs to 8. */
|
||||
max_fbps_count = 8U;
|
||||
nvgpu_posix_io_writel_reg_space(g, top_num_fbps_r(), max_fbps_count);
|
||||
|
||||
/* Call fbp_init_support to initialize g->fbp */
|
||||
val = nvgpu_fbp_init_support(g);
|
||||
if (val != 0) {
|
||||
unit_err(m, "%s: Failed to initialize g->fbp.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
fbp = g->fbp;
|
||||
|
||||
/* Check if the max_fbps_count is read correctly. */
|
||||
max_fbps_count = nvgpu_fbp_get_max_fbps_count(fbp);
|
||||
if (max_fbps_count != 8U) {
|
||||
unit_err(m, "%s: fbp->max_fbps_count is incorrect.\n",
|
||||
__func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the FBP en_mask is calculated correctly.
|
||||
* Note: 0:enable and 1:disable in value read from fuse.
|
||||
* so we've to flip the bits and also set unused bits to zero.
|
||||
*/
|
||||
fbp_en_mask = nvgpu_fbp_get_fbp_en_mask(fbp);
|
||||
if (fbp_en_mask != 0x1EU) {
|
||||
unit_err(m, "%s: fbp->fbp_en_mask is incorrect.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Initialize the FBP floorsweeping status in fuse to 5.
|
||||
* Use different value than above to check if init occurs once.
|
||||
*/
|
||||
max_fbps_count = 5U;
|
||||
nvgpu_posix_io_writel_reg_space(g, top_num_fbps_r(), max_fbps_count);
|
||||
|
||||
/* Call fbp_init_support again to ensure the initialization is
|
||||
* done once.
|
||||
*/
|
||||
val = nvgpu_fbp_init_support(g);
|
||||
if (val != 0) {
|
||||
unit_err(m, "%s: Failed to initialize g->fbp.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the max_fbps_count is NOT set to 5. */
|
||||
max_fbps_count = nvgpu_fbp_get_max_fbps_count(fbp);
|
||||
if (max_fbps_count == 5U) {
|
||||
unit_err(m, "%s: g->fbp initialized again.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test_fbp_remove_support(struct unit_module *m, struct gk20a *g, void *args)
|
||||
{
|
||||
int ret = UNIT_SUCCESS;
|
||||
|
||||
/* Confirm if g->fbp != NULL before calling fbp_remov_support API. */
|
||||
if (g->fbp == NULL) {
|
||||
unit_err(m, "%s: g->fbp is uninitialized.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/* Call fbp_remove_support to cleanup the saved FBP data */
|
||||
nvgpu_fbp_remove_support(g);
|
||||
|
||||
/* Confirm if g->fbp == NULL after cleanup. */
|
||||
if (g->fbp != NULL) {
|
||||
unit_err(m, "%s: g->fbp is not cleaned up.\n", __func__);
|
||||
return UNIT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call fbp_remove_support with fbp pointer set to NULL for branch
|
||||
* coverage.
|
||||
*/
|
||||
nvgpu_fbp_remove_support(g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct unit_module_test fbp_tests[] = {
|
||||
UNIT_TEST(fbp_setup, test_fbp_setup, NULL, 0),
|
||||
UNIT_TEST(fbp_init_and_query, test_fbp_init_and_query, NULL, 0),
|
||||
UNIT_TEST(fbp_remove_support, test_fbp_remove_support, NULL, 0),
|
||||
UNIT_TEST(fbp_free_reg_space, test_fbp_free_reg_space, NULL, 0),
|
||||
};
|
||||
|
||||
UNIT_MODULE(fbp, fbp_tests, UNIT_PRIO_NVGPU_TEST);
|
||||
127
userspace/units/fbp/nvgpu-fbp.h
Normal file
127
userspace/units/fbp/nvgpu-fbp.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UNIT_NVGPU_FBP_H
|
||||
#define UNIT_NVGPU_FBP_H
|
||||
|
||||
struct gk20a;
|
||||
struct unit_module;
|
||||
|
||||
/** @addtogroup SWUTS-fbp
|
||||
* @{
|
||||
*
|
||||
* Software Unit Test Specification for nvgpu.common.fbp
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test specification for: test_fbp_setup
|
||||
*
|
||||
* Description: Setup prerequisites for tests.
|
||||
*
|
||||
* Test Type: Other (setup)
|
||||
*
|
||||
* Input: None
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize HAL function pointers.
|
||||
* - Map the register space for NV_TOP and NV_FUSE.
|
||||
* - Register read/write callback functions.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if encounters an error creating register space;
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_fbp_setup(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_fbp_free_reg_space
|
||||
*
|
||||
* Description: Free resources from test_setup()
|
||||
*
|
||||
* Test Type: Other (cleanup)
|
||||
*
|
||||
* Input: test_fbp_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Free up NV_TOP and NV_FUSE register space.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_SUCCESS
|
||||
*/
|
||||
int test_fbp_free_reg_space(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
/**
|
||||
* Test specification for: test_fbp_init_and_query
|
||||
*
|
||||
* Description: Verify the FBP init and config query APIs exposed by common.fbp.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_fbp_init_support, nvgpu_fbp_get_max_fbps_count, nvgpu_fbp_get_fbp_en_mask
|
||||
*
|
||||
* Input: test_fbp_setup() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Initialize the FBP floorsweeping status in fuse to 0xE1 by writing to fuse
|
||||
* register fuse_status_opt_fbp_r().
|
||||
* - Initialize the maximum number of FBPs to 8 by writing to Top register
|
||||
* top_num_fbps_r().
|
||||
* - Call nvgpu_fbp_init_support to initialize g->fbp.
|
||||
* - Read the g->fbp->max_fbp_count using nvgpu_fbp_get_max_fbps_count().
|
||||
* - Check if the max_fbps_count is initialized and read back correctly.
|
||||
* - Read the g->fbp->fbp_en_mask using nvgpu_fbp_get_fbp_en_mask().
|
||||
* - Check if the FBP en_mask is calculated correctly and read back right too.
|
||||
* - Initialize the FBP floorsweeping status in fuse to 5(Use different value
|
||||
* than before to check if init occurs once.
|
||||
* - Call fbp_init_support again to ensure the initialization is done once.
|
||||
* - Check if the max_fbps_count is NOT set to new value(5).
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if above API fails to init g->fbp or read back values from g->fbp
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_fbp_init_and_query(struct unit_module *m, struct gk20a *g, void *args);
|
||||
|
||||
|
||||
/**
|
||||
* Test specification for: test_fbp_remove_support
|
||||
*
|
||||
* Description: Verify the nvgpu_fbp_remove_support exposed by common.fbp.
|
||||
*
|
||||
* Test Type: Feature
|
||||
*
|
||||
* Targets: nvgpu_fbp_remove_support
|
||||
*
|
||||
* Input: test_fbp_init_and_query() has been executed.
|
||||
*
|
||||
* Steps:
|
||||
* - Confirm if g->fbp != NULL before calling fbp_remov_support API.
|
||||
* - Call fbp_remove_support to cleanup the saved FBP data.
|
||||
* - Confirm if g->fbp == NULL after cleanup.
|
||||
* - Call fbp_remove_support with fbp pointer set to NULL for branch coverage.
|
||||
*
|
||||
* Output:
|
||||
* - UNIT_FAIL if above API fails to cleanup g->fbp;
|
||||
* - UNIT_SUCCESS otherwise
|
||||
*/
|
||||
int test_fbp_remove_support(struct unit_module *m, struct gk20a *g, void *args);
|
||||
#endif /* UNIT_NVGPU_FBP_H */
|
||||
27
userspace/units/fifo/Makefile
Normal file
27
userspace/units/fifo/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-fifo-common.o nvgpu-fifo-gv11b.o
|
||||
|
||||
MODULE = nvgpu-fifo-common
|
||||
|
||||
include ../Makefile.units
|
||||
29
userspace/units/fifo/Makefile.interface.tmk
Normal file
29
userspace/units/fifo/Makefile.interface.tmk
Normal file
@@ -0,0 +1,29 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
# libnvgpu-fifo interface makefile fragment
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION
|
||||
|
||||
NV_INTERFACE_NAME := nvgpu-fifo-common
|
||||
NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME)
|
||||
NV_INTERFACE_SONAME := lib$(NV_INTERFACE_NAME).so
|
||||
|
||||
endif
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
26
userspace/units/fifo/Makefile.tmk
Normal file
26
userspace/units/fifo/Makefile.tmk
Normal file
@@ -0,0 +1,26 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019-2020 NVIDIA CORPORATION. All Rights Reserved.
|
||||
#
|
||||
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
# Component makefile for compiling nvgpu-fifo common tests.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME = nvgpu-fifo-common
|
||||
NVGPU_UNIT_SRCS = nvgpu-fifo-common.c nvgpu-fifo-gv11b.c
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
33
userspace/units/fifo/channel/Makefile
Normal file
33
userspace/units/fifo/channel/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-channel.o
|
||||
MODULE = nvgpu-channel
|
||||
|
||||
LIB_PATHS += -lnvgpu-fifo-common
|
||||
include ../../Makefile.units
|
||||
|
||||
lib$(MODULE).so: fifo
|
||||
|
||||
fifo:
|
||||
$(MAKE) -C ..
|
||||
|
||||
35
userspace/units/fifo/channel/Makefile.interface.tmk
Normal file
35
userspace/units/fifo/channel/Makefile.interface.tmk
Normal file
@@ -0,0 +1,35 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME=nvgpu-channel
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.interface.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
39
userspace/units/fifo/channel/Makefile.tmk
Normal file
39
userspace/units/fifo/channel/Makefile.tmk
Normal file
@@ -0,0 +1,39 @@
|
||||
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||
#
|
||||
# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# tmake for SW Mobile component makefile
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
NVGPU_UNIT_NAME = nvgpu-channel
|
||||
NVGPU_UNIT_SRCS = nvgpu-channel.c
|
||||
|
||||
NVGPU_UNIT_INTERFACE_DIRS := \
|
||||
$(NV_COMPONENT_DIR)/..
|
||||
|
||||
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.tmk
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: t
|
||||
# tab-width: 8
|
||||
# End:
|
||||
# vi: set tabstop=8 noexpandtab:
|
||||
32
userspace/units/fifo/channel/gk20a/Makefile
Normal file
32
userspace/units/fifo/channel/gk20a/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
OBJS = nvgpu-channel-gk20a.o
|
||||
MODULE = nvgpu-channel-gk20a
|
||||
|
||||
LIB_PATHS += -lnvgpu-fifo-common
|
||||
include ../../../Makefile.units
|
||||
|
||||
lib$(MODULE).so: fifo
|
||||
|
||||
fifo:
|
||||
$(MAKE) -C ../..
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user