feat(pcie): add PCIe DOE library

This patch adds PCIe DOE library source files.

Change-Id: Ic2ab11afa0438d74c53cb157a63caada7457d77e
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
diff --git a/include/lib/pcie/pcie.h b/include/lib/pcie/pcie.h
new file mode 100644
index 0000000..aa3911f
--- /dev/null
+++ b/include/lib/pcie/pcie.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PCIE_H
+#define PCIE_H
+
+#include <cdefs.h>
+#include <stdint.h>
+#include <utils_def.h>
+
+typedef struct {
+	unsigned long ecam_base;	/* ECAM base address */
+	unsigned int segment_num;	/* Segment number of this ECAM */
+	unsigned int start_bus_num;	/* Start bus number for this ECAM space */
+	unsigned int end_bus_num;	/* Last bus number */
+} pcie_info_block_t;
+
+typedef struct {
+	unsigned int num_entries;	/* Number of entries */
+	pcie_info_block_t block[];
+} pcie_info_table_t;
+
+typedef struct {
+	uint32_t bdf;
+	uint32_t rp_bdf;
+} pcie_device_attr_t;
+
+typedef struct __packed {
+	uint32_t num_entries;
+	pcie_device_attr_t device[]; /* in the format of Segment/Bus/Dev/Func */
+} pcie_device_bdf_table_t;
+
+/* Address initialisation structure */
+typedef struct {
+	/* 64 bit prefetchable memory start address */
+	uint64_t bar64_p_start;
+	uint64_t rp_bar64_value;
+	/* 32 bit non-prefetchable memory start address */
+	uint32_t bar32_np_start;
+	/* 32 bit prefetchable memory start address */
+	uint32_t bar32_p_start;
+	uint32_t rp_bar32_value;
+} pcie_bar_init_t;
+
+#define PCIE_EXTRACT_BDF_SEG(bdf)	((bdf >> 24) & 0xFF)
+#define PCIE_EXTRACT_BDF_BUS(bdf)	((bdf >> 16) & 0xFF)
+#define PCIE_EXTRACT_BDF_DEV(bdf)	((bdf >> 8) & 0xFF)
+#define PCIE_EXTRACT_BDF_FUNC(bdf)	(bdf & 0xFF)
+
+/* PCI-compatible region */
+#define PCI_CMP_CFG_SIZE	256
+
+/* PCI Express Extended Configuration Space */
+#define PCIE_CFG_SIZE		4096
+
+#define PCIE_MAX_BUS		256
+#define PCIE_MAX_DEV		32
+#define PCIE_MAX_FUNC		8
+
+#define PCIE_CREATE_BDF(Seg, Bus, Dev, Func)	\
+			((Seg << 24) | (Bus << 16) | (Dev << 8) | Func)
+
+#define PCIE_SUCCESS		0x00000000  /* Operation completed successfully */
+#define PCIE_NO_MAPPING		0x10000001  /* A mapping to a Function does not exist */
+#define PCIE_CAP_NOT_FOUND	0x10000010  /* The specified capability was not found */
+#define PCIE_UNKNOWN_RESPONSE	0xFFFFFFFF  /* Function not found or UR response from completer */
+
+/* Allows storage of 2048 valid BDFs */
+#define PCIE_DEVICE_BDF_TABLE_SZ	8192
+
+typedef enum {
+	HEADER = 0,
+	PCIE_CAP = 1,
+	PCIE_ECAP = 2
+} bitfield_reg_type_t;
+
+typedef enum {
+	HW_INIT = 0,
+	READ_ONLY = 1,
+	STICKY_RO = 2,
+	RSVDP_RO = 3,
+	RSVDZ_RO = 4,
+	READ_WRITE = 5,
+	STICKY_RW = 6
+} bitfield_attr_type_t;
+
+/* Class Code Masks */
+#define CC_SUB_MASK	0xFF	/* Sub Class */
+#define CC_BASE_MASK	0xFF	/* Base Class */
+
+/* Class Code Shifts */
+#define CC_SHIFT	8
+#define CC_SUB_SHIFT	16
+#define CC_BASE_SHIFT	24
+
+void pcie_create_info_table(void);
+pcie_device_bdf_table_t *pcie_get_bdf_table(void);
+uint32_t pcie_find_capability(uint32_t bdf, uint32_t cid_type, uint32_t cid,
+				uint32_t *cid_offset);
+uint32_t pcie_read_cfg(uint32_t bdf, uint32_t offset);
+void pcie_write_cfg(uint32_t bdf, uint32_t offset, uint32_t data);
+
+#endif /* PCIE_H */
diff --git a/include/lib/pcie/pcie_doe.h b/include/lib/pcie/pcie_doe.h
new file mode 100644
index 0000000..4e12afd
--- /dev/null
+++ b/include/lib/pcie/pcie_doe.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2024, Arm Limited or its affiliates. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PCIE_DOE_H
+#define PCIE_DOE_H
+
+/* DOE Extended Capability */
+#define DOE_CAP_ID			0x002E
+
+#define DOE_CAP_REG			0x4
+#define DOE_CTRL_REG			0x8
+#define DOE_STATUS_REG			0xC
+#define DOE_WRITE_DATA_MAILBOX_REG	0x10
+#define DOE_READ_DATA_MAILBOX_REG	0x14
+
+#define DOE_CTRL_ABORT_BIT		(1 << 0)
+#define DOE_CTRL_GO_BIT			(1 << 31)
+
+#define DOE_STATUS_BUSY_BIT		(1 << 0)
+#define DOE_STATUS_ERROR_BIT		(1 << 2)
+#define DOE_STATUS_READY_BIT		(1 << 31)
+
+/* Time intervals in ms */
+#define PCI_DOE_TIMEOUT			1000
+#define PCI_DOE_POLL_TIME		10
+
+#define PCI_DOE_POLL_LOOP		(PCI_DOE_TIMEOUT / PCI_DOE_POLL_TIME)
+
+/* DOE Data Object Header 2 Reserved field [31:18] */
+#define PCI_DOE_RESERVED_SHIFT		18
+#define PCI_DOE_RESERVED_MASK		0xFFFC0000
+
+/* Max data object length is 2^18 DW */
+#define PCI_DOE_MAX_LENGTH		(1 << PCI_DOE_RESERVED_SHIFT)
+
+/* SPDM GET_VERSION response DW length */
+#define SPDM_GET_VERS_RESP_LEN						\
+	((sizeof(spdm_version_response_t) +				\
+	(sizeof(spdm_version_number_t) * SPDM_MAX_VERSION_COUNT) +	\
+	(sizeof(uint32_t) - 1)) << 2)
+
+/* PCI-SIG Vendor ID */
+#define PSI_SIG_VENDOR_ID	1
+
+/* Data Object Protocols */
+#define DOE_DISC_PROTOCOL	0
+#define CMA_SPDM_PROTOCOL	1
+#define SEC_CMA_SPDM_PROTOCOL	2
+
+#define DOE_HEADER(_type)	((_type << 16) | PSI_SIG_VENDOR_ID)
+
+#define DOE_HEADER_0		DOE_HEADER(DOE_DISC_PROTOCOL)
+#define DOE_HEADER_1		DOE_HEADER(CMA_SPDM_PROTOCOL)
+#define DOE_HEADER_2		DOE_HEADER(SEC_CMA_SPDM_PROTOCOL)
+#define DOE_HEADER_LENGTH	2
+
+/*
+ * SPDM VERSION structure:
+ * bit[15:12] major_version
+ * bit[11:8]  minor_version
+ * bit[7:4]   update_version_number
+ * bit[3:0]   alpha
+ */
+#define SPDM_VER_MAJOR_SHIFT	12
+#define SPDM_VER_MAJOR_WIDTH	4
+#define SPDM_VER_MINOR_SHIFT	8
+#define SPDM_VER_MINOR_WIDTH	4
+#define SPDM_VER_UPDATE_SHIFT	4
+#define SPDM_VER_UPDATE_WIDTH	4
+#define SPDM_VER_ALPHA_SHIFT	0
+#define SPDM_VER_ALPHA_WIDTH	4
+
+/* DOE Discovery */
+typedef struct {
+	uint8_t index;
+	uint8_t reserved[3];
+} pcie_doe_disc_req_t;
+
+typedef struct {
+	uint16_t vendor_id;
+	uint8_t data_object_type;
+	uint8_t next_index;
+} pcie_doe_disc_resp_t;
+
+void print_doe_disc(pcie_doe_disc_resp_t *data);
+int pcie_doe_send_req(uint32_t header, uint32_t bdf, uint32_t doe_cap_base,
+			uint32_t *req_addr, uint32_t req_len);
+int pcie_doe_recv_resp(uint32_t bdf, uint32_t doe_cap_base,
+			uint32_t *resp_addr, uint32_t *resp_len);
+
+#endif /* PCIE_DOE_H */
diff --git a/include/lib/pcie/pcie_spec.h b/include/lib/pcie/pcie_spec.h
new file mode 100644
index 0000000..31fd98b
--- /dev/null
+++ b/include/lib/pcie/pcie_spec.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2024, Arm Limited or its affiliates. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PCIE_SPEC_H
+#define PCIE_SPEC_H
+
+/* Header Type */
+#define TYPE0_HEADER		0
+#define TYPE1_HEADER		1
+
+/* TYPE 0/1 Cmn Cfg reg offsets */
+#define TYPE01_VIDR		0x0
+#define TYPE01_CR		0x4
+#define TYPE01_RIDR		0x8
+#define TYPE01_CLSR		0xc
+#define TYPE01_BAR		0x10
+#define TYPE01_CPR		0x34
+#define TYPE01_ILR		0x3c
+
+/* TYPE 0/1 Cmn Cfg reg shifts and masks */
+#define TYPE01_VIDR_SHIFT	0
+#define TYPE01_VIDR_MASK	0xffff
+#define TYPE01_DIDR_SHIFT	16
+#define TYPE01_DIDR_MASK	0xffff
+#define TYPE01_CCR_SHIFT	8
+#define TYPE01_CCR_MASK		0xffffff
+#define TYPE01_CPR_SHIFT	0
+#define TYPE01_CPR_MASK		0xff
+#define TYPE01_HTR_SHIFT	16
+#define TYPE01_HTR_MASK		0xff
+#define TYPE01_IPR_SHIFT	8
+#define TYPE01_IPR_MASK		0xFF
+#define TYPE01_ILR_SHIFT	0
+#define TYPE01_ILR_MASK		0xFF
+#define TYPE01_BCC_SHIFT	24
+
+#define HB_BASE_CLASS		0x06
+#define HB_SUB_CLASS		0x00
+
+/* Header type reg shifts and masks */
+#define HTR_HL_SHIFT		0x0
+#define HTR_HL_MASK		0x7f
+#define HTR_MFD_SHIFT		7
+#define HTR_MFD_MASK		0x1
+
+/* BAR offset */
+#define BAR0_OFFSET		0x10
+#define BAR_TYPE_0_MAX_OFFSET	0x24
+#define BAR_TYPE_1_MAX_OFFSET	0x14
+#define BAR_NP_TYPE		0x0
+#define BAR_P_TYPE		0x1
+#define BAR_64_BIT		0x1
+#define BAR_32_BIT		0x0
+#define BAR_REG(bar_reg_value)	((bar_reg_value >> 2) & 0x1)
+
+/* Type 1 Cfg reg offsets */
+#define TYPE1_PBN		0x18
+#define TYPE1_SEC_STA		0x1C
+#define TYPE1_NP_MEM		0x20
+#define TYPE1_P_MEM		0x24
+#define TYPE1_P_MEM_BU		0x28	/* Prefetchable Base Upper Offset */
+#define TYPE1_P_MEM_LU		0x2C	/* Prefetchable Limit Upper Offset */
+
+/* Bus Number reg shifts */
+#define SECBN_SHIFT		8
+#define SUBBN_SHIFT		16
+
+/* Bus Number reg masks */
+#define PRIBN_MASK		0xff
+#define SECBN_MASK		0xff
+#define SUBBN_MASK		0xff
+#define SECBN_EXTRACT		0xffff00ff
+
+/* Capability header reg shifts */
+#define PCIE_CIDR_SHIFT		0
+#define PCIE_NCPR_SHIFT		8
+#define PCIE_ECAP_CIDR_SHIFT	0
+#define PCIE_ECAP_NCPR_SHIFT	20
+
+/* Capability header reg masks */
+#define PCIE_CIDR_MASK		0xff
+#define PCIE_NCPR_MASK		0xff
+#define PCIE_ECAP_CIDR_MASK	0xffff
+#define PCIE_ECAP_NCPR_MASK	0xfff
+
+#define PCIE_CAP_START		0x40
+#define PCIE_CAP_END		0xFC
+#define PCIE_ECAP_START		0x100
+#define PCIE_ECAP_END		0xFFC
+
+/* Capability Structure IDs */
+#define CID_PCIECS		0x10
+#define CID_MSI			0x05
+#define CID_MSIX		0x11
+#define CID_PMC			0x01
+#define CID_EA			0x14
+#define ECID_AER		0x0001
+#define ECID_RCECEA		0x0007
+#define ECID_ACS		0x000D
+#define ECID_ARICS		0x000E
+#define ECID_ATS		0x000F
+#define ECID_PRI		0x0013
+#define ECID_PASID		0x001B
+#define ECID_DPC		0x001D
+#define ECID_DVSEC		0x0023
+
+/* PCI Express capability struct offsets */
+#define CIDR_OFFSET		0x0
+#define PCIECR_OFFSET		0x2
+#define DCAPR_OFFSET		0x4
+#define ACSCR_OFFSET		0x4
+#define DCTLR_OFFSET		0x8
+#define LCAPR_OFFSET		0xC
+#define LCTRLR_OFFSET		0x10
+#define DCAP2R_OFFSET		0x24
+#define DCTL2R_OFFSET		0x28
+#define DCTL2R_MASK		0xFFFF
+#define LCAP2R_OFFSET		0x2C
+#define LCTL2R_OFFSET		0x30
+#define DCTL2R_MASK		0xFFFF
+#define DSTS_SHIFT		16
+#define DS_UNCORR_MASK		0x6
+#define DS_CORR_MASK		0x1
+
+/* PCIe capabilities reg shifts and masks */
+#define PCIECR_DPT_SHIFT	4
+#define PCIECR_DPT_MASK		0xf
+
+/* Device bitmask definitions */
+#define RCiEP			(1 << 0b1001)
+#define RCEC			(1 << 0b1010)
+#define EP			(1 << 0b0000)
+#define RP			(1 << 0b0100)
+#define UP			(1 << 0b0101)
+#define DP			(1 << 0b0110)
+#define iEP_EP			(1 << 0b1100)
+#define iEP_RP			(1 << 0b1011)
+#define PCI_PCIE		(1 << 0b1000)
+#define PCIE_PCI		(1 << 0b0111)
+#define PCIe_ALL		(iEP_RP | iEP_EP | RP | EP | RCEC | RCiEP)
+
+#endif /* PCIE_SPEC_H */