diff --git a/userspace/SWUTS.h b/userspace/SWUTS.h index 6a62f62ab..247f43bbe 100644 --- a/userspace/SWUTS.h +++ b/userspace/SWUTS.h @@ -33,8 +33,8 @@ * - @ref SWUTS-enabled * - @ref SWUTS-init * - @ref SWUTS-interface-atomic + * - @ref SWUTS-mm-nvgpu-mem * - @ref SWUTS-mm-vm * - @ref SWUTS-sdl * */ - diff --git a/userspace/SWUTS.sources b/userspace/SWUTS.sources index 893a5c932..a09902d78 100644 --- a/userspace/SWUTS.sources +++ b/userspace/SWUTS.sources @@ -2,5 +2,5 @@ INPUT += ../../../userspace/SWUTS.h INPUT += ../../../userspace/units/enabled/nvgpu-enabled.h INPUT += ../../../userspace/units/init/nvgpu-init.h INPUT += ../../../userspace/units/interface/atomic/atomic.h +INPUT += ../../../userspace/units/mm/nvgpu_mem/nvgpu_mem.h INPUT += ../../../userspace/units/mm/vm/vm.h - diff --git a/userspace/units/mm/nvgpu_mem/nvgpu_mem.c b/userspace/units/mm/nvgpu_mem/nvgpu_mem.c index d61e6d960..d4f2e63bf 100644 --- a/userspace/units/mm/nvgpu_mem/nvgpu_mem.c +++ b/userspace/units/mm/nvgpu_mem/nvgpu_mem.c @@ -41,6 +41,8 @@ #include #include +#include "nvgpu_mem.h" + /* * MEM_ADDRESS represents arbitrary memory start address. Init function will * allocate MEM_PAGES number of pages in memory. @@ -128,17 +130,9 @@ static void free_vidmem_env(struct unit_module *m, struct gk20a *g) } /* - * Test APERTURE_VIDMEM branch of: - * nvgpu_memset() - * nvgpu_mem_wr() - * nvgpu_mem_rd() - * nvgpu_mem_wr_n() - * nvgpu_mem_rd_n() - * - * For vidmem, all write, read or memset calls are converted to pramin calls. - * As pramin functions are already tested, this test checks branch execution. + * Test APERTURE_VIDMEM branch of nvgpu_mem read and write functions */ -static int test_nvgpu_mem_vidmem(struct unit_module *m, +int test_nvgpu_mem_vidmem(struct unit_module *m, struct gk20a *g, void *args) { int err; @@ -159,35 +153,14 @@ static int test_nvgpu_mem_vidmem(struct unit_module *m, unit_return_fail(m, "Vidmem init failed with err=%d\n", err); } - /* - * Test nvgpu_memset() - APERTURE_VIDMEM branch - * For vidmem, nvgpu_pramin_memset is tested in pramin module. - */ nvgpu_memset(g, test_mem, 0, memset_pattern, TEST_SIZE); - /* - * Test nvgpu_mem_wr() - APERTURE_VIDMEM branch - * For vidmem, nvgpu_pramin_wr is tested in pramin module. - */ nvgpu_mem_wr(g, test_mem, 0, memset_pattern); - /* - * Test nvgpu_mem_rd() - APERTURE_VIDMEM branch - * For vidmem, nvgpu_pramin_rd_n is tested in pramin module. - */ nvgpu_mem_rd(g, test_mem, 0); - /* - * Test nvgpu_mem_wr_n() - APERTURE_VIDMEM branch - * For vidmem, nvgpu_pramin_wr_n is tested in pramin module. - */ - nvgpu_mem_wr_n(g, test_mem, 0, data_src, data_size); - /* - * Test nvgpu_mem_rd_n() - APERTURE_VIDMEM branch - * For vidmem, nvgpu_pramin_rd_n is tested by pramin module. - */ nvgpu_mem_rd_n(g, test_mem, 0, (void *)data_src, data_size); nvgpu_kfree(g, data_src); @@ -200,11 +173,7 @@ static int test_nvgpu_mem_vidmem(struct unit_module *m, } #endif -/* - * Test nvgpu_aperture_mask() - * Check if appropriate mask is returned for each case. - */ -static int test_nvgpu_aperture_mask(struct unit_module *m, +int test_nvgpu_aperture_mask(struct unit_module *m, struct gk20a *g, void *args) { u32 sysmem_mask = 1; @@ -309,11 +278,9 @@ static int test_nvgpu_aperture_mask(struct unit_module *m, } /* - * Test: test_nvgpu_mem_phys_ops - * - * Test all nvgpu_sgt_ops functions provided by nvgpu_mem unit -*/ -static int test_nvgpu_mem_iommu_translate(struct unit_module *m, + * Test for iommu translate + */ +int test_nvgpu_mem_iommu_translate(struct unit_module *m, struct gk20a *g, void *args) { u64 temp_phys; @@ -322,7 +289,6 @@ static int test_nvgpu_mem_iommu_translate(struct unit_module *m, struct nvgpu_os_posix *p = nvgpu_os_posix_from_gk20a(g); /* - * Test nvgpu_mem_iommu_translate * Case: mm is not iommuable * This is specified in nvgpu_os_posix structure. */ @@ -334,7 +300,6 @@ static int test_nvgpu_mem_iommu_translate(struct unit_module *m, } /* - * Test nvgpu_mem_iommu_translate * Case: mm is not iommuable * But, mm_is_iommuable = true. */ @@ -347,7 +312,6 @@ static int test_nvgpu_mem_iommu_translate(struct unit_module *m, } /* - * Test nvgpu_mem_iommu_translate * Case: mm is iommuable * Set HAL to enable iommu_translate */ @@ -359,7 +323,7 @@ static int test_nvgpu_mem_iommu_translate(struct unit_module *m, "iommu_translate did not translate address\n"); } - /* Reset settings */ + /* Reset iommuable settings */ p->mm_is_iommuable = false; return UNIT_SUCCESS; @@ -371,7 +335,7 @@ static int test_nvgpu_mem_iommu_translate(struct unit_module *m, * Testing function in APERTURE_SYSMEM and APERTURE_INVALID case. * */ -static int test_nvgpu_memset_sysmem(struct unit_module *m, +int test_nvgpu_memset_sysmem(struct unit_module *m, struct gk20a *g, void *args) { u32 i; @@ -410,19 +374,9 @@ static int test_nvgpu_memset_sysmem(struct unit_module *m, } /* - * Test: - * nvgpu_mem_is_valid() - * nvgpu_mem_is_sysmem() - * APERTURE_SYSMEM and APERTURE_INVALID branch of: - * nvgpu_memset() - * nvgpu_mem_wr() - * nvgpu_mem_rd() - * nvgpu_mem_wr_n() - * nvgpu_mem_rd_n() - * - * Test all write and read calls. + * Test all memory write and read calls. */ -static int test_nvgpu_mem_wr_rd(struct unit_module *m, +int test_nvgpu_mem_wr_rd(struct unit_module *m, struct gk20a *g, void *args) { u32 i; @@ -438,13 +392,12 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, /* Case: APERTURE_INVALID */ test_mem->aperture = APERTURE_INVALID; - /* Confirm nvgpu_mem is set to SYSMEM*/ + if (nvgpu_mem_is_sysmem(test_mem) != false) { unit_return_fail(m, "nvgpu_mem_is_sysmem " "returns true for APERTURE_INVALID\n"); } - /* Confirm nvgpu_mem is allocated*/ if (nvgpu_mem_is_valid(test_mem) != false) { unit_return_fail(m, "nvgpu_mem_is_valid " "returns true for APERTURE_INVALID\n"); @@ -460,7 +413,7 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, /* Case: APERTURE_SYSMEM */ test_mem->aperture = APERTURE_SYSMEM; - /* Confirm nvgpu_mem is set to SYSMEM*/ + if (nvgpu_mem_is_sysmem(test_mem) != true) { unit_return_fail(m, "nvgpu_mem_is_sysmem " "returns false for APERTURE_SYSMEM\n"); @@ -476,10 +429,6 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, /* Case: APERTURE_SYSMEM */ - /* - * Test nvgpu_mem_wr() - * further calls nvgpu_mem_wr32() - */ nvgpu_mem_wr(g, test_mem, test_offset, data_pattern); if (test_cpu_va[(test_offset / (u32)sizeof(u32))] != data_pattern) { unit_err(m, @@ -487,10 +436,6 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, goto return_fail; } - /* - * Test nvgpu_mem_rd() - * further calls nvgpu_mem_rd32() - */ data_rd = nvgpu_mem_rd(g, test_mem, test_offset); if (data_rd != data_pattern) { unit_err(m, @@ -498,9 +443,6 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, goto return_fail; } - /* - * Test nvgpu_mem_wr_n() - */ data_src = (u32 *) nvgpu_kmalloc(g, data_size); if (data_src == NULL) { unit_err(m, "Could not allocate data_src\n"); @@ -517,9 +459,6 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, } } - /* - * Test nvgpu_mem_rd_n() - */ data_rd_buf = (u32 *) nvgpu_kzalloc(g, data_size); if (data_rd_buf == NULL) { unit_err(m, "Could not allocate data_rd_buf\n"); @@ -535,9 +474,6 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, } } - /* - * Test nvgpu_mem_rd32_pair() - */ data_rd_pair = nvgpu_mem_rd32_pair(g, test_mem, 0, 1); if (data_rd_pair != ((u64)data_pattern | ((u64)data_pattern << 32ULL))) { @@ -548,39 +484,24 @@ static int test_nvgpu_mem_wr_rd(struct unit_module *m, /* Case: APERTURE_INVALID */ test_mem->aperture = APERTURE_INVALID; - /* - * Test nvgpu_mem_wr() - * further calls nvgpu_mem_wr32() - */ if (!EXPECT_BUG(nvgpu_mem_wr(g, test_mem, test_offset, data_pattern))) { unit_err(m, "APERTURE_INVALID: mem_wr did not BUG() as expected\n"); goto free_buffers; } - /* - * Test nvgpu_mem_rd() - * further calls nvgpu_mem_rd32() - */ if (!EXPECT_BUG(nvgpu_mem_rd(g, test_mem, test_offset))) { unit_err(m, "APERTURE_INVALID: " "mem_rd did not BUG() as expected\n"); goto free_buffers; } - /* - * Test nvgpu_mem_wr_n() - */ if (!EXPECT_BUG(nvgpu_mem_wr_n(g, test_mem, 0, data_src, data_size))) { unit_err(m, "APERTURE_INVALID: " "mem_wr_n did not BUG() as expected\n"); goto free_buffers; } - - /* - * Test nvgpu_mem_rd_n() - */ if (!EXPECT_BUG(nvgpu_mem_rd_n(g, test_mem, 0, (void *)data_rd_buf, data_size))) { unit_err(m, "APERTURE_INVALID: " @@ -609,10 +530,8 @@ return_fail: /* * Test: test_nvgpu_mem_phys_ops - * - * Test all nvgpu_sgt_ops functions provided by nvgpu_mem unit -*/ -static int test_nvgpu_mem_phys_ops(struct unit_module *m, + */ +int test_nvgpu_mem_phys_ops(struct unit_module *m, struct gk20a *g, void *args) { u64 ret; @@ -620,7 +539,6 @@ static int test_nvgpu_mem_phys_ops(struct unit_module *m, struct nvgpu_sgt *test_sgt = test_mem->phys_sgt; struct nvgpu_sgl *test_sgl = test_sgt->sgl; - /* Test nvgpu_mem_phys_sgl_next */ struct nvgpu_sgl *temp_sgl = test_sgt->ops->sgl_next(test_sgl); if (temp_sgl != NULL) { @@ -628,46 +546,39 @@ static int test_nvgpu_mem_phys_ops(struct unit_module *m, "nvgpu_mem_phys_sgl_next not NULL as expected\n"); } - /* Test nvgpu_mem_phys_sgl_dma */ ret = test_sgt->ops->sgl_dma(test_sgl); if (ret != MEM_ADDRESS) { unit_return_fail(m, "nvgpu_mem_phys_sgl_dma not equal to phys as expected\n"); } - /* Test nvgpu_mem_phys_sgl_phys */ ret = test_sgt->ops->sgl_phys(g, test_sgl); if (ret != MEM_ADDRESS) { unit_return_fail(m, "nvgpu_mem_phys_sgl_phys not equal to phys as expected\n"); } - /* Test nvgpu_mem_phys_sgl_ipa */ ret = test_sgt->ops->sgl_ipa(g, test_sgl); if (ret != MEM_ADDRESS) { unit_return_fail(m, "nvgpu_mem_phys_sgl_ipa incorrect\n"); } - /* Test nvgpu_mem_phys_sgl_ipa_to_pa */ ret = test_sgt->ops->sgl_ipa_to_pa(g, test_sgl, 0ULL, NULL); if (ret != 0ULL) { unit_return_fail(m, "nvgpu_mem_phys_sgl_ipa_to_pa not zero as expected\n"); } - /* Test nvgpu_mem_phys_sgl_length */ ret = test_sgt->ops->sgl_length(test_sgl); if (ret != MEM_SIZE) { unit_return_fail(m, "nvgpu_mem_phys_sgl_length incorrect\n"); } - /* Test nvgpu_mem_phys_sgl_gpu_addr */ ret = test_sgt->ops->sgl_gpu_addr(g, test_sgl, attrs); if (ret != MEM_ADDRESS) { unit_return_fail(m, "nvgpu_mem_phys_sgl_gpu_addr incorrect\n"); } - /* Test nvgpu_mem sgt_iommuable */ if (test_sgt->ops->sgt_iommuable != NULL) { unit_return_fail(m, "physical nvgpu_mems is not IOMMU'able\n"); } @@ -680,17 +591,7 @@ static int test_nvgpu_mem_phys_ops(struct unit_module *m, return UNIT_SUCCESS; } -/* - * Test nvgpu_mem_create_from_phys() - * - * 1. With memory failure, check that init fails with -ENOMEM - * 2. Init works in regular scenario - * - * This test should be first to execute. Newly inited memory will be - * used by rest of the tests in this module. - */ - -static int test_nvgpu_mem_create_from_phys(struct unit_module *m, +int test_nvgpu_mem_create_from_phys(struct unit_module *m, struct gk20a *g, void *args) { int err; @@ -751,7 +652,7 @@ static int test_nvgpu_mem_create_from_phys(struct unit_module *m, return UNIT_SUCCESS; } -static int test_free_nvgpu_mem(struct unit_module *m, +int test_free_nvgpu_mem(struct unit_module *m, struct gk20a *g, void *args) { test_mem->aperture = APERTURE_SYSMEM; diff --git a/userspace/units/mm/nvgpu_mem/nvgpu_mem.h b/userspace/units/mm/nvgpu_mem/nvgpu_mem.h new file mode 100644 index 000000000..2037bba0c --- /dev/null +++ b/userspace/units/mm/nvgpu_mem/nvgpu_mem.h @@ -0,0 +1,194 @@ +/* + * 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_MEM_H +#define UNIT_NVGPU_MEM_H + +struct gk20a; +struct unit_module; + +/** @addtogroup SWUTS-mm-nvgpu-mem + * @{ + * + * Software Unit Test Specification for mm.nvgpu_mem + */ + +/** + * Test specification for: test_nvgpu_mem_create_from_phys + * + * Description: Initialize nvgpu_mem for given size and base address. + * + * Test Type: Feature based + * + * Input: None + * + * Steps: + * - Initialize nvgpu_mem + * - Allocate memory for nvgpu_mem sgt and sgl + * - Initialize nvgpu_mem structure members to appropriate value. + * - Allocate cpu_va memory for later tests + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_mem_create_from_phys(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_mem_phys_ops + * + * Description: Check all nvgpu_sgt_ops functions + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Execute nvgpu_sgt_ops functions + * - Check if each nvgpu_sgt_ops function executes and returns expected value. + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_mem_phys_ops(struct unit_module *m, struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_memset_sysmem + * + * Description: Store pre-defined pattern at allocated nvgpu_mem address + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Store data pattern and check value for multiple cases + * - Execute below steps for APERTURE_SYSMEM and APERTURE_INVALID cases + * - Using nvgpu_memset() store pre-defined data pattern in part of allocated + * memory + * - Check if set data pattern is correctly stored + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_memset_sysmem(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_mem_wr_rd + * + * Description: Test read and write functions for sysmem + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Check if memory is of sysmem type + * - Check if memory aperture is not invalid + * - Execute below steps for APERTURE_SYSMEM and APERTURE_INVALID cases + * - Execute all write functions and confirm data written + * - Write preset data pattern to allocated nvgpu_mem + * - Confirm data written at the memory location is correct + * - Execute read functions and confirm data read + * - Read data from a segment of allocated memory + * - Confirm read data is correct + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_mem_wr_rd(struct unit_module *m, struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_mem_iommu_translate + * + * Description: Test if given address is iommuable + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Check if nvgpu_mem is iommuable + * - Return value is equal to nvgpu_mem phys address value + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_mem_iommu_translate(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_aperture_mask + * + * Description: Check if nvgpu_mem aperture is correct + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Execute these steps for all the aperture types + * - Check if nvgpu_mem aperture mask values returned are as expected + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_aperture_mask(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_nvgpu_mem_vidmem + * + * Description: Test read and write memory functions for vidmem + * + * Test Type: Feature based + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Execute read and write calls for vidmem which are converted to pramin calls + * - pramin functions are tested in pramin module + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_mem_vidmem(struct unit_module *m, struct gk20a *g, void *args); + +/** + * Test specification for: test_free_nvgpu_mem + * + * Description: Cleanup allocated memory for nvgpu_mem structure + * + * Test Type: Other (cleanup) + * + * Input: test_nvgpu_mem_create_from_phys + * + * Steps: + * - Free allocated memory + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_free_nvgpu_mem(struct unit_module *m, struct gk20a *g, void *args); + +#endif /* UNIT_NVGPU_MEM_H */