diff options
Diffstat (limited to 'mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c')
-rw-r--r-- | mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c b/mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c new file mode 100644 index 0000000..5a42bd6 --- /dev/null +++ b/mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +/* + * + * (C) COPYRIGHT 2022 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms + * of such GNU license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can access it online at + * http://www.gnu.org/licenses/gpl-2.0.html. + * + */ +#include <linux/module.h> +#include "mali_kbase.h" +#include <kutf/kutf_suite.h> +#include <kutf/kutf_utils.h> +#include <kutf/kutf_helpers.h> +#include <kutf/kutf_helpers_user.h> + +#define MINOR_FOR_FIRST_KBASE_DEV (-1) + +#define BASE_MEM_GROUP_COUNT (16) +#define PA_MAX ((1ULL << 48) - 1) +#define PA_START_BIT 12 +#define ENTRY_ACCESS_BIT (1ULL << 10) + +#define ENTRY_IS_ATE_L3 3ULL +#define ENTRY_IS_ATE_L02 1ULL + +#define MGM_INTEGRATION_SUITE_NAME "mgm_integration" +#define MGM_INTEGRATION_PTE_TRANSLATION "pte_translation" + +static char msg_buf[KUTF_MAX_LINE_LENGTH]; + +/* KUTF test application pointer for this test */ +struct kutf_application *mgm_app; + +/** + * struct kutf_mgm_fixture_data - test fixture used by test functions + * @kbdev: kbase device for the GPU. + * @group_id: Memory group ID to test based on fixture index. + */ +struct kutf_mgm_fixture_data { + struct kbase_device *kbdev; + int group_id; +}; + +/** + * mali_kutf_mgm_pte_translation_test() - Tests forward and reverse translation + * of PTE by the MGM module + * @context: KUTF context within which to perform the test. + * + * This test creates PTEs with physical addresses in the range + * 0x0000-0xFFFFFFFFF000 and tests that mgm_update_gpu_pte() returns a different + * PTE and mgm_pte_to_original_pte() returns the original PTE. This is tested + * at MMU level 2 and 3 as mgm_update_gpu_pte() is called for ATEs only. + * + * This test is run for a specific group_id depending on the fixture_id. + */ +static void mali_kutf_mgm_pte_translation_test(struct kutf_context *context) +{ + struct kutf_mgm_fixture_data *data = context->fixture; + struct kbase_device *kbdev = data->kbdev; + struct memory_group_manager_device *mgm_dev = kbdev->mgm_dev; + u64 addr; + + for (addr = 1 << (PA_START_BIT - 1); addr <= PA_MAX; addr <<= 1) { + /* Mask 1 << 11 by ~0xFFF to get 0x0000 at first iteration */ + phys_addr_t pa = addr; + u8 mmu_level; + + /* Test MMU level 3 and 2 (2MB pages) only */ + for (mmu_level = MIDGARD_MMU_LEVEL(2); mmu_level <= MIDGARD_MMU_LEVEL(3); + mmu_level++) { + u64 translated_pte; + u64 returned_pte; + u64 original_pte; + + if (mmu_level == MIDGARD_MMU_LEVEL(3)) + original_pte = + (pa & PAGE_MASK) | ENTRY_ACCESS_BIT | ENTRY_IS_ATE_L3; + else + original_pte = + (pa & PAGE_MASK) | ENTRY_ACCESS_BIT | ENTRY_IS_ATE_L02; + + dev_dbg(kbdev->dev, "Testing group_id=%u, mmu_level=%u, pte=0x%llx\n", + data->group_id, mmu_level, original_pte); + + translated_pte = mgm_dev->ops.mgm_update_gpu_pte(mgm_dev, data->group_id, + mmu_level, original_pte); + if (translated_pte == original_pte) { + snprintf( + msg_buf, sizeof(msg_buf), + "PTE unchanged. translated_pte (0x%llx) == original_pte (0x%llx) for mmu_level=%u, group_id=%d", + translated_pte, original_pte, mmu_level, data->group_id); + kutf_test_fail(context, msg_buf); + return; + } + + returned_pte = mgm_dev->ops.mgm_pte_to_original_pte( + mgm_dev, data->group_id, mmu_level, translated_pte); + dev_dbg(kbdev->dev, "\treturned_pte=%llx\n", returned_pte); + + if (returned_pte != original_pte) { + snprintf( + msg_buf, sizeof(msg_buf), + "Original PTE not returned. returned_pte (0x%llx) != origin al_pte (0x%llx) for mmu_level=%u, group_id=%d", + returned_pte, original_pte, mmu_level, data->group_id); + kutf_test_fail(context, msg_buf); + return; + } + } + } + snprintf(msg_buf, sizeof(msg_buf), "Translation passed for group_id=%d", data->group_id); + kutf_test_pass(context, msg_buf); +} + +/** + * mali_kutf_mgm_integration_create_fixture() - Creates the fixture data + * required for all tests in the mgm integration suite. + * @context: KUTF context. + * + * Return: Fixture data created on success or NULL on failure + */ +static void *mali_kutf_mgm_integration_create_fixture(struct kutf_context *context) +{ + struct kutf_mgm_fixture_data *data; + struct kbase_device *kbdev; + + pr_debug("Finding kbase device\n"); + kbdev = kbase_find_device(MINOR_FOR_FIRST_KBASE_DEV); + if (kbdev == NULL) { + kutf_test_fail(context, "Failed to find kbase device"); + return NULL; + } + pr_debug("Creating fixture\n"); + + data = kutf_mempool_alloc(&context->fixture_pool, sizeof(struct kutf_mgm_fixture_data)); + if (!data) + return NULL; + data->kbdev = kbdev; + data->group_id = context->fixture_index; + + pr_debug("Fixture created\n"); + return data; +} + +/** + * mali_kutf_mgm_integration_remove_fixture() - Destroy fixture data previously + * created by mali_kutf_mgm_integration_create_fixture. + * @context: KUTF context. + */ +static void mali_kutf_mgm_integration_remove_fixture(struct kutf_context *context) +{ + struct kutf_mgm_fixture_data *data = context->fixture; + struct kbase_device *kbdev = data->kbdev; + + kbase_release_device(kbdev); +} + +/** + * mali_kutf_mgm_integration_test_main_init() - Module entry point for this test. + * + * Return: 0 on success, error code on failure. + */ +static int __init mali_kutf_mgm_integration_test_main_init(void) +{ + struct kutf_suite *suite; + + mgm_app = kutf_create_application("mgm"); + + if (mgm_app == NULL) { + pr_warn("Creation of mgm KUTF app failed!\n"); + return -ENOMEM; + } + suite = kutf_create_suite(mgm_app, MGM_INTEGRATION_SUITE_NAME, BASE_MEM_GROUP_COUNT, + mali_kutf_mgm_integration_create_fixture, + mali_kutf_mgm_integration_remove_fixture); + if (suite == NULL) { + pr_warn("Creation of %s suite failed!\n", MGM_INTEGRATION_SUITE_NAME); + kutf_destroy_application(mgm_app); + return -ENOMEM; + } + kutf_add_test(suite, 0x0, MGM_INTEGRATION_PTE_TRANSLATION, + mali_kutf_mgm_pte_translation_test); + return 0; +} + +/** + * mali_kutf_mgm_integration_test_main_exit() - Module exit point for this test. + */ +static void __exit mali_kutf_mgm_integration_test_main_exit(void) +{ + kutf_destroy_application(mgm_app); +} + +module_init(mali_kutf_mgm_integration_test_main_init); +module_exit(mali_kutf_mgm_integration_test_main_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION("1.0"); |