diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index abfab2251..2522c9a16 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -110,6 +110,7 @@ gv11b_blcg_hshub_gating_prod_size gv11b_blcg_hshub_get_gating_prod gv11b_netlist_is_firmware_defined gv11b_top_get_num_lce +nvgpu_acr_bootstrap_hs_acr nvgpu_acr_construct_execute nvgpu_acr_init nvgpu_acr_is_lsf_lazy_bootstrap diff --git a/userspace/required_tests.json b/userspace/required_tests.json index dfee8f0cb..968428c98 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -1838,7 +1838,11 @@ "test_level": 0, "unit": "nvgpu-acr" }, - + { + "test": "acr_bootstrap_hs_acr", + "test_level": 0, + "unit": "nvgpu-acr" + }, { "test": "acr_free_falcon_test_env", "test_level": 0, diff --git a/userspace/units/acr/nvgpu-acr.c b/userspace/units/acr/nvgpu-acr.c index 802a12675..09c59934f 100644 --- a/userspace/units/acr/nvgpu-acr.c +++ b/userspace/units/acr/nvgpu-acr.c @@ -164,7 +164,6 @@ static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) /* * Register space: FB_MMU - * */ if (nvgpu_posix_io_add_reg_space(g, fb_niso_intr_r(), 0x800) != 0) { unit_return_fail(m, "nvgpu_posix_io_add_reg_space failed\n"); @@ -172,7 +171,6 @@ static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) /* * Register space: HW_FLUSH - * */ if (nvgpu_posix_io_add_reg_space(g, flush_fb_flush_r(), 0x20) != 0) { unit_return_fail(m, "nvgpu_posix_io_add_reg_space failed\n"); @@ -186,7 +184,6 @@ static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) /* * Initialize utf & nvgpu falcon * for test usage - * */ pmu_flcn = nvgpu_utf_falcon_init(m, g, FALCON_ID_PMU); if (pmu_flcn == NULL) { @@ -200,172 +197,228 @@ static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) return 0; } +static int init_test_env(struct unit_module *m, struct gk20a *g) +{ + int err; + + err = test_gr_setup_gv11b_reg_space(m, g); + if (err != 0) { + goto fail; + } + + /* + * initialize falcon and set the required flags + */ + if (init_acr_falcon_test_env(m, g) != 0) { + unit_return_fail(m, "Module init failed\n"); + } + + nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); + + err = nvgpu_gr_alloc(g); + if (err != 0) { + unit_err(m, " Gr allocation failed!\n"); + return -ENOMEM; + } + + /* + * initialize PMU + */ + err = g->ops.pmu.pmu_early_init(g); + if (err != 0) { + unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); + } + + /* + * initialize ACR + */ + err = g->ops.acr.acr_init(g); + if (err != 0) { + unit_return_fail(m, "nvgpu_acr_init failed\n"); + } + + /* + * Initialize the MM unit required in ucode blob + * preparation + */ + + err = g->ops.mm.init_mm_support(g); + if (err != 0) { + unit_return_fail(m, "failed to init gk20a mm"); + } + + return 0; +fail: + return UNIT_FAIL; + +} + +static int prepare_gr_hw_sw(struct unit_module *m, struct gk20a *g) +{ + int err; + + /* + * prepare portion of sw required + * for enable hw + */ + err = nvgpu_gr_prepare_sw(g); + if (err != 0) { + nvgpu_mutex_release(&g->tpc_pg_lock); + unit_return_fail(m, "failed to prepare sw"); + } + + err = nvgpu_gr_enable_hw(g); + if (err != 0) { + nvgpu_mutex_release(&g->tpc_pg_lock); + unit_return_fail(m, "failed to enable gr"); + } + + return 0; +} +int test_acr_bootstrap_hs_acr(struct unit_module *m, + struct gk20a *g, void *args) + +{ + int err; + struct nvgpu_reg_access access; + + /* + * Initialise the test env + * and register space needed for the test + */ + if (init_test_env(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); + } + + nvgpu_mutex_acquire(&g->tpc_pg_lock); + + /* + * Prepare HW and SW setup needed + * for the test + */ + if (prepare_gr_hw_sw(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); + } + + /* + * Set the falcon_falcon_cpuctl_halt_intr_m bit + * for the register falcon_falcon_cpuctl_r + */ + access.addr = pmu_flcn->flcn->flcn_base + falcon_falcon_cpuctl_r(); + access.value = falcon_falcon_cpuctl_halt_intr_m(); + nvgpu_utf_falcon_writel_access_reg_fn(g, pmu_flcn, &access); + + /* + * Prepare the ucode blob + * + */ + err = g->acr->prepare_ucode_blob(g); + if (err != 0) { + unit_return_fail(m, "test failed\n"); + } + + /* + * case 1: Calling nvgpu_acr_bootstrap_hs_acr() + * twice to coverrecovery branch + */ + err = nvgpu_acr_bootstrap_hs_acr(g, g->acr); + err = nvgpu_acr_bootstrap_hs_acr(g, g->acr); + if (err != 0) { + unit_return_fail(m, "test_acr_bootstrap_hs_acr() failed"); + } + + /* + * case 2: Fail scenario of nvgpu_acr_bootstrap_hs_acr() + * by passing g->acr = NULL + */ + g->acr = NULL; + err = nvgpu_acr_bootstrap_hs_acr(g, g->acr); + + if (err != -EINVAL) { + unit_return_fail(m, "test_acr_bootstrap_hs_acr() didn't fail \ + as expected\n"); + } + + nvgpu_mutex_release(&g->tpc_pg_lock); + + return UNIT_SUCCESS; +} + int test_acr_construct_execute(struct unit_module *m, struct gk20a *g, void *args) { int err; struct nvgpu_reg_access access; - err = test_gr_setup_gv11b_reg_space(m, g); - if (err != 0) { - goto fail; - } - /* - * initialize falcon - * + * Initialise the test env + * and register space needed for the test */ - if (init_acr_falcon_test_env(m, g) != 0) { - unit_return_fail(m, "Module init failed\n"); - } - - nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); - - nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true); - err = nvgpu_gr_alloc(g); - if (err != 0) { - unit_err(m, " Gr allocation failed!\n"); - return -ENOMEM; - } - - /* - * initialize PMU - * - */ - err = g->ops.pmu.pmu_early_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); - } - - /* - * initialize ACR - * - */ - err = g->ops.acr.acr_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_acr_init failed\n"); - } - - /* - * Initialize the MM unit required in ucode blob - * preparation - */ - - err = g->ops.mm.init_mm_support(g); - if (err != 0) { - unit_return_fail(m, "failed to init gk20a mm"); + if (init_test_env(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } nvgpu_mutex_acquire(&g->tpc_pg_lock); /* - * prepare portion of sw required - * for enable hw - * + * Prepare HW and SW setup needed for the test */ - err = nvgpu_gr_prepare_sw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to prepare sw"); - } - err = nvgpu_gr_enable_hw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to enable gr"); + if (prepare_gr_hw_sw(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } /* * Set the falcon_falcon_cpuctl_halt_intr_m bit * for the register falcon_falcon_cpuctl_r - * */ access.addr = pmu_flcn->flcn->flcn_base + falcon_falcon_cpuctl_r(); access.value = falcon_falcon_cpuctl_halt_intr_m(); nvgpu_utf_falcon_writel_access_reg_fn(g, pmu_flcn, &access); - /* case 1: pass scenario */ + /* + * case 1: pass scenario + */ err = g->ops.acr.acr_construct_execute(g); if (err != 0) { unit_return_fail(m, "Bootstrap HS ACR failed"); } + /* + * case 2: pass g->acr as NULL to create fail scenario + */ + g->acr = NULL; + err = g->ops.acr.acr_construct_execute(g); + if (err != -EINVAL) { + unit_return_fail(m, "Bootstrap HS ACR didn't failed as \ + expected\n"); + } + nvgpu_mutex_release(&g->tpc_pg_lock); + return UNIT_SUCCESS; - -fail: - return UNIT_FAIL; - } int test_acr_is_lsf_lazy_bootstrap(struct unit_module *m, struct gk20a *g, void *args) { bool ret = false; - int err; - /* - * initialize falcon - * - */ - if (init_acr_falcon_test_env(m, g) != 0) { - unit_return_fail(m, "Module init failed\n"); - } - - err = test_gr_setup_gv11b_reg_space(m, g); - if (err != 0) { - goto fail; - } - - nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); - err = nvgpu_gr_alloc(g); - if (err != 0) { - unit_err(m, " Gr allocation failed!\n"); - return -ENOMEM; - } /* - * initialize PMU - * + * Initialise the test env and register space needed + * for the test */ - err = g->ops.pmu.pmu_early_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); + if (init_test_env(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } - /* - * initialize ACR - * - */ - err = g->ops.acr.acr_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_acr_init failed\n"); - } - - /* - * Initialize the MM unit required in ucode blob - * preparation - */ - err = g->ops.mm.init_mm_support(g); - if (err != 0) { - unit_return_fail(m, "failed to init gk20a mm"); - } nvgpu_mutex_acquire(&g->tpc_pg_lock); /* - * prepare portion of sw required - * for enable hw - * + * Prepare HW and SW setup needed for the test */ - err = nvgpu_gr_prepare_sw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to prepare sw"); - } - - err = nvgpu_gr_enable_hw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to enable gr"); + if (prepare_gr_hw_sw(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } /* @@ -378,8 +431,7 @@ int test_acr_is_lsf_lazy_bootstrap(struct unit_module *m, } /* - * case 2: pass invalid falcon id - * to fail the function + * case 2: pass invalid falcon id to fail the function */ ret = nvgpu_acr_is_lsf_lazy_bootstrap(g, g->acr, FALCON_ID_INVALID); @@ -403,10 +455,6 @@ int test_acr_is_lsf_lazy_bootstrap(struct unit_module *m, nvgpu_mutex_release(&g->tpc_pg_lock); return UNIT_SUCCESS; - -fail: - return UNIT_FAIL; - } int test_acr_prepare_ucode_blob(struct unit_module *m, @@ -415,74 +463,25 @@ int test_acr_prepare_ucode_blob(struct unit_module *m, int err; /* - * initialize falcon - * + * Initialise the test env and register space + * needed for the test */ - if (init_acr_falcon_test_env(m, g) != 0) { - unit_return_fail(m, "Module init failed\n"); + if (init_test_env(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } - err = test_gr_setup_gv11b_reg_space(m, g); - if (err != 0) { - goto fail; - } - - nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); - - err = nvgpu_gr_alloc(g); - if (err != 0) { - unit_err(m, " Gr allocation failed!\n"); - return -ENOMEM; - } - - /* - * initialize PMU - * - */ - err = g->ops.pmu.pmu_early_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); - } - - /* - * initialize ACR - * - */ - err = g->ops.acr.acr_init(g); - if (err != 0) { - unit_return_fail(m, "nvgpu_acr_init failed\n"); - } - - /* - * Initialize the MM unit required in ucode blob - * preparation - */ - err = g->ops.mm.init_mm_support(g); - if (err != 0) { - unit_return_fail(m, "failed to init gk20a mm"); - } nvgpu_mutex_acquire(&g->tpc_pg_lock); /* - * prepare portion of sw required - * for enable hw - * + * Prepare HW and SW setup needed for the test */ - err = nvgpu_gr_prepare_sw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to prepare sw"); + if (prepare_gr_hw_sw(m, g) != 0) { + unit_return_fail(m, "Test env init failed\n"); } - err = nvgpu_gr_enable_hw(g); - if (err != 0) { - nvgpu_mutex_release(&g->tpc_pg_lock); - unit_return_fail(m, "failed to enable gr"); - } - - /* case:pass scenario - * + /* + * case:pass scenario */ err = g->acr->prepare_ucode_blob(g); if (err != 0) { @@ -492,10 +491,6 @@ int test_acr_prepare_ucode_blob(struct unit_module *m, nvgpu_mutex_release(&g->tpc_pg_lock); return UNIT_SUCCESS; - -fail: - return UNIT_FAIL; - } int test_acr_init(struct unit_module *m, @@ -521,8 +516,7 @@ int test_acr_init(struct unit_module *m, } /* - * Case 1: nvgpu_acr_init() fails - * due to memory allocation failure + * Case 1: nvgpu_acr_init() fails due to memory allocation failure */ nvgpu_posix_enable_fault_injection(kmem_fi, true, 0); err = nvgpu_acr_init(g); @@ -576,8 +570,7 @@ int free_falcon_test_env(struct unit_module *m, struct gk20a *g, } /* - * Uninitialize the PMU after - * the test is done + * Uninitialize the PMU after the test is done */ nvgpu_pmu_remove_support(g, g->pmu); if (g->pmu != NULL) { @@ -599,7 +592,8 @@ struct unit_module_test nvgpu_acr_tests[] = { test_acr_is_lsf_lazy_bootstrap, NULL, 0), UNIT_TEST(acr_construct_execute, test_acr_construct_execute, NULL, 0), - + UNIT_TEST(acr_bootstrap_hs_acr, test_acr_bootstrap_hs_acr, + NULL, 0), UNIT_TEST(acr_free_falcon_test_env, free_falcon_test_env, NULL, 0), }; diff --git a/userspace/units/acr/nvgpu-acr.h b/userspace/units/acr/nvgpu-acr.h index 1a67268ca..bce6ed724 100644 --- a/userspace/units/acr/nvgpu-acr.h +++ b/userspace/units/acr/nvgpu-acr.h @@ -55,7 +55,7 @@ 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_init shall test the blob creation of + * Description: The test_acr_prepare_ucode_blob shall test the blob creation of * the ACR unit * * Test Type: Feature based @@ -80,8 +80,8 @@ int test_acr_prepare_ucode_blob(struct unit_module *m, struct gk20a *g, /** * Test specification for: test_acr_is_lsf_lazy_bootstrap * - * Description: The test_acr_init shall test the lazy bootstrap of - * the ACR unit + * Description: The test_acr_is_lsf_lazy_bootstrap shall test the + * lazy bootstrap of the ACR unit * * Test Type: Feature based * @@ -103,9 +103,68 @@ int test_acr_prepare_ucode_blob(struct unit_module *m, struct gk20a *g, 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 based + * + * Input: None + * + * Steps: + * - Initialize the falcon test environment + * - Set the flag NVGPU_SEC_SECUREGPCCS + * - Allocate memory for GR + * - Initialize the PMU + * - Initialize the ACR unit + * - Initialize the MMU + * - Prepare SW and HW for GR + * - Set the falcon_falcon_cpuctl_halt_intr_m bit for the + * register falcon_falcon_cpuctl_r + * - Call nvgpu_acr_construct_execute() via ACR sw ops. + * + * 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 based + * + * Input: None + * + * Steps: + * - Initialize the falcon test environment + * - Set the flag NVGPU_SEC_SECUREGPCCS + * - Allocate memory for GR + * - Initialize the PMU + * - Initialize the ACR unit + * - Initialize the MMU + * - Prepare SW and HW for GR + * - Set the falcon_falcon_cpuctl_halt_intr_m bit for the + * register falcon_falcon_cpuctl_r + * - Prepare the ucode blob + * - Call nvgpu_acr_bootstrap_hs_acr() twice to cover recovery branch. + * - Create fail/negative scenario of nvgpu_acr_bootstrap_hs_acr() + by passing g->acr = NULL. nvgpu_acr_bootstrap_hs_acr() should fail. + * + * 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); + /** * Test specification for: free_falcon_test_env *