summaryrefslogtreecommitdiffstats
path: root/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h
diff options
context:
space:
mode:
Diffstat (limited to 'DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h')
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h
new file mode 100644
index 0000000000..6e0027abea
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h
@@ -0,0 +1,143 @@
+/** @file
+ Arm PCI Configuration Space Parser.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml
+ - PCI Firmware Specification - Revision 3.0
+ - Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9
+ - Devicetree Specification Release v0.3
+ - linux kernel code
+**/
+
+#ifndef ARM_PCI_CONFIG_SPACE_PARSER_H_
+#define ARM_PCI_CONFIG_SPACE_PARSER_H_
+
+/** Read LEN bits at OFF offsets bits of the ADDR.
+
+ @param [in] ADDR Address to read the bits from.
+ @param [in] OFF Offset of the bits to read.
+ @param [in] LEN Number of bits to read.
+
+ @return The bits read.
+**/
+#define READ_BITS(ADDR, OFF, LEN) (((ADDR) >> (OFF)) & ((1<<(LEN))-1))
+
+/* Pci address attributes.
+*/
+/// 0 if relocatable.
+#define READ_PCI_N(ADDR) READ_BITS((ADDR), 31, 1)
+/// 1 if prefetchable.
+#define READ_PCI_P(ADDR) READ_BITS((ADDR), 30, 1)
+/// 1 if aliased.
+#define READ_PCI_T(ADDR) READ_BITS((ADDR), 29, 1)
+
+/** Space code.
+
+ 00: Configuration Space
+ 01: I/O Space
+ 10: 32-bit-address Memory Space
+ 11: 64-bit-address Memory Space
+*/
+#define READ_PCI_SS(ADDR) READ_BITS((ADDR), 24, 2)
+/// Bus number.
+#define READ_PCI_BBBBBBBB(ADDR) READ_BITS((ADDR), 16, 8)
+/// Device number.
+#define READ_PCI_DDDDD(ADDR) READ_BITS((ADDR), 11, 5)
+
+/** Number of device-tree cells used for PCI nodes properties.
+
+ Values are well defined, except the "#interrupt-cells" which
+ is assumed to be 1.
+*/
+#define PCI_ADDRESS_CELLS 3U
+#define PCI_SIZE_CELLS 2U
+#define PCI_INTERRUPTS_CELLS 1U
+
+/** PCI interrupt flags for device-tree.
+
+ Local Bus Specification Revision 3.0, s2.2.6., Interrupt Pins:
+ - 'Interrupts on PCI are optional and defined as "level sensitive,"
+ asserted low (negative true)'
+*/
+#define DT_PCI_IRQ_FLAGS(x) (((x) & 0xF) == BIT0)
+
+/** Indexes in the mapping table.
+*/
+typedef enum PciMappingTable {
+ PciMappingTableAddress, ///< 0 - Address mapping
+ PciMappingTableInterrupt, ///< 1 - Interrupt mapping
+ PciMappingTableMax, ///< 2 - Max
+} PCI_MAPPING_TABLE;
+
+#pragma pack(1)
+
+/** PCI parser table
+
+ Multiple address-map and interrupt map can correspond to
+ one host-pci device. This structure allows to temporarily
+ store the CmObjects created and generate tokens once
+ the whole device tree is parsed.
+*/
+typedef struct PciParserTable {
+ /// PCI Configuration Space Info
+ CM_ARM_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo;
+
+ /// Store the address mapping and interrupt mapping as CmObjDesc
+ /// before adding them to the Configuration Manager.
+ CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax];
+} PCI_PARSER_TABLE;
+
+#pragma pack()
+
+/** CM_ARM_PCI_CONFIG_SPACE_INFO parser function.
+
+ The following structure is populated:
+ typedef struct CmArmPciConfigSpaceInfo {
+ UINT64 BaseAddress; // {Populated}
+ UINT16 PciSegmentGroupNumber; // {Populated}
+ UINT8 StartBusNumber; // {Populated}
+ UINT8 EndBusNumber; // {Populated}
+ } CM_ARM_PCI_CONFIG_SPACE_INFO;
+
+ typedef struct CmArmPciAddressMapInfo {
+ UINT8 SpaceCode; // {Populated}
+ UINT64 PciAddress; // {Populated}
+ UINT64 CpuAddress; // {Populated}
+ UINT64 AddressSize; // {Populated}
+ } CM_ARM_PCI_ADDRESS_MAP_INFO;
+
+ typedef struct CmArmPciInterruptMapInfo {
+ UINT8 PciBus; // {Populated}
+ UINT8 PciDevice; // {Populated}
+ UINT8 PciInterrupt; // {Populated}
+ CM_ARM_GENERIC_INTERRUPT IntcInterrupt; // {Populated}
+ } CM_ARM_PCI_INTERRUPT_MAP_INFO;
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+
+ @param [in] FdtParserHandle A handle to the parser instance.
+ @param [in] FdtBranch When searching for DT node name, restrict
+ the search to this Device Tree branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+ArmPciConfigInfoParser (
+ IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+ IN INT32 FdtBranch
+ );
+
+#endif // ARM_PCI_CONFIG_SPACE_PARSER_H_