\r
#define TOTAL_DMA_BUFFER_SIZE SIZE_4MB\r
\r
-EDKII_VTD_INFO_PPI *mVTdInfoPpi;\r
+EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;\r
+VTD_INFO *mVTdInfo;\r
+UINT64 mEngineMask;\r
UINTN mDmaBufferBase;\r
UINTN mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE;\r
UINTN mDmaBufferCurrentTop;\r
\r
PEI Memory Layout:\r
\r
+ +------------------+ <=============== PHMR.Limit (Top of memory)\r
+ | Mem Resource |\r
+ | |\r
+\r
+------------------+ <------- EfiMemoryTop\r
| PEI allocated |\r
- =========== +==================+\r
+ =========== +==================+ <=============== PHMR.Base\r
^ | Commom Buf |\r
| | -------------- |\r
DMA Buffer | * DMA FREE * |\r
| | -------------- |\r
V | Read/Write Buf |\r
- =========== +==================+\r
+ =========== +==================+ <=============== PLMR.Limit\r
| PEI allocated |\r
| -------------- | <------- EfiFreeMemoryTop\r
| * PEI FREE * |\r
| Mem Alloc Hob |\r
+------------------+\r
\r
+ | |\r
+ | Mem Resource |\r
+ +------------------+ <=============== PLMR.Base (0)\r
**/\r
\r
\r
/**\r
Get the highest memory.\r
\r
- @param HobList the HOB list.\r
-\r
@return the highest memory.\r
**/\r
UINT64\r
GetTopMemory (\r
- IN VOID *HobList\r
+ VOID\r
)\r
{\r
+ VOID *HobList;\r
EFI_PEI_HOB_POINTERS Hob;\r
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;\r
UINT64 TopMemory;\r
UINT64 ResourceTop;\r
\r
+ HobList = GetHobList ();\r
+\r
TopMemory = 0;\r
for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {\r
if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
\r
ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop);\r
\r
- LowMemoryAlignment = GetLowMemoryAlignment ();\r
- HighMemoryAlignment = GetHighMemoryAlignment ();\r
+ LowMemoryAlignment = GetLowMemoryAlignment (mEngineMask);\r
+ HighMemoryAlignment = GetHighMemoryAlignment (mEngineMask);\r
if (LowMemoryAlignment < HighMemoryAlignment) {\r
MemoryAlignment = (UINTN)HighMemoryAlignment;\r
} else {\r
LowBottom = 0;\r
LowTop = *DmaBufferBase;\r
HighBottom = *DmaBufferBase + DmaBufferSize;\r
- HighTop = GetTopMemory (HobList);\r
+ HighTop = GetTopMemory ();\r
\r
Status = SetDmaProtectedRange (\r
+ mEngineMask,\r
(UINT32)LowBottom,\r
(UINT32)(LowTop - LowBottom),\r
HighBottom,\r
return Status;\r
}\r
\r
+/**\r
+ Dump DMAR DeviceScopeEntry.\r
+\r
+ @param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry\r
+**/\r
+VOID\r
+DumpDmarDeviceScopeEntry (\r
+ IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry\r
+ )\r
+{\r
+ UINTN PciPathNumber;\r
+ UINTN PciPathIndex;\r
+ EFI_ACPI_DMAR_PCI_PATH *PciPath;\r
+\r
+ if (DmarDeviceScopeEntry == NULL) {\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " *************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " * DMA-Remapping Device Scope Entry Structure *\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " *************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ (sizeof(UINTN) == sizeof(UINT64)) ?\r
+ " DMAR Device Scope Entry address ...................... 0x%016lx\n" :\r
+ " DMAR Device Scope Entry address ...................... 0x%08x\n",\r
+ DmarDeviceScopeEntry\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Device Scope Entry Type ............................ 0x%02x\n",\r
+ DmarDeviceScopeEntry->Type\r
+ ));\r
+ switch (DmarDeviceScopeEntry->Type) {\r
+ case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:\r
+ DEBUG ((DEBUG_INFO,\r
+ " PCI Endpoint Device\n"\r
+ ));\r
+ break;\r
+ case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:\r
+ DEBUG ((DEBUG_INFO,\r
+ " PCI Sub-hierachy\n"\r
+ ));\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DEBUG ((DEBUG_INFO,\r
+ " Length ............................................. 0x%02x\n",\r
+ DmarDeviceScopeEntry->Length\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Enumeration ID ..................................... 0x%02x\n",\r
+ DmarDeviceScopeEntry->EnumerationId\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Starting Bus Number ................................ 0x%02x\n",\r
+ DmarDeviceScopeEntry->StartBusNumber\r
+ ));\r
+\r
+ PciPathNumber = (DmarDeviceScopeEntry->Length - sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER)) / sizeof(EFI_ACPI_DMAR_PCI_PATH);\r
+ PciPath = (EFI_ACPI_DMAR_PCI_PATH *)(DmarDeviceScopeEntry + 1);\r
+ for (PciPathIndex = 0; PciPathIndex < PciPathNumber; PciPathIndex++) {\r
+ DEBUG ((DEBUG_INFO,\r
+ " Device ............................................. 0x%02x\n",\r
+ PciPath[PciPathIndex].Device\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Function ........................................... 0x%02x\n",\r
+ PciPath[PciPathIndex].Function\r
+ ));\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " *************************************************************************\n\n"\r
+ ));\r
+\r
+ return;\r
+}\r
+\r
+/**\r
+ Dump DMAR RMRR table.\r
+\r
+ @param[in] Rmrr DMAR RMRR table\r
+**/\r
+VOID\r
+DumpDmarRmrr (\r
+ IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;\r
+ INTN RmrrLen;\r
+\r
+ if (Rmrr == NULL) {\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " * Reserved Memory Region Reporting Structure *\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ (sizeof(UINTN) == sizeof(UINT64)) ?\r
+ " RMRR address ........................................... 0x%016lx\n" :\r
+ " RMRR address ........................................... 0x%08x\n",\r
+ Rmrr\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Type ................................................. 0x%04x\n",\r
+ Rmrr->Header.Type\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Length ............................................... 0x%04x\n",\r
+ Rmrr->Header.Length\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Segment Number ....................................... 0x%04x\n",\r
+ Rmrr->SegmentNumber\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Reserved Memory Region Base Address .................. 0x%016lx\n",\r
+ Rmrr->ReservedMemoryRegionBaseAddress\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Reserved Memory Region Limit Address ................. 0x%016lx\n",\r
+ Rmrr->ReservedMemoryRegionLimitAddress\r
+ ));\r
+\r
+ RmrrLen = Rmrr->Header.Length - sizeof(EFI_ACPI_DMAR_RMRR_HEADER);\r
+ DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Rmrr + 1);\r
+ while (RmrrLen > 0) {\r
+ DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);\r
+ RmrrLen -= DmarDeviceScopeEntry->Length;\r
+ DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n\n"\r
+ ));\r
+\r
+ return;\r
+}\r
+\r
+/**\r
+ Dump DMAR DRHD table.\r
+\r
+ @param[in] Drhd DMAR DRHD table\r
+**/\r
+VOID\r
+DumpDmarDrhd (\r
+ IN EFI_ACPI_DMAR_DRHD_HEADER *Drhd\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;\r
+ INTN DrhdLen;\r
+\r
+ if (Drhd == NULL) {\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " * DMA-Remapping Hardware Definition Structure *\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ (sizeof(UINTN) == sizeof(UINT64)) ?\r
+ " DRHD address ........................................... 0x%016lx\n" :\r
+ " DRHD address ........................................... 0x%08x\n",\r
+ Drhd\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Type ................................................. 0x%04x\n",\r
+ Drhd->Header.Type\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Length ............................................... 0x%04x\n",\r
+ Drhd->Header.Length\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Flags ................................................ 0x%02x\n",\r
+ Drhd->Flags\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " INCLUDE_PCI_ALL .................................... 0x%02x\n",\r
+ Drhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Segment Number ....................................... 0x%04x\n",\r
+ Drhd->SegmentNumber\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Register Base Address ................................ 0x%016lx\n",\r
+ Drhd->RegisterBaseAddress\r
+ ));\r
+\r
+ DrhdLen = Drhd->Header.Length - sizeof(EFI_ACPI_DMAR_DRHD_HEADER);\r
+ DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Drhd + 1);\r
+ while (DrhdLen > 0) {\r
+ DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);\r
+ DrhdLen -= DmarDeviceScopeEntry->Length;\r
+ DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " ***************************************************************************\n\n"\r
+ ));\r
+\r
+ return;\r
+}\r
+\r
+/**\r
+ Dump DMAR ACPI table.\r
+\r
+ @param[in] Dmar DMAR ACPI table\r
+**/\r
+VOID\r
+DumpAcpiDMAR (\r
+ IN EFI_ACPI_DMAR_HEADER *Dmar\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;\r
+ INTN DmarLen;\r
+\r
+ if (Dmar == NULL) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Dump Dmar table\r
+ //\r
+ DEBUG ((DEBUG_INFO,\r
+ "*****************************************************************************\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ "* DMAR Table *\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ "*****************************************************************************\n"\r
+ ));\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ (sizeof(UINTN) == sizeof(UINT64)) ?\r
+ "DMAR address ............................................. 0x%016lx\n" :\r
+ "DMAR address ............................................. 0x%08x\n",\r
+ Dmar\r
+ ));\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ " Table Contents:\n"\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Host Address Width ................................... 0x%02x\n",\r
+ Dmar->HostAddressWidth\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " Flags ................................................ 0x%02x\n",\r
+ Dmar->Flags\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " INTR_REMAP ......................................... 0x%02x\n",\r
+ Dmar->Flags & EFI_ACPI_DMAR_FLAGS_INTR_REMAP\r
+ ));\r
+ DEBUG ((DEBUG_INFO,\r
+ " X2APIC_OPT_OUT_SET ................................. 0x%02x\n",\r
+ Dmar->Flags & EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT\r
+ ));\r
+\r
+ DmarLen = Dmar->Header.Length - sizeof(EFI_ACPI_DMAR_HEADER);\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)(Dmar + 1);\r
+ while (DmarLen > 0) {\r
+ switch (DmarHeader->Type) {\r
+ case EFI_ACPI_DMAR_TYPE_DRHD:\r
+ DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);\r
+ break;\r
+ case EFI_ACPI_DMAR_TYPE_RMRR:\r
+ DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DmarLen -= DmarHeader->Length;\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ "*****************************************************************************\n\n"\r
+ ));\r
+\r
+ return;\r
+}\r
+\r
+/**\r
+ Get VTd engine number.\r
+\r
+ @return the VTd engine number.\r
+**/\r
+UINTN\r
+GetVtdEngineNumber (\r
+ VOID\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;\r
+ UINTN VtdIndex;\r
+\r
+ VtdIndex = 0;\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(mAcpiDmarTable + 1));\r
+ while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + mAcpiDmarTable->Header.Length) {\r
+ switch (DmarHeader->Type) {\r
+ case EFI_ACPI_DMAR_TYPE_DRHD:\r
+ VtdIndex++;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);\r
+ }\r
+ return VtdIndex ;\r
+}\r
+\r
+/**\r
+ Process DMAR DHRD table.\r
+\r
+ @param[in] VtdIndex The index of VTd engine.\r
+ @param[in] DmarDrhd The DRHD table.\r
+**/\r
+VOID\r
+ProcessDhrd (\r
+ IN UINTN VtdIndex,\r
+ IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd\r
+ )\r
+{\r
+ DEBUG ((DEBUG_INFO," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex, DmarDrhd->RegisterBaseAddress));\r
+ mVTdInfo->VTdEngineAddress[VtdIndex] = DmarDrhd->RegisterBaseAddress;\r
+}\r
+\r
+/**\r
+ Parse DMAR DRHD table.\r
+\r
+ @return EFI_SUCCESS The DMAR DRHD table is parsed.\r
+**/\r
+EFI_STATUS\r
+ParseDmarAcpiTableDrhd (\r
+ VOID\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;\r
+ UINTN VtdUnitNumber;\r
+ UINTN VtdIndex;\r
+\r
+ VtdUnitNumber = GetVtdEngineNumber ();\r
+ if (VtdUnitNumber == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ mVTdInfo = AllocateZeroPool (sizeof(VTD_INFO) + (VtdUnitNumber - 1) * sizeof(UINT64));\r
+ if (mVTdInfo == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ mVTdInfo->HostAddressWidth = mAcpiDmarTable->HostAddressWidth;\r
+ mVTdInfo->VTdEngineCount = VtdUnitNumber;\r
+\r
+ VtdIndex = 0;\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(mAcpiDmarTable + 1));\r
+ while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + mAcpiDmarTable->Header.Length) {\r
+ switch (DmarHeader->Type) {\r
+ case EFI_ACPI_DMAR_TYPE_DRHD:\r
+ ASSERT (VtdIndex < VtdUnitNumber);\r
+ ProcessDhrd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);\r
+ VtdIndex++;\r
+\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);\r
+ }\r
+ ASSERT (VtdIndex == VtdUnitNumber);\r
+\r
+ //\r
+ // Initialize the engine mask to all.\r
+ //\r
+ mEngineMask = LShiftU64 (1, VtdUnitNumber) - 1;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Return the VTd engine index according to the Segment and DevScopeEntry.\r
+\r
+ @param Segment The segment of the VTd engine\r
+ @param DevScopeEntry The DevScopeEntry of the VTd engine\r
+\r
+ @return The VTd engine index according to the Segment and DevScopeEntry.\r
+ @retval -1 The VTd engine is not found.\r
+**/\r
+UINTN\r
+GetVTdEngineFromDevScopeEntry (\r
+ IN UINT16 Segment,\r
+ IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DevScopeEntry\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;\r
+ UINTN VtdIndex;\r
+ EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd;\r
+ EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *ThisDevScopeEntry;\r
+\r
+ VtdIndex = 0;\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(mAcpiDmarTable + 1));\r
+ while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + mAcpiDmarTable->Header.Length) {\r
+ switch (DmarHeader->Type) {\r
+ case EFI_ACPI_DMAR_TYPE_DRHD:\r
+ DmarDrhd = (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader;\r
+ if (DmarDrhd->SegmentNumber != Segment) {\r
+ // Mismatch\r
+ break;\r
+ }\r
+ if ((DmarDrhd->Header.Length == sizeof(EFI_ACPI_DMAR_DRHD_HEADER)) ||\r
+ ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0)) {\r
+ // No DevScopeEntry\r
+ // Do not handle PCI_ALL\r
+ break;\r
+ }\r
+ ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd + 1));\r
+ while ((UINTN)ThisDevScopeEntry < (UINTN)DmarDrhd + DmarDrhd->Header.Length) {\r
+ if ((ThisDevScopeEntry->Length == DevScopeEntry->Length) &&\r
+ (CompareMem (ThisDevScopeEntry, DevScopeEntry, DevScopeEntry->Length) == 0)) {\r
+ return VtdIndex;\r
+ }\r
+ ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)ThisDevScopeEntry + ThisDevScopeEntry->Length);\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);\r
+ }\r
+ return (UINTN)-1;\r
+}\r
+\r
+/**\r
+ Process DMAR RMRR table.\r
+\r
+ @param[in] DmarRmrr The RMRR table.\r
+**/\r
+VOID\r
+ProcessRmrr (\r
+ IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;\r
+ UINTN VTdIndex;\r
+ UINT64 RmrrMask;\r
+ UINTN LowBottom;\r
+ UINTN LowTop;\r
+ UINTN HighBottom;\r
+ UINT64 HighTop;\r
+\r
+ DEBUG ((DEBUG_INFO," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));\r
+\r
+ if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||\r
+ (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {\r
+ return ;\r
+ }\r
+\r
+ DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarRmrr + 1));\r
+ while ((UINTN)DmarDevScopeEntry < (UINTN)DmarRmrr + DmarRmrr->Header.Length) {\r
+ ASSERT (DmarDevScopeEntry->Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT);\r
+\r
+ VTdIndex = GetVTdEngineFromDevScopeEntry (DmarRmrr->SegmentNumber, DmarDevScopeEntry);\r
+ if (VTdIndex != (UINTN)-1) {\r
+ RmrrMask = LShiftU64 (1, VTdIndex);\r
+\r
+ LowBottom = 0;\r
+ LowTop = (UINTN)DmarRmrr->ReservedMemoryRegionBaseAddress;\r
+ HighBottom = (UINTN)DmarRmrr->ReservedMemoryRegionLimitAddress + 1;\r
+ HighTop = GetTopMemory ();\r
+\r
+ SetDmaProtectedRange (\r
+ RmrrMask,\r
+ 0,\r
+ (UINT32)(LowTop - LowBottom),\r
+ HighBottom,\r
+ HighTop - HighBottom\r
+ );\r
+\r
+ //\r
+ // Remove the engine from the engine mask.\r
+ // The assumption is that any other PEI driver does not access\r
+ // the device covered by this engine.\r
+ //\r
+ mEngineMask = mEngineMask & (~RmrrMask);\r
+ }\r
+\r
+ DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDevScopeEntry + DmarDevScopeEntry->Length);\r
+ }\r
+}\r
+\r
+/**\r
+ Parse DMAR DRHD table.\r
+**/\r
+VOID\r
+ParseDmarAcpiTableRmrr (\r
+ VOID\r
+ )\r
+{\r
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;\r
+\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(mAcpiDmarTable + 1));\r
+ while ((UINTN)DmarHeader < (UINTN)mAcpiDmarTable + mAcpiDmarTable->Header.Length) {\r
+ switch (DmarHeader->Type) {\r
+ case EFI_ACPI_DMAR_TYPE_RMRR:\r
+ ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);\r
+ }\r
+}\r
+\r
/**\r
Initializes the Intel VTd PMR PEIM.\r
\r
&gEdkiiVTdInfoPpiGuid,\r
0,\r
NULL,\r
- (VOID **)&mVTdInfoPpi\r
+ (VOID **)&mAcpiDmarTable\r
);\r
ASSERT_EFI_ERROR(Status);\r
\r
+ DumpAcpiDMAR (mAcpiDmarTable);\r
+\r
+ //\r
+ // Get DMAR information to local VTdInfo\r
+ //\r
+ Status = ParseDmarAcpiTableDrhd ();\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // If there is RMRR memory, parse it here.\r
+ //\r
+ ParseDmarAcpiTableRmrr ();\r
+\r
//\r
// Find a pre-memory in resource hob as DMA buffer\r
// Mark PEI memory to be DMA protected.\r