pcienumerator.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,178 行 · 第 1/4 页
C
2,178 行
//
// Program Mem32 resources
//
ProgramResource (
Mem32Base,
Mem32Bridge
);
//
// Program PMem32 resources
//
ProgramResource (
PMem32Base,
PMem32Bridge
);
//
// Program Mem64 resources
//
ProgramResource (
Mem64Base,
Mem64Bridge
);
//
// Program PMem64 resources
//
ProgramResource (
PMem64Base,
PMem64Bridge
);
DestroyResourceTree (IoBridge);
DestroyResourceTree (Mem32Bridge);
DestroyResourceTree (PMem32Bridge);
DestroyResourceTree (PMem64Bridge);
DestroyResourceTree (Mem64Bridge);
gBS->FreePool (IoBridge);
gBS->FreePool (Mem32Bridge);
gBS->FreePool (PMem32Bridge);
gBS->FreePool (PMem64Bridge);
gBS->FreePool (Mem64Bridge);
return EFI_SUCCESS;
}
EFI_STATUS
GetResourceBaseFromBridge (
IN PCI_IO_DEVICE *Bridge,
OUT UINT64 *IoBase,
OUT UINT64 *Mem32Base,
OUT UINT64 *PMem32Base,
OUT UINT64 *Mem64Base,
OUT UINT64 *PMem64Base
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: Bridge - 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_OUT_OF_RESOURCES - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
if (!Bridge->Allocated) {
return EFI_OUT_OF_RESOURCES;
}
*IoBase = gAllOne;
*Mem32Base = gAllOne;
*PMem32Base = gAllOne;
*Mem64Base = gAllOne;
*PMem64Base = gAllOne;
if (IS_PCI_BRIDGE (&Bridge->Pci)) {
if (Bridge->PciBar[PPB_IO_RANGE].Length) {
*IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;
}
if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {
*Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;
}
if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {
*PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;
}
if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {
*PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;
} else {
*PMem64Base = gAllOne;
}
}
if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {
if (Bridge->PciBar[P2C_IO_1].Length) {
*IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;
} else {
if (Bridge->PciBar[P2C_IO_2].Length) {
*IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;
}
}
if (Bridge->PciBar[P2C_MEM_1].Length) {
if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {
*PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
}
if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {
*Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
}
}
if (Bridge->PciBar[P2C_MEM_2].Length) {
if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {
*PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
}
if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {
*Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
}
}
}
return EFI_SUCCESS;
}
EFI_STATUS
NotifyPhase (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: PciResAlloc - add argument and description to function comment
// TODO: Phase - add argument and description to function comment
// TODO: EFI_NOT_FOUND - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_HANDLE HostBridgeHandle;
EFI_HANDLE RootBridgeHandle;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
EFI_STATUS Status;
HostBridgeHandle = NULL;
RootBridgeHandle = NULL;
if (gPciPlatformProtocol != NULL) {
//
// Get Host Bridge Handle.
//
PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);
//
// Get the rootbridge Io protocol to find the host bridge handle
//
Status = gBS->HandleProtocol (
RootBridgeHandle,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **) &PciRootBridgeIo
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
HostBridgeHandle = PciRootBridgeIo->ParentHandle;
//
// Call PlatformPci::PhaseNotify() if the protocol is present.
//
gPciPlatformProtocol->PhaseNotify (
gPciPlatformProtocol,
HostBridgeHandle,
Phase,
ChipsetEntry
);
}
Status = PciResAlloc->NotifyPhase (
PciResAlloc,
Phase
);
if (gPciPlatformProtocol != NULL) {
//
// Call PlatformPci::PhaseNotify() if the protocol is present.
//
gPciPlatformProtocol->PhaseNotify (
gPciPlatformProtocol,
HostBridgeHandle,
Phase,
ChipsetExit
);
}
return EFI_SUCCESS;
}
EFI_STATUS
PreprocessController (
IN PCI_IO_DEVICE *Bridge,
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Func,
IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: Bridge - add argument and description to function comment
// TODO: Bus - add argument and description to function comment
// TODO: Device - add argument and description to function comment
// TODO: Func - add argument and description to function comment
// TODO: Phase - add argument and description to function comment
// TODO: EFI_UNSUPPORTED - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;
EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;
EFI_HANDLE RootBridgeHandle;
EFI_HANDLE HostBridgeHandle;
EFI_STATUS Status;
//
// Get the host bridge handle
//
HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;
//
// Get the pci host bridge resource allocation protocol
//
Status = gBS->OpenProtocol (
HostBridgeHandle,
&gEfiPciHostBridgeResourceAllocationProtocolGuid,
(VOID **) &PciResAlloc,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// Get Root Brige Handle
//
while (Bridge->Parent) {
Bridge = Bridge->Parent;
}
RootBridgeHandle = Bridge->Handle;
RootBridgePciAddress.Register = 0;
RootBridgePciAddress.Function = Func;
RootBridgePciAddress.Device = Device;
RootBridgePciAddress.Bus = Bus;
RootBridgePciAddress.ExtendedRegister = 0;
if (gPciPlatformProtocol != NULL) {
//
// Call PlatformPci::PrepController() if the protocol is present.
//
gPciPlatformProtocol->PlatformPrepController (
gPciPlatformProtocol,
HostBridgeHandle,
RootBridgeHandle,
RootBridgePciAddress,
Phase,
ChipsetEntry
);
}
Status = PciResAlloc->PreprocessController (
PciResAlloc,
RootBridgeHandle,
RootBridgePciAddress,
Phase
);
if (gPciPlatformProtocol != NULL) {
//
// Call PlatformPci::PrepController() if the protocol is present.
//
gPciPlatformProtocol->PlatformPrepController (
gPciPlatformProtocol,
HostBridgeHandle,
RootBridgeHandle,
RootBridgePciAddress,
Phase,
ChipsetExit
);
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PciHotPlugRequestNotify (
IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,
IN EFI_PCI_HOTPLUG_OPERATION Operation,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,
IN OUT UINT8 *NumberOfChildren,
IN OUT EFI_HANDLE * ChildHandleBuffer
)
/*++
Routine Description:
Hot plug request notify.
Arguments:
This - A pointer to the hot plug request protocol.
Operation - The operation.
Controller - A pointer to the controller.
RemainningDevicePath - A pointer to the device path.
NumberOfChildren - A the number of child handle in the ChildHandleBuffer.
ChildHandleBuffer - A pointer to the array contain the child handle.
Returns:
Status code.
--*/
// TODO: RemainingDevicePath - add argument and description to function comment
// TODO: EFI_NOT_FOUND - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
PCI_IO_DEVICE *Bridge;
PCI_IO_DEVICE *Temp;
EFI_PCI_IO_PROTOCOL *PciIo;
UINTN Index;
EFI_HANDLE RootBridgeHandle;
EFI_STATUS Status;
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
gPciBusDriverBinding.DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);
//
// Get root bridge handle
//
Temp = Bridge;
while (Temp->Parent) {
Temp = Temp->Parent;
}
RootBridgeHandle = Temp->Handle;
if (Operation == EfiPciHotPlugRequestAdd) {
if (NumberOfChildren != NULL) {
*NumberOfChildren = 0;
}
if (IsListEmpty (&Bridge->ChildList)) {
Status = PciBridgeEnumerator (Bridge);
if (EFI_ERROR (Status)) {
return Status;
}
}
Status = StartPciDevicesOnBridge (
RootBridgeHandle,
Bridge,
RemainingDevicePath,
NumberOfChildren,
ChildHandleBuffer
);
return EFI_SUCCESS;
}
if (Operation == EfiPciHotplugRequestRemove) {
if (*NumberOfChildren == 0) {
//
// Remove all devices on the bridge
//
Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);
return Status;
}
for (Index = 0; Index < *NumberOfChildren; Index++) {
//
// De register all the pci device
//
Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// End for
//
return EFI_SUCCESS;
}
return EFI_SUCCESS;
}
BOOLEAN
SearchHostBridgeHandle (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: RootBridgeHandle - add argument and description to function comment
{
EFI_HANDLE HostBridgeHandle;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
UINTN Index;
EFI_STATUS Status;
//
// Get the rootbridge Io protocol to find the host bridge handle
//
Status = gBS->OpenProtocol (
RootBridgeHandle,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **) &PciRootBridgeIo,
gPciBusDriverBinding.DriverBindingHandle,
RootBridgeHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return FALSE;
}
HostBridgeHandle = PciRootBridgeIo->ParentHandle;
for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
return TRUE;
}
}
return FALSE;
}
EFI_STATUS
AddHostBridgeEnumerator (
IN EFI_HANDLE HostBridgeHandle
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
// TODO: HostBridgeHandle - add argument and description to function comment
// TODO: EFI_ABORTED - add return value to function comment
// TODO: EFI_ABORTED - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
UINTN Index;
if (!HostBridgeHandle) {
return EFI_ABORTED;
}
for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
return EFI_ABORTED;
}
}
if (Index < PCI_MAX_HOST_BRIDGE_NUM) {
gPciHostBrigeHandles[Index] = HostBridgeHandle;
gPciHostBridgeNumber++;
}
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?