lightpcilib.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 893 行 · 第 1/2 页
C
893 行
GetResourceBase (
AcpiConfig,
&IoBase,
&Mem32Base,
&PMem32Base,
&Mem64Base,
&PMem64Base
);
//
// Process option rom for this root bridge
//
Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);
//
// Create the entire system resource map from the information collected by
// enumerator. Several resource tree was created
//
Status = GetResourceMap (
RootBridgeDev,
&IoBridge,
&Mem32Bridge,
&PMem32Bridge,
&Mem64Bridge,
&PMem64Bridge,
&IoPool,
&Mem32Pool,
&PMem32Pool,
&Mem64Pool,
&PMem64Pool
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Program IO resources
//
ProgramResource (
IoBase,
IoBridge
);
//
// Program Mem32 resources
//
ProgramResource (
Mem32Base,
Mem32Bridge
);
//
// Program PMem32 resources
//
ProgramResource (
PMem32Base,
PMem32Bridge
);
//
// Program Mem64 resources
//
ProgramResource (
Mem64Base,
Mem64Bridge
);
//
// Program PMem64 resources
//
ProgramResource (
PMem64Base,
PMem64Bridge
);
if (AcpiConfig != NULL) {
gBS->FreePool (AcpiConfig);
}
}
//
// Destroy all the resource tree
//
DestroyResourceTree (&IoPool);
DestroyResourceTree (&Mem32Pool);
DestroyResourceTree (&PMem32Pool);
DestroyResourceTree (&Mem64Pool);
DestroyResourceTree (&PMem64Pool);
//
// Notify the resource allocation phase is to end
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);
return EFI_SUCCESS;
}
EFI_STATUS
PciScanBus (
IN PCI_IO_DEVICE *Bridge,
IN UINT8 StartBusNumber,
OUT UINT8 *SubBusNumber,
OUT UINT8 *PaddedBusRange
)
/*++
Routine Description:
This routine is used to assign bus number to the given PCI bus system
Arguments:
Returns:
None
--*/
// TODO: Bridge - add argument and description to function comment
// TODO: StartBusNumber - add argument and description to function comment
// TODO: SubBusNumber - add argument and description to function comment
// TODO: PaddedBusRange - add argument and description to function comment
// TODO: EFI_DEVICE_ERROR - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
PCI_TYPE00 Pci;
UINT8 Device;
UINT8 Func;
UINT64 Address;
UINTN SecondBus;
UINT16 Register;
PCI_IO_DEVICE *PciDevice;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
PciRootBridgeIo = Bridge->PciRootBridgeIo;
SecondBus = 0;
Register = 0;
ResetAllPpbBusReg (Bridge, StartBusNumber);
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
//
// Check to see whether a pci device is present
//
Status = PciDevicePresent (
PciRootBridgeIo,
&Pci,
StartBusNumber,
Device,
Func
);
if (!EFI_ERROR (Status) &&
(IS_PCI_BRIDGE (&Pci) ||
IS_CARDBUS_BRIDGE (&Pci))) {
//
// Get the bridge information
//
Status = PciSearchDevice (
Bridge,
&Pci,
StartBusNumber,
Device,
Func,
&PciDevice
);
if (EFI_ERROR (Status)) {
return Status;
}
(*SubBusNumber)++;
SecondBus = (*SubBusNumber);
Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);
Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,
EfiPciWidthUint16,
Address,
1,
&Register
);
//
// Initialize SubBusNumber to SecondBus
//
Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,
EfiPciWidthUint8,
Address,
1,
SubBusNumber
);
//
// If it is PPB, resursively search down this bridge
//
if (IS_PCI_BRIDGE (&Pci)) {
//
// Temporarily initialize SubBusNumber to maximum bus number to ensure the
// PCI configuration transaction to go through any PPB
//
Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
Register = 0xFF;
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,
EfiPciWidthUint8,
Address,
1,
&Register
);
PreprocessController (
PciDevice,
PciDevice->BusNumber,
PciDevice->DeviceNumber,
PciDevice->FunctionNumber,
EfiPciBeforeChildBusEnumeration
);
Status = PciScanBus (
PciDevice,
(UINT8) (SecondBus),
SubBusNumber,
PaddedBusRange
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
}
//
// Set the current maximum bus number under the PPB
//
Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);
Status = PciRootBridgeIo->Pci.Write (
PciRootBridgeIo,
EfiPciWidthUint8,
Address,
1,
SubBusNumber
);
}
if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
//
// Skip sub functions, this is not a multi function device
//
Func = PCI_MAX_FUNC;
}
}
}
return EFI_SUCCESS;
}
//
// Light PCI bus driver woundn't support P2C
// Return instead
//
EFI_STATUS
PciHostBridgeP2CProcess (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: PciResAlloc - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
return EFI_SUCCESS;
}
//
// Light PCI bus driver woundn't support hotplug device
// Simplified the code
//
EFI_STATUS
PciHostBridgeEnumerator (
EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc
)
/*++
Routine Description:
This function is used to enumerate the entire host bridge
in a given platform
Arguments:
PciResAlloc A pointer to the protocol to allocate resource.
Returns:
None
--*/
// 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
{
EFI_HANDLE RootBridgeHandle;
PCI_IO_DEVICE *RootBridgeDev;
EFI_STATUS Status;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
UINT16 MinBus;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
InitializeHotPlugSupport ();
//
// Notify the bus allocation phase is about to start
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);
RootBridgeHandle = NULL;
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
//
// if a root bridge instance is found, create root bridge device for it
//
RootBridgeDev = CreateRootBridge (RootBridgeHandle);
if (RootBridgeDev == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Enumerate all the buses under this root bridge
//
Status = PciRootBridgeEnumerator (
PciResAlloc,
RootBridgeDev
);
if (EFI_ERROR (Status)) {
return Status;
}
DestroyRootBridge (RootBridgeDev);
//
// Error proccess here
//
}
//
// Notify the bus allocation phase is to end
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
//
// Notify the resource allocation phase is to start
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation);
RootBridgeHandle = NULL;
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
//
// if a root bridge instance is found, create root bridge device for it
//
RootBridgeDev = CreateRootBridge (RootBridgeHandle);
if (RootBridgeDev == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = StartManagingRootBridge (RootBridgeDev);
if (EFI_ERROR (Status)) {
return Status;
}
PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo;
Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Determine root bridge attribute by calling interface of Pcihostbridge
// protocol
//
DetermineRootBridgeAttributes (
PciResAlloc,
RootBridgeDev
);
//
// Collect all the resource information under this root bridge
// A database that records all the information about pci device subject to this
// root bridge will then be created
//
Status = PciPciDeviceInfoCollector (
RootBridgeDev,
(UINT8) MinBus
);
if (EFI_ERROR (Status)) {
return Status;
}
InsertRootBridge (RootBridgeDev);
//
// Record the hostbridge handle
//
AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle);
}
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?