\r
#include <IndustryStandard/Acpi10.h>\r
\r
+#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/DevicePathLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
// This structure is interpreted by the ApplyResourcePadding() function in the\r
// edk2 PCI Bus UEFI_DRIVER.\r
//\r
+// We can request padding for at most four resource types, each of which is\r
+// optional, independently of the others:\r
+// (a) bus numbers,\r
+// (b) IO space,\r
+// (c) non-prefetchable MMIO space (32-bit only),\r
+// (d) prefetchable MMIO space (either 32-bit or 64-bit, never both).\r
+//\r
#pragma pack (1)\r
typedef struct {\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR MmioPadding;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR IoPadding;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Padding[4];\r
EFI_ACPI_END_TAG_DESCRIPTOR EndDesc;\r
} RESOURCE_PADDING;\r
#pragma pack ()\r
\r
-STATIC CONST RESOURCE_PADDING mPadding = {\r
- //\r
- // MmioPadding\r
- //\r
- {\r
- ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc\r
- (UINT16)( // Len\r
- sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -\r
- OFFSET_OF (\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,\r
- ResType\r
- )\r
- ),\r
- ACPI_ADDRESS_SPACE_TYPE_MEM, // ResType\r
- 0, // GenFlag:\r
- // ignored\r
- 0, // SpecificFlag:\r
- // non-prefetchable\r
- 32, // AddrSpaceGranularity:\r
- // reserve 32-bit aperture\r
- 0, // AddrRangeMin:\r
- // ignored\r
- SIZE_2MB - 1, // AddrRangeMax:\r
- // align at 2MB\r
- 0, // AddrTranslationOffset:\r
- // ignored\r
- SIZE_2MB // AddrLen:\r
- // 2MB padding\r
- },\r
+\r
+/**\r
+ Initialize a RESOURCE_PADDING object.\r
+\r
+ @param[out] ResourcePadding The caller-allocated RESOURCE_PADDING object to\r
+ initialize.\r
+**/\r
+STATIC\r
+VOID\r
+InitializeResourcePadding (\r
+ OUT RESOURCE_PADDING *ResourcePadding\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ ZeroMem (ResourcePadding, sizeof *ResourcePadding);\r
\r
//\r
- // IoPadding\r
+ // Fill in the Padding fields that don't vary across resource types.\r
//\r
- {\r
- ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc\r
- (UINT16)( // Len\r
- sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -\r
- OFFSET_OF (\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,\r
- ResType\r
- )\r
- ),\r
- ACPI_ADDRESS_SPACE_TYPE_IO,// ResType\r
- 0, // GenFlag:\r
- // ignored\r
- 0, // SpecificFlag:\r
- // ignored\r
- 0, // AddrSpaceGranularity:\r
- // ignored\r
- 0, // AddrRangeMin:\r
- // ignored\r
- 512 - 1, // AddrRangeMax:\r
- // align at 512 IO ports\r
- 0, // AddrTranslationOffset:\r
- // ignored\r
- 512 // AddrLen:\r
- // 512 IO ports\r
- },\r
+ for (Index = 0; Index < ARRAY_SIZE (ResourcePadding->Padding); ++Index) {\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+\r
+ Descriptor = ResourcePadding->Padding + Index;\r
+ Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Descriptor->Len = (UINT16)(\r
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -\r
+ OFFSET_OF (\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,\r
+ ResType\r
+ )\r
+ );\r
+ }\r
\r
//\r
- // EndDesc\r
+ // Fill in the End Tag.\r
//\r
- {\r
- ACPI_END_TAG_DESCRIPTOR, // Desc\r
- 0 // Checksum: to be ignored\r
- }\r
-};\r
+ ResourcePadding->EndDesc.Desc = ACPI_END_TAG_DESCRIPTOR;\r
+}\r
\r
\r
/**\r
OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes\r
)\r
{\r
+ BOOLEAN DefaultIo;\r
+ BOOLEAN DefaultMmio;\r
+ RESOURCE_PADDING ReservationRequest;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FirstResource;\r
+\r
DEBUG_CODE (\r
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *Address;\r
CHAR16 *DevicePathString;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- *Padding = AllocateCopyPool (sizeof mPadding, &mPadding);\r
+ DefaultIo = TRUE;\r
+ DefaultMmio = TRUE;\r
+\r
+ //\r
+ // Init ReservationRequest, and point FirstResource one past the last\r
+ // descriptor entry. We're going to build the entries backwards from\r
+ // ReservationRequest.EndDesc.\r
+ //\r
+ InitializeResourcePadding (&ReservationRequest);\r
+ FirstResource = ReservationRequest.Padding +\r
+ ARRAY_SIZE (ReservationRequest.Padding);\r
+\r
+ //\r
+ // (b) Reserve IO space.\r
+ //\r
+ if (DefaultIo) {\r
+ //\r
+ // Request defaults.\r
+ //\r
+ --FirstResource;\r
+ FirstResource->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ FirstResource->AddrRangeMax = 512 - 1; // align at 512 IO ports\r
+ FirstResource->AddrLen = 512; // 512 IO ports\r
+ }\r
+\r
+ //\r
+ // (c) Reserve non-prefetchable MMIO space (32-bit only).\r
+ //\r
+ if (DefaultMmio) {\r
+ //\r
+ // Request defaults.\r
+ //\r
+ --FirstResource;\r
+ FirstResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ FirstResource->SpecificFlag = 0; // non-prefetchable\r
+ FirstResource->AddrSpaceGranularity = 32; // 32-bit aperture\r
+ FirstResource->AddrRangeMax = SIZE_2MB - 1; // align at 2MB\r
+ FirstResource->AddrLen = SIZE_2MB; // 2MB padding\r
+ }\r
+\r
+ //\r
+ // Output a copy of ReservationRequest from the lowest-address populated\r
+ // entry until the end of the structure (including\r
+ // ReservationRequest.EndDesc). If no reservations are necessary, we'll only\r
+ // output the End Tag.\r
+ //\r
+ *Padding = AllocateCopyPool (\r
+ (UINT8 *)(&ReservationRequest + 1) - (UINT8 *)FirstResource,\r
+ FirstResource\r
+ );\r
if (*Padding == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r