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
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
{\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
}\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
// 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