MdeModulePkg/PciBus: Fix a bug PPB MEM32 BAR isn't restored sometimes
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciResourceSupport.c
index f5ae3d8..70e4504 100644 (file)
@@ -1661,57 +1661,52 @@ ProgramUpstreamBridgeForRom (
   IN BOOLEAN         Enable\r
   )\r
 {\r
-  PCI_IO_DEVICE     *Parent;\r
-  PCI_RESOURCE_NODE Node;\r
-  UINT64            Base;\r
-  UINT64            Length;\r
+  PCI_IO_DEVICE       *Parent;\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  UINT16              Base;\r
+  UINT16              Limit;\r
   //\r
   // For root bridge, just return.\r
   //\r
   Parent = PciDevice->Parent;\r
-  ZeroMem (&Node, sizeof (Node));\r
   while (Parent != NULL) {\r
     if (!IS_PCI_BRIDGE (&Parent->Pci)) {\r
       break;\r
     }\r
 \r
-    Node.PciDev     = Parent;\r
-    Node.Alignment  = 0;\r
-    Node.Bar        = PPB_MEM32_RANGE;\r
-    Node.ResType    = PciBarTypeMem32;\r
-    Node.Offset     = 0;\r
+    PciIo = &Parent->PciIo;\r
 \r
     //\r
     // Program PPB to only open a single <= 16MB aperture\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
+      Base  = (UINT16) (OptionRomBase >> 16);\r
+      Limit = (UINT16) ((OptionRomBase + PciDevice->RomSize - 1) >> 16);\r
+      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase),  1, &Base);\r
+      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit);\r
 \r
       PCI_ENABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
     } else {\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
+      if (Parent->PciBar[PPB_MEM32_RANGE].Length == 0) {\r
+        //\r
+        // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO.\r
+        //\r
+        Base  = (UINT16) gAllOne;\r
+        Limit = (UINT16) gAllZero;\r
+      } else {\r
+        Base  = (UINT16) ((UINT32) Parent->PciBar[PPB_MEM32_RANGE].BaseAddress >> 16);\r
+        Limit = (UINT16) ((UINT32) (Parent->PciBar[PPB_MEM32_RANGE].BaseAddress\r
+                                    + Parent->PciBar[PPB_MEM32_RANGE].Length - 1) >> 16);\r
+      }\r
+      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase),  1, &Base);\r
+      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), 1, &Limit);\r
+\r
       PCI_DISABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE);\r
     }\r
 \r