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