pcienumerator.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,178 行 · 第 1/4 页
C
2,178 行
EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
0,
&gEfiCallerIdGuid,
(EFI_STATUS_CODE_DATA *) &AllocFailExtendedData
);
//
// Add it to the array and indicate at least a device has been rejected
//
RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;
AllocationAjusted = TRUE;
}
}
//
// End for
//
if (AllocationAjusted) {
return EFI_SUCCESS;
} else {
return EFI_ABORTED;
}
}
EFI_STATUS
ConstructAcpiResourceRequestor (
IN PCI_IO_DEVICE *Bridge,
IN PCI_RESOURCE_NODE *IoNode,
IN PCI_RESOURCE_NODE *Mem32Node,
IN PCI_RESOURCE_NODE *PMem32Node,
IN PCI_RESOURCE_NODE *Mem64Node,
IN PCI_RESOURCE_NODE *PMem64Node,
OUT VOID **pConfig
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: Bridge - add argument and description to function comment
// TODO: IoNode - add argument and description to function comment
// TODO: Mem32Node - add argument and description to function comment
// TODO: PMem32Node - add argument and description to function comment
// TODO: Mem64Node - add argument and description to function comment
// TODO: PMem64Node - add argument and description to function comment
// TODO: pConfig - add argument and description to function comment
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
UINT8 NumConfig;
UINT8 Aperture;
UINT8 *Configuration;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;
NumConfig = 0;
Aperture = 0;
*pConfig = NULL;
//
// if there is io request, add to the io aperture
//
if (ResourceRequestExisted (IoNode)) {
NumConfig++;
Aperture |= 0x01;
}
//
// if there is mem32 request, add to the mem32 aperture
//
if (ResourceRequestExisted (Mem32Node)) {
NumConfig++;
Aperture |= 0x02;
}
//
// if there is pmem32 request, add to the pmem32 aperture
//
if (ResourceRequestExisted (PMem32Node)) {
NumConfig++;
Aperture |= 0x04;
}
//
// if there is mem64 request, add to the mem64 aperture
//
if (ResourceRequestExisted (Mem64Node)) {
NumConfig++;
Aperture |= 0x08;
}
//
// if there is pmem64 request, add to the pmem64 aperture
//
if (ResourceRequestExisted (PMem64Node)) {
NumConfig++;
Aperture |= 0x10;
}
if (NumConfig != 0) {
//
// If there is at least one type of resource request,
// allocate a acpi resource node
//
Configuration = EfiLibAllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
if (Configuration == NULL) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem (
Configuration,
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
);
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
//
// Deal with io aperture
//
if (Aperture & 0x01) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
//
// Io
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
//
// non ISA range
//
Ptr->SpecificFlag = 1;
Ptr->AddrLen = IoNode->Length;
Ptr->AddrRangeMax = IoNode->Alignment;
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
}
//
// Deal with mem32 aperture
//
if (Aperture & 0x02) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// Nonprefechable
//
Ptr->SpecificFlag = 0;
//
// 32 bit
//
Ptr->AddrSpaceGranularity = 32;
Ptr->AddrLen = Mem32Node->Length;
Ptr->AddrRangeMax = Mem32Node->Alignment;
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
}
//
// Deal with Pmem32 aperture
//
if (Aperture & 0x04) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// prefechable
//
Ptr->SpecificFlag = 0x6;
//
// 32 bit
//
Ptr->AddrSpaceGranularity = 32;
Ptr->AddrLen = PMem32Node->Length;
Ptr->AddrRangeMax = PMem32Node->Alignment;
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
}
//
// Deal with mem64 aperture
//
if (Aperture & 0x08) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// nonprefechable
//
Ptr->SpecificFlag = 0;
//
// 64 bit
//
Ptr->AddrSpaceGranularity = 64;
Ptr->AddrLen = Mem64Node->Length;
Ptr->AddrRangeMax = Mem64Node->Alignment;
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
}
//
// Deal with Pmem64 aperture
//
if (Aperture & 0x10) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// prefechable
//
Ptr->SpecificFlag = 0x06;
//
// 64 bit
//
Ptr->AddrSpaceGranularity = 64;
Ptr->AddrLen = PMem64Node->Length;
Ptr->AddrRangeMax = PMem64Node->Alignment;
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
}
//
// put the checksum
//
PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);
PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
PtrEnd->Checksum = 0;
} else {
//
// If there is no resource request
//
Configuration = EfiLibAllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
if (Configuration == NULL) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
PtrEnd->Checksum = 0;
}
*pConfig = Configuration;
return EFI_SUCCESS;
}
EFI_STATUS
GetResourceBase (
IN VOID *pConfig,
OUT UINT64 *IoBase,
OUT UINT64 *Mem32Base,
OUT UINT64 *PMem32Base,
OUT UINT64 *Mem64Base,
OUT UINT64 *PMem64Base
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: pConfig - add argument and description to function comment
// TODO: IoBase - add argument and description to function comment
// TODO: Mem32Base - add argument and description to function comment
// TODO: PMem32Base - add argument and description to function comment
// TODO: Mem64Base - add argument and description to function comment
// TODO: PMem64Base - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
UINT8 *Temp;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
UINT64 ResStatus;
*IoBase = 0xFFFFFFFFFFFFFFFF;
*Mem32Base = 0xFFFFFFFFFFFFFFFF;
*PMem32Base = 0xFFFFFFFFFFFFFFFF;
*Mem64Base = 0xFFFFFFFFFFFFFFFF;
*PMem64Base = 0xFFFFFFFFFFFFFFFF;
Temp = (UINT8 *) pConfig;
while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
ResStatus = Ptr->AddrTranslationOffset;
if (ResStatus == EFI_RESOURCE_SATISFIED) {
switch (Ptr->ResType) {
//
// Memory type aperture
//
case 0:
//
// Check to see the granularity
//
if (Ptr->AddrSpaceGranularity == 32) {
if (Ptr->SpecificFlag & 0x06) {
*PMem32Base = Ptr->AddrRangeMin;
} else {
*Mem32Base = Ptr->AddrRangeMin;
}
}
if (Ptr->AddrSpaceGranularity == 64) {
if (Ptr->SpecificFlag & 0x06) {
*PMem64Base = Ptr->AddrRangeMin;
} else {
*Mem64Base = Ptr->AddrRangeMin;
}
}
break;
case 1:
//
// Io type aperture
//
*IoBase = Ptr->AddrRangeMin;
break;
default:
break;
}
//
// End switch
//
}
//
// End for
//
Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
}
return EFI_SUCCESS;
}
EFI_STATUS
PciBridgeEnumerator (
IN PCI_IO_DEVICE *BridgeDev
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: BridgeDev - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
UINT8 SubBusNumber;
UINT8 StartBusNumber;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_STATUS Status;
SubBusNumber = 0;
StartBusNumber = 0;
PciIo = &(BridgeDev->PciIo);
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciAssignBusNumber (
BridgeDev,
StartBusNumber,
&SubBusNumber
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciBridgeResourceAllocator (BridgeDev);
if (EFI_ERROR (Status)) {
return Status;
}
Status = DetermineDeviceAttribute (BridgeDev);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
PciBridgeResourceAllocator (
IN PCI_IO_DEVICE *Bridge
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: Bridge - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
PCI_RESOURCE_NODE *IoBridge;
PCI_RESOURCE_NODE *Mem32Bridge;
PCI_RESOURCE_NODE *PMem32Bridge;
PCI_RESOURCE_NODE *Mem64Bridge;
PCI_RESOURCE_NODE *PMem64Bridge;
UINT64 IoBase;
UINT64 Mem32Base;
UINT64 PMem32Base;
UINT64 Mem64Base;
UINT64 PMem64Base;
EFI_STATUS Status;
IoBridge = CreateResourceNode (
Bridge,
0,
0xFFF,
0,
PciBarTypeIo16,
PciResUsageTypical
);
Mem32Bridge = CreateResourceNode (
Bridge,
0,
0xFFFFF,
0,
PciBarTypeMem32,
PciResUsageTypical
);
PMem32Bridge = CreateResourceNode (
Bridge,
0,
0xFFFFF,
0,
PciBarTypePMem32,
PciResUsageTypical
);
Mem64Bridge = CreateResourceNode (
Bridge,
0,
0xFFFFF,
0,
PciBarTypeMem64,
PciResUsageTypical
);
PMem64Bridge = CreateResourceNode (
Bridge,
0,
0xFFFFF,
0,
PciBarTypePMem64,
PciResUsageTypical
);
//
// Create resourcemap by going through all the devices subject to this root bridge
//
Status = CreateResourceMap (
Bridge,
IoBridge,
Mem32Bridge,
PMem32Bridge,
Mem64Bridge,
PMem64Bridge
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = GetResourceBaseFromBridge (
Bridge,
&IoBase,
&Mem32Base,
&PMem32Base,
&Mem64Base,
&PMem64Base
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Program IO resources
//
ProgramResource (
IoBase,
IoBridge
);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?