]> 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 f3e51d61508512f4c6e9e309318b0edebfedbfff..d3cbefbadfefe56854a279327dd667ec787a655a 100644 (file)
@@ -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
@@ -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