feat(amd): add test for IOCTL EEMI API
Add a new test case for the IOCTL EEMI API within the TF-A test
framework. The objective of this test is to verify the functionality
and behavior of the IOCTL commands.
Test cover following IOCTL IDs:
- IOCTL_GET_RPU_OPER_MODE
- To get the RPU operating mode like split or lockstep
- IOCTL_SET_RPU_OPER_MODE
- To set the RPU operating mode like split or lockstep
These IOCTL Ids require RPU to be enabled either as the default
subsystem or as a RPU subsytem.
Note: This initial test does not cover all IOCTL IDs, as the purpose
of the test is to validate the IOCTL EEMI API interface.
Change-Id: I9c95facaab171af862ad633f7fdcab0b18b7f9e4
Signed-off-by: Madhav Bhatt <madhav.bhatt@amd.com>
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.c b/tftf/tests/plat/amd/common/common_files/eemi_api.c
index 29d9426..e09ca19 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.c
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.c
@@ -223,3 +223,17 @@
return ret;
}
+
+int xpm_ioctl(const uint32_t node_id, const uint32_t ioctl_id, const uint32_t arg1,
+ const uint32_t arg2, uint32_t *const response)
+{
+ uint32_t ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ ret = eemi_call(PM_IOCTL, ((uint64_t)ioctl_id << 32 | node_id),
+ ((uint64_t)arg2 << 32 | arg1), 0, 0, 0, 0, 0, ret_payload);
+ if (ret == PM_RET_SUCCESS)
+ *response = ret_payload[1];
+
+ return ret;
+}
diff --git a/tftf/tests/plat/amd/common/common_files/eemi_api.h b/tftf/tests/plat/amd/common/common_files/eemi_api.h
index ebed5a7..8f7eca1 100644
--- a/tftf/tests/plat/amd/common/common_files/eemi_api.h
+++ b/tftf/tests/plat/amd/common/common_files/eemi_api.h
@@ -20,6 +20,13 @@
struct xpm_notifier *next; /**< Pointer to next notifier in linked list */
} xpm_notifier;
+struct test_ioctl {
+ uint32_t node_id; /**< Node ID */
+ uint32_t ioctl_id; /**< Ioctl ID */
+ uint32_t ioctl_arg1; /**< Arg1 for Ioctl-ID if required */
+ uint32_t ioctl_arg2; /**< Arg2 for Ioctl-ID if required */
+};
+
int xpm_get_api_version(uint32_t *version);
int xpm_get_chip_id(uint32_t *id_code, uint32_t *version);
int xpm_feature_check(const uint32_t api_id, uint32_t *const version);
@@ -30,5 +37,7 @@
const uint32_t qos, const uint32_t ack);
int xpm_register_notifier(xpm_notifier * const notifier);
int xpm_unregister_notifier(xpm_notifier * const notifier);
+int xpm_ioctl(const uint32_t node_id, const uint32_t ioctl_id, const uint32_t arg1,
+ const uint32_t arg2, uint32_t *const response);
#endif /* __EEMI_API_H__ */
diff --git a/tftf/tests/plat/amd/common/common_files/xpm_defs.h b/tftf/tests/plat/amd/common/common_files/xpm_defs.h
index 0e48418..6252dec 100644
--- a/tftf/tests/plat/amd/common/common_files/xpm_defs.h
+++ b/tftf/tests/plat/amd/common/common_files/xpm_defs.h
@@ -31,6 +31,10 @@
#define PM_GET_CALLBACK_DATA 0xa01U
#define TF_A_PM_REGISTER_SGI 0xa04U
+/* RPU operation mode */
+#define XPM_RPU_MODE_LOCKSTEP 0U
+#define XPM_RPU_MODE_SPLIT 1U
+
/* API IDs */
enum pm_api_id {
PM_API_MIN, /**< 0x0 */
@@ -134,4 +138,10 @@
PM_NOTIFY_CB = 32U, /**< Notify callback */
};
+/* IOCTL IDs */
+typedef enum {
+ IOCTL_GET_RPU_OPER_MODE = 0, /**< Get RPU mode */
+ IOCTL_SET_RPU_OPER_MODE = 1, /**< Set RPU mode */
+} pm_ioctl_id;
+
#endif /* XPM_DEFS_H_ */
diff --git a/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h b/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
index e485b67..3a41ed9 100644
--- a/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
+++ b/tftf/tests/plat/amd/common/common_files/xpm_nodeid.h
@@ -10,6 +10,7 @@
/*
* Device Nodes
*/
+#define PM_DEV_RPU0_0 0x18110005U
#define PM_DEV_USB_0 0x18224018U
#endif /* XPM_NODEID_H_ */
diff --git a/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c b/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c
new file mode 100644
index 0000000..e2c0170
--- /dev/null
+++ b/tftf/tests/plat/amd/common/ioctl_test/ioctl_test.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "eemi_api.h"
+#include "xpm_defs.h"
+#include "xpm_nodeid.h"
+
+struct test_ioctl test_ioctl_list[] = {
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_GET_RPU_OPER_MODE,
+ .ioctl_arg1 = 0U,
+ .ioctl_arg2 = 0U,
+ },
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_SET_RPU_OPER_MODE,
+ .ioctl_arg1 = XPM_RPU_MODE_SPLIT,
+ .ioctl_arg2 = 0U,
+ },
+ {
+ .node_id = PM_DEV_RPU0_0,
+ .ioctl_id = IOCTL_GET_RPU_OPER_MODE,
+ .ioctl_arg1 = 0U,
+ .ioctl_arg2 = 0U,
+ },
+};
+
+/*
+ * This function calls IOCTL to firmware for device control and
+ * configuration.
+ */
+test_result_t test_ioctl_api(void)
+{
+ uint32_t ioctl_response = 0U;
+ int32_t status, i;
+
+ for (i = 0; i < (int32_t)ARRAY_SIZE(test_ioctl_list); i++) {
+ status = xpm_ioctl(test_ioctl_list[i].node_id,
+ test_ioctl_list[i].ioctl_id,
+ test_ioctl_list[i].ioctl_arg1,
+ test_ioctl_list[i].ioctl_arg2,
+ &ioctl_response);
+ if (status != PM_RET_SUCCESS) {
+ tftf_testcase_printf("%s ERROR Fails for IOCTL Id: %u, Status: 0x%x",
+ __func__, test_ioctl_list[i].ioctl_id, status);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (test_ioctl_list[i].ioctl_id == IOCTL_GET_RPU_OPER_MODE) {
+ tftf_testcase_printf("%s RPU_OPER_MODE: 0x%x\n", __func__,
+ ioctl_response);
+ } else {
+ tftf_testcase_printf("%s Mode Set done successfully\n",
+ __func__);
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-versal.xml b/tftf/tests/tests-versal.xml
index ce681dd..97fa600 100644
--- a/tftf/tests/tests-versal.xml
+++ b/tftf/tests/tests-versal.xml
@@ -16,6 +16,7 @@
<testcase name="Get Platform Chip ID" function="test_get_chip_id" />
<testcase name="Feature Check" function="test_feature_check" />
<testcase name="Notifier EEMI API" function="test_notifier_api" />
+ <testcase name="Ioctl EEMI API" function="test_ioctl_api" />
</testsuite>
</testsuites>