refactor(realm): define PCIe helpers
This patch refactors the existing PCIe and DOE
helpers to define generic helpers to make them
reusable across more tests.
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Change-Id: I56a9f5c59715c7916f3f737ed6d3af94b0e3679f
diff --git a/lib/pcie/pcie.c b/lib/pcie/pcie.c
index 5f8c97f..8de2825 100644
--- a/lib/pcie/pcie.c
+++ b/lib/pcie/pcie.c
@@ -5,11 +5,13 @@
*/
#include <assert.h>
+#include <errno.h>
#include <stddef.h>
#include <debug.h>
#include <mmio.h>
#include <pcie.h>
+#include <pcie_doe.h>
#include <pcie_spec.h>
#include <platform.h>
#include <tftf_lib.h>
@@ -617,3 +619,14 @@
pcie_create_device_bdf_table();
pcie_print_device_info();
}
+
+void pcie_init(void)
+{
+ static bool is_init;
+
+ /* Create PCIe table and enumeration */
+ if (!is_init) {
+ pcie_create_info_table();
+ is_init = true;
+ }
+}
diff --git a/lib/pcie/pcie_doe.c b/lib/pcie/pcie_doe.c
index 3c6819c..bd8e53a 100644
--- a/lib/pcie/pcie_doe.c
+++ b/lib/pcie/pcie_doe.c
@@ -5,7 +5,9 @@
*
*/
+#include <assert.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@@ -14,12 +16,6 @@
#include <pcie_doe.h>
#include <tftf_lib.h>
-#if LOG_LEVEL >= LOG_LEVEL_INFO
-#define DOE_INFO(...) mp_printf(__VA_ARGS__)
-#else
-#define DOE_INFO(...)
-#endif
-
static int pcie_doe_wait_ready(uint32_t bdf, uint32_t doe_cap_base)
{
uint32_t value;
@@ -65,9 +61,9 @@
INFO("Vendor ID: 0x%x, ", data->vendor_id);
if (type >= ARRAY_SIZE(doe_object_type)) {
- DOE_INFO("Unknown type: 0x%x\n", type);
+ INFO("Unknown type: 0x%x\n", type);
} else {
- DOE_INFO("%s\n", doe_object_type[type]);
+ INFO("%s\n", doe_object_type[type]);
}
}
@@ -77,16 +73,16 @@
if (last) {
if ((j & 7) == 0) {
- INFO(" %08x\n", data);
+ VERBOSE(" %08x\n", data);
} else {
- DOE_INFO(" %08x\n", data);
+ VERBOSE(" %08x\n", data);
}
} else if ((j & 7) == 0) {
- INFO(" %08x", data);
+ VERBOSE(" %08x", data);
} else if ((j & 7) == 7) {
- DOE_INFO(" %08x\n", data);
+ VERBOSE(" %08x\n", data);
} else {
- DOE_INFO(" %08x", data);
+ VERBOSE(" %08x", data);
}
}
@@ -121,11 +117,11 @@
/* Calculated adjusted data length in DW */
doe_length = (rem_length == 0) ? send_length : (send_length + 1);
- INFO(">%08x", header);
+ VERBOSE(">%08x", header);
pcie_write_cfg(bdf, doe_cap_base + DOE_WRITE_DATA_MAILBOX_REG,
header);
- DOE_INFO(" %08x", doe_length + DOE_HEADER_LENGTH);
+ VERBOSE(" %08x", doe_length + DOE_HEADER_LENGTH);
pcie_write_cfg(bdf, doe_cap_base + DOE_WRITE_DATA_MAILBOX_REG,
doe_length + DOE_HEADER_LENGTH);
@@ -144,7 +140,7 @@
pcie_write_cfg(bdf, doe_cap_base + DOE_WRITE_DATA_MAILBOX_REG, value);
} else if (((i + DOE_HEADER_LENGTH) & 7) != 0) {
- DOE_INFO("\n");
+ VERBOSE("\n");
}
/* Set Go bit */
@@ -178,7 +174,7 @@
* Vendor ID and Data Object Type
*/
value = pcie_read_cfg(bdf, doe_cap_base + DOE_READ_DATA_MAILBOX_REG);
- INFO("<%08x", value);
+ VERBOSE("<%08x", value);
/* Indicate a successful transfer of the current data object DW */
pcie_write_cfg(bdf, doe_cap_base + DOE_READ_DATA_MAILBOX_REG, 0);
@@ -188,13 +184,13 @@
* Length in DW
*/
value = pcie_read_cfg(bdf, doe_cap_base + DOE_READ_DATA_MAILBOX_REG);
- DOE_INFO(" %08x", value);
+ VERBOSE(" %08x", value);
pcie_write_cfg(bdf, doe_cap_base + DOE_READ_DATA_MAILBOX_REG, 0);
/* Check value */
if ((value & PCI_DOE_RESERVED_MASK) != 0) {
- DOE_INFO("\n");
+ VERBOSE("\n");
ERROR("DOE Data Object Header 2 error\n");
return -EIO;
}
@@ -214,7 +210,7 @@
}
if (((i + DOE_HEADER_LENGTH) & 7) != 0) {
- DOE_INFO("\n");
+ VERBOSE("\n");
}
value = pcie_read_cfg(bdf, doe_cap_base + DOE_STATUS_REG);
@@ -225,3 +221,55 @@
return 0;
}
+
+int pcie_doe_communicate(uint32_t header, uint32_t bdf, uint32_t doe_cap_base,
+ void *req_buf, size_t req_sz, void *rsp_buf, size_t *rsp_sz)
+{
+ int rc;
+
+ assert(header == DOE_HEADER_0 || header == DOE_HEADER_1 || header == DOE_HEADER_2);
+
+ rc = pcie_doe_send_req(header, bdf, doe_cap_base,
+ (uint32_t *)req_buf, (uint32_t)req_sz);
+ if (rc != 0) {
+ ERROR("PCIe DOE %s failed %d\n", "Request", rc);
+ return rc;
+ }
+
+ rc = pcie_doe_recv_resp(bdf, doe_cap_base, (uint32_t *)rsp_buf,
+ (uint32_t *)rsp_sz);
+ return rc;
+}
+
+int pcie_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;
+}