summaryrefslogtreecommitdiffstats
path: root/userspace
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2018-06-27 17:45:07 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-08-10 02:11:06 -0400
commit691bf904451bfe2e4c44ea05319149996abbbbf1 (patch)
tree0fe66bd37989f9d619234b7f4d2be1df6ed61c85 /userspace
parent6e746a97cc7ee2bc5a3adee04dd9c65b3921eee5 (diff)
gpu: nvgpu: unit: Add unit testing FW
Full documentation for this is in the unit testing confluence page. JIRA NVGPU-525 Bug 2261555 Change-Id: I463e6267eb0eb12b7313f8b275266e8faabe5ccf Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1683915 GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'userspace')
-rw-r--r--userspace/Makefile95
-rw-r--r--userspace/Makefile.sources16
-rw-r--r--userspace/include/unit/args.h58
-rw-r--r--userspace/include/unit/core.h63
-rw-r--r--userspace/include/unit/io.h88
-rw-r--r--userspace/include/unit/module.h31
-rw-r--r--userspace/include/unit/results.h70
-rw-r--r--userspace/include/unit/unit.h100
-rw-r--r--userspace/src/args.c134
-rw-r--r--userspace/src/exec.c90
-rw-r--r--userspace/src/io.c105
-rw-r--r--userspace/src/module.c167
-rw-r--r--userspace/src/nvgpu.c78
-rw-r--r--userspace/src/results.c128
-rw-r--r--userspace/src/unit_main.c76
-rwxr-xr-xuserspace/unit.sh16
-rw-r--r--userspace/units/Makefile.units45
17 files changed, 1343 insertions, 17 deletions
diff --git a/userspace/Makefile b/userspace/Makefile
index 70e93bad..56709ec4 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -18,6 +18,10 @@
18# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 18# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19# DEALINGS IN THE SOFTWARE. 19# DEALINGS IN THE SOFTWARE.
20 20
21# TODO:
22# - Separate rule for nvgpu_unit shared library
23# - Proper header dependency checking.
24
21# Turn off suffix rules. They are deprecated. 25# Turn off suffix rules. They are deprecated.
22.SUFFIXES: 26.SUFFIXES:
23 27
@@ -28,25 +32,35 @@ TWD=$(CURDIR)
28# Top level out dir. 32# Top level out dir.
29OUT=$(TWD)/build 33OUT=$(TWD)/build
30 34
35# Core unit test framework.
36CORE_SRC=$(TWD)/src
37CORE_OUT=$(OUT)/nvgpu_unit_core
38
31# Nvgpu driver code. 39# Nvgpu driver code.
32NVGPU_SRC=$(TWD)/../drivers/gpu/nvgpu 40NVGPU_SRC=$(TWD)/../drivers/gpu/nvgpu
33NVGPU_OUT=$(OUT)/libnvgpu 41NVGPU_OUT=$(OUT)/libnvgpu
34 42
35INCLUDES= \ 43# Unit tests themselves.
36 -I$(NVGPU_SRC) \ 44UNIT_SRC=$(TWD)/units
37 -I$(NVGPU_SRC)/include \ 45UNIT_OUT=$(OUT)/units
38 -I../include \
39 -I../include/uapi
40 46
41CONFIGS= \ 47INCLUDES= \
42 -D__NVGPU_POSIX__ 48 -I$(NVGPU_SRC) \
49 -I$(NVGPU_SRC)/include \
50 -I$(TWD)/../include \
51 -I$(TWD)/../include/uapi \
52 -I$(TWD)/include
53
54CONFIGS=-D__NVGPU_POSIX__
43 55
44# Compiler, c-flags, etc. 56# Compiler, c-flags, etc.
45 57
46# CC = clang 58# CC = clang
47CC = gcc 59CC = gcc
48CFLAGS = -Wall -ggdb -Werror -fPIC $(INCLUDES) $(CONFIGS) 60CFLAGS = -Wall -ggdb -Werror -fPIC $(INCLUDES) $(CONFIGS)
49LIBS = -lpthread -pthread 61LIB_PATHS = -L$(OUT)
62LIBS = -lpthread -pthread -lgcov -ldl
63
50 64
51# Source files. We expect $(OBJS) and $(HEADERS) to get filled in here. 65# Source files. We expect $(OBJS) and $(HEADERS) to get filled in here.
52include Makefile.sources 66include Makefile.sources
@@ -55,19 +69,68 @@ include Makefile.sources
55# Linux kernel. 69# Linux kernel.
56include Makefile.configs 70include Makefile.configs
57 71
58all: $(OUT)/libnvgpu-drv.so 72all: $(OUT)/nvgpu_unit $(UNITS)
73
74# Convenience targets.
75.PHONY: libnvgpu core units
76libnvgpu: $(OUT)/libnvgpu-drv.so
77core: $(OUT)/nvgpu_unit
78units: $(UNITS)
79
80# Note the weird libnvgpu_unit.so file: this is a bit of a hack. It lets the
81# unit tests link back against the nvgpu_unit executable so that they can call
82# functions (like unit_info()) directly. This shared library isn't actually
83# used for anything beyond that.
84#
85# Also it really should have its own rule...
86$(OUT)/nvgpu_unit: $(OUT)/libnvgpu-drv.so $(CORE_OBJS)
87 $(CC) -shared -o $(OUT)/libnvgpu_unit.so \
88 $(CORE_OBJS) $(LIB_PATHS) $(LIBS)
89 $(CC) --coverage \
90 -o $(OUT)/nvgpu_unit $(CORE_OBJS) $(LIB_PATHS) $(LIBS)
59 91
60$(OUT)/libnvgpu-drv.so: $(OBJS) 92$(OUT)/libnvgpu-drv.so: $(OBJS)
61 $(CC) -shared -o $(OUT)/libnvgpu-drv.so $(OBJS) -lgcov 93 $(CC) -shared -o $(OUT)/libnvgpu-drv.so $(OBJS) -lgcov
62 94
63# Default build target for all the object files we want to build in userspace. 95# Default build target for all the nvgpu driver object files we want to build in
96# userspace. These get bundled into libnvgpu-drv.so.
64$(NVGPU_OUT)/%.o : $(NVGPU_SRC)/%.c $(HEADERS) 97$(NVGPU_OUT)/%.o : $(NVGPU_SRC)/%.c $(HEADERS)
65 @if [ ! -d $(dir $@) ] ; then \ 98 @if [ ! -d $(dir $@) ] ; then \
66 mkdir -p $(dir $@) ; \ 99 mkdir -p $(dir $@) ; \
67 fi 100 fi
68 $(CC) $(CFLAGS) $(configs) -c -o $@ $< 101 $(CC) --coverage $(CFLAGS) $(configs) -c -o $@ $<
102
103# Build target for unit test files. These are not part of the libnvgpu-drv.so.
104# These comprise the unit test framework.
105$(CORE_OUT)/%.o : $(CORE_SRC)/%.c $(CORE_HEADERS)
106 @if [ ! -d $(dir $@) ] ; then \
107 mkdir -p $(dir $@) ; \
108 fi
109 $(CC) --coverage $(CFLAGS) $(configs) -c -o $@ $<
110
111# Certain variables should be exported to the unit test module builds.
112export TWD INCLUDES CONFIGS UNIT_SRC UNIT_OUT
113export CC CFLAGS LIB_PATHS LIBS
69 114
70.PHONY: clean 115.PHONY: $(UNITS)
116$(UNITS): $(OUT)/libnvgpu-drv.so
117 @echo "Building unit module: $@"
118 @+$(MAKE) --no-print-directory -C $@
71 119
72clean: 120.PHONY: clean nvgpu_clean core_clean unit_clean
121
122clean: nvgpu_clean core_clean unit_clean
73 rm -rf $(OUT) 123 rm -rf $(OUT)
124
125nvgpu_clean:
126 rm -rf $(OUT)/libnvgpu*
127
128core_clean:
129 rm -rf $(OUT)/nvgpu_unit*
130
131unit_clean:
132 @for d in $(UNITS); do \
133 echo Cleaning $$d; \
134 $(MAKE) --no-print-directory -C $$d clean; \
135 done
136 rm -rf $(OUT)/units
diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources
index 3598c971..cb46573a 100644
--- a/userspace/Makefile.sources
+++ b/userspace/Makefile.sources
@@ -24,7 +24,6 @@ include ../drivers/gpu/nvgpu/Makefile.sources
24 24
25OBJS := $(srcs:%.c=$(NVGPU_OUT)/%.o) 25OBJS := $(srcs:%.c=$(NVGPU_OUT)/%.o)
26 26
27
28HEADERS := \ 27HEADERS := \
29 $(NVGPU_SRC)/include/nvgpu/*.h \ 28 $(NVGPU_SRC)/include/nvgpu/*.h \
30 $(NVGPU_SRC)/include/nvgpu/hw/*/*.h \ 29 $(NVGPU_SRC)/include/nvgpu/hw/*/*.h \
@@ -32,3 +31,18 @@ HEADERS := \
32 $(NVGPU_SRC)/gm20b/*.h \ 31 $(NVGPU_SRC)/gm20b/*.h \
33 $(NVGPU_SRC)/gp10b/*.h \ 32 $(NVGPU_SRC)/gp10b/*.h \
34 $(NVGPU_SRC)/gv11b/*.h 33 $(NVGPU_SRC)/gv11b/*.h
34
35CORE_OBJS := \
36 $(CORE_OUT)/unit_main.o \
37 $(CORE_OUT)/nvgpu.o \
38 $(CORE_OUT)/args.o \
39 $(CORE_OUT)/io.o \
40 $(CORE_OUT)/module.o \
41 $(CORE_OUT)/results.o \
42 $(CORE_OUT)/exec.o
43
44CORE_HEADERS := \
45 $(CORE_SRC)/../include/unit/*.h
46
47# Each directory under the UNIT_SRC directory should correspond to one module.
48UNITS :=
diff --git a/userspace/include/unit/args.h b/userspace/include/unit/args.h
new file mode 100644
index 00000000..def84a29
--- /dev/null
+++ b/userspace/include/unit/args.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_ARGS_H__
24#define __UNIT_ARGS_H__
25
26#include <stdbool.h>
27
28/*
29 * Allow defaults to be changed at compile time.
30 */
31#define __stringify(x) #x
32#define stringify(x) __stringify(x)
33
34#ifndef __DEFAULT_ARG_UNIT_LOAD_PATH
35#define __DEFAULT_ARG_UNIT_LOAD_PATH build/units
36#endif
37#define DEFAULT_ARG_UNIT_LOAD_PATH stringify(__DEFAULT_ARG_UNIT_LOAD_PATH)
38
39struct unit_fw;
40
41struct unit_fw_args {
42 bool help;
43 int verbose_lvl;
44 bool no_color;
45
46 const char *unit_name;
47 const char *unit_load_path;
48};
49
50int core_parse_args(struct unit_fw *fw, int argc, char **argv);
51void core_print_help(struct unit_fw *fw);
52
53/*
54 * Convenience for getting the args struct pointer.
55 */
56#define args(fw) ((fw)->args)
57
58#endif
diff --git a/userspace/include/unit/core.h b/userspace/include/unit/core.h
new file mode 100644
index 00000000..d9d119db
--- /dev/null
+++ b/userspace/include/unit/core.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_CORE_H__
24#define __UNIT_CORE_H__
25
26struct unit_fw_args;
27struct unit_modules;
28struct unit_results;
29
30struct gk20a;
31
32/*
33 * The core unit testing framework data structure. Keeps track of global state
34 * for the unit test app.
35 */
36struct unit_fw {
37 struct unit_fw_args *args;
38
39 struct unit_module **modules;
40
41 struct unit_results *results;
42
43 /*
44 * nvgpu-drv interface. Currently the only two directly referenced
45 * functions are:
46 *
47 * nvgpu_posix_probe()
48 * nvgpu_posix_cleanup()
49 *
50 * There will get populated so that we can call them before/after each
51 * module.
52 */
53 void *nvgpu_so;
54 struct {
55 struct gk20a *(*nvgpu_posix_probe)(void);
56 void (*nvgpu_posix_cleanup)(struct gk20a *g);
57 } nvgpu;
58};
59
60int core_load_nvgpu(struct unit_fw *fw);
61int core_exec(struct unit_fw *fw);
62
63#endif
diff --git a/userspace/include/unit/io.h b/userspace/include/unit/io.h
new file mode 100644
index 00000000..1fd0fa43
--- /dev/null
+++ b/userspace/include/unit/io.h
@@ -0,0 +1,88 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_IO_H__
24#define __UNIT_IO_H__
25
26struct unit_fw;
27struct unit_module;
28
29/*
30 * necessary for args(fw) macro. IO will always, in general, depend on args
31 * since the args will specify where IO should be directed to.
32 */
33#include <unit/args.h>
34
35#define core_msg(fw, msg, ...) \
36 core_vbs(fw, 0, msg, ##__VA_ARGS__)
37#define core_msg_color(fw, color, msg, ...) \
38 core_vbs_color(fw, color, 0, msg, ##__VA_ARGS__)
39
40#define core_vbs_color(fw, color, lvl, msg, ...) \
41 do { \
42 if ((lvl) > args(fw)->verbose_lvl) \
43 continue; \
44 \
45 /* Print if verbosity level is high enough. */ \
46 __core_print_stdout(fw, color, msg, ##__VA_ARGS__); \
47 } while (0)
48#define core_vbs(fw, lvl, msg, ...) \
49 core_vbs_color(fw, NULL, lvl, msg, ##__VA_ARGS__)
50
51#define core_err(fw, msg, ...) \
52 __core_print_stderr(fw, "(%s:%d) " msg, \
53 __func__, __LINE__, ##__VA_ARGS__)
54
55/*
56 * Output macro for unit tests to use.
57 */
58#define unit_info(unit, msg, ...) \
59 __unit_info_color(unit, NULL, msg, ##__VA_ARGS__)
60#define unit_err(unit, msg, ...) \
61 __unit_info_color(unit, C_RED, msg, ##__VA_ARGS__)
62
63/*
64 * Don't go overboard with these!!!
65 */
66#define C_RED "\x1B[31m"
67#define C_GREEN "\x1B[32m"
68#define C_YELLOW "\x1B[33m"
69#define C_BLUE "\x1B[34m"
70#define C_MAGENTA "\x1B[35m"
71#define C_CYAN "\x1B[36m"
72#define C_WHITE "\x1B[37m"
73#define C_RESET "\x1B[0m"
74
75/*
76 * Printing functions. Do not use these directly. Instead use the provided
77 * macros.
78 */
79__attribute__((format (printf, 3, 4)))
80void __core_print_stdout(struct unit_fw *fw, const char *color,
81 const char *fmt, ...);
82__attribute__((format (printf, 2, 3)))
83void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...);
84__attribute__((format (printf, 3, 4)))
85void __unit_info_color(struct unit_module *unit, const char *color,
86 const char *fmt, ...);
87
88#endif
diff --git a/userspace/include/unit/module.h b/userspace/include/unit/module.h
new file mode 100644
index 00000000..79737d61
--- /dev/null
+++ b/userspace/include/unit/module.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_MODULE_H__
24#define __UNIT_MODULE_H__
25
26struct unit_fw;
27struct unit_module;
28
29struct unit_module **core_load_modules(struct unit_fw *fw);
30
31#endif
diff --git a/userspace/include/unit/results.h b/userspace/include/unit/results.h
new file mode 100644
index 00000000..fb88e59d
--- /dev/null
+++ b/userspace/include/unit/results.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_RESULTS_H__
24#define __UNIT_RESULTS_H__
25
26/*
27 * Keep track of the the results of a set of unit tests. This is effectively
28 * just a single linked list of records for each test.
29 */
30
31struct unit_test_record {
32 /*
33 * Let's us determine the name of the test.
34 */
35 struct unit_module *mod;
36 struct unit_module_test *test;
37
38 /*
39 * True for pass, false for fail.
40 */
41 bool status;
42
43 struct unit_test_record *next;
44};
45
46struct unit_test_list {
47 struct unit_test_record *head;
48 struct unit_test_record *last;
49};
50
51struct unit_results {
52 struct unit_test_list passing;
53 struct unit_test_list failing;
54
55 int nr_tests;
56 int nr_passing;
57};
58
59#define for_record_in_test_list(__test_list, __test) \
60 for ((__test) = (__test_list)->head; \
61 (__test) != NULL; \
62 (__test) = (__test)->next)
63
64int core_add_test_record(struct unit_fw *fw,
65 struct unit_module *mod,
66 struct unit_module_test *test,
67 bool success);
68void core_print_test_status(struct unit_fw *fw);
69
70#endif
diff --git a/userspace/include/unit/unit.h b/userspace/include/unit/unit.h
new file mode 100644
index 00000000..9438d4d9
--- /dev/null
+++ b/userspace/include/unit/unit.h
@@ -0,0 +1,100 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __UNIT_UNIT_H__
24#define __UNIT_UNIT_H__
25
26struct gk20a;
27
28struct unit_module;
29typedef int (*module_test_fn)(struct unit_module *m,
30 struct gk20a *g, void *args);
31
32#define UNIT_SUCCESS 0
33#define UNIT_FAIL -1
34
35struct unit_module_test {
36 /*
37 * Name of the test.
38 */
39 const char *name;
40
41 /*
42 * Function to call to execute the test.
43 */
44 module_test_fn fn;
45
46 /*
47 * A void pointer to arbitrary arguments. Lets the same unit test
48 * function perform multiple tests. This gets passed into the
49 * module_test_fn as @args.
50 */
51 void *args;
52};
53
54/*
55 * Interface to the unit test framework module loader. Each unit test module
56 * will have exactly one of these.
57 */
58struct unit_module {
59 /*
60 * Name of the module.
61 */
62 const char *name;
63
64 /*
65 * NULL terminated list of tests within the module.
66 */
67 struct unit_module_test *tests;
68 unsigned long nr_tests;
69
70 /*
71 * For the core FW to use. Not for modules!!!
72 */
73 void *lib_handle;
74 struct unit_fw *fw;
75};
76
77#define UNIT_MODULE(__name, __tests) \
78 struct unit_module __unit_module__ = { \
79 .name = #__name, \
80 .tests = __tests, \
81 .nr_tests = (sizeof(__tests) / \
82 sizeof(struct unit_module_test)), \
83 .lib_handle = NULL, \
84 }
85
86#define UNIT_TEST(__name, __fn, __args) \
87 { \
88 .name = #__name, \
89 .fn = __fn, \
90 .args = __args, \
91 }
92
93#define unit_return_fail(m, msg, ...) \
94 do { \
95 unit_err(m, "%s():%d " msg, \
96 __func__, __LINE__, ##__VA_ARGS__); \
97 return UNIT_FAIL; \
98 } while (0)
99
100#endif
diff --git a/userspace/src/args.c b/userspace/src/args.c
new file mode 100644
index 00000000..d91c6f6e
--- /dev/null
+++ b/userspace/src/args.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdio.h>
24#include <getopt.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include <unit/core.h>
29#include <unit/args.h>
30#include <unit/io.h>
31
32static struct option core_opts[] = {
33 { "help", 0, NULL, 'h' },
34 { "verbose", 0, NULL, 'v' },
35 { "quiet", 0, NULL, 'q' },
36 { "no-color", 0, NULL, 'C' },
37
38 { "unit-load-path", 1, NULL, 'L' },
39
40 { NULL, 0, NULL, 0 }
41};
42
43static const char *core_opts_str = "hvqCL:";
44
45void core_print_help(struct unit_fw *fw)
46{
47 const char **line, *help_msg[] = {
48"NvGpu Unit Testing FW. Basic usage\n",
49"\n",
50" $ nvgpu_unit [options] <unit>\n",
51"\n",
52"Basic usage consists of one or more options and a particular unit test to\n",
53"execute.\n",
54"\n",
55"Available options are as follows:\n",
56"\n",
57" -h, --help Print this help message and exit.\n",
58" -v, --verbose Increment the verbosity level. Can be specified\n",
59" multiple times.\n",
60" -q, --quiet Set the verbose level back to 0.\n",
61" -C, --no-color Disable color printing; for example, if writing\n",
62" output to a file the color escape sequences will\n",
63" corrupt that file.\n",
64" -L, --unit-load-path <PATH>\n",
65" Path to where the unit test libraries reside.\n",
66"\n",
67"Note: mandatory arguments to long arguments are mandatory for short\n",
68"arguments as well.\n",
69NULL
70 };
71
72 line = help_msg;
73 while (*line != NULL) {
74 core_msg(fw, "%s", *line);
75 line++;
76 }
77}
78
79static void set_arg_defaults(struct unit_fw_args *args)
80{
81 args->unit_load_path = DEFAULT_ARG_UNIT_LOAD_PATH;
82}
83
84/*
85 * Parse command line arguments.
86 */
87int core_parse_args(struct unit_fw *fw, int argc, char **argv)
88{
89 int c, opt_index;
90 struct unit_fw_args *args;
91
92 args = malloc(sizeof(*args));
93 if (!args)
94 return -1;
95
96 memset(args, 0, sizeof(*args));
97 set_arg_defaults(args);
98
99 fw->args = args;
100
101 while (1) {
102 c = getopt_long(argc, argv,
103 core_opts_str, core_opts, &opt_index);
104
105 if (c == -1)
106 break;
107
108 switch (c) {
109 case 'h':
110 args->help = true;
111 break;
112 case 'v':
113 args->verbose_lvl += 1;
114 break;
115 case 'q':
116 args->verbose_lvl = 0;
117 break;
118 case 'C':
119 args->no_color = true;
120 break;
121 case 'L':
122 args->unit_load_path = optarg;
123 break;
124 case '?':
125 args->help = true;
126 return -1;
127 default:
128 core_err(fw, "bug?!\n");
129 return -1;
130 }
131 }
132
133 return 0;
134}
diff --git a/userspace/src/exec.c b/userspace/src/exec.c
new file mode 100644
index 00000000..b9ba1336
--- /dev/null
+++ b/userspace/src/exec.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdlib.h>
24
25#include <unit/io.h>
26#include <unit/core.h>
27#include <unit/unit.h>
28#include <unit/module.h>
29#include <unit/results.h>
30
31#include <nvgpu/posix/probe.h>
32
33/*
34 * Execute a module and all its subtests. This function builds a gk20a for the
35 * test to use by executing nvgpu_posix_probe() and nvgpu_posix_cleanup();
36 */
37static int core_exec_module(struct unit_fw *fw,
38 struct unit_module *module)
39{
40 unsigned int i;
41 struct gk20a *g = fw->nvgpu.nvgpu_posix_probe();
42
43 if (!g)
44 return -1;
45
46 core_vbs(fw, 1, "Execing module: %s\n", module->name);
47
48 /*
49 * Execute each test within the module. No reinit is done between tests.
50 * Thats up to the module itself to handle. Any setup/teardown between
51 * unit tests must be handled within the module.
52 */
53 for (i = 0; i < module->nr_tests; i++) {
54 struct unit_module_test *t = module->tests + i;
55 int test_status;
56
57 core_msg(fw, "Running %s.%s\n", module->name, t->name);
58 test_status = t->fn(module, g, t->args);
59
60 if (test_status != UNIT_SUCCESS)
61 core_msg_color(fw, C_RED,
62 " Unit error! Test %s.%s FAILED!\n",
63 module->name, t->name);
64
65 core_add_test_record(fw, module, t,
66 test_status == UNIT_SUCCESS);
67 }
68
69 fw->nvgpu.nvgpu_posix_cleanup(g);
70
71 return 0;
72}
73
74/*
75 * Execute all modules loaded by the unit test framework.
76 */
77int core_exec(struct unit_fw *fw)
78{
79 int ret;
80 struct unit_module **modules;
81
82 for (modules = fw->modules; *modules != NULL; modules++) {
83 ret = core_exec_module(fw, *modules);
84
85 if (ret != 0)
86 return ret;
87 }
88
89 return 0;
90}
diff --git a/userspace/src/io.c b/userspace/src/io.c
new file mode 100644
index 00000000..21ac54da
--- /dev/null
+++ b/userspace/src/io.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26
27#include <unit/io.h>
28#include <unit/args.h>
29#include <unit/core.h>
30#include <unit/unit.h>
31
32#define MAX_LOG_LINE_LENGTH 4096
33
34static void __core_print_file(struct unit_fw *fw, FILE *filp,
35 const char *prefix, const char *msg,
36 const char *color)
37{
38 if (color == NULL || args(fw)->no_color)
39 color = "";
40
41 fprintf(filp, "[%s%s%s] %s%s%s",
42 color, prefix, C_RESET,
43 color, msg, C_RESET);
44}
45
46__attribute__((format (printf, 3, 4)))
47void __core_print_stdout(struct unit_fw *fw, const char *color,
48 const char *fmt, ...)
49{
50 va_list args;
51 char buf[MAX_LOG_LINE_LENGTH];
52
53 va_start(args, fmt);
54 vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
55 va_end(args);
56
57 buf[MAX_LOG_LINE_LENGTH - 1] = 0;
58
59 __core_print_file(fw, stdout, "C", buf, color);
60}
61
62__attribute__((format (printf, 2, 3)))
63void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...)
64{
65 va_list args;
66 char buf[MAX_LOG_LINE_LENGTH];
67
68 va_start(args, fmt);
69 vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
70 va_end(args);
71
72 buf[MAX_LOG_LINE_LENGTH - 1] = 0;
73
74 __core_print_file(fw, stdout, "E", buf, C_RED);
75}
76
77__attribute__((format (printf, 3, 4)))
78void __unit_info_color(struct unit_module *unit, const char *color,
79 const char *fmt, ...)
80{
81 va_list args;
82 char buf[MAX_LOG_LINE_LENGTH];
83 char *msg_start;
84 int written;
85
86 /*
87 * Default color for module prints is blue. Users can still turn this
88 * off with '-C'.
89 */
90 if (color == NULL)
91 color = C_BLUE;
92
93 /*
94 * First prepend the unit name to the print.
95 */
96 written = snprintf(buf, MAX_LOG_LINE_LENGTH, " [%s] ", unit->name);
97
98 msg_start = buf + written;
99
100 va_start(args, fmt);
101 vsnprintf(msg_start, MAX_LOG_LINE_LENGTH - written, fmt, args);
102 va_end(args);
103
104 __core_print_file(unit->fw, stdout, "T", buf, color);
105}
diff --git a/userspace/src/module.c b/userspace/src/module.c
new file mode 100644
index 00000000..c111c6cb
--- /dev/null
+++ b/userspace/src/module.c
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <errno.h>
24#include <dlfcn.h>
25#include <dirent.h>
26#include <string.h>
27#include <stdlib.h>
28
29#include <sys/types.h>
30
31#include <unit/core.h>
32#include <unit/io.h>
33#include <unit/args.h>
34#include <unit/unit.h>
35
36static int check_module(struct unit_fw *fw, struct unit_module *mod)
37{
38 unsigned int i;
39
40 /*
41 * Make sure this module has reasonable data.
42 */
43 if (mod->name == NULL) {
44 core_err(fw, "Unnamed module!");
45 return -1;
46 }
47
48 if (mod->tests == NULL || mod->nr_tests == 0) {
49 core_err(fw, "%s: Empty module!\n", mod->name);
50 return -1;
51 }
52
53 for (i = 0; i < mod->nr_tests; i++) {
54 struct unit_module_test *test = &mod->tests[i];
55
56 if (test->name == NULL) {
57 core_err(fw, "%s: Unnamed test\n", mod->name);
58 return -1;
59 }
60
61 if (test->fn == NULL) {
62 core_err(fw, "%s: Test %s missing function \n",
63 mod->name, test->name);
64 return -1;
65 }
66 }
67
68 return 0;
69}
70
71static struct unit_module *load_one_module(struct unit_fw *fw,
72 struct dirent *dent)
73{
74 void *lib_handle;
75 struct unit_module *mod;
76
77 core_vbs(fw, 1, "Loading: %s\n", dent->d_name);
78
79 lib_handle = dlopen(dent->d_name, RTLD_NOW);
80 if (lib_handle == NULL) {
81 core_err(fw, "Failed to load %s: %s\n",
82 dent->d_name, dlerror());
83 return NULL;
84 }
85
86 mod = dlsym(lib_handle, "__unit_module__");
87 if (mod == NULL) {
88 core_vbs(fw, 1,
89 "Failed to resolve __unit_module__ in %s: %s\n",
90 dent->d_name, dlerror());
91 return NULL;
92 }
93
94 mod->lib_handle = lib_handle;
95 mod->fw = fw;
96
97 core_vbs(fw, 1, " '%s' contains %lu tests\n", mod->name, mod->nr_tests);
98
99 return mod;
100}
101
102/*
103 * Load all the modules we can from the module load path. Return the list of
104 * loaded module as an array of pointers to modules. The returned list of
105 * modules is NULL terminated.
106 */
107struct unit_module **core_load_modules(struct unit_fw *fw)
108{
109 int nr_modules = 0, i;
110 DIR *load_dir;
111 struct dirent *ent;
112 const char *load_path = args(fw)->unit_load_path;
113 struct unit_module **modules, *mod;
114
115 core_vbs(fw, 1, "Loading modules from %s\n", load_path);
116
117 /*
118 * Open and count the number of files in the dir.
119 */
120 load_dir = opendir(load_path);
121 if (!load_dir) {
122 core_err(fw, "%s: Unable to open dir (%s)\n",
123 load_path, strerror(errno));
124 return NULL;
125 }
126
127 while (readdir(load_dir) != NULL)
128 nr_modules += 1;
129
130 /* '.' and '..' should be skipped. */
131 nr_modules -= 2;
132
133 /*
134 * Now allocate necessary space for storing pointers to the modules and
135 * load the modules. +1 for the last NULL entry.
136 */
137 modules = malloc(sizeof(*modules) * (nr_modules + 1));
138 if (!modules) {
139 core_err(fw, "Out of mem! (huh?)\n");
140 goto err;
141 }
142
143 rewinddir(load_dir);
144 i = 0;
145 while ((ent = readdir(load_dir)) != NULL) {
146 if (strcmp(".", ent->d_name) == 0 ||
147 strcmp("..", ent->d_name) == 0)
148 continue;
149
150 mod = load_one_module(fw, ent);
151 if (mod == NULL)
152 continue;
153
154 if (check_module(fw, mod) != 0)
155 continue;
156
157 modules[i] = mod;
158 i++;
159 }
160
161 modules[i] = NULL;
162 return modules;
163
164err:
165 closedir(load_dir);
166 return NULL;
167}
diff --git a/userspace/src/nvgpu.c b/userspace/src/nvgpu.c
new file mode 100644
index 00000000..a9b7ced3
--- /dev/null
+++ b/userspace/src/nvgpu.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <dlfcn.h>
24#include <stdlib.h>
25
26#include <unit/io.h>
27#include <unit/core.h>
28
29/*
30 * Load libnvgpu-drv.so. This is done with dlopen() since this will make
31 * resolving addresses into symbols easier in the future.
32 *
33 * Also, this makes people think carefully about what functions to call in
34 * nvgpu-drv from the unit test FW. The interaction should really be limited
35 * and doing explicit name lookups is a good way to prevent too much coupling.
36 */
37int core_load_nvgpu(struct unit_fw *fw)
38{
39 const char *msg;
40
41 /*
42 * Specify a GLOBAL binding so that subsequently loaded unit tests see
43 * the nvgpu-drv library. They will of course need it (and will access
44 * it directly). I.e they will link against nvgpu-drv and this should
45 * satisfy that linkage.
46 */
47 fw->nvgpu_so = dlopen("libnvgpu-drv.so", RTLD_NOW | RTLD_GLOBAL);
48
49 if (fw->nvgpu_so == NULL) {
50 msg = dlerror();
51 core_err(fw, "Failed to load nvgpu-drv: %s\n", msg);
52 return -1;
53 }
54
55 /*
56 * We directly check the value of the returned symbol for these
57 * functions against NULL because if it is NULL then something is
58 * terribly wrong.
59 */
60
61 fw->nvgpu.nvgpu_posix_probe = dlsym(fw->nvgpu_so,
62 "nvgpu_posix_probe");
63 if (fw->nvgpu.nvgpu_posix_probe == NULL) {
64 msg = dlerror();
65 core_err(fw, "Failed to resolve nvgpu_posix_probe: %s\n", msg);
66 return -1;
67 }
68
69 fw->nvgpu.nvgpu_posix_cleanup = dlsym(fw->nvgpu_so,
70 "nvgpu_posix_cleanup");
71 if (fw->nvgpu.nvgpu_posix_cleanup == NULL) {
72 msg = dlerror();
73 core_err(fw, "Failed to resolve nvgpu_posix_cleanup: %s\n", msg);
74 return -1;
75 }
76
77 return 0;
78}
diff --git a/userspace/src/results.c b/userspace/src/results.c
new file mode 100644
index 00000000..ae077b82
--- /dev/null
+++ b/userspace/src/results.c
@@ -0,0 +1,128 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdlib.h>
24#include <string.h>
25
26#include <unit/io.h>
27#include <unit/core.h>
28#include <unit/unit.h>
29#include <unit/results.h>
30
31static int __init_results(struct unit_fw *fw)
32{
33 struct unit_results *results;
34
35 if (fw->results != NULL)
36 return 0;
37
38 results = malloc(sizeof(*results));
39 if (results == NULL)
40 return -1;
41
42 memset(results, 0, sizeof(*results));
43
44 fw->results = results;
45
46 return 0;
47}
48
49static void add_record(struct unit_test_list *list,
50 struct unit_test_record *tr)
51{
52 /*
53 * First entry.
54 */
55 if (list->head == NULL) {
56 list->head = tr;
57 list->last = tr;
58 return;
59 }
60
61 /*
62 * Add to the end of the list and update the pointer to the last entry
63 * in the list. This gives us O(1) add time.
64 */
65 list->last->next = tr;
66 list->last = tr;
67}
68
69int core_add_test_record(struct unit_fw *fw,
70 struct unit_module *mod,
71 struct unit_module_test *test,
72 bool success)
73{
74 struct unit_test_record *tr;
75
76 /*
77 * Dones nothing if results are already inited.
78 */
79 if (__init_results(fw) != 0)
80 return -1;
81
82 tr = malloc(sizeof(*tr));
83 if (tr == NULL)
84 return -1;
85
86 tr->mod = mod;
87 tr->test = test;
88 tr->status = success;
89 tr->next = NULL;
90
91 if (success)
92 add_record(&fw->results->passing, tr);
93 else
94 add_record(&fw->results->failing, tr);
95
96 fw->results->nr_tests += 1;
97 if (success)
98 fw->results->nr_passing += 1;
99
100 return 0;
101}
102
103void core_print_test_status(struct unit_fw *fw)
104{
105 struct unit_test_list *failing_tests = &fw->results->failing;
106 struct unit_test_record *rec;
107
108 /*
109 * Print stats for the tests.
110 */
111 core_msg(fw, "\n");
112 core_msg(fw, "Test results:\n");
113 core_msg(fw, "-------------\n");
114 core_msg(fw, "\n");
115 core_msg(fw, " Passing: %d\n", fw->results->nr_passing);
116 core_msg(fw, " Failing: %d\n",
117 fw->results->nr_tests - fw->results->nr_passing);
118 core_msg(fw, " Total: %d\n", fw->results->nr_tests);
119 core_msg(fw, "\n");
120 core_msg(fw, "Failing tests:\n");
121 core_msg(fw, "\n");
122
123 for_record_in_test_list(failing_tests, rec) {
124 core_msg(fw, " %s.%s\n",
125 rec->mod->name,
126 rec->test->name);
127 }
128}
diff --git a/userspace/src/unit_main.c b/userspace/src/unit_main.c
new file mode 100644
index 00000000..31c31d50
--- /dev/null
+++ b/userspace/src/unit_main.c
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23/**
24 * NvGpu unit testing framework!
25 */
26
27#include <stdlib.h>
28#include <string.h>
29
30#include <unit/io.h>
31#include <unit/core.h>
32#include <unit/args.h>
33#include <unit/module.h>
34#include <unit/results.h>
35
36int main(int argc, char **argv)
37{
38 struct unit_fw *fw;
39 int ret;
40
41 fw = malloc(sizeof(*fw));
42 if (!fw)
43 return 1;
44
45 memset(fw, 0, sizeof(*fw));
46
47 ret = core_parse_args(fw, argc, argv);
48 if (ret) {
49 core_err(fw, "Enable to parse args.\n");
50 core_err(fw, "Exiting!\n");
51 return 1;
52 }
53
54 core_vbs(fw, 1, "Welcome to the nvgpu unit testing framework!\n");
55
56 if (args(fw)->help) {
57 core_print_help(fw);
58 return 1;
59 }
60
61 ret = core_load_nvgpu(fw);
62 if (ret != 0)
63 return ret;
64
65 fw->modules = core_load_modules(fw);
66 if (fw->modules == NULL)
67 return -1;
68
69 ret = core_exec(fw);
70 if (ret != 0)
71 return ret;
72
73 core_print_test_status(fw);
74
75 return 0;
76}
diff --git a/userspace/unit.sh b/userspace/unit.sh
new file mode 100755
index 00000000..078512f8
--- /dev/null
+++ b/userspace/unit.sh
@@ -0,0 +1,16 @@
1#!/bin/bash
2
3#
4# Execute the unit test. Args to this script are passed on to the unit test
5# core. This just serves to set the LD_LIBRARY_PATH environment variable such
6# that unit tests are found and nvgpu-drv is found.
7#
8
9LD_LIBRARY_PATH="build:build/units"
10NVGPU_UNIT=build/nvgpu_unit
11
12export LD_LIBRARY_PATH
13
14echo "$ $NVGPU_UNIT $*"
15
16$NVGPU_UNIT $*
diff --git a/userspace/units/Makefile.units b/userspace/units/Makefile.units
new file mode 100644
index 00000000..64b9e07d
--- /dev/null
+++ b/userspace/units/Makefile.units
@@ -0,0 +1,45 @@
1# -*- mode: makefile -*-
2#
3# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and associated documentation files (the "Software"),
7# to deal in the Software without restriction, including without limitation
8# the rights to use, copy, modify, merge, publish, distribute, sublicense,
9# and/or sell copies of the Software, and to permit persons to whom the
10# Software is furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in
13# all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21# DEALINGS IN THE SOFTWARE.
22
23#
24# Inlcude this in unit test makefiles to get useful rules.
25#
26
27LOCAL_HEADERS = (shell ls *.h)
28
29.PHONY: all clean
30all: lib$(MODULE).so
31 @true
32
33#
34# Inherits from the top level makefile. As such the unit test make files cannot
35# be invoked by themselves.
36%.o : %.c # $(LOCAL_HEADERS)
37 $(CC) $(CFLAGS) -c -o $@ $<
38
39lib$(MODULE).so: $(OBJS)
40 $(CC) -shared -o $@ $(OBJS)
41 @mkdir -p $(UNIT_OUT)/
42 @cp $@ $(UNIT_OUT)/
43
44clean:
45 rm -rf *.o *.so