gcd.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,443 行 · 第 1/5 页
C
2,443 行
Returns:
None
--*/
{
Descriptor->BaseAddress = Entry->BaseAddress;
Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
Descriptor->Capabilities = Entry->Capabilities;
Descriptor->Attributes = Entry->Attributes;
Descriptor->GcdMemoryType = Entry->GcdMemoryType;
Descriptor->ImageHandle = Entry->ImageHandle;
Descriptor->DeviceHandle = Entry->DeviceHandle;
}
EFI_STATUS
CoreGetMemorySpaceDescriptor (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
)
/*++
Routine Description:
Retrieves the descriptor for a memory region containing a specified address.
Arguments:
BaseAddress - Specified start address
Descriptor - Specified length
Returns:
EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Successfully get memory space descriptor.
--*/
{
EFI_STATUS Status;
EFI_LIST_ENTRY *StartLink;
EFI_LIST_ENTRY *EndLink;
EFI_GCD_MAP_ENTRY *Entry;
//
// Make sure parameters are valid
//
if (Descriptor == NULL) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireGcdMemoryLock ();
//
// Search for the list of descriptors that contain BaseAddress
//
Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
} else {
//
// Copy the contents of the found descriptor into Descriptor
//
Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
BuildMemoryDescriptor (Descriptor, Entry);
}
CoreReleaseGcdMemoryLock ();
return Status;
}
EFI_STATUS
CoreSetMemorySpaceAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length,
IN UINT64 Attributes
)
/*++
Routine Description:
Modifies the attributes for a memory region in the global coherency domain of the
processor.
Arguments:
BaseAddress - Specified start address
Length - Specified length
Attributes - Specified attributes
Returns:
EFI_SUCCESS - Successfully set attribute of a segment of memory space.
--*/
{
return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, Attributes);
}
EFI_STATUS
CoreGetMemorySpaceMap (
OUT UINTN *NumberOfDescriptors,
OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap
)
/*++
Routine Description:
Returns a map of the memory resources in the global coherency domain of the
processor.
Arguments:
NumberOfDescriptors - Number of descriptors.
MemorySpaceMap - Descriptor array
Returns:
EFI_INVALID_PARAMETER - Invalid parameter
EFI_OUT_OF_RESOURCES - No enough buffer to allocate
EFI_SUCCESS - Successfully get memory space map.
--*/
{
EFI_STATUS Status;
EFI_LIST_ENTRY *Link;
EFI_GCD_MAP_ENTRY *Entry;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor;
//
// Make sure parameters are valid
//
if (NumberOfDescriptors == NULL) {
return EFI_INVALID_PARAMETER;
}
if (MemorySpaceMap == NULL) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireGcdMemoryLock ();
//
// Count the number of descriptors
//
*NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdMemorySpaceMap);
//
// Allocate the MemorySpaceMap
//
*MemorySpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
if (*MemorySpaceMap == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// Fill in the MemorySpaceMap
//
Descriptor = *MemorySpaceMap;
Link = mGcdMemorySpaceMap.ForwardLink;
while (Link != &mGcdMemorySpaceMap) {
Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
BuildMemoryDescriptor (Descriptor, Entry);
Descriptor++;
Link = Link->ForwardLink;
}
Status = EFI_SUCCESS;
Done:
CoreReleaseGcdMemoryLock ();
return Status;
}
EFI_STATUS
CoreAddIoSpace (
IN EFI_GCD_IO_TYPE GcdIoType,
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
/*++
Routine Description:
Adds reserved I/O or I/O resources to the global coherency domain of the processor.
Arguments:
GcdIoType - IO type of the segment.
BaseAddress - Base address of the segment.
Length - Length of the segment.
Returns:
EFI_SUCCESS - Merged this segment into GCD map.
EFI_INVALID_PARAMETER - Parameter not valid
--*/
{
//
// Make sure parameters are valid
//
if (GcdIoType <= EfiGcdIoTypeNonExistent || GcdIoType >= EfiGcdIoTypeMaximum) {
return EFI_INVALID_PARAMETER;
}
return CoreConvertSpace (GCD_ADD_IO_OPERATION, 0, GcdIoType, BaseAddress, Length, 0, 0);
}
EFI_STATUS
CoreAllocateIoSpace (
IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
IN EFI_GCD_IO_TYPE GcdIoType,
IN UINTN Alignment,
IN UINT64 Length,
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE DeviceHandle OPTIONAL
)
/*++
Routine Description:
Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency
domain of the processor.
Arguments:
GcdAllocateType - The type of allocate operation
GcdIoType - The desired IO type
Alignment - Align with 2^Alignment
Length - Length to allocate
BaseAddress - Base address to allocate
ImageHandle - The image handle consume the allocated space.
DeviceHandle - The device handle consume the allocated space.
Returns:
EFI_INVALID_PARAMETER - Invalid parameter.
EFI_NOT_FOUND - No descriptor contains the desired space.
EFI_SUCCESS - IO space successfully allocated.
--*/
{
return CoreAllocateSpace (
GCD_ALLOCATE_IO_OPERATION,
GcdAllocateType,
0,
GcdIoType,
Alignment,
Length,
BaseAddress,
ImageHandle,
DeviceHandle
);
}
EFI_STATUS
CoreFreeIoSpace (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
/*++
Routine Description:
Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency
domain of the processor.
Arguments:
BaseAddress - Base address of the segment.
Length - Length of the segment.
Returns:
EFI_SUCCESS - Space successfully freed.
--*/
{
return CoreConvertSpace (GCD_FREE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
}
EFI_STATUS
CoreRemoveIoSpace (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
/*++
Routine Description:
Removes reserved I/O or I/O resources from the global coherency domain of the
processor.
Arguments:
BaseAddress - Base address of the segment.
Length - Length of the segment.
Returns:
EFI_SUCCESS - Successfully removed a segment of IO space.
--*/
{
return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
}
VOID
BuildIoDescriptor (
IN EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor,
IN EFI_GCD_MAP_ENTRY *Entry
)
/*++
Routine Description:
Build a IO descriptor according to an entry.
Arguments:
Descriptor - The descriptor to be built
Entry - According to this entry
Returns:
None
--*/
{
Descriptor->BaseAddress = Entry->BaseAddress;
Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
Descriptor->GcdIoType = Entry->GcdIoType;
Descriptor->ImageHandle = Entry->ImageHandle;
Descriptor->DeviceHandle = Entry->DeviceHandle;
}
EFI_STATUS
CoreGetIoSpaceDescriptor (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor
)
/*++
Routine Description:
Retrieves the descriptor for an I/O region containing a specified address.
Arguments:
BaseAddress - Specified start address
Descriptor - Specified length
Returns:
EFI_INVALID_PARAMETER - Descriptor is NULL.
EFI_SUCCESS - Successfully get the IO space descriptor.
--*/
{
EFI_STATUS Status;
EFI_LIST_ENTRY *StartLink;
EFI_LIST_ENTRY *EndLink;
EFI_GCD_MAP_ENTRY *Entry;
//
// Make sure parameters are valid
//
if (Descriptor == NULL) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireGcdIoLock ();
//
// Search for the list of descriptors that contain BaseAddress
//
Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
} else {
//
// Copy the contents of the found descriptor into Descriptor
//
Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
BuildIoDescriptor (Descriptor, Entry);
}
CoreReleaseGcdIoLock ();
return Status;
}
EFI_STATUS
CoreGetIoSpaceMap (
OUT UINTN *NumberOfDescriptors,
OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap
)
/*++
Routine Description:
Returns a map of the I/O resources in the global coherency domain of the processor.
Arguments:
NumberOfDescriptors - Number of descriptors.
IoSpaceMap - Descriptor array
Returns:
EFI_INVALID_PARAMETER - Invalid parameter
EFI_OUT_OF_RESOURCES - No enough buffer to allocate
EFI_SUCCESS - Successfully get IO space map.
--*/
{
EFI_STATUS Status;
EFI_LIST_ENTRY *Link;
EFI_GCD_MAP_ENTRY *Entry;
EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor;
//
// Make sure parameters are valid
//
if (NumberOfDescriptors == NULL) {
return EFI_INVALID_PARAMETER;
}
if (IoSpaceMap == NULL) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireGcdIoLock ();
//
// Count the number of descriptors
//
*NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap);
//
// Allocate the IoSpaceMap
//
*IoSpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));
if (*IoSpaceMap == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// Fill in the IoSpaceMap
//
Descriptor = *IoSpaceMap;
Link = mGcdIoSpaceMap.ForwardLink;
while (Link != &mGcdIoSpaceMap) {
Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
BuildIoDescriptor (Descriptor, Entry);
Descriptor++;
Link = Link->ForwardLink;
}
Status = EFI_SUCCESS;
Done:
CoreReleaseGcdIoLock ();
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?