/** @file\r
\r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, 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
BOOLEAN mVgaInstallationInProgress = FALSE;\r
UINT32 mRomCount = 0x00;\r
ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES];\r
-\r
+EDKII_IOMMU_PROTOCOL *mIoMmu;\r
\r
/**\r
Query shadowed legacy ROM parameters registered by RomShadow() previously.\r
RomShadow (\r
IN EFI_HANDLE PciHandle,\r
IN UINT32 ShadowAddress,\r
- IN UINT32 ShadowedSize, \r
+ IN UINT32 ShadowedSize,\r
IN UINT8 DiskStart,\r
IN UINT8 DiskEnd\r
)\r
}\r
\r
/**\r
- Find the PC-AT ROM Image in the raw PCI Option ROM. Also return the \r
+ Find the PC-AT ROM Image in the raw PCI Option ROM. Also return the\r
related information from the header.\r
\r
@param Csm16Revision The PCI interface version of underlying CSM16\r
break;\r
}\r
\r
- if ((UINTN)(RomHeader.Raw - (UINT8 *) *Rom) + Pcir->ImageLength * 512 > *ImageSize) {\r
+ if (((UINTN)RomHeader.Raw - (UINTN)*Rom) + Pcir->ImageLength * 512 > *ImageSize) {\r
break;\r
}\r
- \r
+\r
if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
Match = FALSE;\r
if (Pcir->VendorId == VendorId) {\r
DEBUG ((EFI_D_ERROR, "GetPciLegacyRom - OpRom not match (%04x-%04x)\n", (UINTN)VendorId, (UINTN)DeviceId));\r
}\r
}\r
- \r
+\r
if ((Pcir->Indicator & 0x80) == 0x80) {\r
break;\r
} else {\r
}\r
\r
if (OpRomRevision != NULL) {\r
- // \r
+ //\r
// Optional return PCI Data Structure revision\r
//\r
if (Pcir->Length >= 0x1C) {\r
//\r
Regs.X.BX = (UINT16) 0x1;\r
//\r
- // 16-byte boundary alignment requirement according to \r
+ // 16-byte boundary alignment requirement according to\r
// PCI IRQ Routing Table Specification\r
//\r
Regs.X.DX = 0x10;\r
if (Regs.X.AX != 0) {\r
DEBUG ((EFI_D_ERROR, "PIRQ table length insufficient - %x\n", PirqTableSize));\r
} else {\r
- DEBUG ((EFI_D_INFO, "PIRQ table in legacy region - %x\n", Private->Legacy16Table->IrqRoutingTablePointer)); \r
+ DEBUG ((EFI_D_INFO, "PIRQ table in legacy region - %x\n", Private->Legacy16Table->IrqRoutingTablePointer));\r
Private->Legacy16Table->IrqRoutingTableLength = (UINT32)PirqTableSize;\r
CopyMem (\r
(VOID *) (UINTN)Private->Legacy16Table->IrqRoutingTablePointer,\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
Status = PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationEnable,\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
&HandleBuffer,\r
&HandleCount,\r
NULL\r
- ); \r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_UNSUPPORTED;\r
}\r
- \r
+\r
VgaHandle = HandleBuffer[0];\r
\r
Status = gBS->LocateHandleBuffer (\r
sizeof (Pci) / sizeof (UINT32),\r
&Pci\r
);\r
- \r
+\r
//\r
- // Only one Video OPROM can be given control in BIOS phase. If there are multiple Video devices, \r
- // one will work in legacy mode (OPROM will be given control) and \r
+ // Only one Video OPROM can be given control in BIOS phase. If there are multiple Video devices,\r
+ // one will work in legacy mode (OPROM will be given control) and\r
// other Video devices will work in native mode (OS driver will handle these devices).\r
- // \r
- if (IS_PCI_DISPLAY (&Pci) && Index != 0) { \r
+ //\r
+ if (IS_PCI_DISPLAY (&Pci) && Index != 0) {\r
continue;\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
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
Status = PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationEnable,\r
@param RomSize Size of ROM Image\r
@param Flags Indicates if ROM found and if PC-AT.\r
\r
- @retval EFI_SUCCESS Legacy Option ROM availible for this device\r
+ @retval EFI_SUCCESS Legacy Option ROM available for this device\r
@retval EFI_UNSUPPORTED Legacy Option ROM not supported.\r
\r
**/\r
@param[out] OpromRevision Revision of the PCI Rom\r
@param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header\r
\r
- @return EFI_SUCCESS Legacy Option ROM availible for this device\r
+ @return EFI_SUCCESS Legacy Option ROM available for this device\r
@return EFI_ALREADY_STARTED This device is already managed by its Oprom\r
@return EFI_UNSUPPORTED Legacy Option ROM not supported.\r
\r
PCI_TYPE00 PciConfigHeader;\r
VOID *LocalConfigUtilityCodeHeader;\r
\r
+ LocalConfigUtilityCodeHeader = NULL;\r
*Flags = NO_ROM;\r
Status = gBS->HandleProtocol (\r
PciHandle,\r
//\r
Status = IsLegacyRom (PciHandle);\r
if (!EFI_ERROR (Status)) {\r
- *Flags |= (ROM_FOUND | VALID_LEGACY_ROM);\r
+ *Flags |= (UINTN)(ROM_FOUND | VALID_LEGACY_ROM);\r
return EFI_SUCCESS;\r
}\r
//\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
for (Index = 0; Index < EntryCount; Index++) {\r
if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
Status = gBS->HandleProtocol (\r
}\r
}\r
}\r
- \r
+\r
//\r
// Kick off the native EFI driver\r
//\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \\r
- EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16;\r
+ Supports &= (UINT64)(EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
Status = PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationEnable,\r
UINTN Function;\r
EFI_IA32_REGISTER_SET Regs;\r
UINT8 VideoMode;\r
+ UINT8 OldVideoMode;\r
EFI_TIME BootTime;\r
UINT32 *BdaPtr;\r
UINT32 LocalTime;\r
UINT32 StartBbsIndex;\r
UINT32 EndBbsIndex;\r
+ UINT32 MaxRomAddr;\r
UINTN TempData;\r
UINTN InitAddress;\r
UINTN RuntimeAddress;\r
Device = 0;\r
Function = 0;\r
VideoMode = 0;\r
+ OldVideoMode = 0;\r
PhysicalAddress = 0;\r
+ MaxRomAddr = PcdGet32 (PcdEndOpromShadowAddress);\r
+\r
+ if ((Private->Legacy16Table->TableLength >= OFFSET_OF(EFI_COMPATIBILITY16_TABLE, HiPermanentMemoryAddress)) &&\r
+ (Private->Legacy16Table->UmaAddress != 0) &&\r
+ (Private->Legacy16Table->UmaSize != 0) &&\r
+ (MaxRomAddr > (Private->Legacy16Table->UmaAddress))) {\r
+ MaxRomAddr = Private->Legacy16Table->UmaAddress;\r
+ }\r
+\r
\r
PciProgramAllInterruptLineRegisters (Private);\r
\r
EFI_SIZE_TO_PAGES (ImageSize),\r
&PhysicalAddress\r
);\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
// then test if there is enough space for its RT code\r
//\r
RuntimeAddress = Private->OptionRom;\r
- if (RuntimeAddress + *RuntimeImageLength > PcdGet32 (PcdEndOpromShadowAddress)) {\r
+ if (RuntimeAddress + *RuntimeImageLength > MaxRomAddr) {\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
// test if there is enough space for its INIT code\r
//\r
InitAddress = PCI_START_ADDRESS (Private->OptionRom);\r
- if (InitAddress + ImageSize > PcdGet32 (PcdEndOpromShadowAddress)) {\r
+ if (InitAddress + ImageSize > MaxRomAddr) {\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
(UINT32) ImageSize,\r
&Granularity\r
);\r
- \r
+\r
DEBUG ((EFI_D_INFO, " Shadowing OpROM init/runtime/isize = %x/%x/%x\n", InitAddress, RuntimeAddress, ImageSize));\r
\r
CopyMem ((VOID *) InitAddress, RomImage, ImageSize);\r
// 2. BBS compliants drives will not change 40:75 until boot time.\r
// 3. Onboard IDE controllers will change 40:75\r
//\r
- LocalDiskStart = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80);\r
- if ((Private->Disk4075 + 0x80) < LocalDiskStart) {\r
- //\r
- // Update table since onboard IDE drives found\r
- //\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = 0xff;\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = 0xff;\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = 0xff;\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = 0xff;\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = (UINT8) (Private->Disk4075 + 0x80);\r
- Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = LocalDiskStart;\r
- Private->LegacyEfiHddTableIndex ++;\r
- Private->Disk4075 = (UINT8) (LocalDiskStart & 0x7f);\r
- Private->DiskEnd = LocalDiskStart;\r
- }\r
+ ACCESS_PAGE0_CODE (\r
+ LocalDiskStart = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80);\r
+ if ((Private->Disk4075 + 0x80) < LocalDiskStart) {\r
+ //\r
+ // Update table since onboard IDE drives found\r
+ //\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = 0xff;\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = 0xff;\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = 0xff;\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = 0xff;\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = (UINT8) (Private->Disk4075 + 0x80);\r
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = LocalDiskStart;\r
+ Private->LegacyEfiHddTableIndex ++;\r
+ Private->Disk4075 = (UINT8) (LocalDiskStart & 0x7f);\r
+ Private->DiskEnd = LocalDiskStart;\r
+ }\r
\r
- if (PciHandle != mVgaHandle) {\r
+ if (PciHandle != mVgaHandle) {\r
\r
- EnablePs2Keyboard ();\r
+ EnablePs2Keyboard ();\r
+\r
+ //\r
+ // Store current mode settings since PrepareToScanRom may change mode.\r
+ //\r
+ VideoMode = *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE));\r
+ }\r
+ );\r
\r
- //\r
- // Store current mode settings since PrepareToScanRom may change mode.\r
- //\r
- VideoMode = *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE));\r
- }\r
//\r
// Notify the platform that we are about to scan the ROM\r
//\r
//\r
gRT->GetTime (&BootTime, NULL);\r
LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second;\r
- \r
+\r
//\r
// Multiply result by 18.2 for number of ticks since midnight.\r
// Use 182/10 to avoid floating point math.\r
//\r
- LocalTime = (LocalTime * 182) / 10;\r
- BdaPtr = (UINT32 *) ((UINTN) 0x46C);\r
- *BdaPtr = LocalTime;\r
- \r
+ ACCESS_PAGE0_CODE (\r
+ LocalTime = (LocalTime * 182) / 10;\r
+ BdaPtr = (UINT32 *) ((UINTN) 0x46C);\r
+ *BdaPtr = LocalTime;\r
+ );\r
+\r
//\r
// Pass in handoff data\r
//\r
PciEnableStatus = EFI_UNSUPPORTED;\r
ZeroMem (&Regs, sizeof (Regs));\r
if (PciHandle != NULL) {\r
- \r
+\r
Status = gBS->HandleProtocol (\r
PciHandle,\r
&gEfiPciIoProtocolGuid,\r
(VOID **) &PciIo\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
//\r
// Enable command register.\r
//\r
EFI_PCI_DEVICE_ENABLE,\r
NULL\r
);\r
- \r
+\r
PciIo->GetLocation (\r
PciIo,\r
&Segment,\r
);\r
DEBUG ((EFI_D_INFO, "Shadowing OpROM on the PCI device %x/%x/%x\n", Bus, Device, Function));\r
}\r
- \r
+\r
mIgnoreBbsUpdateFlag = FALSE;\r
Regs.X.AX = Legacy16DispatchOprom;\r
- \r
+\r
//\r
// Generate DispatchOpRomTable data\r
//\r
} else {\r
Regs.X.BX = 0;\r
}\r
- \r
+\r
if (Private->IntThunk->DispatchOpromTable.NumberBbsEntries != (UINT8) Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries) {\r
Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT8) Private->IntThunk->DispatchOpromTable.NumberBbsEntries;\r
mIgnoreBbsUpdateFlag = TRUE;\r
//\r
// Set mode settings since PrepareToScanRom may change mode\r
//\r
- if (VideoMode != *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE))) {\r
+ ACCESS_PAGE0_CODE ({\r
+ OldVideoMode = *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE));\r
+ });\r
+\r
+ if (VideoMode != OldVideoMode) {\r
//\r
// The active video mode is changed, restore it to original mode.\r
//\r
//\r
// The ROM could have updated it's size so we need to read again.\r
//\r
- if ((((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) &&\r
- (((EFI_LEGACY_EXPANSION_ROM_HEADER *) InitAddress)->Size512 == 0)) {\r
+ if (((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
//\r
- // The INIT function didn't copy the RUNTIME code to RuntimeAddress\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
}\r
}\r
\r
- LocalDiskEnd = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80);\r
- \r
+ ACCESS_PAGE0_CODE (\r
+ LocalDiskEnd = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80);\r
+ );\r
+\r
//\r
// Allow platform to perform any required actions after the\r
// OPROM has been initialized.\r
Private->OptionRom = (UINT32) (RuntimeAddress + *RuntimeImageLength);\r
\r
Status = EFI_SUCCESS;\r
- \r
+\r
Done:\r
if (PhysicalAddress != 0) {\r
//\r
return Status;\r
}\r
\r
+/**\r
+ Let IOMMU grant DMA access for the PCI device.\r
+\r
+ @param PciHandle The EFI handle for the PCI device.\r
+ @param HostAddress The system memory address to map to the PCI controller.\r
+ @param NumberOfBytes The number of bytes to map.\r
+\r
+ @retval EFI_SUCCESS The DMA access is granted.\r
+**/\r
+EFI_STATUS\r
+IoMmuGrantAccess (\r
+ IN EFI_HANDLE PciHandle,\r
+ IN EFI_PHYSICAL_ADDRESS HostAddress,\r
+ IN UINTN NumberOfBytes\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
+ VOID *Mapping;\r
+ EFI_STATUS Status;\r
+\r
+ if (PciHandle == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ if (mIoMmu == NULL) {\r
+ gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmu);\r
+ }\r
+ if (mIoMmu != NULL) {\r
+ Status = mIoMmu->Map (\r
+ mIoMmu,\r
+ EdkiiIoMmuOperationBusMasterCommonBuffer,\r
+ (VOID *)(UINTN)HostAddress,\r
+ &NumberOfBytes,\r
+ &DeviceAddress,\r
+ &Mapping\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuMap - %r\n", Status));\r
+ } else {\r
+ ASSERT (DeviceAddress == HostAddress);\r
+ Status = mIoMmu->SetAttribute (\r
+ mIoMmu,\r
+ PciHandle,\r
+ Mapping,\r
+ EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuSetAttribute - %r\n", Status));\r
+ }\r
+ }\r
+ }\r
+ return Status;\r
+}\r
+\r
/**\r
Load a legacy PC-AT OPROM on the PciHandle device. Return information\r
about how many disks were added by the OPROM and the shadow address and\r
*Flags = 0;\r
if ((PciHandle != NULL) && (RomImage == NULL)) {\r
//\r
- // If PciHandle has OpRom to Execute \r
+ // If PciHandle has OpRom to Execute\r
// and OpRom are all associated with Hardware\r
//\r
Status = gBS->HandleProtocol (\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (!Private->VgaInstalled) {\r
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle (\r
+ Private->LegacyBiosPlatform,\r
+ EfiGetPlatformVgaHandle,\r
+ 0,\r
+ &HandleBuffer,\r
+ &HandleCount,\r
+ NULL\r
+ );\r
+ if ((!EFI_ERROR (Status)) && (!Private->VgaInstalled)) {\r
//\r
// A return status of EFI_NOT_FOUND is considered valid (No EFI\r
// driver is controlling video.\r
mVgaInstallationInProgress = FALSE;\r
return EFI_UNSUPPORTED;\r
}\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
+ if ((Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) || (Pcir->CodeType != PCI_CODE_TYPE_PCAT_IMAGE)) {\r
mVgaInstallationInProgress = FALSE;\r
return EFI_UNSUPPORTED;\r
}\r
RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;\r
}\r
}\r
+\r
+ //\r
+ // Grant access for below 1M\r
+ // BDA/EBDA/LowPMM and scratch memory for OPROM.\r
+ //\r
+ IoMmuGrantAccess (PciHandle, 0, SIZE_1MB);\r
+ //\r
+ // Grant access for HiPmm\r
+ //\r
+ IoMmuGrantAccess (\r
+ PciHandle,\r
+ Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemory,\r
+ Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemorySizeInBytes\r
+ );\r
+\r
//\r
// Shadow and initialize the OpROM.\r
//\r