-\r
-STATIC\r
-VOID\r
-LoadVideoRom (\r
- VOID\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