From 6344cd3892402b9216f28a4613bdc8ec50bb7b0f Mon Sep 17 00:00:00 2001 From: Divya Singhatwaria Date: Fri, 5 Jul 2019 10:47:18 +0530 Subject: [PATCH] gpu: nvgpu: PMU unit test Add unit tests for the PMU unit for the following: nvgpu_pmu_early_init() nvgpu_pmu_remove_support() nvgpu_pmu_reset() JIRA NVGPU-2159 Change-Id: I6207a1f4f713401249e47086c2ea59cbd604d077 Signed-off-by: Divya Singhatwaria Reviewed-on: https://git-master.nvidia.com/r/2148471 Reviewed-by: Sagar Kamble Tested-by: Sagar Kamble GVS: Gerrit_Virtual_Submit Reviewed-by: Vaibhav Kachore Reviewed-by: mobile promotions Tested-by: mobile promotions --- Makefile.umbrella.tmk | 1 + drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 3 + userspace/Makefile.sources | 3 +- userspace/required_tests.json | 15 ++ userspace/units/pmu/Makefile | 33 +++ userspace/units/pmu/Makefile.interface.tmk | 35 +++ userspace/units/pmu/Makefile.tmk | 40 +++ userspace/units/pmu/nvgpu-pmu.c | 268 +++++++++++++++++++++ 8 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 userspace/units/pmu/Makefile create mode 100644 userspace/units/pmu/Makefile.interface.tmk create mode 100644 userspace/units/pmu/Makefile.tmk create mode 100644 userspace/units/pmu/nvgpu-pmu.c diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk index 843378cb8..45f8726e6 100644 --- a/Makefile.umbrella.tmk +++ b/Makefile.umbrella.tmk @@ -67,6 +67,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/list NV_REPOSITORY_COMPONENTS += userspace/units/enabled NV_REPOSITORY_COMPONENTS += userspace/units/falcon NV_REPOSITORY_COMPONENTS += userspace/units/falcon/falcon_tests +NV_REPOSITORY_COMPONENTS += userspace/units/pmu endif # Local Variables: diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 8c5bcd1bc..0535cb96a 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -155,6 +155,9 @@ nvgpu_pd_free nvgpu_pd_gpu_addr nvgpu_pd_offset_from_index nvgpu_pd_write +nvgpu_pmu_early_init +nvgpu_pmu_remove_support +nvgpu_pmu_reset nvgpu_posix_bug nvgpu_posix_cleanup nvgpu_posix_enable_fault_injection diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources index 052ac47bf..4b1842237 100644 --- a/userspace/Makefile.sources +++ b/userspace/Makefile.sources @@ -71,7 +71,8 @@ UNITS := \ $(UNIT_SRC)/list \ $(UNIT_SRC)/enabled \ $(UNIT_SRC)/falcon \ - $(UNIT_SRC)/falcon/falcon_tests + $(UNIT_SRC)/falcon/falcon_tests \ + $(UNIT_SRC)/pmu ifeq ($(CONFIG_NVGPU_HAL_NON_FUSA),1) UNITS += $(UNIT_SRC)/fuse diff --git a/userspace/required_tests.json b/userspace/required_tests.json index 53b9abe5b..3d63ca957 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -1312,5 +1312,20 @@ "test": "falcon_free_test_env", "test_level": 0, "unit": "falcon" + }, + { + "test": "pmu_early_init", + "test_level": 0, + "unit": "nvgpu-pmu" + }, + { + "test": "pmu_reset", + "test_level": 0, + "unit": "nvgpu-pmu" + }, + { + "test": "pmu_remove_support", + "test_level": 0, + "unit": "nvgpu-pmu" } ] diff --git a/userspace/units/pmu/Makefile b/userspace/units/pmu/Makefile new file mode 100644 index 000000000..ee06724ec --- /dev/null +++ b/userspace/units/pmu/Makefile @@ -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-pmu.o +MODULE = nvgpu-pmu + +LIB_PATHS += -lfalcon_utf + +include ../Makefile.units + +lib$(MODULE).so: falcon_utf + +falcon_utf: + $(MAKE) -C ../falcon diff --git a/userspace/units/pmu/Makefile.interface.tmk b/userspace/units/pmu/Makefile.interface.tmk new file mode 100644 index 000000000..71218f0b7 --- /dev/null +++ b/userspace/units/pmu/Makefile.interface.tmk @@ -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-pmu + +include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/pmu/Makefile.tmk b/userspace/units/pmu/Makefile.tmk new file mode 100644 index 000000000..a9192be47 --- /dev/null +++ b/userspace/units/pmu/Makefile.tmk @@ -0,0 +1,40 @@ +################################### 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-pmu +NVGPU_UNIT_SRCS=nvgpu-pmu.c + +NVGPU_UNIT_INTERFACE_DIRS := \ + $(NV_COMPONENT_DIR)/../falcon \ + $(NV_SOURCE)/kernel/nvgpu/drivers/gpu/nvgpu + +include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/pmu/nvgpu-pmu.c b/userspace/units/pmu/nvgpu-pmu.c new file mode 100644 index 000000000..8c10cd475 --- /dev/null +++ b/userspace/units/pmu/nvgpu-pmu.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 "../falcon/falcon_utf.h" + +struct utf_falcon *pmu_flcn; + +#define NV_PMC_BOOT_0_ARCHITECTURE_GV110 (0x00000015 << \ + NVGPU_GPU_ARCHITECTURE_SHIFT) +#define NV_PMC_BOOT_0_IMPLEMENTATION_B 0xB + +static bool stub_gv11b_is_pmu_supported(struct gk20a *g) +{ + /* set to false to disable LS PMU ucode support */ + return false; +} + +static struct utf_falcon *pmu_flcn_from_addr(struct gk20a *g, u32 addr) +{ + struct utf_falcon *flcn = NULL; + u32 flcn_base; + + if (pmu_flcn == NULL || pmu_flcn->flcn == NULL) { + return NULL; + } + + flcn_base = pmu_flcn->flcn->flcn_base; + if ((addr >= flcn_base) && + (addr < (flcn_base + UTF_FALCON_MAX_REG_OFFSET))) { + flcn = pmu_flcn; + } + + return flcn; +} + +static void writel_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + struct utf_falcon *flcn = NULL; + + flcn = pmu_flcn_from_addr(g, access->addr); + if (flcn != NULL) { + nvgpu_utf_falcon_writel_access_reg_fn(g, flcn, access); + } else { + 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) +{ + struct utf_falcon *flcn = NULL; + + flcn = pmu_flcn_from_addr(g, access->addr); + if (flcn != NULL) { + nvgpu_utf_falcon_readl_access_reg_fn(g, flcn, access); + } else { + access->value = nvgpu_posix_io_readl_reg_space(g, access->addr); + } +} + +static struct nvgpu_posix_io_callbacks utf_falcon_reg_callbacks = { + .writel = writel_access_reg_fn, + .writel_check = writel_access_reg_fn, + .bar1_writel = writel_access_reg_fn, + .usermode_writel = writel_access_reg_fn, + + .__readl = readl_access_reg_fn, + .readl = readl_access_reg_fn, + .bar1_readl = readl_access_reg_fn, +}; + +static void utf_falcon_register_io(struct gk20a *g) +{ + nvgpu_posix_register_io(g, &utf_falcon_reg_callbacks); +} + +static int init_pmu_falcon_test_env(struct unit_module *m, struct gk20a *g) +{ + int err = 0; + + nvgpu_posix_io_init_reg_space(g); + utf_falcon_register_io(g); + + /* + * 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 -ENOMEM; + } + + /* HAL init parameters for gv11b */ + g->params.gpu_arch = NV_PMC_BOOT_0_ARCHITECTURE_GV110; + g->params.gpu_impl = NV_PMC_BOOT_0_IMPLEMENTATION_B; + + /* HAL init required for getting the falcon ops initialized. */ + err = nvgpu_init_hal(g); + if (err != 0) { + return -ENODEV; + } + + /* Initialize utf & nvgpu falcon for test usage */ + pmu_flcn = nvgpu_utf_falcon_init(m, g, FALCON_ID_PMU); + if (pmu_flcn == NULL) { + return -ENODEV; + } + + return 0; +} + +static int test_pmu_early_init(struct unit_module *m, + struct gk20a *g, void *args) +{ + int err; + struct nvgpu_posix_fault_inj *kmem_fi = + nvgpu_kmem_get_fault_injection(); + + /* + * Case 1: nvgpu_pmu_early_init() fails due to memory + * allocation failure + */ + nvgpu_posix_enable_fault_injection(kmem_fi, true, 0); + err = nvgpu_pmu_early_init(g, &g->pmu); + + if (err != -ENOMEM) { + unit_return_fail(m, + "nvgpu_pmu_early_init init didn't fail as expected\n"); + } + nvgpu_posix_enable_fault_injection(kmem_fi, false, 0); + + nvgpu_pmu_remove_support(g, g->pmu); + + /* Case 2: nvgpu_pmu_early_init() passes */ + err = nvgpu_pmu_early_init(g, &g->pmu); + if (err != 0) { + unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); + } + + nvgpu_pmu_remove_support(g, g->pmu); + + + /* case 3: */ + g->support_ls_pmu = false; + err = nvgpu_pmu_early_init(g, &g->pmu); + if (err != 0) { + unit_return_fail(m, "support_ls_pmu failed\n"); + } + + nvgpu_pmu_remove_support(g, g->pmu); + + /* case 4: */ + g->support_ls_pmu = true; + g->ops.pmu.is_pmu_supported = stub_gv11b_is_pmu_supported; + err = nvgpu_pmu_early_init(g, &g->pmu); + + if (g->support_ls_pmu != false || g->can_elpg != false || + g->elpg_enabled != false || g->aelpg_enabled != false) { + + unit_return_fail(m, "is_pmu_supported failed\n"); + } + + nvgpu_pmu_remove_support(g, g->pmu); + + return UNIT_SUCCESS; +} + +static int test_pmu_remove_support(struct unit_module *m, + struct gk20a *g, void *args) +{ + int err; + + err = nvgpu_pmu_early_init(g, &g->pmu); + if (err != 0) { + unit_return_fail(m, "support_ls_pmu failed\n"); + } + + /* case 1: nvgpu_pmu_remove_support() passes */ + nvgpu_pmu_remove_support(g, g->pmu); + if (g->pmu != NULL) { + unit_return_fail(m, "nvgpu_pmu_remove_support failed\n"); + } + + return UNIT_SUCCESS; +} + +static int test_pmu_reset(struct unit_module *m, + struct gk20a *g, void *args) +{ + int err; + + /* initialize falcon */ + if (init_pmu_falcon_test_env(m, g) != 0) { + unit_return_fail(m, "Module init failed\n"); + } + + /* initialize PMU */ + err = nvgpu_pmu_early_init(g, &g->pmu); + if (err != 0) { + unit_return_fail(m, "nvgpu_pmu_early_init failed\n"); + } + + /* case 1: reset passes */ + err = nvgpu_falcon_reset(g->pmu->flcn); + if (err != 0 || (g->ops.pmu.is_engine_in_reset(g) != false)) { + unit_return_fail(m, "nvgpu_pmu_reset failed\n"); + } + + /* case 2: reset fails */ + nvgpu_utf_falcon_set_dmactl(g, pmu_flcn, 0x2); + err = nvgpu_falcon_reset(g->pmu->flcn); + + if (err == 0) { + unit_return_fail(m, "nvgpu_pmu_reset failed\n"); + } + + return UNIT_SUCCESS; +} + +static int free_falcon_test_env(struct unit_module *m, struct gk20a *g, + void *__args) +{ + nvgpu_utf_falcon_free(g, pmu_flcn); + return UNIT_SUCCESS; +} + +struct unit_module_test nvgpu_pmu_tests[] = { + UNIT_TEST(pmu_early_init, test_pmu_early_init, NULL, 0), + UNIT_TEST(pmu_remove_support, test_pmu_remove_support, NULL, 0), + UNIT_TEST(pmu_reset, test_pmu_reset, NULL, 0), + + UNIT_TEST(falcon_free_test_env, free_falcon_test_env, NULL, 0), +}; + +UNIT_MODULE(nvgpu-pmu, nvgpu_pmu_tests, UNIT_PRIO_NVGPU_TEST);