L"PMem32",\r
L" Mem64",\r
L"PMem64",\r
+ L" OpRom",\r
L" Io",\r
L" Mem",\r
L"Unknow"\r
PCI_RESOURCE_NODE PMem32Pool;\r
PCI_RESOURCE_NODE Mem64Pool;\r
PCI_RESOURCE_NODE PMem64Pool;\r
- BOOLEAN ReAllocate;\r
EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData;\r
EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData;\r
\r
- //\r
- // Reallocate flag\r
- //\r
- ReAllocate = FALSE;\r
-\r
//\r
// It may try several times if the resource allocation fails\r
//\r
PciResUsageTypical\r
);\r
\r
+ //\r
+ // Get the max ROM size that the root bridge can process\r
+ // Insert to resource map so that there will be dedicate MEM32 resource range for Option ROM.\r
+ // All devices' Option ROM share the same MEM32 resource.\r
+ //\r
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
+ RootBridgeDev->PciBar[0].BarType = PciBarTypeOpRom;\r
+ RootBridgeDev->PciBar[0].Length = MaxOptionRomSize;\r
+ RootBridgeDev->PciBar[0].Alignment = MaxOptionRomSize - 1;\r
+ GetResourceFromDevice (RootBridgeDev, IoBridge, Mem32Bridge, PMem32Bridge, Mem64Bridge, PMem64Bridge);\r
+\r
//\r
// Create resourcemap by going through all the devices subject to this root bridge\r
//\r
PMem64Bridge\r
);\r
\r
- //\r
- // Get the max ROM size that the root bridge can process\r
- //\r
- RootBridgeDev->RomSize = Mem32Bridge->Length;\r
-\r
- //\r
- // Skip to enlarge the resource request during realloction\r
- //\r
- if (!ReAllocate) {\r
- //\r
- // Get Max Option Rom size for current root bridge\r
- //\r
- MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
-\r
- //\r
- // Enlarger the mem32 resource to accomdate the option rom\r
- // if the mem32 resource is not enough to hold the rom\r
- //\r
- if (MaxOptionRomSize > Mem32Bridge->Length) {\r
-\r
- Mem32Bridge->Length = MaxOptionRomSize;\r
- RootBridgeDev->RomSize = MaxOptionRomSize;\r
-\r
- //\r
- // Alignment should be adjusted as well\r
- //\r
- if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
- Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
- }\r
- }\r
- }\r
-\r
//\r
// Based on the all the resource tree, construct ACPI resource node to\r
// submit the resource aperture to pci host bridge protocol\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
-\r
- ReAllocate = TRUE;\r
}\r
}\r
//\r
&PMem64Base\r
);\r
\r
- //\r
- // Process option rom for this root bridge\r
- //\r
- ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
-\r
//\r
// Create the entire system resource map from the information collected by\r
// enumerator. Several resource tree was created\r
PMem64Bridge\r
);\r
\r
+ //\r
+ // Process Option ROM for this root bridge after all BARs are programmed.\r
+ // The PPB's MEM32 RANGE BAR is re-programmed to the Option ROM BAR Base in order to\r
+ // shadow the Option ROM of the devices under the PPB.\r
+ // After the shadow, Option ROM BAR decoding is turned off and the PPB's MEM32 RANGE\r
+ // BAR is restored back to the original value.\r
+ // The original value is programmed by ProgramResource() above.\r
+ //\r
+ DEBUG ((\r
+ DEBUG_INFO, "Process Option ROM: BAR Base/Length = %lx/%lx\n",\r
+ RootBridgeDev->PciBar[0].BaseAddress, RootBridgeDev->PciBar[0].Length\r
+ ));\r
+ ProcessOptionRom (RootBridgeDev, RootBridgeDev->PciBar[0].BaseAddress, RootBridgeDev->PciBar[0].Length);\r
+\r
IoBridge ->PciDev->PciBar[IoBridge ->Bar].BaseAddress = IoBase;\r
Mem32Bridge ->PciDev->PciBar[Mem32Bridge ->Bar].BaseAddress = Mem32Base;\r
PMem32Bridge->PciDev->PciBar[PMem32Bridge->Bar].BaseAddress = PMem32Base;\r
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