\r
#include <IndustryStandard/Acpi10.h>\r
\r
+#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/DevicePathLib.h>\r
}\r
\r
\r
+/**\r
+ Set up a descriptor entry for reserving IO space.\r
+\r
+ @param[in,out] Descriptor The descriptor to configure. The caller shall have\r
+ initialized Descriptor earlier, with\r
+ InitializeResourcePadding().\r
+\r
+ @param[in] SizeExponent The size and natural alignment of the reservation\r
+ are determined by raising two to this power.\r
+**/\r
+STATIC\r
+VOID\r
+SetIoPadding (\r
+ IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor,\r
+ IN UINTN SizeExponent\r
+ )\r
+{\r
+ Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ Descriptor->AddrLen = LShiftU64 (1, SizeExponent);\r
+ Descriptor->AddrRangeMax = Descriptor->AddrLen - 1;\r
+}\r
+\r
+\r
+/**\r
+ Set up a descriptor entry for reserving MMIO space.\r
+\r
+ @param[in,out] Descriptor The descriptor to configure. The caller shall\r
+ have initialized Descriptor earlier, with\r
+ InitializeResourcePadding().\r
+\r
+ @param[in] Prefetchable TRUE if the descriptor should reserve\r
+ prefetchable MMIO space. Pass FALSE for\r
+ reserving non-prefetchable MMIO space.\r
+\r
+ @param[in] ThirtyTwoBitOnly TRUE if the reservation should be limited to\r
+ 32-bit address space. FALSE if the reservation\r
+ can be satisfied from 64-bit address space.\r
+ ThirtyTwoBitOnly is ignored if Prefetchable is\r
+ FALSE; in that case ThirtyTwoBitOnly is always\r
+ considered TRUE.\r
+\r
+ @param[in] SizeExponent The size and natural alignment of the\r
+ reservation are determined by raising two to\r
+ this power.\r
+**/\r
+STATIC\r
+VOID\r
+SetMmioPadding (\r
+ IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor,\r
+ IN BOOLEAN Prefetchable,\r
+ IN BOOLEAN ThirtyTwoBitOnly,\r
+ IN UINTN SizeExponent\r
+ )\r
+{\r
+ Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ if (Prefetchable) {\r
+ Descriptor->SpecificFlag =\r
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;\r
+ Descriptor->AddrSpaceGranularity = ThirtyTwoBitOnly ? 32 : 64;\r
+ } else {\r
+ Descriptor->SpecificFlag =\r
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE;\r
+ Descriptor->AddrSpaceGranularity = 32;\r
+ }\r
+ Descriptor->AddrLen = LShiftU64 (1, SizeExponent);\r
+ Descriptor->AddrRangeMax = Descriptor->AddrLen - 1;\r
+}\r
+\r
+\r
+/**\r
+ Round up a positive 32-bit value to the next whole power of two, and return\r
+ the bit position of the highest bit set in the result. Equivalent to\r
+ ceil(log2(x)).\r
+\r
+ @param[in] Operand The 32-bit operand to evaluate.\r
+\r
+ @retval -1 Operand is zero.\r
+\r
+ @retval -1 Operand is positive, not a whole power of two, and rounding it\r
+ up to the next power of two does not fit into 32 bits.\r
+\r
+ @retval 0..31 Otherwise, return ceil(log2(Value)).\r
+**/\r
+STATIC\r
+INTN\r
+HighBitSetRoundUp32 (\r
+ IN UINT32 Operand\r
+ )\r
+{\r
+ INTN HighBit;\r
+\r
+ HighBit = HighBitSet32 (Operand);\r
+ if (HighBit == -1) {\r
+ //\r
+ // Operand is zero.\r
+ //\r
+ return HighBit;\r
+ }\r
+ if ((Operand & (Operand - 1)) != 0) {\r
+ //\r
+ // Operand is not a whole power of two.\r
+ //\r
+ ++HighBit;\r
+ }\r
+ return (HighBit < 32) ? HighBit : -1;\r
+}\r
+\r
+\r
+/**\r
+ Round up a positive 64-bit value to the next whole power of two, and return\r
+ the bit position of the highest bit set in the result. Equivalent to\r
+ ceil(log2(x)).\r
+\r
+ @param[in] Operand The 64-bit operand to evaluate.\r
+\r
+ @retval -1 Operand is zero.\r
+\r
+ @retval -1 Operand is positive, not a whole power of two, and rounding it\r
+ up to the next power of two does not fit into 64 bits.\r
+\r
+ @retval 0..63 Otherwise, return ceil(log2(Value)).\r
+**/\r
+STATIC\r
+INTN\r
+HighBitSetRoundUp64 (\r
+ IN UINT64 Operand\r
+ )\r
+{\r
+ INTN HighBit;\r
+\r
+ HighBit = HighBitSet64 (Operand);\r
+ if (HighBit == -1) {\r
+ //\r
+ // Operand is zero.\r
+ //\r
+ return HighBit;\r
+ }\r
+ if ((Operand & (Operand - 1)) != 0) {\r
+ //\r
+ // Operand is not a whole power of two.\r
+ //\r
+ ++HighBit;\r
+ }\r
+ return (HighBit < 64) ? HighBit : -1;\r
+}\r
+\r
+\r
/**\r
Returns a list of root Hot Plug Controllers (HPCs) that require\r
initialization during the boot process.\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
+ SetIoPadding (--FirstResource, (UINTN)HighBitSetRoundUp64 (512));\r
}\r
\r
//\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
+ SetMmioPadding (\r
+ --FirstResource,\r
+ FALSE,\r
+ TRUE,\r
+ (UINTN)HighBitSetRoundUp32 (SIZE_2MB)\r
+ );\r
}\r
\r
//\r