-/**@file\r
+/** @file\r
+ PCI Rom supporting funtions implementation for PCI Bus module.\r
\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+Copyright (c) 2006 - 2009, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PciBus.h"\r
+\r
+/**\r
+ Load the EFI Image from Option ROM\r
+\r
+ @param PciIoDevice PCI IO device instance.\r
+ @param FilePath The file path of the EFI Image\r
+ @param BufferSize On input the size of Buffer in bytes. On output with a return\r
+ code of EFI_SUCCESS, the amount of data transferred to Buffer.\r
+ On output with a return code of EFI_BUFFER_TOO_SMALL,\r
+ the size of Buffer required to retrieve the requested file.\r
+ @param Buffer The memory buffer to transfer the file to. If Buffer is NULL,\r
+ then no the size of the requested file is returned in BufferSize.\r
+\r
+ @retval EFI_SUCCESS The file was loaded.\r
+ @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or\r
+ BufferSize is NULL.\r
+ @retval EFI_NOT_FOUND Not found PCI Option Rom on PCI device.\r
+ @retval EFI_DEVICE_ERROR Failed to decompress PCI Option Rom image.\r
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
+ BufferSize has been updated with the size needed to complete the request.\r
**/\r
+EFI_STATUS\r
+LocalLoadFile2 (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ IN OUT UINTN *BufferSize,\r
+ IN VOID *Buffer OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *EfiOpRomImageNode;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+ UINT32 ImageSize;\r
+ UINT8 *ImageBuffer;\r
+ UINT32 ImageLength;\r
+ UINT32 DestinationSize;\r
+ UINT32 ScratchSize;\r
+ VOID *Scratch;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
+\r
+ EfiOpRomImageNode = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) FilePath;\r
+ if ((EfiOpRomImageNode == NULL) ||\r
+ (DevicePathType (FilePath) != MEDIA_DEVICE_PATH) ||\r
+ (DevicePathSubType (FilePath) != MEDIA_RELATIVE_OFFSET_RANGE_DP) ||\r
+ (DevicePathNodeLength (FilePath) != sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)) ||\r
+ (!IsDevicePathEnd (NextDevicePathNode (FilePath))) ||\r
+ (EfiOpRomImageNode->StartingOffset > EfiOpRomImageNode->EndingOffset) ||\r
+ (EfiOpRomImageNode->EndingOffset >= PciIoDevice->RomSize) ||\r
+ (BufferSize == NULL)\r
+ ) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (\r
+ (UINT8 *) PciIoDevice->PciIo.RomImage + EfiOpRomImageNode->StartingOffset\r
+ );\r
+ if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+\r
+ Pcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) EfiRomHeader + EfiRomHeader->PcirOffset);\r
+\r
+\r
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&\r
+ ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) &&\r
+ (EfiRomHeader->CompressionType <= EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED)\r
+ ) {\r
+\r
+ ImageSize = (UINT32) EfiRomHeader->InitializationSize * 512;\r
+ ImageBuffer = (UINT8 *) EfiRomHeader + EfiRomHeader->EfiImageHeaderOffset;\r
+ ImageLength = ImageSize - EfiRomHeader->EfiImageHeaderOffset;\r
+\r
+ if (EfiRomHeader->CompressionType != EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ //\r
+ // Uncompressed: Copy the EFI Image directly to user's buffer\r
+ //\r
+ if (Buffer == NULL || *BufferSize < ImageLength) {\r
+ *BufferSize = ImageLength;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *BufferSize = ImageLength;\r
+ CopyMem (Buffer, ImageBuffer, ImageLength);\r
+ return EFI_SUCCESS;\r
+\r
+ } else {\r
+ //\r
+ // Compressed: Uncompress before copying\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ Status = Decompress->GetInfo (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Buffer == NULL || *BufferSize < DestinationSize) {\r
+ *BufferSize = DestinationSize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *BufferSize = DestinationSize;\r
+ Scratch = AllocatePool (ScratchSize);\r
+ if (Scratch == NULL) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = Decompress->Decompress (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ Buffer,\r
+ DestinationSize,\r
+ Scratch,\r
+ ScratchSize\r
+ );\r
+ FreePool (Scratch);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Initialize a PCI LoadFile2 instance.\r
\r
-#include "pcibus.h"\r
-#include "PciResourceSupport.h"\r
-\r
-#include <IndustryStandard/Pci23.h>\r
-\r
-//\r
-// Module global for a template of the PCI option ROM Image Device Path Node\r
-//\r
-MEMMAP_DEVICE_PATH mPciOptionRomImageDevicePathNodeTemplate = {\r
- { \r
- HARDWARE_DEVICE_PATH,\r
- HW_MEMMAP_DP,\r
- sizeof (MEMMAP_DEVICE_PATH)\r
- },\r
- EfiMemoryMappedIO,\r
- 0,\r
- 0\r
-};\r
+ @param PciIoDevice PCI IO Device.\r
\r
+**/\r
+VOID\r
+InitializePciLoadFile2 (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ PciIoDevice->LoadFile2.LoadFile = LoadFile2;\r
+}\r
+\r
+/**\r
+ Causes the driver to load a specified file.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param FilePath The device specific path of the file to load.\r
+ @param BootPolicy Should always be FALSE.\r
+ @param BufferSize On input the size of Buffer in bytes. On output with a return\r
+ code of EFI_SUCCESS, the amount of data transferred to Buffer.\r
+ On output with a return code of EFI_BUFFER_TOO_SMALL,\r
+ the size of Buffer required to retrieve the requested file.\r
+ @param Buffer The memory buffer to transfer the file to. If Buffer is NULL,\r
+ then no the size of the requested file is returned in BufferSize.\r
+\r
+ @retval EFI_SUCCESS The file was loaded.\r
+ @retval EFI_UNSUPPORTED BootPolicy is TRUE.\r
+ @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or\r
+ BufferSize is NULL.\r
+ @retval EFI_NOT_FOUND Not found PCI Option Rom on PCI device.\r
+ @retval EFI_DEVICE_ERROR Failed to decompress PCI Option Rom image.\r
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
+ BufferSize has been updated with the size needed to complete the request.\r
+\r
+**/\r
EFI_STATUS\r
-GetOpRomInfo (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+EFIAPI\r
+LoadFile2 (\r
+ IN EFI_LOAD_FILE2_PROTOCOL *This,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ IN BOOLEAN BootPolicy,\r
+ IN OUT UINTN *BufferSize,\r
+ IN VOID *Buffer OPTIONAL\r
)\r
-/*++\r
+{\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+\r
+ if (BootPolicy) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ PciIoDevice = PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS (This);\r
+\r
+ return LocalLoadFile2 (\r
+ PciIoDevice,\r
+ FilePath,\r
+ BufferSize,\r
+ Buffer\r
+ );\r
+}\r
\r
-Routine Description:\r
+/**\r
+ Get Pci device's oprom infor bits.\r
\r
-Arguments:\r
+ @param PciIoDevice Pci device instance.\r
\r
-Returns:\r
+ @retval EFI_NOT_FOUND Pci device has not Option Rom.\r
+ @retval EFI_SUCCESS Pci device has Option Rom.\r
\r
---*/\r
-// TODO: PciIoDevice - add argument and description to function comment\r
-// TODO: EFI_NOT_FOUND - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+GetOpRomInfo (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
{\r
UINT8 RomBarIndex;\r
UINT32 AllOnes;\r
PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;\r
\r
//\r
- // offset is 0x30 if is not ppb\r
+ // Offset is 0x30 if is not ppb\r
//\r
\r
//\r
// 0x30\r
//\r
- RomBarIndex = PCI_DEVICE_ROMBAR;\r
+ RomBarIndex = PCI_EXPANSION_ROM_BASE;\r
\r
if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
//\r
- // if is ppb\r
+ // If is ppb\r
//\r
\r
//\r
RomBarIndex = PCI_BRIDGE_ROMBAR;\r
}\r
//\r
- // the bit0 is 0 to prevent the enabling of the Rom address decoder\r
+ // The bit0 is 0 to prevent the enabling of the Rom address decoder\r
//\r
AllOnes = 0xfffffffe;\r
Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex);\r
&AllOnes\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ return EFI_NOT_FOUND;\r
}\r
\r
//\r
- // read back\r
+ // Read back\r
//\r
Status = PciRootBridgeIoRead (\r
PciRootBridgeIo,\r
&AllOnes\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ return EFI_NOT_FOUND;\r
}\r
//\r
// Bits [1, 10] are reserved\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-LoadOpRomImage (\r
- IN PCI_IO_DEVICE *PciDevice,\r
- IN UINT64 RomBase\r
+/**\r
+ Check if the RomImage contains EFI Images.\r
+\r
+ @param RomImage The ROM address of Image for check.\r
+ @param RomSize Size of ROM for check.\r
+\r
+ @retval TRUE ROM contain EFI Image.\r
+ @retval FALSE ROM not contain EFI Image.\r
+\r
+**/\r
+BOOLEAN\r
+ContainEfiImage (\r
+ IN VOID *RomImage,\r
+ IN UINT64 RomSize\r
)\r
-/*++\r
+{\r
+ PCI_EXPANSION_ROM_HEADER *RomHeader;\r
+ PCI_DATA_STRUCTURE *RomPcir;\r
+ BOOLEAN FirstCheck;\r
+\r
+ FirstCheck = TRUE;\r
+ RomHeader = RomImage;\r
+\r
+ while ((UINT8 *) RomHeader < (UINT8 *) RomImage + RomSize) {\r
+ if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ if (FirstCheck) {\r
+ return FALSE;\r
+ } else {\r
+ RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + 512);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ FirstCheck = FALSE;\r
+ RomPcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) RomHeader + RomHeader->PcirOffset);\r
+\r
+ if (RomPcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
+ return TRUE;\r
+ }\r
+\r
+ RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + RomPcir->Length * 512);\r
+ }\r
+\r
+ return FALSE;\r
+}\r
\r
-Routine Description:\r
- \r
- Load option rom image for specified PCI device\r
\r
-Arguments:\r
+/**\r
+ Load Option Rom image for specified PCI device.\r
\r
-Returns:\r
+ @param PciDevice Pci device instance.\r
+ @param RomBase Base address of Option Rom.\r
\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: RomBase - add argument and description to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+ @retval EFI_OUT_OF_RESOURCES No enough memory to hold image.\r
+ @retval EFI_SUCESS Successfully loaded Option Rom.\r
+\r
+**/\r
+EFI_STATUS\r
+LoadOpRomImage (\r
+ IN PCI_IO_DEVICE *PciDevice,\r
+ IN UINT64 RomBase\r
+ )\r
{\r
UINT8 RomBarIndex;\r
UINT8 Indicator;\r
UINT16 OffsetPcir;\r
UINT32 RomBarOffset;\r
UINT32 RomBar;\r
- EFI_STATUS retStatus;\r
+ EFI_STATUS RetStatus;\r
BOOLEAN FirstCheck;\r
UINT8 *Image;\r
PCI_EXPANSION_ROM_HEADER *RomHeader;\r
//\r
// 0x30\r
//\r
- RomBarIndex = PCI_DEVICE_ROMBAR;\r
+ RomBarIndex = PCI_EXPANSION_ROM_BASE;\r
if (IS_PCI_BRIDGE (&(PciDevice->Pci))) {\r
//\r
// if is ppb\r
\r
RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE));\r
if (RomPcir == NULL) {\r
- gBS->FreePool (RomHeader);\r
+ FreePool (RomHeader);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
RomDecode (PciDevice, RomBarIndex, RomBar, TRUE);\r
\r
RomBarOffset = RomBar;\r
- retStatus = EFI_NOT_FOUND;\r
+ RetStatus = EFI_NOT_FOUND;\r
FirstCheck = TRUE;\r
\r
do {\r
}\r
\r
if (RomImageSize > 0) {\r
- retStatus = EFI_SUCCESS;\r
+ RetStatus = EFI_SUCCESS;\r
Image = AllocatePool ((UINT32) RomImageSize);\r
if (Image == NULL) {\r
RomDecode (PciDevice, RomBarIndex, RomBar, FALSE);\r
- gBS->FreePool (RomHeader);\r
- gBS->FreePool (RomPcir);\r
+ FreePool (RomHeader);\r
+ FreePool (RomPcir);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- \r
+\r
//\r
// Copy Rom image into memory\r
//\r
PciDevice->PciIo.RomSize = RomImageSize;\r
PciDevice->PciIo.RomImage = RomInMemory;\r
\r
+ //\r
+ // For OpROM read from PCI device:\r
+ // Add the Rom Image to internal database for later PCI light enumeration\r
+ //\r
PciRomAddImageMapping (\r
NULL,\r
PciDevice->PciRootBridgeIo->SegmentNumber,\r
//\r
// Free allocated memory\r
//\r
- gBS->FreePool (RomHeader);\r
- gBS->FreePool (RomPcir);\r
+ FreePool (RomHeader);\r
+ FreePool (RomPcir);\r
\r
- return retStatus;\r
+ return RetStatus;\r
}\r
\r
-EFI_STATUS\r
+/**\r
+ Enable/Disable Option Rom decode.\r
+\r
+ @param PciDevice Pci device instance.\r
+ @param RomBarIndex The BAR index of the standard PCI Configuration header to use as the\r
+ base address for resource range. The legal range for this field is 0..5.\r
+ @param RomBar Base address of Option Rom.\r
+ @param Enable Flag for enable/disable decode.\r
+\r
+**/\r
+VOID\r
RomDecode (\r
IN PCI_IO_DEVICE *PciDevice,\r
IN UINT8 RomBarIndex,\r
IN UINT32 RomBar,\r
IN BOOLEAN Enable\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-// TODO: PciDevice - add argument and description to function comment\r
-// TODO: RomBarIndex - add argument and description to function comment\r
-// TODO: RomBar - add argument and description to function comment\r
-// TODO: Enable - add argument and description to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
{\r
UINT32 Value32;\r
UINT32 Offset;\r
for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
PciIoWrite (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero);\r
}\r
- \r
+\r
//\r
// set the Rom base address: now is hardcode\r
// enable its decoder\r
//\r
// Setting the memory space bit in the function's command register\r
//\r
- PciEnableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+ PCI_ENABLE_COMMAND_REGISTER(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
\r
} else {\r
- \r
+\r
//\r
// disable command register decode to memory\r
//\r
- PciDisableCommandRegister(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
+ PCI_DISABLE_COMMAND_REGISTER(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE);\r
\r
//\r
// Destroy the programmed bar in all the upstream bridge.\r
);\r
\r
}\r
+}\r
\r
- return EFI_SUCCESS;\r
+/**\r
+ Load and start the Option Rom image.\r
\r
-}\r
+ @param PciDevice Pci device instance.\r
+\r
+ @retval EFI_SUCCESS Successfully loaded and started PCI Option Rom image.\r
+ @retval EFI_NOT_FOUND Failed to process PCI Option Rom image.\r
\r
+**/\r
EFI_STATUS\r
ProcessOpRomImage (\r
- PCI_IO_DEVICE *PciDevice\r
+ IN PCI_IO_DEVICE *PciDevice\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Process the oprom image.\r
- \r
-Arguments:\r
- PciDevice A pointer to a pci device.\r
-\r
-Returns:\r
-\r
- EFI Status.\r
- \r
---*/\r
{\r
- UINT8 Indicator;\r
- UINT32 ImageSize;\r
- UINT16 ImageOffset;\r
- VOID *RomBar;\r
- UINT8 *RomBarOffset;\r
- EFI_HANDLE ImageHandle;\r
- EFI_STATUS Status;\r
- EFI_STATUS retStatus;\r
- BOOLEAN FirstCheck;\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
- EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
- PCI_DATA_STRUCTURE *Pcir;\r
- EFI_DEVICE_PATH_PROTOCOL *PciOptionRomImageDevicePath;\r
+ UINT8 Indicator;\r
+ UINT32 ImageSize;\r
+ VOID *RomBar;\r
+ UINT8 *RomBarOffset;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS RetStatus;\r
+ BOOLEAN FirstCheck;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+ EFI_DEVICE_PATH_PROTOCOL *PciOptionRomImageDevicePath;\r
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH EfiOpRomImageNode;\r
+ VOID *Buffer;\r
+ UINTN BufferSize;\r
\r
Indicator = 0;\r
\r
//\r
- // Get the Address of the Rom image\r
+ // Get the Address of the Option Rom image\r
//\r
RomBar = PciDevice->PciIo.RomImage;\r
RomBarOffset = (UINT8 *) RomBar;\r
- retStatus = EFI_NOT_FOUND;\r
+ RetStatus = EFI_NOT_FOUND;\r
FirstCheck = TRUE;\r
\r
do {\r
EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
- RomBarOffset = RomBarOffset + 512;\r
+ RomBarOffset += 512;\r
if (FirstCheck) {\r
break;\r
} else {\r
ImageSize = (UINT32) (Pcir->ImageLength * 512);\r
Indicator = Pcir->Indicator;\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 = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
-\r
- ImageBuffer = (VOID *) (RomBarOffset + ImageOffset);\r
- ImageLength = ImageSize - (UINT32)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
- // Build full device path to the PCI Option ROM Image being loaded\r
- //\r
- mPciOptionRomImageDevicePathNodeTemplate.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)RomBarOffset;\r
- mPciOptionRomImageDevicePathNodeTemplate.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(RomBarOffset + ImageSize - 1);\r
- PciOptionRomImageDevicePath = AppendDevicePathNode (PciDevice->DevicePath, (const EFI_DEVICE_PATH_PROTOCOL *)&mPciOptionRomImageDevicePathNodeTemplate);\r
- ASSERT (PciOptionRomImageDevicePath != NULL);\r
-\r
- //\r
- // load image and start image\r
- //\r
- Status = gBS->LoadImage (\r
- FALSE,\r
- gPciBusDriverBinding.DriverBindingHandle,\r
- PciOptionRomImageDevicePath,\r
- ImageBuffer,\r
- ImageLength,\r
- &ImageHandle\r
- );\r
-\r
- //\r
- // Free the device path after it has been used by LoadImage\r
- //\r
- gBS->FreePool (PciOptionRomImageDevicePath);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
- if (!EFI_ERROR (Status)) {\r
- AddDriver (PciDevice, ImageHandle);\r
- PciRomAddImageMapping (\r
- ImageHandle,\r
- PciDevice->PciRootBridgeIo->SegmentNumber,\r
- PciDevice->BusNumber,\r
- PciDevice->DeviceNumber,\r
- PciDevice->FunctionNumber,\r
- (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
- PciDevice->PciIo.RomSize\r
- );\r
- retStatus = EFI_SUCCESS;\r
- }\r
- }\r
- }\r
+ //\r
+ // Create Pci Option Rom Image device path header\r
+ //\r
+ EfiOpRomImageNode.Header.Type = MEDIA_DEVICE_PATH;\r
+ EfiOpRomImageNode.Header.SubType = MEDIA_RELATIVE_OFFSET_RANGE_DP;\r
+ SetDevicePathNodeLength (&EfiOpRomImageNode.Header, sizeof (EfiOpRomImageNode));\r
+ EfiOpRomImageNode.StartingOffset = (UINTN) RomBarOffset - (UINTN) RomBar;\r
+ EfiOpRomImageNode.EndingOffset = (UINTN) RomBarOffset + ImageSize - 1 - (UINTN) RomBar;\r
\r
- RomBarOffset = RomBarOffset + ImageSize;\r
- } else {\r
- RomBarOffset = RomBarOffset + ImageSize;\r
+ PciOptionRomImageDevicePath = AppendDevicePathNode (PciDevice->DevicePath, &EfiOpRomImageNode.Header);\r
+ ASSERT (PciOptionRomImageDevicePath != NULL);\r
+\r
+ //\r
+ // load image and start image\r
+ //\r
+ BufferSize = 0;\r
+ Buffer = NULL;\r
+ Status = EFI_SUCCESS;\r
+ ImageHandle = NULL;\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ PciOptionRomImageDevicePath,\r
+ Buffer,\r
+ BufferSize,\r
+ &ImageHandle\r
+ );\r
+ }\r
+\r
+ //\r
+ // load image and start image\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ PciOptionRomImageDevicePath,\r
+ Buffer,\r
+ BufferSize,\r
+ &ImageHandle\r
+ );\r
+ }\r
+\r
+ FreePool (PciOptionRomImageDevicePath);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ AddDriver (PciDevice, ImageHandle);\r
+ PciRomAddImageMapping (\r
+ ImageHandle,\r
+ PciDevice->PciRootBridgeIo->SegmentNumber,\r
+ PciDevice->BusNumber,\r
+ PciDevice->DeviceNumber,\r
+ PciDevice->FunctionNumber,\r
+ (UINT64) (UINTN) PciDevice->PciIo.RomImage,\r
+ PciDevice->PciIo.RomSize\r
+ );\r
+ RetStatus = EFI_SUCCESS;\r
}\r
- } else {\r
- RomBarOffset = RomBarOffset + ImageSize;\r
}\r
\r
- } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
+ RomBarOffset += ImageSize;\r
\r
- return retStatus;\r
+ } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize));\r
\r
+ return RetStatus;\r
}\r
+\r