summaryrefslogtreecommitdiff
path: root/mali_kbase/tests/mali_kutf_mgm_integration_test/mali_kutf_mgm_integration_test_main.c
diff options
context:
space:
mode:
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.c210
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");