Load video option ROM which is not embedded in system firmware image.

QEMU will automatically fill the video BIOS image into memory at the
legacy video BIOS memory location (0xc0000).  This code will look
there for a EFI option rom image, and load it if it found.  This
allows the video option ROM to be separated out from the main system
firmware image.

QEMU does not appear to emulate the PCI rom expansion method
for making the video BIOS available to the system.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8942 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jljusten 2009-07-14 23:32:32 +00:00
parent 347bbfc6ed
commit 5106d42295
3 changed files with 189 additions and 1 deletions

View File

@ -32,6 +32,17 @@ InstallDevicePathCallback (
VOID
);
STATIC
VOID
LoadVideoRom (
);
STATIC
EFI_STATUS
PciRomLoadEfiDriversFromRomImage (
IN EFI_PHYSICAL_ADDRESS Rom,
IN UINTN RomSize
);
//
// BDS Platform Functions
@ -58,6 +69,7 @@ Returns:
{
DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));
InstallDevicePathCallback ();
LoadVideoRom ();
}
@ -1203,3 +1215,175 @@ LockKeyboards (
{
return EFI_UNSUPPORTED;
}
STATIC
VOID
LoadVideoRom (
)
{
PCI_DATA_STRUCTURE *Pcir;
UINTN RomSize;
//
// The virtual machines sometimes load the video rom image
// directly at the legacy video BIOS location of C000:0000,
// and do not implement the PCI expansion ROM feature.
//
Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000;
RomSize = Pcir->ImageLength * 512;
PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize);
}
STATIC
EFI_STATUS
PciRomLoadEfiDriversFromRomImage (
IN EFI_PHYSICAL_ADDRESS Rom,
IN UINTN RomSize
)
{
CHAR16 *FileName;
EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;
PCI_DATA_STRUCTURE *Pcir;
UINTN ImageIndex;
UINTN RomOffset;
UINT32 ImageSize;
UINT16 ImageOffset;
EFI_HANDLE ImageHandle;
EFI_STATUS Status;
EFI_STATUS retStatus;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
BOOLEAN SkipImage;
UINT32 DestinationSize;
UINT32 ScratchSize;
UINT8 *Scratch;
VOID *ImageBuffer;
VOID *DecompressedImageBuffer;
UINT32 ImageLength;
EFI_DECOMPRESS_PROTOCOL *Decompress;
FileName = L"PciRomInMemory";
//FileName = L"PciRom Addr=0000000000000000";
//HexToString (&FileName[12], Rom, 16);
ImageIndex = 0;
retStatus = EFI_NOT_FOUND;
RomOffset = (UINTN) Rom;
do {
EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;
if (EfiRomHeader->Signature != 0xaa55) {
return retStatus;
}
Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset);
ImageSize = Pcir->ImageLength * 512;
if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&
(EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {
if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||
(EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {
ImageOffset = EfiRomHeader->EfiImageHeaderOffset;
ImageSize = EfiRomHeader->InitializationSize * 512;
ImageBuffer = (VOID *) (UINTN) (RomOffset + ImageOffset);
ImageLength = ImageSize - ImageOffset;
DecompressedImageBuffer = NULL;
//
// decompress here if needed
//
SkipImage = FALSE;
if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
SkipImage = TRUE;
}
if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {
Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
if (EFI_ERROR (Status)) {
SkipImage = TRUE;
} else {
SkipImage = TRUE;
Status = Decompress->GetInfo (
Decompress,
ImageBuffer,
ImageLength,
&DestinationSize,
&ScratchSize
);
if (!EFI_ERROR (Status)) {
DecompressedImageBuffer = NULL;
DecompressedImageBuffer = AllocatePool (DestinationSize);
if (DecompressedImageBuffer != NULL) {
Scratch = AllocatePool (ScratchSize);
if (Scratch != NULL) {
Status = Decompress->Decompress (
Decompress,
ImageBuffer,
ImageLength,
DecompressedImageBuffer,
DestinationSize,
Scratch,
ScratchSize
);
if (!EFI_ERROR (Status)) {
ImageBuffer = DecompressedImageBuffer;
ImageLength = DestinationSize;
SkipImage = FALSE;
}
gBS->FreePool (Scratch);
}
}
}
}
}
if (!SkipImage) {
//
// load image and start image
//
FilePath = FileDevicePath (NULL, FileName);
Status = gBS->LoadImage (
FALSE,
gImageHandle,
FilePath,
ImageBuffer,
ImageLength,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
Status = gBS->StartImage (ImageHandle, NULL, NULL);
if (!EFI_ERROR (Status)) {
retStatus = Status;
}
}
if (FilePath != NULL) {
gBS->FreePool (FilePath);
}
}
if (DecompressedImageBuffer != NULL) {
gBS->FreePool (DecompressedImageBuffer);
}
}
}
RomOffset = RomOffset + ImageSize;
ImageIndex++;
} while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize));
return retStatus;
}

View File

@ -29,7 +29,7 @@ Abstract:
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/SmBios.h>
//#include <IndustryStandard/LegacyBiosMpTable.h>
#include <IndustryStandard/PeImage.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
@ -47,6 +47,7 @@ Abstract:
#include <Library/DevicePathLib.h>
#include <Library/IoLib.h>
#include <Protocol/Decompress.h>
#include <Protocol/PciIo.h>
#include <Protocol/FirmwareVolume2.h>

View File

@ -55,3 +55,6 @@
[Pcd.IA32, Pcd.X64]
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
[Protocols]
gEfiDecompressProtocolGuid