OvmfPkg/PciHotPlugInitDxe: add helper functions for setting up paddings

Extract the SetIoPadding() and SetMmioPadding() functions, so that we can
set EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR fields using parameter names and
values that are more friendly than the original field names and their
expected values.

Introduce the HighBitSetRoundUp32() and HighBitSetRoundUp64() functions
for calculating the last parameter ("SizeExponent") of SetIoPadding() and
SetMmioPadding().

Put the new functions to use when requesting the default reservations. (In
order to be consistent with a later patch, "SizeExponent" is calculated
for SetIoPadding() with HighBitSetRoundUp64().)

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2017-09-22 00:31:12 +02:00
parent a980324709
commit 4776d5cb3a
2 changed files with 156 additions and 10 deletions

View File

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

View File

@ -29,6 +29,7 @@
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
DevicePathLib