]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
MdeModulePkg/PciBus: Shadow option ROM after BARs are programmed
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciResourceSupport.c
index 2f713fcee95eb0479e37b87ee8411aebe10ac5c7..d3cbefbadfefe56854a279327dd667ec787a655a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PCI resouces support functions implemntation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 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
@@ -446,13 +446,14 @@ GetResourceFromDevice (
     switch ((PciDev->PciBar)[Index].BarType) {\r
 \r
     case PciBarTypeMem32:\r
+    case PciBarTypeOpRom:\r
 \r
       Node = CreateResourceNode (\r
               PciDev,\r
               (PciDev->PciBar)[Index].Length,\r
               (PciDev->PciBar)[Index].Alignment,\r
               Index,\r
-              PciBarTypeMem32,\r
+              (PciDev->PciBar)[Index].BarType,\r
               PciResUsageTypical\r
               );\r
 \r
@@ -1116,7 +1117,7 @@ DegradeResource (
         PMem64Node,\r
         TRUE\r
         );\r
-    } \r
+    }\r
 \r
     //\r
     // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied\r
@@ -1307,7 +1308,13 @@ ProgramBar (
                  1,\r
                  &Address\r
                  );\r
+  //\r
+  // Continue to the case PciBarTypeOpRom to set the BaseAddress.\r
+  // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture\r
+  // the MEM32 resource requirement for Option ROM shadow.\r
+  //\r
 \r
+  case PciBarTypeOpRom:\r
     Node->PciDev->PciBar[Node->Bar].BaseAddress = Address;\r
 \r
     break;\r
@@ -1656,6 +1663,8 @@ ProgrameUpstreamBridgeForRom (
 {\r
   PCI_IO_DEVICE     *Parent;\r
   PCI_RESOURCE_NODE Node;\r
+  UINT64            Base;\r
+  UINT64            Length;\r
   //\r
   // For root bridge, just return.\r
   //\r
@@ -1667,7 +1676,6 @@ ProgrameUpstreamBridgeForRom (
     }\r
 \r
     Node.PciDev     = Parent;\r
-    Node.Length     = PciDevice->RomSize;\r
     Node.Alignment  = 0;\r
     Node.Bar        = PPB_MEM32_RANGE;\r
     Node.ResType    = PciBarTypeMem32;\r
@@ -1677,10 +1685,33 @@ ProgrameUpstreamBridgeForRom (
     // Program PPB to only open a single <= 16MB apperture\r
     //\r
     if (Enable) {\r
+      //\r
+      // Save the original PPB_MEM32_RANGE BAR.\r
+      // The values will be changed by ProgramPpbApperture().\r
+      //\r
+      Base   = Parent->PciBar[Node.Bar].BaseAddress;\r
+      Length = Parent->PciBar[Node.Bar].Length;\r
+\r
+      //\r
+      // Only cover MMIO for Option ROM.\r
+      //\r
+      Node.Length     = PciDevice->RomSize;\r
       ProgramPpbApperture (OptionRomBase, &Node);\r
+\r
+      //\r
+      // Restore the original PPB_MEM32_RANGE BAR.\r
+      // So the MEM32 RANGE BAR register can be restored when disable the decoding.\r
+      //\r
+      Parent->PciBar[Node.Bar].BaseAddress = Base;\r
+      Parent->PciBar[Node.Bar].Length      = Length;\r
+\r
       PCI_ENABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
     } else {\r
-      InitializePpb (Parent);\r
+      //\r
+      // Cover 32bit MMIO for devices below the bridge.\r
+      //\r
+      Node.Length     = Parent->PciBar[Node.Bar].Length;\r
+      ProgramPpbApperture (Parent->PciBar[Node.Bar].BaseAddress, &Node);\r
       PCI_DISABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
     }\r
 \r