pcihostbridge.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,244 行 · 第 1/3 页
C
1,244 行
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
EFI_LIST_ENTRY *List;
PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
UINT8 *Temp;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
UINT64 AddrLen;
UINT64 Alignment;
//
// Check the input parameter: Configuration
//
if (Configuration == NULL) {
return EFI_INVALID_PARAMETER;
}
HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
List = HostBridgeInstance->Head.ForwardLink;
Temp = (UINT8 *) Configuration;
while (*Temp == 0x8A) {
Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
}
if (*Temp != 0x79) {
return EFI_INVALID_PARAMETER;
}
Temp = (UINT8 *) Configuration;
while (List != &HostBridgeInstance->Head) {
RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
if (RootBridgeHandle == RootBridgeInstance->Handle) {
while (*Temp == 0x8A) {
ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
//
// Check Address Length
//
if (ptr->AddrLen > 0xffffffff) {
return EFI_INVALID_PARAMETER;
}
//
// Check address range alignment
//
if (ptr->AddrRangeMax >= 0xffffffff ||
ptr->AddrRangeMax != (Power2MaxMemory(ptr->AddrRangeMax + 1) - 1)) {
return EFI_INVALID_PARAMETER;
}
switch (ptr->ResType) {
case 0:
//
// Check invalid Address Sapce Granularity
//
if (ptr->AddrSpaceGranularity != 32) {
return EFI_INVALID_PARAMETER;
}
//
// check the memory resource request is supported by PCI root bridge
//
if (RootBridgeInstance->RootBridgeAttrib == EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM &&
ptr->SpecificFlag == 0x06 ) {
return EFI_INVALID_PARAMETER;
}
AddrLen = ptr->AddrLen;
Alignment = ptr->AddrRangeMax;
if (ptr->AddrSpaceGranularity == 32) {
if (ptr->SpecificFlag == 0x06) {
//
// Apply from GCD
//
RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;
} else {
RootBridgeInstance->ResAllocNode[TypeMem32].Length = AddrLen;
RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;
RootBridgeInstance->ResAllocNode[TypeMem32].Status = ResRequested;
HostBridgeInstance->ResourceSubmited = TRUE;
}
}
if (ptr->AddrSpaceGranularity == 64) {
if (ptr->SpecificFlag == 0x06) {
RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;
} else {
RootBridgeInstance->ResAllocNode[TypeMem64].Status = ResSubmitted;
}
}
break;
case 1:
AddrLen = (UINTN) ptr->AddrLen;
Alignment = (UINTN) ptr->AddrRangeMax;
RootBridgeInstance->ResAllocNode[TypeIo].Length = AddrLen;
RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;
RootBridgeInstance->ResAllocNode[TypeIo].Status = ResRequested;
HostBridgeInstance->ResourceSubmited = TRUE;
break;
default:
break;
}
Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
}
return EFI_SUCCESS;
}
List = List->ForwardLink;
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
EFIAPI
GetProposedResources (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
IN EFI_HANDLE RootBridgeHandle,
OUT VOID **Configuration
)
/*++
Routine Description:
This function returns the proposed resource settings for the specified
PCI Root Bridge
Arguments:
This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
RootBridgeHandle -- The PCI Root Bridge handle
Configuration -- The pointer to the pointer to the PCI I/O
and memory resource descriptor
Returns:
--*/
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
EFI_LIST_ENTRY *List;
PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
UINTN Index;
UINTN Number;
VOID *Buffer;
UINT8 *Temp;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
EFI_STATUS Status;
UINT64 ResStatus;
Buffer = NULL;
Number = 0;
//
// Get the Host Bridge Instance from the resource allocation protocol
//
HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
List = HostBridgeInstance->Head.ForwardLink;
//
// Enumerate the root bridges in this host bridge
//
while (List != &HostBridgeInstance->Head) {
RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
if (RootBridgeHandle == RootBridgeInstance->Handle) {
for (Index = 0; Index < TypeBus; Index++) {
if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
Number++;
}
}
if (Number > 0) {
Status = gBS->AllocatePool (
EfiBootServicesData,
Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
&Buffer
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem (Buffer, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Number + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
} else {
return EFI_INVALID_PARAMETER;
}
Temp = Buffer;
for (Index = 0; Index < TypeBus; Index++) {
if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
switch (Index) {
case TypeIo:
//
// Io
//
ptr->Desc = 0x8A;
ptr->Len = 0x2B;
ptr->ResType = 1;
ptr->GenFlag = 0;
ptr->SpecificFlag = 0;
ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
ptr->AddrRangeMax = 0;
ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
break;
case TypeMem32:
//
// Memory 32
//
ptr->Desc = 0x8A;
ptr->Len = 0x2B;
ptr->ResType = 0;
ptr->GenFlag = 0;
ptr->SpecificFlag = 0;
ptr->AddrSpaceGranularity = 32;
ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
ptr->AddrRangeMax = 0;
ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
break;
case TypePMem32:
//
// Prefetch memory 32
//
ptr->Desc = 0x8A;
ptr->Len = 0x2B;
ptr->ResType = 0;
ptr->GenFlag = 0;
ptr->SpecificFlag = 6;
ptr->AddrSpaceGranularity = 32;
ptr->AddrRangeMin = 0;
ptr->AddrRangeMax = 0;
ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
ptr->AddrLen = 0;
break;
case TypeMem64:
//
// Memory 64
//
ptr->Desc = 0x8A;
ptr->Len = 0x2B;
ptr->ResType = 0;
ptr->GenFlag = 0;
ptr->SpecificFlag = 0;
ptr->AddrSpaceGranularity = 64;
ptr->AddrRangeMin = 0;
ptr->AddrRangeMax = 0;
ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
ptr->AddrLen = 0;
break;
case TypePMem64:
//
// Prefetch memory 64
//
ptr->Desc = 0x8A;
ptr->Len = 0x2B;
ptr->ResType = 0;
ptr->GenFlag = 0;
ptr->SpecificFlag = 6;
ptr->AddrSpaceGranularity = 64;
ptr->AddrRangeMin = 0;
ptr->AddrRangeMax = 0;
ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
ptr->AddrLen = 0;
break;
}
Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
}
}
((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc = 0x79;
((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum = 0x0;
*Configuration = Buffer;
return EFI_SUCCESS;
}
List = List->ForwardLink;
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
EFIAPI
PreprocessController (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
IN EFI_HANDLE RootBridgeHandle,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
)
/*++
Routine Description:
This function is called for all the PCI controllers that the PCI
bus driver finds. Can be used to Preprogram the controller.
Arguments:
This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
RootBridgeHandle -- The PCI Root Bridge handle
PciBusAddress -- Address of the controller on the PCI bus
Phase -- The Phase during resource allocation
Returns:
EFI_SUCCESS
--*/
// TODO: PciAddress - add argument and description to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
EFI_LIST_ENTRY *List;
HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
List = HostBridgeInstance->Head.ForwardLink;
//
// Enumerate the root bridges in this host bridge
//
while (List != &HostBridgeInstance->Head) {
RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
if (RootBridgeHandle == RootBridgeInstance->Handle) {
return EFI_SUCCESS;
}
List = List->ForwardLink;
}
return EFI_INVALID_PARAMETER;
}
UINT32
SetPower2 (
IN UINT32 Input
)
/*++
Routine Description:
TODO: Add function description
Arguments:
Input - TODO: add argument description
Returns:
TODO: add return values
--*/
{
UINT32 Result;
Result = 0;
//
// Define: bsr - search the operand for most significant set
// bts - Selects the bit in a bit string & sets the selected bit
//
_asm {
bsr eax, Input
bts Result, eax
}
return Result;
}
UINT64
Power2MaxMemory (
IN UINT64 MemoryLength
)
/*++
Routine Description:
TODO: Add function description
Arguments:
MemoryLength - TODO: add argument description
Returns:
TODO: add return values
--*/
{
UINT64 Result;
if (RShiftU64 (MemoryLength, 32)) {
Result = LShiftU64 ((UINT64) SetPower2 ((UINT32) RShiftU64 (MemoryLength, 32)), 32);
} else {
Result = (UINT64) SetPower2 ((UINT32) MemoryLength);
}
return Result;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?