pcidevicesupport.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,352 行 · 第 1/3 页
C
1,352 行
);
if (EFI_ERROR (Status)) {
return NULL;
}
EfiZeroMem (Dev, sizeof (PCI_IO_DEVICE));
Dev->Signature = PCI_IO_DEVICE_SIGNATURE;
Dev->Handle = RootBridgeHandle;
InitializeListHead (&Dev->ChildList);
Status = gBS->OpenProtocol (
RootBridgeHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
gPciBusDriverBinding.DriverBindingHandle,
RootBridgeHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
gBS->FreePool (Dev);
return NULL;
}
//
// Record the root bridge parent device path
//
Dev->DevicePath = EfiDuplicateDevicePath (ParentDevicePath);
//
// Get the pci root bridge io protocol
//
Status = gBS->OpenProtocol (
RootBridgeHandle,
&gEfiPciRootBridgeIoProtocolGuid,
(VOID **) &PciRootBridgeIo,
gPciBusDriverBinding.DriverBindingHandle,
RootBridgeHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
FreePciDevice (Dev);
return NULL;
}
Dev->PciRootBridgeIo = PciRootBridgeIo;
//
// Initialize the PCI I/O instance structure
//
Status = InitializePciIoInstance (Dev);
Status = InitializePciDriverOverrideInstance (Dev);
//
// Initialize reserved resource list and
// option rom driver list
//
InitializeListHead (&Dev->ReservedResourceList);
InitializeListHead (&Dev->OptionRomDriverList);
return Dev;
}
PCI_IO_DEVICE *
GetRootBridgeByHandle (
EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
Arguments:
RootBridgeHandle - An efi handle.
Returns:
None
--*/
{
PCI_IO_DEVICE *RootBridgeDev;
EFI_LIST_ENTRY *CurrentLink;
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (RootBridgeDev->Handle == RootBridgeHandle) {
return RootBridgeDev;
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}
BOOLEAN
RootBridgeExisted (
IN EFI_HANDLE RootBridgeHandle
)
/*++
Routine Description:
This function searches if RootBridgeHandle has already existed
in current device pool.
If so, it means the given root bridge has been already enumerated.
Arguments:
RootBridgeHandle - An efi handle.
Returns:
None
--*/
{
PCI_IO_DEVICE *Bridge;
Bridge = GetRootBridgeByHandle (RootBridgeHandle);
if (Bridge != NULL) {
return TRUE;
}
return FALSE;
}
BOOLEAN
PciDeviceExisted (
IN PCI_IO_DEVICE *Bridge,
IN PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Arguments:
Bridge - A pointer to the PCI_IO_DEVICE.
PciIoDevice - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
PCI_IO_DEVICE *Temp;
EFI_LIST_ENTRY *CurrentLink;
CurrentLink = Bridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &Bridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp == PciIoDevice) {
return TRUE;
}
if (!IsListEmpty (&Temp->ChildList)) {
if (PciDeviceExisted (Temp, PciIoDevice)) {
return TRUE;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return FALSE;
}
PCI_IO_DEVICE *
ActiveVGADeviceOnTheSameSegment (
IN PCI_IO_DEVICE *VgaDevice
)
/*++
Routine Description:
Arguments:
VgaDevice - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
EFI_LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) {
Temp = ActiveVGADeviceOnTheRootBridge (Temp);
if (Temp != NULL) {
return Temp;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}
PCI_IO_DEVICE *
ActiveVGADeviceOnTheRootBridge (
IN PCI_IO_DEVICE *RootBridge
)
/*++
Routine Description:
Arguments:
RootBridge - A pointer to the PCI_IO_DEVICE.
Returns:
None
--*/
{
EFI_LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Temp;
CurrentLink = RootBridge->ChildList.ForwardLink;
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (IS_PCI_VGA(&Temp->Pci) &&
(Temp->Attributes &
(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY |
EFI_PCI_IO_ATTRIBUTE_VGA_IO |
EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) {
return Temp;
}
if (IS_PCI_BRIDGE (&Temp->Pci)) {
Temp = ActiveVGADeviceOnTheRootBridge (Temp);
if (Temp != NULL) {
return Temp;
}
}
CurrentLink = CurrentLink->ForwardLink;
}
return NULL;
}
EFI_STATUS
GetHpcPciAddress (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
OUT UINT64 *PciAddress
)
/*++
Routine Description:
Arguments:
PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
PciAddress - A pointer to the pci address.
Returns:
None
--*/
// TODO: EFI_NOT_FOUND - add return value to function comment
// TODO: EFI_NOT_FOUND - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_NOT_FOUND - add return value to function comment
{
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
EFI_DEV_PATH_PTR Node;
EFI_LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *RootBridge;
EFI_STATUS Status;
CurrentDevicePath = HpcDevicePath;
//
// Get the remaining device path for this PCI device, if it is a PCI device
//
while (!EfiIsDevicePathEnd (CurrentDevicePath)) {
Node.DevPath = CurrentDevicePath;
//
// Check if it is PCI device Path?
//
if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
Node.DevPath->SubType != HW_PCI_DP &&
DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)) {
CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
continue;
}
break;
}
//
// Check if it is not PCI device path
//
if (EfiIsDevicePathEnd (CurrentDevicePath)) {
return EFI_NOT_FOUND;
}
CurrentLink = gPciDevicePool.ForwardLink;
while (CurrentLink && CurrentLink != &gPciDevicePool) {
RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
//
// Locate the right root bridge to start
//
if (RootBridge->PciRootBridgeIo == PciRootBridgeIo) {
Status = GetHpcPciAddressFromRootBridge (
RootBridge,
CurrentDevicePath,
PciAddress
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
CurrentLink = CurrentLink->ForwardLink;
}
return EFI_NOT_FOUND;
}
EFI_STATUS
GetHpcPciAddressFromRootBridge (
IN PCI_IO_DEVICE *RootBridge,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
OUT UINT64 *PciAddress
)
/*++
Routine Description:
Arguments:
PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
PciAddress - A pointer to the pci address.
Returns:
None
--*/
// TODO: RootBridge - add argument and description to function comment
// TODO: RemainingDevicePath - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_NOT_FOUND - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_DEV_PATH_PTR Node;
PCI_IO_DEVICE *Temp;
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
EFI_LIST_ENTRY *CurrentLink;
BOOLEAN MisMatch;
MisMatch = FALSE;
CurrentDevicePath = RemainingDevicePath;
Node.DevPath = CurrentDevicePath;
Temp = NULL;
while (!EfiIsDevicePathEnd (CurrentDevicePath)) {
CurrentLink = RootBridge->ChildList.ForwardLink;
Node.DevPath = CurrentDevicePath;
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Node.Pci->Device == Temp->DeviceNumber &&
Node.Pci->Function == Temp->FunctionNumber) {
RootBridge = Temp;
break;
}
CurrentLink = CurrentLink->ForwardLink;
}
//
// Check if we find the bridge
//
if (CurrentLink == &RootBridge->ChildList) {
MisMatch = TRUE;
break;
}
CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
}
if (MisMatch) {
CurrentDevicePath = EfiNextDevicePathNode (CurrentDevicePath);
if (EfiIsDevicePathEnd (CurrentDevicePath)) {
*PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0);
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}
*PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?