OVMF BDS: Implement routines to make it easier to scan through all PCI devices.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9274 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jljusten 2009-09-16 16:29:00 +00:00
parent 4b45b3cb20
commit e955462be2
1 changed files with 199 additions and 88 deletions

View File

@ -21,12 +21,51 @@
VOID *mEfiDevPathNotifyReg; VOID *mEfiDevPathNotifyReg;
EFI_EVENT mEfiDevPathEvent; EFI_EVENT mEfiDevPathEvent;
BOOLEAN mDetectVgaOnly;
//
// Type definitions
//
typedef
EFI_STATUS
(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(
IN EFI_HANDLE Handle,
IN VOID *Instance,
IN VOID *Context
);
/**
@param[in] Handle - Handle of PCI device instance
@param[in] PciIo - PCI IO protocol instance
@param[in] Pci - PCI Header register block
**/
typedef
EFI_STATUS
(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
IN EFI_HANDLE Handle,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN PCI_TYPE00 *Pci
);
// //
// Function prototypes // Function prototypes
// //
EFI_STATUS
VisitAllInstancesOfProtocol (
IN EFI_GUID *Id,
IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
IN VOID *Context
);
EFI_STATUS
VisitAllPciInstancesOfProtocol (
IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
);
VOID VOID
InstallDevicePathCallback ( InstallDevicePathCallback (
VOID VOID
@ -399,32 +438,17 @@ Returns:
} }
EFI_STATUS EFI_STATUS
DetectAndPreparePlatformPciDevicePath ( VisitAllInstancesOfProtocol (
BOOLEAN DetectVgaOnly IN EFI_GUID *Id,
IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
IN VOID *Context
) )
/*++
Routine Description:
Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
Arguments:
DetectVgaOnly - Only detect VGA device if it's TRUE.
Returns:
EFI_SUCCESS - PCI Device check and Console variable update successfully.
EFI_STATUS - PCI Device check or Console variable update fail.
--*/
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINTN HandleCount; UINTN HandleCount;
EFI_HANDLE *HandleBuffer; EFI_HANDLE *HandleBuffer;
UINTN Index; UINTN Index;
EFI_PCI_IO_PROTOCOL *PciIo; VOID *Instance;
PCI_TYPE00 Pci;
// //
// Start to check all the PciIo to find all possible device // Start to check all the PciIo to find all possible device
@ -433,7 +457,7 @@ Returns:
HandleBuffer = NULL; HandleBuffer = NULL;
Status = gBS->LocateHandleBuffer ( Status = gBS->LocateHandleBuffer (
ByProtocol, ByProtocol,
&gEfiPciIoProtocolGuid, Id,
NULL, NULL,
&HandleCount, &HandleCount,
&HandleBuffer &HandleBuffer
@ -443,75 +467,16 @@ Returns:
} }
for (Index = 0; Index < HandleCount; Index++) { for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo); Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
continue; continue;
} }
// Status = (*CallBackFunction) (
// Check for all PCI device HandleBuffer[Index],
// Instance,
Status = PciIo->Pci.Read ( Context
PciIo, );
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
if (EFI_ERROR (Status)) {
continue;
}
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
ASSERT_EFI_ERROR (Status);
if (!DetectVgaOnly) {
//
// Here we decide whether it is LPC Bridge
//
if ((IS_PCI_LPC (&Pci)) ||
((IS_PCI_ISA_PDECODE (&Pci)) &&
(Pci.Hdr.VendorId == 0x8086) &&
(Pci.Hdr.DeviceId == 0x7000)
)
) {
//
// Add IsaKeyboard to ConIn,
// add IsaSerial to ConOut, ConIn, ErrOut
//
DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
PrepareLpcBridgeDevicePath (HandleBuffer[Index]);
continue;
}
//
// Here we decide which Serial device to enable in PCI bus
//
if (IS_PCI_16550SERIAL (&Pci)) {
//
// Add them to ConOut, ConIn, ErrOut.
//
DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
PreparePciSerialDevicePath (HandleBuffer[Index]);
continue;
}
}
//
// Here we decide which VGA device to enable in PCI bus
//
if (IS_PCI_VGA (&Pci)) {
//
// Add them to ConOut.
//
DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));
PreparePciVgaDevicePath (HandleBuffer[Index]);
continue;
}
} }
gBS->FreePool (HandleBuffer); gBS->FreePool (HandleBuffer);
@ -520,6 +485,152 @@ Returns:
} }
EFI_STATUS
EFIAPI
VisitingAPciInstance (
IN EFI_HANDLE Handle,
IN VOID *Instance,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;
//
// Check for all PCI device
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
if (EFI_ERROR (Status)) {
return Status;
}
return (*(VISIT_PCI_INSTANCE_CALLBACK) Context) (
Handle,
PciIo,
&Pci
);
}
EFI_STATUS
VisitAllPciInstances (
IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
)
{
return VisitAllInstancesOfProtocol (
&gEfiPciIoProtocolGuid,
VisitingAPciInstance,
(VOID*) CallBackFunction
);
}
/**
Do platform specific PCI Device check and add them to
ConOut, ConIn, ErrOut.
@param[in] Handle - Handle of PCI device instance
@param[in] PciIo - PCI IO protocol instance
@param[in] Pci - PCI Header register block
@retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
@retval EFI_STATUS - PCI Device check or Console variable update fail.
**/
EFI_STATUS
DetectAndPreparePlatformPciDevicePath (
IN EFI_HANDLE Handle,
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN PCI_TYPE00 *Pci
)
{
EFI_STATUS Status;
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
ASSERT_EFI_ERROR (Status);
if (!mDetectVgaOnly) {
//
// Here we decide whether it is LPC Bridge
//
if ((IS_PCI_LPC (Pci)) ||
((IS_PCI_ISA_PDECODE (Pci)) &&
(Pci->Hdr.VendorId == 0x8086) &&
(Pci->Hdr.DeviceId == 0x7000)
)
) {
//
// Add IsaKeyboard to ConIn,
// add IsaSerial to ConOut, ConIn, ErrOut
//
DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
PrepareLpcBridgeDevicePath (Handle);
return EFI_SUCCESS;
}
//
// Here we decide which Serial device to enable in PCI bus
//
if (IS_PCI_16550SERIAL (Pci)) {
//
// Add them to ConOut, ConIn, ErrOut.
//
DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
PreparePciSerialDevicePath (Handle);
return EFI_SUCCESS;
}
}
//
// Here we decide which VGA device to enable in PCI bus
//
if (IS_PCI_VGA (Pci)) {
//
// Add them to ConOut.
//
DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));
PreparePciVgaDevicePath (Handle);
return EFI_SUCCESS;
}
return Status;
}
/**
Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
@param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
@retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
@retval EFI_STATUS - PCI Device check or Console variable update fail.
**/
EFI_STATUS
DetectAndPreparePlatformPciDevicePaths (
BOOLEAN DetectVgaOnly
)
{
mDetectVgaOnly = DetectVgaOnly;
return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
}
EFI_STATUS EFI_STATUS
PlatformBdsConnectConsole ( PlatformBdsConnectConsole (
IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
@ -572,7 +683,7 @@ Returns:
// //
// Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
// //
DetectAndPreparePlatformPciDevicePath (FALSE); DetectAndPreparePlatformPciDevicePaths (FALSE);
// //
// Have chance to connect the platform default console, // Have chance to connect the platform default console,
@ -597,7 +708,7 @@ Returns:
// //
// Only detect VGA device and add them to ConOut // Only detect VGA device and add them to ConOut
// //
DetectAndPreparePlatformPciDevicePath (TRUE); DetectAndPreparePlatformPciDevicePaths (TRUE);
} }
// //