mirror of https://github.com/acidanthera/audk.git
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:
parent
347bbfc6ed
commit
5106d42295
|
@ -32,6 +32,17 @@ InstallDevicePathCallback (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
LoadVideoRom (
|
||||||
|
);
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
PciRomLoadEfiDriversFromRomImage (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS Rom,
|
||||||
|
IN UINTN RomSize
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// BDS Platform Functions
|
// BDS Platform Functions
|
||||||
|
@ -58,6 +69,7 @@ Returns:
|
||||||
{
|
{
|
||||||
DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));
|
DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));
|
||||||
InstallDevicePathCallback ();
|
InstallDevicePathCallback ();
|
||||||
|
LoadVideoRom ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1203,3 +1215,175 @@ LockKeyboards (
|
||||||
{
|
{
|
||||||
return EFI_UNSUPPORTED;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ Abstract:
|
||||||
#include <IndustryStandard/Pci.h>
|
#include <IndustryStandard/Pci.h>
|
||||||
#include <IndustryStandard/Acpi.h>
|
#include <IndustryStandard/Acpi.h>
|
||||||
#include <IndustryStandard/SmBios.h>
|
#include <IndustryStandard/SmBios.h>
|
||||||
//#include <IndustryStandard/LegacyBiosMpTable.h>
|
#include <IndustryStandard/PeImage.h>
|
||||||
|
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
@ -47,6 +47,7 @@ Abstract:
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
|
|
||||||
|
#include <Protocol/Decompress.h>
|
||||||
#include <Protocol/PciIo.h>
|
#include <Protocol/PciIo.h>
|
||||||
#include <Protocol/FirmwareVolume2.h>
|
#include <Protocol/FirmwareVolume2.h>
|
||||||
|
|
||||||
|
|
|
@ -55,3 +55,6 @@
|
||||||
[Pcd.IA32, Pcd.X64]
|
[Pcd.IA32, Pcd.X64]
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
|
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiDecompressProtocolGuid
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue