mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/CpuDxe: Copy two functions from PciHostBridge
Copy AddMemoryMappedIoSpace() and IntersectMemoryDescriptor() from MdeModulePkg\Bus\Pci\PciHostBridgeDxe\PciHostBridge.c. https://bugzilla.tianocore.org/show_bug.cgi?id=390 Cc: Laszlo Ersek <lersek@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
parent
d0e92aad46
commit
410590f149
|
@ -888,6 +888,154 @@ IdleLoopEventCallback (
|
|||
CpuSleep ();
|
||||
}
|
||||
|
||||
/**
|
||||
Ensure the compatibility of a memory space descriptor with the MMIO aperture.
|
||||
|
||||
The memory space descriptor can come from the GCD memory space map, or it can
|
||||
represent a gap between two neighboring memory space descriptors. In the
|
||||
latter case, the GcdMemoryType field is expected to be
|
||||
EfiGcdMemoryTypeNonExistent.
|
||||
|
||||
If the memory space descriptor already has type
|
||||
EfiGcdMemoryTypeMemoryMappedIo, and its capabilities are a superset of the
|
||||
required capabilities, then no action is taken -- it is by definition
|
||||
compatible with the aperture.
|
||||
|
||||
Otherwise, the intersection of the memory space descriptor is calculated with
|
||||
the aperture. If the intersection is the empty set (no overlap), no action is
|
||||
taken; the memory space descriptor is compatible with the aperture.
|
||||
|
||||
Otherwise, the type of the descriptor is investigated again. If the type is
|
||||
EfiGcdMemoryTypeNonExistent (representing a gap, or a genuine descriptor with
|
||||
such a type), then an attempt is made to add the intersection as MMIO space
|
||||
to the GCD memory space map, with the specified capabilities. This ensures
|
||||
continuity for the aperture, and the descriptor is deemed compatible with the
|
||||
aperture.
|
||||
|
||||
Otherwise, the memory space descriptor is incompatible with the MMIO
|
||||
aperture.
|
||||
|
||||
@param[in] Base Base address of the aperture.
|
||||
@param[in] Length Length of the aperture.
|
||||
@param[in] Capabilities Capabilities required by the aperture.
|
||||
@param[in] Descriptor The descriptor to ensure compatibility with the
|
||||
aperture for.
|
||||
|
||||
@retval EFI_SUCCESS The descriptor is compatible. The GCD memory
|
||||
space map may have been updated, for
|
||||
continuity within the aperture.
|
||||
@retval EFI_INVALID_PARAMETER The descriptor is incompatible.
|
||||
@return Error codes from gDS->AddMemorySpace().
|
||||
**/
|
||||
EFI_STATUS
|
||||
IntersectMemoryDescriptor (
|
||||
IN UINT64 Base,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Capabilities,
|
||||
IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
|
||||
)
|
||||
{
|
||||
UINT64 IntersectionBase;
|
||||
UINT64 IntersectionEnd;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo &&
|
||||
(Descriptor->Capabilities & Capabilities) == Capabilities) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
IntersectionBase = MAX (Base, Descriptor->BaseAddress);
|
||||
IntersectionEnd = MIN (Base + Length,
|
||||
Descriptor->BaseAddress + Descriptor->Length);
|
||||
if (IntersectionBase >= IntersectionEnd) {
|
||||
//
|
||||
// The descriptor and the aperture don't overlap.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
|
||||
Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
|
||||
IntersectionBase, IntersectionEnd - IntersectionBase,
|
||||
Capabilities);
|
||||
|
||||
DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE,
|
||||
"%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__,
|
||||
IntersectionBase, IntersectionEnd, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "
|
||||
"with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__,
|
||||
Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length,
|
||||
(UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities,
|
||||
Base, Base + Length, Capabilities));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/**
|
||||
Add MMIO space to GCD.
|
||||
The routine checks the GCD database and only adds those which are
|
||||
not added in the specified range to GCD.
|
||||
|
||||
@param Base Base address of the MMIO space.
|
||||
@param Length Length of the MMIO space.
|
||||
@param Capabilities Capabilities of the MMIO space.
|
||||
|
||||
@retval EFI_SUCCES The MMIO space was added successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AddMemoryMappedIoSpace (
|
||||
IN UINT64 Base,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Capabilities
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINTN NumberOfDescriptors;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
||||
|
||||
Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",
|
||||
gEfiCallerBaseName, __FUNCTION__, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
||||
Status = IntersectMemoryDescriptor (Base, Length, Capabilities,
|
||||
&MemorySpaceMap[Index]);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FreeMemorySpaceMap;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_CODE (
|
||||
//
|
||||
// Make sure there are adjacent descriptors covering [Base, Base + Length).
|
||||
// It is possible that they have not been merged; merging can be prevented
|
||||
// by allocation and different capabilities.
|
||||
//
|
||||
UINT64 CheckBase;
|
||||
EFI_STATUS CheckStatus;
|
||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
|
||||
|
||||
for (CheckBase = Base;
|
||||
CheckBase < Base + Length;
|
||||
CheckBase = Descriptor.BaseAddress + Descriptor.Length) {
|
||||
CheckStatus = gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor);
|
||||
ASSERT_EFI_ERROR (CheckStatus);
|
||||
ASSERT (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo);
|
||||
ASSERT ((Descriptor.Capabilities & Capabilities) == Capabilities);
|
||||
}
|
||||
);
|
||||
|
||||
FreeMemorySpaceMap:
|
||||
FreePool (MemorySpaceMap);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the state information for the CPU Architectural Protocol.
|
||||
|
|
Loading…
Reference in New Issue