]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.c
OvmfPkg/PciHotPlugInitDxe: add helper functions for setting up paddings
[mirror_edk2.git] / OvmfPkg / PciHotPlugInitDxe / PciHotPlugInit.c
index b1b2c5cd8ddc06175d0ea144023242df00774520..39646973794bfd04a4d2b29f1296dff7e34a48af 100644 (file)
@@ -15,6 +15,7 @@
 \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
@@ -98,6 +99,153 @@ InitializeResourcePadding (
 }\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
@@ -298,10 +446,7 @@ GetResourcePadding (
     //\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
@@ -311,12 +456,12 @@ GetResourcePadding (
     //\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