(Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0 ? L"CombineMemPMem " : L"",\r
(Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0 ? L"Mem64Decode" : L""\r
));\r
- DEBUG ((EFI_D_INFO, " Bus: %lx - %lx\n", Bridge->Bus.Base, Bridge->Bus.Limit));\r
- DEBUG ((EFI_D_INFO, " Io: %lx - %lx\n", Bridge->Io.Base, Bridge->Io.Limit));\r
- DEBUG ((EFI_D_INFO, " Mem: %lx - %lx\n", Bridge->Mem.Base, Bridge->Mem.Limit));\r
- DEBUG ((EFI_D_INFO, " MemAbove4G: %lx - %lx\n", Bridge->MemAbove4G.Base, Bridge->MemAbove4G.Limit));\r
- DEBUG ((EFI_D_INFO, " PMem: %lx - %lx\n", Bridge->PMem.Base, Bridge->PMem.Limit));\r
- DEBUG ((EFI_D_INFO, " PMemAbove4G: %lx - %lx\n", Bridge->PMemAbove4G.Base, Bridge->PMemAbove4G.Limit));\r
+ DEBUG ((\r
+ EFI_D_INFO, " Bus: %lx - %lx Translation=%lx\n",\r
+ Bridge->Bus.Base, Bridge->Bus.Limit, Bridge->Bus.Translation\r
+ ));\r
+ //\r
+ // Translation for bus is not supported.\r
+ //\r
+ ASSERT (Bridge->Bus.Translation == 0);\r
+ if (Bridge->Bus.Translation != 0) {\r
+ return NULL;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO, " Io: %lx - %lx Translation=%lx\n",\r
+ Bridge->Io.Base, Bridge->Io.Limit, Bridge->Io.Translation\r
+ ));\r
+ DEBUG ((\r
+ DEBUG_INFO, " Mem: %lx - %lx Translation=%lx\n",\r
+ Bridge->Mem.Base, Bridge->Mem.Limit, Bridge->Mem.Translation\r
+ ));\r
+ DEBUG ((\r
+ DEBUG_INFO, " MemAbove4G: %lx - %lx Translation=%lx\n",\r
+ Bridge->MemAbove4G.Base, Bridge->MemAbove4G.Limit, Bridge->MemAbove4G.Translation\r
+ ));\r
+ DEBUG ((\r
+ DEBUG_INFO, " PMem: %lx - %lx Translation=%lx\n",\r
+ Bridge->PMem.Base, Bridge->PMem.Limit, Bridge->PMem.Translation\r
+ ));\r
+ DEBUG ((\r
+ DEBUG_INFO, " PMemAbove4G: %lx - %lx Translation=%lx\n",\r
+ Bridge->PMemAbove4G.Base, Bridge->PMemAbove4G.Limit, Bridge->PMemAbove4G.Translation\r
+ ));\r
\r
//\r
// Make sure Mem and MemAbove4G apertures are valid\r
}\r
RootBridge->ResAllocNode[Index].Type = Index;\r
if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) {\r
- RootBridge->ResAllocNode[Index].Base = Aperture->Base;\r
+ //\r
+ // Base in ResAllocNode is a host address, while Base in Aperture is a\r
+ // device address.\r
+ //\r
+ RootBridge->ResAllocNode[Index].Base = TO_HOST_ADDRESS (Aperture->Base,\r
+ Aperture->Translation);\r
RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1;\r
RootBridge->ResAllocNode[Index].Status = ResAllocated;\r
} else {\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Use address to match apertures of memory type and then get the corresponding\r
+ translation.\r
+\r
+ @param RootBridge The root bridge instance.\r
+ @param Address The address used to match aperture.\r
+ @param Translation Pointer containing the output translation.\r
+\r
+ @return EFI_SUCCESS Get translation successfully.\r
+ @return EFI_INVALID_PARAMETER No matched memory aperture; the input Address\r
+ must be invalid.\r
+**/\r
+EFI_STATUS\r
+RootBridgeIoGetMemTranslationByAddress (\r
+ IN PCI_ROOT_BRIDGE_INSTANCE *RootBridge,\r
+ IN UINT64 Address,\r
+ IN OUT UINT64 *Translation\r
+ )\r
+{\r
+ if (Address >= RootBridge->Mem.Base && Address <= RootBridge->Mem.Limit) {\r
+ *Translation = RootBridge->Mem.Translation;\r
+ } else if (Address >= RootBridge->PMem.Base && Address <= RootBridge->PMem.Limit) {\r
+ *Translation = RootBridge->PMem.Translation;\r
+ } else if (Address >= RootBridge->MemAbove4G.Base && Address <= RootBridge->MemAbove4G.Limit) {\r
+ *Translation = RootBridge->MemAbove4G.Translation;\r
+ } else if (Address >= RootBridge->PMemAbove4G.Base && Address <= RootBridge->PMemAbove4G.Limit) {\r
+ *Translation = RootBridge->PMemAbove4G.Translation;\r
+ } else {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Polls an address in memory mapped I/O space until an exit condition is met,\r
or a timeout occurs.\r
)\r
{\r
EFI_STATUS Status;\r
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
+ UINT64 Translation;\r
\r
Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address,\r
Count, Buffer);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer);\r
+\r
+ RootBridge = ROOT_BRIDGE_FROM_THIS (This);\r
+ Status = RootBridgeIoGetMemTranslationByAddress (RootBridge, Address, &Translation);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Address passed to CpuIo->Mem.Read needs to be a host address instead of\r
+ // device address.\r
+ return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
+ TO_HOST_ADDRESS (Address, Translation), Count, Buffer);\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
+ UINT64 Translation;\r
\r
Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address,\r
Count, Buffer);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer);\r
+\r
+ RootBridge = ROOT_BRIDGE_FROM_THIS (This);\r
+ Status = RootBridgeIoGetMemTranslationByAddress (RootBridge, Address, &Translation);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Address passed to CpuIo->Mem.Write needs to be a host address instead of\r
+ // device address.\r
+ return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
+ TO_HOST_ADDRESS (Address, Translation), Count, Buffer);\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
+\r
Status = RootBridgeIoCheckParameter (\r
This, IoOperation, Width,\r
Address, Count, Buffer\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer);\r
+\r
+ RootBridge = ROOT_BRIDGE_FROM_THIS (This);\r
+\r
+ // Address passed to CpuIo->Io.Read needs to be a host address instead of\r
+ // device address.\r
+ return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
+ TO_HOST_ADDRESS (Address, RootBridge->Io.Translation), Count, Buffer);\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;\r
+\r
Status = RootBridgeIoCheckParameter (\r
This, IoOperation, Width,\r
Address, Count, Buffer\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer);\r
+\r
+ RootBridge = ROOT_BRIDGE_FROM_THIS (This);\r
+\r
+ // Address passed to CpuIo->Io.Write needs to be a host address instead of\r
+ // device address.\r
+ return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
+ TO_HOST_ADDRESS (Address, RootBridge->Io.Translation), Count, Buffer);\r
}\r
\r
/**\r
\r
Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ // According to UEFI 2.7, RootBridgeIo->Configuration should return address\r
+ // range in CPU view (host address), and ResAllocNode->Base is already a CPU\r
+ // view address (host address).\r
Descriptor->AddrRangeMin = ResAllocNode->Base;\r
Descriptor->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
Descriptor->AddrLen = ResAllocNode->Length;\r
+ Descriptor->AddrTranslationOffset = GetTranslationByResourceType (\r
+ RootBridge,\r
+ ResAllocNode->Type\r
+ );\r
+\r
switch (ResAllocNode->Type) {\r
\r
case TypeIo:\r