From f0f6c77c01bdbf2c3a9f786908e913639f4c9c95 Mon Sep 17 00:00:00 2001 From: vinodg Date: Mon, 9 Dec 2019 11:08:56 -0800 Subject: [PATCH] gpu: nvgpu: Add tests for code coverage in gr.falcon Add more tests for branch and line coverages in gr.falcon common and hal code. Jira NVGPU-4453 Change-Id: Ie01bac73ad18773bba1c27bf4bcb2b2776970f29 Signed-off-by: vinodg Reviewed-on: https://git-master.nvidia.com/r/2258557 Reviewed-by: Deepak Nibade GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 2 + userspace/required_tests.json | 12 + userspace/units/gr/falcon/Makefile | 4 +- userspace/units/gr/falcon/Makefile.tmk | 3 +- .../units/gr/falcon/nvgpu-gr-falcon-gk20a.c | 268 ++++++++++++++++++ .../units/gr/falcon/nvgpu-gr-falcon-gk20a.h | 70 +++++ userspace/units/gr/falcon/nvgpu-gr-falcon.c | 68 ++++- userspace/units/gr/intr/nvgpu-gr-intr.c | 6 +- 8 files changed, 426 insertions(+), 7 deletions(-) create mode 100644 userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.c create mode 100644 userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.h diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 72dcab053..1aefcd1ef 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -70,6 +70,7 @@ gm20b_priv_set_timeout_settings gm20b_priv_ring_enum_ltc gm20b_priv_ring_get_gpc_count gm20b_priv_ring_get_fbp_count +gm20b_gr_falcon_submit_fecs_method_op gp10b_ce_nonstall_isr gp10b_get_max_page_table_levels gp10b_mm_get_default_big_page_size @@ -396,6 +397,7 @@ nvgpu_init_enabled_flags nvgpu_init_hal nvgpu_init_mm_support nvgpu_inst_block_addr +nvgpu_free_inst_block nvgpu_inst_block_ptr nvgpu_is_enabled nvgpu_big_alloc_impl diff --git a/userspace/required_tests.json b/userspace/required_tests.json index 16bf25da2..4a7e9e14e 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -1847,6 +1847,18 @@ "unit": "nvgpu_gr_falcon", "test_level": 0 }, + { + "test": "test_gr_falcon_fail_ctxsw_ucode", + "case": "gr_falcon_fail_ctxsw_ucode", + "unit": "nvgpu_gr_falcon", + "test_level": 0 + }, + { + "test": "test_gr_falcon_gk20a_ctrl_ctxsw", + "case": "gr_falcon_gk20a_ctrl_ctxsw", + "unit": "nvgpu_gr_falcon", + "test_level": 0 + }, { "test": "test_gr_falcon_deinit", "case": "gr_falcon_deinit", diff --git a/userspace/units/gr/falcon/Makefile b/userspace/units/gr/falcon/Makefile index 834ec7617..e173dfc1a 100644 --- a/userspace/units/gr/falcon/Makefile +++ b/userspace/units/gr/falcon/Makefile @@ -20,7 +20,9 @@ .SUFFIXES: -OBJS = nvgpu-gr-falcon.o +OBJS = nvgpu-gr-falcon.o \ + nvgpu-gr-falcon-gk20a.o + MODULE = nvgpu-gr-falcon LIB_PATHS += -lnvgpu-gr diff --git a/userspace/units/gr/falcon/Makefile.tmk b/userspace/units/gr/falcon/Makefile.tmk index 3a701f37b..ca5ec99b3 100644 --- a/userspace/units/gr/falcon/Makefile.tmk +++ b/userspace/units/gr/falcon/Makefile.tmk @@ -25,7 +25,8 @@ ############################################################################### NVGPU_UNIT_NAME = nvgpu-gr-falcon -NVGPU_UNIT_SRCS = nvgpu-gr-falcon.c +NVGPU_UNIT_SRCS = nvgpu-gr-falcon.c \ + nvgpu-gr-falcon-gk20a.c NVGPU_UNIT_INTERFACE_DIRS := \ $(NV_COMPONENT_DIR)/.. \ diff --git a/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.c b/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.c new file mode 100644 index 000000000..dbed1624c --- /dev/null +++ b/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.c @@ -0,0 +1,268 @@ +/* + * 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "common/gr/gr_priv.h" +#include "common/gr/gr_falcon_priv.h" + +#include "hal/gr/falcon/gr_falcon_gm20b.h" + +#include "../nvgpu-gr.h" +#include "nvgpu-gr-falcon-gk20a.h" + +struct gr_falcon_gk20a_fecs_op { + u32 id; + u32 data; + u32 ok; + u32 fail; + u32 cond_ok; + u32 cond_fail; + u32 result; +}; + +static void gr_falcon_fecs_dump_stats(struct gk20a *g) +{ + /* Do Nothing */ +} + +static int gr_falcon_gk20a_submit_fecs_mthd_op(struct unit_module *m, + struct gk20a *g) +{ + int err, i; + struct nvgpu_fecs_method_op op = { + .mailbox = { .id = 4U, .data = 0U, .ret = NULL, + .clr = ~U32(0U), .ok = 0U, .fail = 0U}, + .method.data = 0U, + .cond.ok = GR_IS_UCODE_OP_SKIP, + .cond.fail = GR_IS_UCODE_OP_SKIP, + }; + + struct gr_falcon_gk20a_fecs_op fecs_op_stat[] = { + [0] = { + .id = 4U, + .data = 0U, + .ok = 0U, + .fail = 0U, + .cond_ok = GR_IS_UCODE_OP_SKIP, + .cond_fail = GR_IS_UCODE_OP_SKIP, + .result = 0U, + }, + [1] = { + .id = 2U, + .data = 1U, + .ok = 0U, + .fail = 2U, + .cond_ok = GR_IS_UCODE_OP_SKIP, + .cond_fail = GR_IS_UCODE_OP_LESSER_EQUAL, + .result = 1U, + }, + [2] = { + .id = 2U, + .data = 1U, + .ok = 2U, + .fail = 0U, + .cond_ok = GR_IS_UCODE_OP_LESSER_EQUAL, + .cond_fail = 10, + .result = 1U, + }, + [3] = { + .id = 2U, + .data = 1U, + .ok = 2U, + .fail = 1U, + .cond_ok = GR_IS_UCODE_OP_LESSER, + .cond_fail = GR_IS_UCODE_OP_EQUAL, + .result = 1U, + }, + [4] = { + .id = 2U, + .data = 1U, + .ok = 0U, + .fail = 1U, + .cond_ok = GR_IS_UCODE_OP_LESSER_EQUAL, + .cond_fail = GR_IS_UCODE_OP_AND, + .result = 1U, + }, + [5] = { + .id = 2U, + .data = 1U, + .ok = 0U, + .fail = 2U, + .cond_ok = GR_IS_UCODE_OP_LESSER, + .cond_fail = GR_IS_UCODE_OP_LESSER, + .result = 1U, + }, + [6] = { + .id = 2U, + .data = 1U, + .ok = 1U, + .fail = 2U, + .cond_ok = GR_IS_UCODE_OP_NOT_EQUAL, + .cond_fail = GR_IS_UCODE_OP_NOT_EQUAL, + .result = 1U, + }, + [7] = { + .id = 2U, + .data = 1U, + .ok = 1U, + .fail = 2U, + .cond_ok = GR_IS_UCODE_OP_EQUAL, + .cond_fail = GR_IS_UCODE_OP_EQUAL, + .result = 0U, + }, + }; + int arry_cnt = sizeof(fecs_op_stat)/ + sizeof(struct gr_falcon_gk20a_fecs_op); + + g->ops.gr.falcon.dump_stats = gr_falcon_fecs_dump_stats; + for (i = 0; i < arry_cnt; i++) { + op.mailbox.ok = fecs_op_stat[i].ok; + op.mailbox.fail = fecs_op_stat[i].fail; + op.mailbox.id = fecs_op_stat[i].id; + op.mailbox.data = fecs_op_stat[i].data; + op.cond.ok = fecs_op_stat[i].cond_ok; + op.cond.fail = fecs_op_stat[i].cond_fail; + + err = gm20b_gr_falcon_submit_fecs_method_op(g, op, false); + if ((fecs_op_stat[i].result == 0) && err) { + unit_return_fail(m, "submit_fecs_method_op failed\n"); + } else if (fecs_op_stat[i].result && (err == 0)){ + unit_return_fail(m, "submit_fecs_method_op failed\n"); + } + } + + return UNIT_SUCCESS; +} + +static int gr_falcon_timer_init_error(struct unit_module *m, + struct gk20a *g) +{ + int err, i; + u32 fecs_imem = 0, gpccs_imem = 0; + struct nvgpu_gr_falcon_query_sizes sizes; + struct nvgpu_posix_fault_inj *timer_fi = + nvgpu_timers_get_fault_injection(); + + nvgpu_posix_enable_fault_injection(timer_fi, true, 0); + err = g->ops.gr.falcon.wait_mem_scrubbing(g); + nvgpu_posix_enable_fault_injection(timer_fi, false, 0); + if (err == 0) { + unit_return_fail(m, + "gr_falcon_wait_mem_scrubbing timer failed\n"); + } + + for (i = 0; i < 2; i++) { + switch (i) { + case 0: + fecs_imem = gr_fecs_dmactl_imem_scrubbing_m(); + break; + case 1: + fecs_imem = 0; + gpccs_imem = gr_gpccs_dmactl_imem_scrubbing_m(); + break; + } + nvgpu_posix_io_writel_reg_space(g, gr_fecs_dmactl_r(), + fecs_imem); + nvgpu_posix_io_writel_reg_space(g, gr_gpccs_dmactl_r(), + gpccs_imem); + err = g->ops.gr.falcon.wait_mem_scrubbing(g); + if (err == 0) { + unit_return_fail(m, + "gr_falcon_wait_mem_scrubbing case %d failed\n", i); + } + } + + nvgpu_posix_enable_fault_injection(timer_fi, true, 0); + err = g->ops.gr.falcon.wait_ctxsw_ready(g); + nvgpu_posix_enable_fault_injection(timer_fi, false, 0); + if (err == 0) { + unit_return_fail(m, + "gr_falcon_wait_ctxsw_ready timer failed\n"); + } + + nvgpu_posix_enable_fault_injection(timer_fi, true, 0); + err = g->ops.gr.falcon.init_ctx_state(g, &sizes); + nvgpu_posix_enable_fault_injection(timer_fi, false, 0); + if (err == 0) { + unit_return_fail(m, + "gr_falcon_init_ctx_state failed\n"); + } + + /* branch coverage check */ + nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, false); + nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false); + err = g->ops.gr.falcon.wait_ctxsw_ready(g); + if (err != 0) { + unit_return_fail(m, + "gr_falcon_wait_ctxsw_ready failed\n"); + } + nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); + + return UNIT_SUCCESS; +} + +int test_gr_falcon_gk20a_ctrl_ctxsw(struct unit_module *m, + struct gk20a *g, void *args) +{ + int err = 0; + u32 data = 0; + + err = g->ops.gr.falcon.ctrl_ctxsw(g, + NVGPU_GR_FALCON_METHOD_GOLDEN_IMAGE_SAVE, data, NULL); + if (err) { + unit_return_fail(m, "falcon_gk20a_ctrl_ctxsw failed\n"); + } + + /* Invalid Method */ + err = g->ops.gr.falcon.ctrl_ctxsw(g, 0, data, NULL); + if (err) { + unit_return_fail(m, "falcon_gk20a_ctrl_ctxsw failed\n"); + } + + err = gr_falcon_timer_init_error(m, g); + if (err) { + unit_return_fail(m, "gr_falcon_timer_init_error failed\n"); + } + + err = gr_falcon_gk20a_submit_fecs_mthd_op(m, g); + if (err) { + unit_return_fail(m, "gr_falcon_gk20a_fecs_mthd_op failed\n"); + } + + return UNIT_SUCCESS; +} diff --git a/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.h b/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.h new file mode 100644 index 000000000..d92e2f5c6 --- /dev/null +++ b/userspace/units/gr/falcon/nvgpu-gr-falcon-gk20a.h @@ -0,0 +1,70 @@ +/* + * 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_GR_FALCON_GK20A_H +#define UNIT_NVGPU_GR_FALCON_GK20A_H + +#include + +struct unit_module; +struct gk20a; + +/** @addtogroup SWUTS-gr-falcon + * @{ + * + * Software Unit Test Specification for common.gr.falcon + */ + +/** + * Test specification for: test_gr_falcon_gk20a_ctrl_ctxsw + * + * Description: Helps to verify various failure and conditional checking + * in falcon gm20b hal functions. + * + * Test Type: Error injection + * + * Input: #test_fifo_init_support() run for this GPU + * + * Targets: gm20b_gr_falcon_wait_mem_scrubbing, + * gm20b_gr_falcon_wait_ctxsw_ready, + * gm20b_gr_falcon_init_ctx_state, + * gm20b_gr_falcon_submit_fecs_method_op, + * gm20b_gr_falcon_ctrl_ctxsw. + * + * Steps: + * - Call g->ops.gr.falcon.ctrl_ctxsw with Invalid Method. + * - Enable timer init failure injection in various functions. + * - g->ops.gr.falcon.wait_ctxsw_ready. + * - g->ops.gr.falcon.init_ctx_state. + * - g->ops.gr.falcon.wait_mem_scrubbing. + * - Call gm20b_gr_falcon_submit_fecs_method_op with various + * method op codes. + * - Check that enable_set bit is set for ccsr_channel_r + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gr_falcon_gk20a_ctrl_ctxsw(struct unit_module *m, + struct gk20a *g, void *args); +/** + * @} + */ + +#endif /* UNIT_NVGPU_GR_FALCON_GK20A_H */ diff --git a/userspace/units/gr/falcon/nvgpu-gr-falcon.c b/userspace/units/gr/falcon/nvgpu-gr-falcon.c index 8fd1846da..cc1082433 100644 --- a/userspace/units/gr/falcon/nvgpu-gr-falcon.c +++ b/userspace/units/gr/falcon/nvgpu-gr-falcon.c @@ -35,12 +35,16 @@ #include #include +#include + #include "common/gr/gr_priv.h" #include "common/gr/gr_falcon_priv.h" #include "common/acr/acr_priv.h" + #include "hal/gr/falcon/gr_falcon_gm20b.h" #include "../nvgpu-gr.h" +#include "nvgpu-gr-falcon-gk20a.h" #include "nvgpu-gr-falcon.h" struct gr_gops_falcon_orgs { @@ -92,6 +96,8 @@ int test_gr_falcon_init(struct unit_module *m, struct gk20a *g, void *args) { int err = 0; + u32 fecs_base, ctx_state_rev_id; + u32 gpccs_base, gpccs_start_offset; struct nvgpu_posix_fault_inj *kmem_fi = nvgpu_kmem_get_fault_injection(); @@ -118,17 +124,66 @@ int test_gr_falcon_init(struct unit_module *m, unit_return_fail(m, "nvgpu_gr_falcon_init_support failed\n"); } + fecs_base = g->ops.gr.falcon.fecs_base_addr(); + if (fecs_base == 0) { + unit_return_fail(m, "Get fecs_base failed\n"); + } + + gpccs_base = g->ops.gr.falcon.gpccs_base_addr(); + if (gpccs_base == 0) { + unit_return_fail(m, "Get gpccs_base failed\n"); + } + + gpccs_start_offset = g->ops.gr.falcon.get_gpccs_start_reg_offset(); + if (gpccs_start_offset == 0) { + unit_return_fail(m, "Get gpccs_base start failed\n"); + } + + ctx_state_rev_id = + g->ops.gr.falcon.get_fecs_ctx_state_store_major_rev_id(g); + if (ctx_state_rev_id != 0) { + unit_return_fail(m, "ctx_state rev_id failed\n"); + } + return UNIT_SUCCESS; } +static int gr_falcon_bind_instblk(struct unit_module *m, struct gk20a *g) +{ + int err; + struct nvgpu_ctxsw_ucode_info *ucode_info = + &unit_gr_falcon->ctxsw_ucode_info; + + err = nvgpu_alloc_inst_block(g, &ucode_info->inst_blk_desc); + if (err != 0) + return UNIT_FAIL; + + g->ops.gr.falcon.bind_instblk = gr_falcon_gops.bind_instblk; + err = nvgpu_gr_falcon_init_ctxsw(g, unit_gr_falcon); + if (err != 0) { + unit_return_fail(m, + "falcon_init_ctxsw secure recovery failed\n"); + } + + /* Set ctxsw_status_busy for branch coverage */ + nvgpu_posix_io_writel_reg_space(g, gr_fecs_ctxsw_status_1_r(), + (0x1U << 12U)); + err = nvgpu_gr_falcon_init_ctxsw(g, unit_gr_falcon); + if (err != 0) { + unit_return_fail(m, + "falcon_init_ctxsw secure recovery failed\n"); + } + + nvgpu_free_inst_block(g, &ucode_info->inst_blk_desc); + return err; +} + int test_gr_falcon_init_ctxsw(struct unit_module *m, struct gk20a *g, void *args) { int err = 0; struct nvgpu_acr gr_falcon_acr_test; - unit_gr_falcon->ctxsw_ucode_info.gpccs.boot_signature = - FALCON_UCODE_SIG_T18X_GPCCS_WITH_RESERVED; /* Test secure gpccs */ err = nvgpu_gr_falcon_init_ctxsw(g, unit_gr_falcon); if (err) { @@ -153,6 +208,13 @@ int test_gr_falcon_init_ctxsw(struct unit_module *m, "falcon_init_ctxsw secure recovery failed\n"); } + /* Test for falcon bind instblk */ + err = gr_falcon_bind_instblk(m, g); + if (err != 0) { + unit_return_fail(m, + "falcon_bind_instblk failed\n"); + } + return UNIT_SUCCESS; } @@ -276,6 +338,8 @@ struct unit_module_test nvgpu_gr_falcon_tests[] = { test_gr_falcon_init_ctx_state, NULL, 0), UNIT_TEST(gr_falcon_fail_ctxsw_ucode, test_gr_falcon_fail_ctxsw_ucode, NULL, 0), + UNIT_TEST(gr_falcon_gk20a_ctrl_ctxsw, + test_gr_falcon_gk20a_ctrl_ctxsw, NULL, 0), UNIT_TEST(gr_falcon_deinit, test_gr_falcon_deinit, NULL, 0), }; diff --git a/userspace/units/gr/intr/nvgpu-gr-intr.c b/userspace/units/gr/intr/nvgpu-gr-intr.c index 5c0f0a4fb..213d5a67a 100644 --- a/userspace/units/gr/intr/nvgpu-gr-intr.c +++ b/userspace/units/gr/intr/nvgpu-gr-intr.c @@ -652,11 +652,11 @@ int test_gr_intr_fecs_exceptions(struct unit_module *m, struct gk20a *g, void *args) { int err, i, j = 0; - int arry_cnt = 10; + int arry_cnt = 11; - u32 fecs_status[10] = { + u32 fecs_status[11] = { 0, - gr_fecs_host_int_enable_ctxsw_intr0_enable_f() | + gr_fecs_host_int_enable_ctxsw_intr0_enable_f(), gr_fecs_host_int_enable_ctxsw_intr1_enable_f(), gr_fecs_host_int_enable_fault_during_ctxsw_enable_f(), gr_fecs_host_int_enable_umimp_firmware_method_enable_f(),