]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacyPci.c
index e32ebacd9404ea4fb55cc28b732f549286e75fe1..8245a2b65e1404636809bc81743210aef7311699 100644 (file)
@@ -1,6 +1,6 @@
 /** @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
@@ -41,7 +41,7 @@ BOOLEAN                             mIgnoreBbsUpdateFlag;
 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
@@ -150,7 +150,7 @@ EFI_STATUS
 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
@@ -258,7 +258,7 @@ IsLegacyRom (
 }\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
@@ -318,10 +318,10 @@ GetPciLegacyRom (
       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
@@ -384,7 +384,7 @@ GetPciLegacyRom (
         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
@@ -415,7 +415,7 @@ GetPciLegacyRom (
   }\r
 \r
   if (OpRomRevision != NULL) {\r
-    // \r
+    //\r
     // Optional return PCI Data Structure revision\r
     //\r
     if (Pcir->Length >= 0x1C) {\r
@@ -815,7 +815,7 @@ CopyPirqTable (
     //\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
@@ -832,7 +832,7 @@ CopyPirqTable (
     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
@@ -1198,7 +1198,7 @@ PciProgramAllInterruptLineRegisters (
                       &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
@@ -1500,54 +1500,52 @@ UpdateBevBcvTable (
     }\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
@@ -1597,11 +1595,11 @@ PciShadowRoms (
                                           &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
@@ -1701,13 +1699,13 @@ PciShadowRoms (
                  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
@@ -1717,6 +1715,20 @@ PciShadowRoms (
     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
@@ -1760,7 +1772,7 @@ PciShadowRoms (
                           &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
@@ -1800,7 +1812,7 @@ PciShadowRoms (
   @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
@@ -1842,7 +1854,7 @@ LegacyBiosCheckPciRom (
     @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
@@ -1867,6 +1879,7 @@ LegacyBiosCheckPciRomEx (
   PCI_TYPE00                      PciConfigHeader;\r
   VOID                            *LocalConfigUtilityCodeHeader;\r
 \r
+  LocalConfigUtilityCodeHeader = NULL;\r
   *Flags = NO_ROM;\r
   Status = gBS->HandleProtocol (\r
                   PciHandle,\r
@@ -1882,7 +1895,7 @@ LegacyBiosCheckPciRomEx (
   //\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
@@ -2091,7 +2104,7 @@ LegacyBiosInstallVgaRom (
   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
@@ -2110,7 +2123,7 @@ LegacyBiosInstallVgaRom (
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Kick off the native EFI driver\r
   //\r
@@ -2174,8 +2187,8 @@ LegacyBiosInstallVgaRom (
                     &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
@@ -2266,11 +2279,13 @@ LegacyBiosInstallRom (
   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
@@ -2285,7 +2300,17 @@ LegacyBiosInstallRom (
   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
@@ -2301,7 +2326,7 @@ LegacyBiosInstallRom (
                     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
@@ -2318,7 +2343,7 @@ LegacyBiosInstallRom (
     //   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
@@ -2336,7 +2361,7 @@ LegacyBiosInstallRom (
     //   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
@@ -2364,7 +2389,7 @@ LegacyBiosInstallRom (
                            (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
@@ -2378,31 +2403,34 @@ LegacyBiosInstallRom (
   // 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
@@ -2438,29 +2466,31 @@ LegacyBiosInstallRom (
   //\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
@@ -2470,7 +2500,7 @@ LegacyBiosInstallRom (
                                EFI_PCI_DEVICE_ENABLE,\r
                                NULL\r
                                );\r
-  \r
+\r
     PciIo->GetLocation (\r
              PciIo,\r
              &Segment,\r
@@ -2480,10 +2510,10 @@ LegacyBiosInstallRom (
              );\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
@@ -2515,7 +2545,7 @@ LegacyBiosInstallRom (
   } 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
@@ -2541,7 +2571,11 @@ LegacyBiosInstallRom (
     //\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
@@ -2557,10 +2591,10 @@ LegacyBiosInstallRom (
   //\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
@@ -2581,8 +2615,10 @@ LegacyBiosInstallRom (
     }\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
@@ -2651,7 +2687,7 @@ LegacyBiosInstallRom (
   Private->OptionRom = (UINT32) (RuntimeAddress + *RuntimeImageLength);\r
 \r
   Status = EFI_SUCCESS;\r
-   \r
+\r
 Done:\r
   if (PhysicalAddress != 0) {\r
     //\r
@@ -2673,6 +2709,61 @@ Done:
   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
@@ -2788,7 +2879,7 @@ LegacyBiosInstallPciRom (
   *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
@@ -2902,7 +2993,15 @@ LegacyBiosInstallPciRom (
       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
@@ -2926,11 +3025,11 @@ LegacyBiosInstallPciRom (
       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
@@ -2947,6 +3046,21 @@ LegacyBiosInstallPciRom (
       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