feat(doe): add PCIe DOE tests
This patch adds PCIe DOE tests for
- DOE discovery protocol
- SPDM get version
To build this test suite use 'TEST=pcie-doe'
option.
The spdm.h is imported from https://github.com/DMTF/libspdm
project.
Change-Id: I8db1048d01b4f8061d8a4ddccc198159ed61e6b7
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index b25d1d0..0bae3cf 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,8 @@
-Iinclude/lib \
-Iinclude/lib/${ARCH} \
-Iinclude/lib/extensions \
+ -Iinclude/lib/pcie \
+ -Iinclude/lib/spdm \
-Iinclude/lib/utils \
-Iinclude/lib/xlat_tables \
-Iinclude/plat/common \
diff --git a/tftf/tests/doe_tests/doe_helpers.c b/tftf/tests/doe_tests/doe_helpers.c
new file mode 100644
index 0000000..28b6a86
--- /dev/null
+++ b/tftf/tests/doe_tests/doe_helpers.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <debug.h>
+#include <pcie.h>
+#include <pcie_doe.h>
+#include <spdm.h>
+
+#include <platform_pcie.h>
+
+void pcie_init(void)
+{
+ /* Create PCIe table and enumeration */
+ pcie_create_info_table();
+}
+
+/*
+ * @brief Returns the BDF Table pointer
+ *
+ * @param None
+ *
+ * @return BDF Table pointer
+ */
+pcie_device_bdf_table_t *get_pcie_bdf_table(void)
+{
+ return pcie_get_bdf_table();
+}
+
+int find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr)
+{
+ pcie_device_bdf_table_t *bdf_table_ptr = pcie_get_bdf_table();
+ uint32_t num_bdf = bdf_table_ptr->num_entries;
+
+ INFO("PCI BDF table entries: %u\n", num_bdf);
+
+ /* If no entries in BDF table return error */
+ if (num_bdf == 0) {
+ ERROR("No BDFs entries found\n");
+ return -ENODEV;
+ }
+
+ INFO("PCI BDF table 0x%lx\n", (uintptr_t)bdf_table_ptr);
+
+ while (num_bdf-- != 0) {
+ uint32_t bdf = bdf_table_ptr->device[num_bdf].bdf;
+ uint32_t status, doe_cap_base;
+
+ /* Check for DOE capability */
+ status = pcie_find_capability(bdf, PCIE_ECAP, DOE_CAP_ID, &doe_cap_base);
+ if (status == PCIE_SUCCESS) {
+ INFO("PCIe DOE capability: bdf 0x%x cap_base 0x%x\n", bdf, doe_cap_base);
+ *bdf_ptr = bdf;
+ *cap_base_ptr = doe_cap_base;
+ return 0;
+ }
+ }
+
+ ERROR("No PCIe DOE capability found\n");
+ return -ENODEV;
+}
+
+int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base)
+{
+ uint32_t response[SPDM_GET_VERS_RESP_LEN], resp_len;
+ spdm_version_response_t *ver_resp;
+ spdm_version_number_t *ver_ptr;
+ uint8_t entry_count;
+ int ret;
+ const spdm_get_version_request_t ver_req = {
+ { SPDM_MESSAGE_VERSION, SPDM_GET_VERSION, }
+ };
+
+ ret = pcie_doe_send_req(DOE_HEADER_1, bdf, doe_cap_base,
+ (uint32_t *)&ver_req,
+ sizeof(spdm_get_version_request_t));
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = pcie_doe_recv_resp(bdf, doe_cap_base, response, &resp_len);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ver_resp = (spdm_version_response_t *)response;
+
+ if (ver_resp->header.spdm_version != SPDM_MESSAGE_VERSION) {
+ ERROR("SPDM response v.%u doesn't match requested %u\n",
+ ver_resp->header.spdm_version,
+ SPDM_MESSAGE_VERSION);
+ return -EPROGMISMATCH;
+ }
+
+ if (ver_resp->header.request_response_code != SPDM_VERSION) {
+ ERROR("SPDM response code %u doesn't match expected %u\n",
+ ver_resp->header.request_response_code,
+ SPDM_VERSION);
+ return -EBADMSG;
+ }
+
+ entry_count = ver_resp->version_number_entry_count;
+ INFO("SPDM version entries: %u\n", entry_count);
+
+ ver_ptr = (spdm_version_number_t *)(
+ (uintptr_t)&ver_resp->version_number_entry_count +
+ sizeof(ver_resp->version_number_entry_count));
+
+ while (entry_count-- != 0) {
+ spdm_version_number_t ver = *ver_ptr++;
+
+ INFO("SPDM v%llu.%llu.%llu.%llu\n",
+ EXTRACT(SPDM_VER_MAJOR, ver),
+ EXTRACT(SPDM_VER_MINOR, ver),
+ EXTRACT(SPDM_VER_UPDATE, ver),
+ EXTRACT(SPDM_VER_ALPHA, ver));
+ }
+ return ret;
+}
+
+int doe_discovery(uint32_t bdf, uint32_t doe_cap_base)
+{
+ pcie_doe_disc_req_t request = { 0, };
+ pcie_doe_disc_resp_t response;
+ uint32_t resp_len;
+ int ret;
+
+ do {
+ ret = pcie_doe_send_req(DOE_HEADER_0, bdf, doe_cap_base,
+ (uint32_t *)&request,
+ sizeof(pcie_doe_disc_req_t));
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = pcie_doe_recv_resp(bdf, doe_cap_base,
+ (uint32_t *)&response, &resp_len);
+ if (ret != 0) {
+ return ret;
+ }
+
+ print_doe_disc(&response);
+ request.index = response.next_index;
+
+ } while (response.next_index != 0);
+
+ return 0;
+}
diff --git a/tftf/tests/doe_tests/doe_helpers.h b/tftf/tests/doe_tests/doe_helpers.h
new file mode 100644
index 0000000..08137e3
--- /dev/null
+++ b/tftf/tests/doe_tests/doe_helpers.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DOE_HELPERS_H
+#define DOE_HELPERS_H
+
+void pcie_init(void);
+int find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr);
+int doe_discovery(uint32_t bdf, uint32_t doe_cap_base);
+int get_spdm_version(uint32_t bdf, uint32_t doe_cap_base);
+
+#endif /* DOE_HELPERS_H */
diff --git a/tftf/tests/doe_tests/test_doe.c b/tftf/tests/doe_tests/test_doe.c
new file mode 100644
index 0000000..6eb5079
--- /dev/null
+++ b/tftf/tests/doe_tests/test_doe.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "doe_helpers.h"
+
+#include <test_helpers.h>
+
+#define SKIP_TEST_IF_DOE_NOT_SUPPORTED() \
+ do { \
+ if (find_doe_device(&bdf, &doe_cap_base) != 0) { \
+ tftf_testcase_printf("PCIe DOE not supported\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (false)
+
+test_result_t doe_discovery_test(void)
+{
+ uint32_t bdf, doe_cap_base;
+ int ret;
+
+ pcie_init();
+
+ SKIP_TEST_IF_DOE_NOT_SUPPORTED();
+
+ ret = doe_discovery(bdf, doe_cap_base);
+ if (ret != 0) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+test_result_t spdm_version_test(void)
+{
+ uint32_t bdf, doe_cap_base;
+ int ret;
+
+ SKIP_TEST_IF_DOE_NOT_SUPPORTED();
+
+ ret = get_spdm_version(bdf, doe_cap_base);
+ if (ret != 0) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-pcie-doe.mk b/tftf/tests/tests-pcie-doe.mk
new file mode 100644
index 0000000..14bc9cf
--- /dev/null
+++ b/tftf/tests/tests-pcie-doe.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += \
+ $(addprefix plat/arm/fvp/, \
+ fvp_pcie.c \
+ )
+
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/doe_tests/, \
+ doe_helpers.c \
+ test_doe.c \
+ )
+
+TESTS_SOURCES += \
+ $(addprefix lib/pcie/, \
+ pcie.c \
+ pcie_doe.c \
+ )
diff --git a/tftf/tests/tests-pcie-doe.xml b/tftf/tests/tests-pcie-doe.xml
new file mode 100644
index 0000000..ed8b7cb
--- /dev/null
+++ b/tftf/tests/tests-pcie-doe.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2024, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <testsuite name="PCI Data Object Exchange" description="Check PCI DOE support">
+ <testcase name="PCI DOE Discovery" function="doe_discovery_test" />
+ <testcase name="SPDM Get Version" function="spdm_version_test" />
+ </testsuite>
+</testsuites>