/** @file\r
SSDT Pcie Table Generator.\r
\r
- Copyright (c) 2021, Arm Limited. All rights reserved.<BR>\r
+ Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
- s6.1.1 "_ADR (Address)"\r
- linux kernel code\r
- Arm Base Boot Requirements v1.0\r
+ - Arm Base System Architecture v1.0\r
**/\r
\r
#include <Library/AcpiLib.h>\r
#include <Library/AcpiHelperLib.h>\r
#include <Library/TableHelperLib.h>\r
#include <Library/AmlLib/AmlLib.h>\r
+#include <Library/SsdtPcieSupportLib.h>\r
#include <Protocol/ConfigurationManagerProtocol.h>\r
\r
#include "SsdtPcieGenerator.h"\r
\r
+#define PCI_MAX_DEVICE_COUNT_PER_BUS 32\r
+#define PCI_MAX_FUNCTION_COUNT_PER_DEVICE 8\r
+\r
/** ARM standard SSDT Pcie Table Generator.\r
\r
Requirements:\r
return Status;\r
}\r
\r
-/** Generate a Link device.\r
-\r
- The Link device is added at the beginning of the ASL Pci device definition.\r
-\r
- Each Link device represents a Pci legacy interrupt (INTA-...-INTD).\r
-\r
- ASL code:\r
- Device (<Link Name>) {\r
- Name (_UID, <Uid>])\r
- Name (_HID, EISAID ("PNP0C0F"))\r
- Name (CRS0, ResourceTemplate () {\r
- Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { <Irq>] }\r
- })\r
- Method (_CRS, 0) {\r
- Return CRS0\r
- })\r
- Method (_DIS) { }\r
- }\r
-\r
- The list of objects to define is available at:\r
- PCI Firmware Specification - Revision 3.3,\r
- s3.5. "Device State at Firmware/Operating System Handoff"\r
-\r
- The _PRS and _SRS are not supported, cf Arm Base Boot Requirements v1.0:\r
- "The _PRS (Possible Resource Settings) and _SRS (Set Resource Settings)\r
- are not supported."\r
-\r
- @param [in] Irq Interrupt controller interrupt.\r
- @param [in] IrqFlags Interrupt flags.\r
- @param [in] LinkIndex Legacy Pci interrupt index.\r
- Must be between 0-INTA and 3-INTD.\r
- @param [in, out] PciNode Pci node to amend.\r
-\r
- @retval EFI_SUCCESS Success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-GenerateLinkDevice (\r
- IN UINT32 Irq,\r
- IN UINT32 IrqFlags,\r
- IN UINT32 LinkIndex,\r
- IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
- AML_OBJECT_NODE_HANDLE LinkNode;\r
- AML_OBJECT_NODE_HANDLE CrsNode;\r
- UINT32 EisaId;\r
-\r
- ASSERT (LinkIndex < 4);\r
- ASSERT (PciNode != NULL);\r
-\r
- CopyMem (AslName, "LNKx", AML_NAME_SEG_SIZE + 1);\r
- AslName[AML_NAME_SEG_SIZE - 1] = 'A' + LinkIndex;\r
-\r
- // ASL: Device (LNKx) {}\r
- Status = AmlCodeGenDevice (AslName, NULL, &LinkNode);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- Status = AmlAttachNode (PciNode, LinkNode);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- // Failed to add.\r
- AmlDeleteTree ((AML_NODE_HANDLE)LinkNode);\r
- return Status;\r
- }\r
-\r
- // ASL: Name (_UID, <Uid>)\r
- Status = AmlCodeGenNameInteger ("_UID", LinkIndex, LinkNode, NULL);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // ASL: Name (_HID, EISAID ("PNP0C0F"))\r
- Status = AmlGetEisaIdFromString ("PNP0C0F", &EisaId);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- Status = AmlCodeGenNameInteger ("_HID", EisaId, LinkNode, NULL);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // ASL:\r
- // Name (CRS0, ResourceTemplate () {\r
- // Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { <Irq> }\r
- // })\r
- Status = AmlCodeGenNameResourceTemplate ("CRS0", LinkNode, &CrsNode);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- Status = AmlCodeGenRdInterrupt (\r
- FALSE,\r
- (IrqFlags & BIT0) != 0,\r
- (IrqFlags & BIT1) != 0,\r
- FALSE,\r
- &Irq,\r
- 1,\r
- CrsNode,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // ASL:\r
- // Method (_CRS, 0) {\r
- // Return (CRS0)\r
- // }\r
- Status = AmlCodeGenMethodRetNameString (\r
- "_CRS",\r
- "CRS0",\r
- 0,\r
- FALSE,\r
- 0,\r
- LinkNode,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // ASL:Method (_DIS, 1) {}\r
- // Not possible to disable interrupts.\r
- Status = AmlCodeGenMethodRetNameString (\r
- "_DIS",\r
- NULL,\r
- 0,\r
- FALSE,\r
- 0,\r
- LinkNode,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // _STA:\r
- // ACPI 6.4, s6.3.7 "_STA (Device Status)":\r
- // If a device object describes a device that is not on an enumerable bus\r
- // and the device object does not have an _STA object, then OSPM assumes\r
- // that the device is present, enabled, shown in the UI, and functioning.\r
-\r
- // _MAT:\r
- // Not supported. Mainly used for processors.\r
-\r
- return Status;\r
-}\r
-\r
-/** Generate Pci slots devices.\r
-\r
- PCI Firmware Specification - Revision 3.3,\r
- s4.8 "Generic ACPI PCI Slot Description" requests to describe the PCI slot\r
- used. It should be possible to enumerate them, but this is additional\r
- information.\r
-\r
- @param [in] MappingTable The mapping table structure.\r
- @param [in, out] PciNode Pci node to amend.\r
-\r
- @retval EFI_SUCCESS Success.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-GeneratePciSlots (\r
- IN CONST MAPPING_TABLE *MappingTable,\r
- IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT32 LastIndex;\r
- UINT32 DeviceId;\r
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
- AML_OBJECT_NODE_HANDLE DeviceNode;\r
-\r
- ASSERT (MappingTable != NULL);\r
- ASSERT (PciNode != NULL);\r
-\r
- // Generic device name is "Dxx".\r
- CopyMem (AslName, "Dxx_", AML_NAME_SEG_SIZE + 1);\r
-\r
- LastIndex = MappingTable->LastIndex;\r
-\r
- // There are at most 32 devices on a Pci bus.\r
- if (LastIndex >= 32) {\r
- ASSERT (0);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- for (Index = 0; Index < LastIndex; Index++) {\r
- DeviceId = MappingTable->Table[Index];\r
- AslName[AML_NAME_SEG_SIZE - 3] = AsciiFromHex (DeviceId & 0xF);\r
- AslName[AML_NAME_SEG_SIZE - 2] = AsciiFromHex ((DeviceId >> 4) & 0xF);\r
-\r
- // ASL:\r
- // Device (Dxx) {\r
- // Name (_ADR, <address value>)\r
- // }\r
- Status = AmlCodeGenDevice (AslName, PciNode, &DeviceNode);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- /* ACPI 6.4 specification, Table 6.2: "ADR Object Address Encodings"\r
- High word-Device #, Low word-Function #. (for example, device 3,\r
- function 2 is 0x00030002). To refer to all the functions on a device #,\r
- use a function number of FFFF).\r
- */\r
- Status = AmlCodeGenNameInteger (\r
- "_ADR",\r
- (DeviceId << 16) | 0xFFFF,\r
- DeviceNode,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
- // _SUN object is not generated as we don't know which slot will be used.\r
- }\r
-\r
- return Status;\r
-}\r
-\r
/** Generate a _PRT object (Pci Routing Table) for the Pci device.\r
\r
Cf. ACPI 6.4 specification, s6.2.13 "_PRT (PCI Routing Table)"\r
@param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
Protocol interface.\r
@param [in] PciInfo Pci device information.\r
+ @param [in] Uid Unique Id of the Pci device.\r
@param [in, out] PciNode Pci node to amend.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
IN ACPI_PCI_GENERATOR *Generator,\r
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
+ IN UINT32 Uid,\r
IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
)\r
{\r
EFI_STATUS Status;\r
INT32 Index;\r
- UINT32 IrqTableIndex;\r
AML_OBJECT_NODE_HANDLE PrtNode;\r
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];\r
CM_ARM_OBJ_REF *RefInfo;\r
UINT32 RefCount;\r
CM_ARM_PCI_INTERRUPT_MAP_INFO *IrqMapInfo;\r
- UINT32 IrqFlags;\r
- UINT32 PrevIrqFlags;\r
\r
ASSERT (Generator != NULL);\r
ASSERT (CfgMgrProtocol != NULL);\r
return Status;\r
}\r
\r
- // Initialized IrqTable.\r
- Status = MappingTableInitialize (&Generator->IrqTable, RefCount);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- return Status;\r
- }\r
-\r
// Initialized DeviceTable.\r
Status = MappingTableInitialize (&Generator->DeviceTable, RefCount);\r
if (EFI_ERROR (Status)) {\r
goto exit_handler;\r
}\r
\r
- CopyMem (AslName, "LNKx", AML_NAME_SEG_SIZE + 1);\r
-\r
for (Index = 0; Index < RefCount; Index++) {\r
// Get CM_ARM_PCI_INTERRUPT_MAP_INFO structures one by one.\r
Status = GetEArmObjPciInterruptMapInfo (\r
goto exit_handler;\r
}\r
\r
- // Add the interrupt in the IrqTable and get the link name.\r
- IrqTableIndex = MappingTableAdd (\r
- &Generator->IrqTable,\r
- IrqMapInfo->IntcInterrupt.Interrupt\r
- );\r
- if (IrqTableIndex >= MAX_PCI_LEGACY_INTERRUPT) {\r
- ASSERT (0);\r
- Status = EFI_INVALID_PARAMETER;\r
- goto exit_handler;\r
- }\r
-\r
- AslName[AML_NAME_SEG_SIZE - 1] = 'A' + IrqTableIndex;\r
-\r
- // Check that the interrupts flags are identical for all interrupts.\r
- PrevIrqFlags = IrqFlags;\r
- IrqFlags = IrqMapInfo->IntcInterrupt.Flags;\r
- if ((Index > 0) && (PrevIrqFlags != IrqFlags)) {\r
- ASSERT (0);\r
+ // Check that the interrupts flags are SPIs, level high.\r
+ // Cf. Arm BSA v1.0, sE.6 "Legacy interrupts"\r
+ if ((Index > 0) &&\r
+ (IrqMapInfo->IntcInterrupt.Interrupt >= 32) &&\r
+ (IrqMapInfo->IntcInterrupt.Interrupt < 1020) &&\r
+ ((IrqMapInfo->IntcInterrupt.Flags & 0xB) != 0))\r
+ {\r
Status = EFI_INVALID_PARAMETER;\r
+ ASSERT_EFI_ERROR (Status);\r
goto exit_handler;\r
}\r
\r
Status = AmlAddPrtEntry (\r
(IrqMapInfo->PciDevice << 16) | 0xFFFF,\r
IrqMapInfo->PciInterrupt,\r
- AslName,\r
- 0,\r
+ NULL,\r
+ IrqMapInfo->IntcInterrupt.Interrupt,\r
PrtNode\r
);\r
if (EFI_ERROR (Status)) {\r
}\r
} // for\r
\r
- // Generate the LNKx devices now that we know all the interrupts used.\r
- for (Index = 0; Index < Generator->IrqTable.LastIndex; Index++) {\r
- Status = GenerateLinkDevice (\r
- Generator->IrqTable.Table[Index],\r
- IrqFlags,\r
- Index,\r
- PciNode\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
- goto exit_handler;\r
- }\r
- } // for\r
-\r
- // Attach the _PRT entry now, after the LNKx devices.\r
+ // Attach the _PRT entry.\r
Status = AmlAttachNode (PciNode, PrtNode);\r
if (EFI_ERROR (Status)) {\r
- ASSERT (0);\r
+ ASSERT_EFI_ERROR (Status);\r
goto exit_handler;\r
}\r
\r
PrtNode = NULL;\r
\r
// Generate the Pci slots once all the device have been added.\r
- Status = GeneratePciSlots (&Generator->DeviceTable, PciNode);\r
+ Status = GeneratePciSlots (PciInfo, &Generator->DeviceTable, Uid, PciNode);\r
if (EFI_ERROR (Status)) {\r
ASSERT (0);\r
goto exit_handler;\r
exit_handler:\r
MappingTableFree (&Generator->DeviceTable);\r
exit_handler0:\r
- MappingTableFree (&Generator->IrqTable);\r
if (PrtNode != NULL) {\r
AmlDeleteTree (PrtNode);\r
}\r
UINT32 RefCount;\r
CM_ARM_PCI_ADDRESS_MAP_INFO *AddrMapInfo;\r
AML_OBJECT_NODE_HANDLE CrsNode;\r
+ BOOLEAN IsPosDecode;\r
\r
ASSERT (Generator != NULL);\r
ASSERT (CfgMgrProtocol != NULL);\r
}\r
\r
Translation = (AddrMapInfo->CpuAddress != AddrMapInfo->PciAddress);\r
+ if (AddrMapInfo->CpuAddress >= AddrMapInfo->PciAddress) {\r
+ IsPosDecode = TRUE;\r
+ } else {\r
+ IsPosDecode = FALSE;\r
+ }\r
\r
switch (AddrMapInfo->SpaceCode) {\r
case PCI_SS_IO:\r
FALSE,\r
TRUE,\r
TRUE,\r
- TRUE,\r
+ IsPosDecode,\r
3,\r
0,\r
AddrMapInfo->PciAddress,\r
AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
- Translation ? AddrMapInfo->CpuAddress : 0,\r
+ Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
AddrMapInfo->AddressSize,\r
0,\r
NULL,\r
case PCI_SS_M32:\r
Status = AmlCodeGenRdDWordMemory (\r
FALSE,\r
- TRUE,\r
+ IsPosDecode,\r
TRUE,\r
TRUE,\r
TRUE,\r
0,\r
AddrMapInfo->PciAddress,\r
AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
- Translation ? AddrMapInfo->CpuAddress : 0,\r
+ Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
AddrMapInfo->AddressSize,\r
0,\r
NULL,\r
case PCI_SS_M64:\r
Status = AmlCodeGenRdQWordMemory (\r
FALSE,\r
- TRUE,\r
+ IsPosDecode,\r
TRUE,\r
TRUE,\r
TRUE,\r
0,\r
AddrMapInfo->PciAddress,\r
AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,\r
- Translation ? AddrMapInfo->CpuAddress : 0,\r
+ Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,\r
AddrMapInfo->AddressSize,\r
0,\r
NULL,\r
return Status;\r
}\r
\r
-/** Add an _OSC template method to the PciNode.\r
-\r
- The _OSC method is provided as an AML blob. The blob is\r
- parsed and attached at the end of the PciNode list of variable elements.\r
+/** Generate a RES0 device node to reserve PNP motherboard resources\r
+ for a given PCI node.\r
\r
- @param [in, out] PciNode Pci node to amend.\r
+ @param [in] PciNode Parent PCI node handle of the generated\r
+ resource object.\r
+ @param [out] CrsNode CRS node of the AML tree to populate.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_INVALID_PARAMETER Invalid input parameter.\r
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
**/\r
STATIC\r
EFI_STATUS\r
EFIAPI\r
-AddOscMethod (\r
- IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
+GenerateMotherboardDevice (\r
+ IN AML_OBJECT_NODE_HANDLE PciNode,\r
+ OUT AML_OBJECT_NODE_HANDLE *CrsNode\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_STATUS Status1;\r
- EFI_ACPI_DESCRIPTION_HEADER *SsdtPcieOscTemplate;\r
- AML_ROOT_NODE_HANDLE OscTemplateRoot;\r
- AML_OBJECT_NODE_HANDLE OscNode;\r
+ EFI_STATUS Status;\r
+ UINT32 EisaId;\r
+ AML_OBJECT_NODE_HANDLE ResNode;\r
\r
- ASSERT (PciNode != NULL);\r
+ if (CrsNode == NULL) {\r
+ ASSERT (0);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- // Parse the Ssdt Pci Osc Template.\r
- SsdtPcieOscTemplate = (EFI_ACPI_DESCRIPTION_HEADER *)\r
- ssdtpcieosctemplate_aml_code;\r
+ // ASL: Device (RES0) {}\r
+ Status = AmlCodeGenDevice ("RES0", PciNode, &ResNode);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ return Status;\r
+ }\r
\r
- OscNode = NULL;\r
- OscTemplateRoot = NULL;\r
- Status = AmlParseDefinitionBlock (\r
- SsdtPcieOscTemplate,\r
- &OscTemplateRoot\r
- );\r
+ // ASL: Name (_HID, EISAID ("PNP0C02"))\r
+ Status = AmlGetEisaIdFromString ("PNP0C02", &EisaId); /* PNP Motherboard Resources */\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((\r
- DEBUG_ERROR,\r
- "ERROR: SSDT-PCI-OSC: Failed to parse SSDT PCI OSC Template."\r
- " Status = %r\n",\r
- Status\r
- ));\r
+ ASSERT (0);\r
return Status;\r
}\r
\r
- Status = AmlFindNode (OscTemplateRoot, "\\_OSC", &OscNode);\r
+ Status = AmlCodeGenNameInteger ("_HID", EisaId, ResNode, NULL);\r
if (EFI_ERROR (Status)) {\r
- goto error_handler;\r
+ ASSERT (0);\r
+ return Status;\r
}\r
\r
- Status = AmlDetachNode (OscNode);\r
+ // ASL: Name (_CRS, ResourceTemplate () {})\r
+ Status = AmlCodeGenNameResourceTemplate ("_CRS", ResNode, CrsNode);\r
if (EFI_ERROR (Status)) {\r
- goto error_handler;\r
+ ASSERT (0);\r
+ return Status;\r
}\r
\r
- Status = AmlAttachNode (PciNode, OscNode);\r
+ return Status;\r
+}\r
+\r
+/** Reserves ECAM space for PCI config space\r
+\r
+ @param [in] Generator The SSDT Pci generator.\r
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
+ Protocol interface.\r
+ @param [in] PciInfo Pci device information.\r
+ @param [in, out] PciNode RootNode of the AML tree to populate.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ReserveEcamSpace (\r
+ IN ACPI_PCI_GENERATOR *Generator,\r
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
+ IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,\r
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ AML_OBJECT_NODE_HANDLE CrsNode;\r
+ UINT64 AddressMinimum;\r
+ UINT64 AddressMaximum;\r
+\r
+ Status = GenerateMotherboardDevice (PciNode, &CrsNode);\r
if (EFI_ERROR (Status)) {\r
- // Free the detached node.\r
- AmlDeleteTree (OscNode);\r
- goto error_handler;\r
+ ASSERT (0);\r
+ return Status;\r
}\r
\r
-error_handler:\r
- // Cleanup\r
- Status1 = AmlDeleteTree (OscTemplateRoot);\r
- if (EFI_ERROR (Status1)) {\r
- DEBUG ((\r
- DEBUG_ERROR,\r
- "ERROR: SSDT-PCI-OSC: Failed to cleanup AML tree."\r
- " Status = %r\n",\r
- Status1\r
- ));\r
- // If Status was success but we failed to delete the AML Tree\r
- // return Status1 else return the original error code, i.e. Status.\r
- if (!EFI_ERROR (Status)) {\r
- return Status1;\r
- }\r
+ AddressMinimum = PciInfo->BaseAddress + (PciInfo->StartBusNumber *\r
+ PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB);\r
+ AddressMaximum = PciInfo->BaseAddress + ((PciInfo->EndBusNumber + 1) *\r
+ PCI_MAX_DEVICE_COUNT_PER_BUS * PCI_MAX_FUNCTION_COUNT_PER_DEVICE * SIZE_4KB) - 1;\r
+\r
+ Status = AmlCodeGenRdQWordMemory (\r
+ FALSE,\r
+ TRUE,\r
+ TRUE,\r
+ TRUE,\r
+ FALSE, // non-cacheable\r
+ TRUE,\r
+ 0,\r
+ AddressMinimum,\r
+ AddressMaximum,\r
+ 0, // no translation\r
+ AddressMaximum - AddressMinimum + 1,\r
+ 0,\r
+ NULL,\r
+ 0,\r
+ TRUE,\r
+ CrsNode,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ return Status;\r
}\r
\r
return Status;\r
\r
// Write the name of the PCI device.\r
CopyMem (AslName, "PCIx", AML_NAME_SEG_SIZE + 1);\r
- AslName[AML_NAME_SEG_SIZE - 1] = AsciiFromHex (Uid);\r
+ AslName[AML_NAME_SEG_SIZE - 1] = AsciiFromHex (Uid & 0xF);\r
+ if (Uid > 0xF) {\r
+ AslName[AML_NAME_SEG_SIZE - 2] = AsciiFromHex ((Uid >> 4) & 0xF);\r
+ }\r
\r
// ASL: Device (PCIx) {}\r
Status = AmlCodeGenDevice (AslName, ScopeNode, &PciNode);\r
Generator,\r
CfgMgrProtocol,\r
PciInfo,\r
+ Uid,\r
PciNode\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ // Add the PNP Motherboard Resources Device to reserve ECAM space\r
+ Status = ReserveEcamSpace (Generator, CfgMgrProtocol, PciInfo, PciNode);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT (0);\r
+ return Status;\r
+ }\r
+\r
// Add the template _OSC method.\r
- Status = AddOscMethod (PciNode);\r
+ Status = AddOscMethod (PciInfo, PciNode);\r
ASSERT_EFI_ERROR (Status);\r
+\r
return Status;\r
}\r
\r
UINTN Index;\r
EFI_ACPI_DESCRIPTION_HEADER **TableList;\r
ACPI_PCI_GENERATOR *Generator;\r
+ UINT32 Uid;\r
\r
ASSERT (This != NULL);\r
ASSERT (AcpiTableInfo != NULL);\r
*Table = TableList;\r
\r
for (Index = 0; Index < PciCount; Index++) {\r
+ if (PcdGetBool (PcdPciUseSegmentAsUid)) {\r
+ Uid = PciInfo[Index].PciSegmentGroupNumber;\r
+ if (Uid > MAX_PCI_ROOT_COMPLEXES_SUPPORTED) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "ERROR: SSDT-PCI: Pci root complexes segment number: %d."\r
+ " Greater than maximum number of Pci root complexes supported = %d.\n",\r
+ Uid,\r
+ MAX_PCI_ROOT_COMPLEXES_SUPPORTED\r
+ ));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
+ Uid = Index;\r
+ }\r
+\r
// Build a SSDT table describing the Pci devices.\r
Status = BuildSsdtPciTable (\r
Generator,\r
CfgMgrProtocol,\r
AcpiTableInfo,\r
&PciInfo[Index],\r
- Index,\r
+ Uid,\r
&TableList[Index]\r
);\r
if (EFI_ERROR (Status)) {\r
\r
// Private fields are defined from here.\r
\r
- // IrqTable\r
- {\r
- // Table\r
- NULL,\r
- // LastIndex\r
- 0,\r
- // MaxIndex\r
- 0\r
- },\r
// DeviceTable\r
{\r
// Table\r