/** @file\r
\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
BackupImage = NULL;\r
RomHeader.Raw = *Rom;\r
while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
- if (*ImageSize < \r
- RomHeader.Raw - (UINT8 *) *Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)\r
- ) {\r
- return EFI_NOT_FOUND;\r
+ if (RomHeader.Generic->PcirOffset == 0 ||\r
+ (RomHeader.Generic->PcirOffset & 3) !=0 ||\r
+ *ImageSize < RomHeader.Raw - (UINT8 *) *Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)) {\r
+ break;\r
}\r
\r
Pcir = (PCI_3_0_DATA_STRUCTURE *) (RomHeader.Raw + RomHeader.Generic->PcirOffset);\r
+ //\r
+ // Check signature in the PCI Data Structure.\r
+ //\r
+ if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+ break;\r
+ }\r
\r
+ if ((UINTN)(RomHeader.Raw - (UINT8 *) *Rom) + Pcir->ImageLength * 512 > *ImageSize) {\r
+ break;\r
+ }\r
+ \r
if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
Match = FALSE;\r
if (Pcir->VendorId == VendorId) {\r
}\r
}\r
\r
- if (PciPtr >= (EFI_LEGACY_EXPANSION_ROM_HEADER *) ((UINTN) 0xc8000)) {\r
- while (TRUE) {\r
- Status = FindNextPnpExpansionHeader (Private, Instance, &PnpPtr);\r
- Instance = NOT_FIRST_INSTANCE;\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- //\r
- // There can be additional $PnP headers within the OPROM.\r
- // Example: SCSI can have one per drive.\r
- //\r
- BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
- BbsTable[BbsIndex].DeviceType = DeviceType;\r
- BbsTable[BbsIndex].Bus = (UINT32) Bus;\r
- BbsTable[BbsIndex].Device = (UINT32) Device;\r
- BbsTable[BbsIndex].Function = (UINT32) Function;\r
- BbsTable[BbsIndex].StatusFlags.OldPosition = 0;\r
- BbsTable[BbsIndex].StatusFlags.Reserved1 = 0;\r
- BbsTable[BbsIndex].StatusFlags.Enabled = 0;\r
- BbsTable[BbsIndex].StatusFlags.Failed = 0;\r
- BbsTable[BbsIndex].StatusFlags.MediaPresent = 0;\r
- BbsTable[BbsIndex].StatusFlags.Reserved2 = 0;\r
- BbsTable[BbsIndex].Class = PnpPtr->Class;\r
- BbsTable[BbsIndex].SubClass = PnpPtr->SubClass;\r
- BbsTable[BbsIndex].DescStringOffset = PnpPtr->ProductNamePointer;\r
- BbsTable[BbsIndex].DescStringSegment = mBbsRomSegment;\r
- BbsTable[BbsIndex].MfgStringOffset = PnpPtr->MfgPointer;\r
- BbsTable[BbsIndex].MfgStringSegment = mBbsRomSegment;\r
- BbsTable[BbsIndex].BootHandlerSegment = mBbsRomSegment;\r
-\r
- //\r
- // Have seen case where PXE base code have PnP expansion ROM\r
- // header but no Bcv or Bev vectors.\r
- //\r
- if (PnpPtr->Bcv != 0) {\r
- BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bcv;\r
- ++BbsIndex;\r
- }\r
+ while (TRUE) {\r
+ Status = FindNextPnpExpansionHeader (Private, Instance, &PnpPtr);\r
+ Instance = NOT_FIRST_INSTANCE;\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ //\r
+ // There can be additional $PnP headers within the OPROM.\r
+ // Example: SCSI can have one per drive.\r
+ //\r
+ BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
+ BbsTable[BbsIndex].DeviceType = DeviceType;\r
+ BbsTable[BbsIndex].Bus = (UINT32) Bus;\r
+ BbsTable[BbsIndex].Device = (UINT32) Device;\r
+ BbsTable[BbsIndex].Function = (UINT32) Function;\r
+ BbsTable[BbsIndex].StatusFlags.OldPosition = 0;\r
+ BbsTable[BbsIndex].StatusFlags.Reserved1 = 0;\r
+ BbsTable[BbsIndex].StatusFlags.Enabled = 0;\r
+ BbsTable[BbsIndex].StatusFlags.Failed = 0;\r
+ BbsTable[BbsIndex].StatusFlags.MediaPresent = 0;\r
+ BbsTable[BbsIndex].StatusFlags.Reserved2 = 0;\r
+ BbsTable[BbsIndex].Class = PnpPtr->Class;\r
+ BbsTable[BbsIndex].SubClass = PnpPtr->SubClass;\r
+ BbsTable[BbsIndex].DescStringOffset = PnpPtr->ProductNamePointer;\r
+ BbsTable[BbsIndex].DescStringSegment = mBbsRomSegment;\r
+ BbsTable[BbsIndex].MfgStringOffset = PnpPtr->MfgPointer;\r
+ BbsTable[BbsIndex].MfgStringSegment = mBbsRomSegment;\r
+ BbsTable[BbsIndex].BootHandlerSegment = mBbsRomSegment;\r
+\r
+ //\r
+ // Have seen case where PXE base code have PnP expansion ROM\r
+ // header but no Bcv or Bev vectors.\r
+ //\r
+ if (PnpPtr->Bcv != 0) {\r
+ BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bcv;\r
+ ++BbsIndex;\r
+ }\r
\r
- if (PnpPtr->Bev != 0) {\r
- BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bev;\r
- BbsTable[BbsIndex].DeviceType = BBS_BEV_DEVICE;\r
- ++BbsIndex;\r
- }\r
+ if (PnpPtr->Bev != 0) {\r
+ BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bev;\r
+ BbsTable[BbsIndex].DeviceType = BBS_BEV_DEVICE;\r
+ ++BbsIndex;\r
+ }\r
\r
- if ((PnpPtr == (LEGACY_PNP_EXPANSION_HEADER *) PciPtr) || (PnpPtr > (LEGACY_PNP_EXPANSION_HEADER *) RomEnd)) {\r
- break;\r
- }\r
+ if ((PnpPtr == (LEGACY_PNP_EXPANSION_HEADER *) PciPtr) || (PnpPtr > (LEGACY_PNP_EXPANSION_HEADER *) RomEnd)) {\r
+ break;\r
}\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
continue;\r
}\r
+ \r
+ //\r
+ // If legacy VBIOS Oprom has not been dispatched before, install legacy VBIOS here.\r
+ //\r
+ if (IS_PCI_DISPLAY (&Pci) && Index == 0) { \r
+ Status = LegacyBiosInstallVgaRom (Private);\r
+ //\r
+ // A return status of EFI_NOT_FOUND is considered valid (No EFI\r
+ // driver is controlling video).\r
+ //\r
+ ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND));\r
+ continue;\r
+ }\r
+\r
//\r
// Install legacy ROM\r
//\r
\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));\r
+ //\r
+ // Report Status Code to indicate that there is no enough space for OpROM\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)\r
+ );\r
return EFI_OUT_OF_RESOURCES;\r
}\r
InitAddress = (UINTN) PhysicalAddress;\r
// then test if there is enough space for its RT code\r
//\r
RuntimeAddress = Private->OptionRom;\r
- if (RuntimeAddress + *RuntimeImageLength > mEndOpromShadowAddress) {\r
+ if (RuntimeAddress + *RuntimeImageLength > PcdGet32 (PcdEndOpromShadowAddress)) {\r
DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));\r
gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize));\r
+ //\r
+ // Report Status Code to indicate that there is no enough space for OpROM\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)\r
+ );\r
return EFI_OUT_OF_RESOURCES;\r
}\r
} else {\r
// test if there is enough space for its INIT code\r
//\r
InitAddress = PCI_START_ADDRESS (Private->OptionRom);\r
- if (InitAddress + ImageSize > mEndOpromShadowAddress) {\r
+ if (InitAddress + ImageSize > PcdGet32 (PcdEndOpromShadowAddress)) {\r
DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));\r
+ //\r
+ // Report Status Code to indicate that there is no enough space for OpROM\r
+ //\r
+ REPORT_STATUS_CODE (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)\r
+ );\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
//\r
// Store current mode settings since PrepareToScanRom may change mode.\r
//\r
- VideoMode = *(UINT8 *) ((UINTN) 0x449);\r
+ VideoMode = *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE));\r
}\r
//\r
// Notify the platform that we are about to scan the ROM\r
//\r
// Set mode settings since PrepareToScanRom may change mode\r
//\r
- Regs.H.AH = 0x00;\r
- Regs.H.AL = VideoMode;\r
- Private->LegacyBios.Int86 (&Private->LegacyBios, 0x10, &Regs);\r
+ if (VideoMode != *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE))) {\r
+ //\r
+ // The active video mode is changed, restore it to original mode.\r
+ //\r
+ Regs.H.AH = 0x00;\r
+ Regs.H.AL = VideoMode;\r
+ Private->LegacyBios.Int86 (&Private->LegacyBios, 0x10, &Regs);\r
+ }\r
}\r
//\r
// Regs.X.AX from the adapter initializion is ignored since some adapters\r
//\r
// The ROM could have updated it's size so we need to read again.\r
//\r
- *RuntimeImageLength = ((EFI_LEGACY_EXPANSION_ROM_HEADER *) (RuntimeAddress))->Size512 * 512;\r
+ if (((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
+ //\r
+ // Now we check the signature (0xaa55) to judge whether the run-time code is truly generated by INIT function.\r
+ // If signature is not valid, that means the INIT function didn't copy the run-time code to RuntimeAddress.\r
+ //\r
+ *RuntimeImageLength = 0;\r
+ } else {\r
+ *RuntimeImageLength = ((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Size512 * 512;\r
+ }\r
+\r
DEBUG ((EFI_D_INFO, " fsize = %x\n", *RuntimeImageLength));\r
\r
//\r
return EFI_UNSUPPORTED;\r
}\r
} else {\r
- if (*RomImage == NULL) {\r
+ if ((RomImage == NULL) || (*RomImage == NULL)) {\r
//\r
// If PciHandle is NULL, and no OpRom is to be associated\r
//\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ if (!Private->VgaInstalled) {\r
+ //\r
+ // A return status of EFI_NOT_FOUND is considered valid (No EFI\r
+ // driver is controlling video.\r
+ //\r
+ mVgaInstallationInProgress = TRUE;\r
+ Status = LegacyBiosInstallVgaRom (Private);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status != EFI_NOT_FOUND) {\r
+ mVgaInstallationInProgress = FALSE;\r
+ return Status;\r
+ }\r
+ } else {\r
+ mVgaInstallationInProgress = FALSE;\r
+ }\r
+ }\r
+\r
LocalRomImage = *RomImage;\r
+ if (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE ||\r
+ ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset == 0 ||\r
+ (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset & 3 ) != 0) {\r
+ mVgaInstallationInProgress = FALSE;\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
Pcir = (PCI_3_0_DATA_STRUCTURE *)\r
((UINT8 *) LocalRomImage + ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset);\r
+\r
+ if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+ mVgaInstallationInProgress = FALSE;\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
ImageSize = Pcir->ImageLength * 512;\r
if (Pcir->Length >= 0x1C) {\r
OpromRevision = Pcir->Revision;\r