From: "Sheng Wei" <w.sheng@intel.com>
To: "Ni, Ray" <ray.ni@intel.com>,
"Huang, Jenny" <jenny.huang@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
"Kowalewski, Robert" <robert.kowalewski@intel.com>
Subject: Re: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
Date: Mon, 24 Jan 2022 02:44:22 +0000 [thread overview]
Message-ID: <PH0PR11MB4870E878BB06BAAC0CFE7621E15E9@PH0PR11MB4870.namprd11.prod.outlook.com> (raw)
In-Reply-To: <DM6PR11MB4627D610871592516C0F2ABBE25B9@DM6PR11MB4627.namprd11.prod.outlook.com>
As the review comment form Ray, I will use a fixed MAX VTdUnit number in function VTdInfoNotify().
After that, it will no need to allocate memory at every function call of VTdInfoNotify().
I set the MAX VTd unit number to 42. The total memory usage will just smaller than 4k (1 page). And this number is enough for client and server projects.
I update to patch V6
@Ni, Ray Could you help review and merge the patch ?
Thank you
BR
Sheng Wei
> -----Original Message-----
> From: Huang, Jenny <jenny.huang@intel.com>
> Sent: 2022年1月21日 16:36
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Kowalewski, Robert
> <robert.kowalewski@intel.com>
> Subject: RE: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA
> buffer once.
>
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
>
> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Tuesday, January 18, 2022 4:15 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>;
> Kowalewski, Robert <robert.kowalewski@intel.com>
> Subject: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer
> once.
>
> VTdInfoNotify may be called manay times, PEI DMA buffer should be
> generated only once.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3667
>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Jenny Huang <jenny.huang@intel.com>
> Cc: Robert Kowalewski <robert.kowalewski@intel.com>
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
> Signed-off-by: Sheng Wei <w.sheng@intel.com>
> ---
> .../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 545 +--------------------
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 +++++++---------
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++----
> ----
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++---
> .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 196 ++------
> 5 files changed, 533 insertions(+), 1234 deletions(-)
>
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> index e9c99d0a..acfbc4a8 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> @@ -1,6 +1,7 @@
> /** @file
>
> - Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> **/
> @@ -104,74 +105,6 @@ DumpDmarDeviceScopeEntry (
> return;
> }
>
> -/**
> - Dump DMAR RMRR table.
> -
> - @param[in] Rmrr DMAR RMRR table
> -**/
> -VOID
> -DumpDmarRmrr (
> - IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDeviceScopeEntry;
> - INTN RmrrLen;
> -
> - if (Rmrr == NULL) {
> - return;
> - }
> -
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - " * Reserved Memory Region Reporting Structure *\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - (sizeof (UINTN) == sizeof (UINT64)) ?
> - " RMRR address ........................................... 0x%016lx\n" :
> - " RMRR address ........................................... 0x%08x\n",
> - Rmrr
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Type ................................................. 0x%04x\n",
> - Rmrr->Header.Type
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Length ............................................... 0x%04x\n",
> - Rmrr->Header.Length
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Segment Number ....................................... 0x%04x\n",
> - Rmrr->SegmentNumber
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Reserved Memory Region Base Address .................. 0x%016lx\n",
> - Rmrr->ReservedMemoryRegionBaseAddress
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Reserved Memory Region Limit Address ................. 0x%016lx\n",
> - Rmrr->ReservedMemoryRegionLimitAddress
> - ));
> -
> - RmrrLen = Rmrr->Header.Length -
> sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
> - DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) (Rmrr + 1);
> - while (RmrrLen > 0) {
> - DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
> - RmrrLen -= DmarDeviceScopeEntry->Length;
> - DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
> - }
> -
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n\n"
> - ));
> -
> - return;
> -}
> -
> /**
> Dump DMAR DRHD table.
>
> @@ -312,9 +245,6 @@ DumpAcpiDMAR (
> case EFI_ACPI_DMAR_TYPE_DRHD:
> DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
> break;
> - case EFI_ACPI_DMAR_TYPE_RMRR:
> - DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
> - break;
> default:
> break;
> }
> @@ -329,492 +259,43 @@ DumpAcpiDMAR (
> return;
> }
>
> -/**
> - Get VTd engine number.
> -
> - @param[in] AcpiDmarTable DMAR ACPI table
> -
> - @return the VTd engine number.
> -**/
> -UINTN
> -GetVtdEngineNumber (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> - )
> -{
> - EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> - UINTN VtdIndex;
> -
> - VtdIndex = 0;
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> - while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
> - switch (DmarHeader->Type) {
> - case EFI_ACPI_DMAR_TYPE_DRHD:
> - VtdIndex++;
> - break;
> - default:
> - break;
> - }
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> - }
> - return VtdIndex ;
> -}
> -
> -/**
> - Get PCI device information from DMAR DevScopeEntry.
> -
> - @param[in] Segment The segment number.
> - @param[in] DmarDevScopeEntry DMAR DevScopeEntry
> - @param[out] Bus The bus number.
> - @param[out] Device The device number.
> - @param[out] Function The function number.
> -
> - @retval EFI_SUCCESS The PCI device information is returned.
> -**/
> -EFI_STATUS
> -GetPciBusDeviceFunction (
> - IN UINT16 Segment,
> - IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry,
> - OUT UINT8 *Bus,
> - OUT UINT8 *Device,
> - OUT UINT8 *Function
> - )
> -{
> - EFI_ACPI_DMAR_PCI_PATH *DmarPciPath;
> - UINT8 MyBus;
> - UINT8 MyDevice;
> - UINT8 MyFunction;
> -
> - DmarPciPath = (EFI_ACPI_DMAR_PCI_PATH *) ((UINTN)
> (DmarDevScopeEntry + 1));
> - MyBus = DmarDevScopeEntry->StartBusNumber;
> - MyDevice = DmarPciPath->Device;
> - MyFunction = DmarPciPath->Function;
> -
> - switch (DmarDevScopeEntry->Type) {
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
> - while ((UINTN) DmarPciPath + sizeof (EFI_ACPI_DMAR_PCI_PATH) <
> (UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length) {
> - MyBus = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (Segment,
> MyBus, MyDevice, MyFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> - DmarPciPath ++;
> - MyDevice = DmarPciPath->Device;
> - MyFunction = DmarPciPath->Function;
> - }
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
> - break;
> - }
> -
> - *Bus = MyBus;
> - *Device = MyDevice;
> - *Function = MyFunction;
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Return the index of PCI data.
> -
> - @param[in] VTdUnitInfo The VTd engine unit information.
> - @param[in] Segment The Segment used to identify a VTd engine.
> - @param[in] SourceId The SourceId used to identify a VTd engine and
> table entry.
> -
> - @return The index of the PCI data.
> - @retval (UINTN)-1 The PCI data is not found.
> -**/
> -UINTN
> -GetPciDataIndex (
> - IN VTD_UNIT_INFO *VTdUnitInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId
> - )
> -{
> - UINTN Index;
> - VTD_SOURCE_ID *PciSourceId;
> - PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
> -
> - if (Segment != VTdUnitInfo->Segment) {
> - return (UINTN)-1;
> - }
> -
> - for (Index = 0; Index < VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber;
> Index++) {
> - PciDeviceDataBase = (PEI_PCI_DEVICE_DATA*) (UINTN) VTdUnitInfo-
> >PciDeviceInfo.PciDeviceData;
> - PciSourceId = &PciDeviceDataBase[Index].PciSourceId;
> - if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&
> - (PciSourceId->Bits.Device == SourceId.Bits.Device) &&
> - (PciSourceId->Bits.Function == SourceId.Bits.Function) ) {
> - return Index;
> - }
> - }
> -
> - return (UINTN)-1;
> -}
> -
> -
> -/**
> - Register PCI device to VTd engine.
> -
> - @param[in] VTdUnitInfo The VTd engine unit information.
> - @param[in] Segment The segment of the source.
> - @param[in] SourceId The SourceId of the source.
> - @param[in] DeviceType The DMAR device scope type.
> - @param[in] CheckExist TRUE: ERROR will be returned if the PCI device
> is already registered.
> - FALSE: SUCCESS will be returned if the PCI device is
> registered.
> -
> - @retval EFI_SUCCESS The PCI device is registered.
> - @retval EFI_OUT_OF_RESOURCES No enough resource to register a new
> PCI device.
> - @retval EFI_ALREADY_STARTED The device is already registered.
> -
> -**/
> -EFI_STATUS
> -RegisterPciDevice (
> - IN VTD_UNIT_INFO *VTdUnitInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT8 DeviceType,
> - IN BOOLEAN CheckExist
> - )
> -{
> - PEI_PCI_DEVICE_INFORMATION *PciDeviceInfo;
> - VTD_SOURCE_ID *PciSourceId;
> - UINTN PciDataIndex;
> - UINTN PciDeviceDataSize;
> - PEI_PCI_DEVICE_DATA *NewPciDeviceData;
> - PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
> -
> - PciDeviceInfo = &VTdUnitInfo->PciDeviceInfo;
> -
> - PciDataIndex = GetPciDataIndex (VTdUnitInfo, Segment, SourceId);
> - if (PciDataIndex == (UINTN)-1) {
> - //
> - // Register new
> - //
> -
> - if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo-
> >PciDeviceDataMaxNumber) {
> - //
> - // Reallocate
> - //
> - PciDeviceDataSize = sizeof(*NewPciDeviceData) * (PciDeviceInfo-
> >PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER);
> - DEBUG ((DEBUG_INFO, "New PciDeviceDataSize:%d Page:%d\n",
> PciDeviceDataSize, EFI_SIZE_TO_PAGES (PciDeviceDataSize)));
> - NewPciDeviceData = AllocateZeroPages
> (EFI_SIZE_TO_PAGES(PciDeviceDataSize));
> - if (NewPciDeviceData == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> - PciDeviceInfo->PciDeviceDataMaxNumber +=
> MAX_VTD_PCI_DATA_NUMBER;
> - if (PciDeviceInfo->PciDeviceData != 0) {
> - CopyMem (NewPciDeviceData, (VOID *) (UINTN) PciDeviceInfo-
> >PciDeviceData, sizeof (*NewPciDeviceData) * PciDeviceInfo-
> >PciDeviceDataNumber);
> - FreePages((VOID *) (UINTN) PciDeviceInfo->PciDeviceData,
> PciDeviceInfo->PciDeviceDataPageSize);
> - }
> - PciDeviceInfo->PciDeviceData = (UINT32) (UINTN) NewPciDeviceData;
> - PciDeviceInfo->PciDeviceDataPageSize = (UINT32) EFI_SIZE_TO_PAGES
> (PciDeviceDataSize);
> - }
> -
> - ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo-
> >PciDeviceDataMaxNumber);
> -
> - PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) PciDeviceInfo-
> >PciDeviceData;
> - PciSourceId = &PciDeviceDataBase[PciDeviceInfo-
> >PciDeviceDataNumber].PciSourceId;
> - PciSourceId->Bits.Bus = SourceId.Bits.Bus;
> - PciSourceId->Bits.Device = SourceId.Bits.Device;
> - PciSourceId->Bits.Function = SourceId.Bits.Function;
> -
> - DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x
> F%02x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> -
> - PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber].DeviceType =
> DeviceType;
> -
> - if ((DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT)
> &&
> - (DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
> - DEBUG ((DEBUG_INFO, " (*)"));
> - }
> - DEBUG ((DEBUG_INFO, "\n"));
> -
> - PciDeviceInfo->PciDeviceDataNumber++;
> - } else {
> - if (CheckExist) {
> - DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x
> F%02x already registered\n", Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> - return EFI_ALREADY_STARTED;
> - }
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Process DMAR DRHD table.
> -
> - @param[in] VTdUnitInfo The VTd engine unit information.
> - @param[in] DmarDrhd The DRHD table.
> -
> -**/
> -VOID
> -ProcessDrhd (
> - IN VTD_UNIT_INFO *VTdUnitInfo,
> - IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> - UINT8 Bus;
> - UINT8 Device;
> - UINT8 Function;
> - EFI_STATUS Status;
> - VTD_SOURCE_ID SourceId;
> -
> - DEBUG ((DEBUG_INFO," VTD BaseAddress - 0x%016lx\n", DmarDrhd-
> >RegisterBaseAddress));
> - VTdUnitInfo->VtdUnitBaseAddress = (UINT32) DmarDrhd-
> >RegisterBaseAddress;
> -
> - VTdUnitInfo->EnableQueuedInvalidation = 0;
> -
> - DEBUG ((DEBUG_INFO," VTD Segment - %d\n", DmarDrhd-
> >SegmentNumber));
> - VTdUnitInfo->Segment = DmarDrhd->SegmentNumber;
> -
> - VTdUnitInfo->FixedSecondLevelPagingEntry = 0;
> - VTdUnitInfo->RmrrSecondLevelPagingEntry = 0;
> - VTdUnitInfo->RootEntryTable = 0;
> - VTdUnitInfo->ExtRootEntryTable = 0;
> - VTdUnitInfo->RootEntryTablePageSize = 0;
> - VTdUnitInfo->ExtRootEntryTablePageSize = 0;
> -
> - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
> -
> - if ((DmarDrhd->Flags &
> EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0) {
> - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = TRUE;
> - DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n"));
> - } else {
> - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = FALSE;
> - DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n"));
> - }
> -
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> (DmarDrhd + 1));
> - while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd-
> >Header.Length) {
> -
> - Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> - if (EFI_ERROR (Status)) {
> - return;
> - }
> -
> - DEBUG ((DEBUG_INFO," ProcessDrhd: "));
> - switch (DmarDevScopeEntry->Type) {
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
> - DEBUG ((DEBUG_INFO,"PCI Endpoint"));
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
> - DEBUG ((DEBUG_INFO,"PCI-PCI bridge"));
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
> - DEBUG ((DEBUG_INFO,"IOAPIC"));
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
> - DEBUG ((DEBUG_INFO,"MSI Capable HPET"));
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
> - DEBUG ((DEBUG_INFO,"ACPI Namespace Device"));
> - break;
> - }
> - DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n", DmarDrhd-
> >SegmentNumber, Bus, Device, Function));
> -
> - SourceId.Bits.Bus = Bus;
> - SourceId.Bits.Device = Device;
> - SourceId.Bits.Function = Function;
> -
> - Status = RegisterPciDevice (VTdUnitInfo, DmarDrhd->SegmentNumber,
> SourceId, DmarDevScopeEntry->Type, TRUE);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
> - }
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDevScopeEntry + DmarDevScopeEntry->Length);
> - }
> -}
> -
> -/**
> - Dump the PCI device information managed by this VTd engine.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] VtdIndex The index of VTd engine.
> -
> -**/
> -VOID
> -DumpPciDeviceInfo (
> - IN VTD_INFO *VTdInfo,
> - IN UINTN VtdIndex
> - )
> -{
> - UINTN Index;
> - PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
> -
> - DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll -
> %d):\n",
> - VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,
> - VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag
> - ));
> -
> - PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
> -
> - for (Index = 0; Index < VTdInfo-
> >VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
> - DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n",
> - VTdInfo->VtdUnitInfo[VtdIndex].Segment,
> - PciDeviceDataBase[Index].PciSourceId.Bits.Bus,
> - PciDeviceDataBase[Index].PciSourceId.Bits.Device,
> - PciDeviceDataBase[Index].PciSourceId.Bits.Function
> - ));
> - }
> -}
> -
> /**
> Parse DMAR DRHD table.
>
> @param[in] AcpiDmarTable DMAR ACPI table
> + @param[in] Callback Callback function for handle DRHD
> + @param[in] Context Callback function Context
>
> @return EFI_SUCCESS The DMAR DRHD table is parsed.
>
> **/
> EFI_STATUS
> ParseDmarAcpiTableDrhd (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
> + IN PROCESS_DRHD_CALLBACK_FUNC Callback,
> + IN VOID *Context
> )
> {
> EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> - UINTN VtdUnitNumber;
> - UINTN VtdIndex;
> - VTD_INFO *VTdInfo;
> -
> - VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
> - if (VtdUnitNumber == 0) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO) +
> (VtdUnitNumber - 1) * sizeof (VTD_UNIT_INFO));
> - ASSERT(VTdInfo != NULL);
> - if (VTdInfo == NULL) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - //
> - // Initialize the engine mask to all.
> - //
> - VTdInfo->AcpiDmarTable = (UINT32) (UINTN) AcpiDmarTable;
> - VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
> - VTdInfo->VTdEngineCount = (UINT32) VtdUnitNumber;
> + UINT32 VtdIndex;
>
> VtdIndex = 0;
> DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> +
> while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
> switch (DmarHeader->Type) {
> case EFI_ACPI_DMAR_TYPE_DRHD:
> - ASSERT (VtdIndex < VtdUnitNumber);
> - ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex],
> (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
> + if (Callback != NULL) {
> + Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)
> DmarHeader);
> + }
> VtdIndex++;
> -
> break;
> -
> default:
> break;
> }
> DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> }
> - ASSERT (VtdIndex == VtdUnitNumber);
> -
> - for (VtdIndex = 0; VtdIndex < VtdUnitNumber; VtdIndex++) {
> - DumpPciDeviceInfo (VTdInfo, VtdIndex);
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -
> -/**
> - Process DMAR RMRR table.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] DmarRmrr The RMRR table.
> -
> -**/
> -VOID
> -ProcessRmrr (
> - IN VTD_INFO *VTdInfo,
> - IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> - UINT8 Bus;
> - UINT8 Device;
> - UINT8 Function;
> - EFI_STATUS Status;
> - VTD_SOURCE_ID SourceId;
> -
> - DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n",
> DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr-
> >ReservedMemoryRegionLimitAddress));
> -
> - if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
> - (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
> - return ;
> - }
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> (DmarRmrr + 1));
> - while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr-
> >Header.Length) {
> - if (DmarDevScopeEntry->Type !=
> EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
> - DEBUG ((DEBUG_INFO,"RMRR DevScopeEntryType is not endpoint,
> type[0x%x] \n", DmarDevScopeEntry->Type));
> - return;
> - }
> -
> - Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> - if (EFI_ERROR (Status)) {
> - continue;
> - }
> -
> - DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr-
> >SegmentNumber, Bus, Device, Function));
> -
> - SourceId.Bits.Bus = Bus;
> - SourceId.Bits.Device = Device;
> - SourceId.Bits.Function = Function;
> -
> - Status = EnableRmrrPageAttribute (
> - VTdInfo,
> - DmarRmrr->SegmentNumber,
> - SourceId,
> - DmarRmrr->ReservedMemoryRegionBaseAddress,
> - DmarRmrr->ReservedMemoryRegionLimitAddress,
> - EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute : %r\n", Status));
> - }
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDevScopeEntry + DmarDevScopeEntry->Length);
> - }
> -}
> -
> -/**
> - Parse DMAR DRHD table.
> -
> - @param[in] VTdInfo The VTd engine context information.
> -
> -**/
> -VOID
> -ParseDmarAcpiTableRmrr (
> - IN VTD_INFO *VTdInfo
> - )
> -{
> - EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> - EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
>
> - AcpiDmarTable = (EFI_ACPI_DMAR_HEADER *) (UINTN) VTdInfo-
> >AcpiDmarTable;
> -
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> (AcpiDmarTable + 1));
> - while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable-
> >Header.Length) {
> - switch (DmarHeader->Type) {
> - case EFI_ACPI_DMAR_TYPE_RMRR:
> - ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *)
> DmarHeader);
> - break;
> - default:
> - break;
> - }
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> - }
> + return VtdIndex;
> }
>
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> index 63397a1a..0ed216bb 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -79,77 +79,73 @@ PerpareCacheInvalidationInterface (
> IN VTD_UNIT_INFO *VTdUnitInfo
> )
> {
> - UINT16 QueueSize;
> + UINT16 QiDescLength;
> UINT64 Reg64;
> UINT32 Reg32;
> VTD_ECAP_REG ECapReg;
> + UINTN VtdUnitBaseAddress;
>
> + VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
>
> - if (VTdUnitInfo->VerReg.Bits.Major <= 6) {
> + if (VTdUnitInfo->VerReg.Bits.Major <= 5) {
> VTdUnitInfo->EnableQueuedInvalidation = 0;
> - DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for
> engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
> + DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for
> engine [0x%x]\n", VtdUnitBaseAddress));
> return EFI_SUCCESS;
> }
>
> - ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> + ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
> if (ECapReg.Bits.QI == 0) {
> - DEBUG ((DEBUG_ERROR, "Hardware does not support queued
> invalidations interface for engine [0x%x]\n", VTdUnitInfo-
> >VtdUnitBaseAddress));
> + DEBUG ((DEBUG_ERROR, "Hardware does not support queued
> invalidations interface for engine [0x%x]\n", VtdUnitBaseAddress));
> return EFI_UNSUPPORTED;
> }
>
> VTdUnitInfo->EnableQueuedInvalidation = 1;
> - DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine
> [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
> + DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine
> [0x%x]\n", VtdUnitBaseAddress));
>
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> if ((Reg32 & B_GSTS_REG_QIES) != 0) {
> DEBUG ((DEBUG_INFO,"Queued Invalidation Interface was enabled.\n"));
> Reg32 &= (~B_GSTS_REG_QIES);
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
> do {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while ((Reg32 & B_GSTS_REG_QIES) != 0);
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG,
> 0);
> -
> - if (VTdUnitInfo->QiDesc != NULL) {
> - FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) *
> VTdUnitInfo->QiDescLength));
> - VTdUnitInfo->QiDesc = NULL;
> - VTdUnitInfo->QiDescLength = 0;
> - }
> + MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0);
> }
>
> //
> // Initialize the Invalidation Queue Tail Register to zero.
> //
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> 0);
> + MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, 0);
>
> //
> // Setup the IQ address, size and descriptor width through the Invalidation
> Queue Address Register
> //
> - QueueSize = 0;
> - VTdUnitInfo->QiDescLength = 1 << (QueueSize + 8);
> - VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages
> (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * VTdUnitInfo->QiDescLength));
> -
> if (VTdUnitInfo->QiDesc == NULL) {
> - VTdUnitInfo->QiDescLength = 0;
> - DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"));
> - return EFI_OUT_OF_RESOURCES;
> + VTdUnitInfo->QueueSize = 0;
> + QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
> + VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages
> (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength));
> + if (VTdUnitInfo->QiDesc == NULL) {
> + DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue
> Buffer.\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> }
>
> - DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo-
> >QiDescLength));
> - Reg64 = (UINT64)(UINTN)VTdUnitInfo->QiDesc;
> - Reg64 |= QueueSize;
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG,
> Reg64);
> + DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n",
> QiDescLength));
> + Reg64 = (UINT64) (UINTN) VTdUnitInfo->QiDesc;
> + Reg64 |= VTdUnitInfo->QueueSize;
> + MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64);
>
> //
> // Enable the queued invalidation interface through the Global Command
> Register.
> // When enabled, hardware sets the QIES field in the Global Status Register.
> //
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> Reg32 |= B_GMCD_REG_QIE;
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
> DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG
> = 0x%x\n", Reg32));
> do {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while ((Reg32 & B_GSTS_REG_QIES) == 0);
>
> VTdUnitInfo->QiFreeHead = 0;
> @@ -167,21 +163,23 @@ DisableQueuedInvalidationInterface (
> IN VTD_UNIT_INFO *VTdUnitInfo
> )
> {
> - UINT32 Reg32;
> + UINT32 Reg32;
> + UINT16 QiDescLength;
>
> if (VTdUnitInfo->EnableQueuedInvalidation != 0) {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> Reg32 &= (~B_GMCD_REG_QIE);
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32);
> + MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG,
> Reg32);
> DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface.
> GCMD_REG = 0x%x\n", Reg32));
> do {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> } while ((Reg32 & B_GSTS_REG_QIES) != 0);
>
> if (VTdUnitInfo->QiDesc != NULL) {
> - FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) *
> VTdUnitInfo->QiDescLength));
> + QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
> + FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC)
> * QiDescLength));
> VTdUnitInfo->QiDesc = NULL;
> - VTdUnitInfo->QiDescLength = 0;
> + VTdUnitInfo->QueueSize = 0;
> }
>
> VTdUnitInfo->EnableQueuedInvalidation = 0;
> @@ -203,26 +201,11 @@ QueuedInvalidationCheckFault (
> {
> UINT32 FaultReg;
>
> - FaultReg = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_FSTS_REG);
> -
> - if (FaultReg & B_FSTS_REG_IQE) {
> - DEBUG((DEBUG_ERROR, "Detect Invalidation Queue Error [0x%08x]\n",
> FaultReg));
> - FaultReg |= B_FSTS_REG_IQE;
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> - return RETURN_DEVICE_ERROR;
> - }
> -
> - if (FaultReg & B_FSTS_REG_ITE) {
> - DEBUG((DEBUG_ERROR, "Detect Invalidation Time-out Error [0x%08x]\n",
> FaultReg));
> - FaultReg |= B_FSTS_REG_ITE;
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> - return RETURN_DEVICE_ERROR;
> - }
> -
> - if (FaultReg & B_FSTS_REG_ICE) {
> - DEBUG((DEBUG_ERROR, "Detect Invalidation Completion Error
> [0x%08x]\n", FaultReg));
> - FaultReg |= B_FSTS_REG_ICE;
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> + FaultReg = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress +
> R_FSTS_REG);
> + if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) {
> + DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x]\n",
> FaultReg));
> + FaultReg |= (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE);
> + MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG,
> FaultReg);
> return RETURN_DEVICE_ERROR;
> }
>
> @@ -256,7 +239,7 @@ SubmitQueuedInvalidationDescriptor (
> return EFI_INVALID_PARAMETER;
> }
>
> - QiDescLength = VTdUnitInfo->QiDescLength;
> + QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
> BaseDesc = VTdUnitInfo->QiDesc;
>
> DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%08x, 0x%08x]\n",
> VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High));
> @@ -268,12 +251,12 @@ SubmitQueuedInvalidationDescriptor (
> DEBUG((DEBUG_INFO,"QI Free Head=0x%x\n", VTdUnitInfo-
> >QiFreeHead));
> VTdUnitInfo->QiFreeHead = (VTdUnitInfo->QiFreeHead + 1) %
> QiDescLength;
>
> - Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> + Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> //
> // Update the HW tail register indicating the presence of new descriptors.
> //
> Reg64Iqt = VTdUnitInfo->QiFreeHead << DMAR_IQ_SHIFT;
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> Reg64Iqt);
> + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG,
> Reg64Iqt);
>
> Status = EFI_SUCCESS;
> do {
> @@ -283,7 +266,7 @@ SubmitQueuedInvalidationDescriptor (
> break;
> }
>
> - Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> + Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_IQH_REG);
> } while (Reg64Iqt != Reg64Iqh);
>
> DEBUG((DEBUG_ERROR,"SubmitQueuedInvalidationDescriptor end\n"));
> @@ -307,18 +290,18 @@ InvalidateContextCache (
> //
> // Register-based Invalidation
> //
> - Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> + Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> if ((Reg64 & B_CCMD_REG_ICC) != 0) {
> - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache:
> B_CCMD_REG_ICC is set for VTD(%x)\n", (UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress));
> + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache:
> B_CCMD_REG_ICC is set for VTD(%x)\n", VTdUnitInfo-
> >VtdUnitBaseAddress));
> return EFI_DEVICE_ERROR;
> }
>
> Reg64 &= ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK));
> Reg64 |= (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL);
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG, Reg64);
> + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG,
> Reg64);
>
> do {
> - Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> + Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_CCMD_REG);
> } while ((Reg64 & B_CCMD_REG_ICC) != 0);
> } else {
> //
> @@ -351,26 +334,26 @@ InvalidateIOTLB (
> //
> // Register-based Invalidation
> //
> - ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> + ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_ECAP_REG);
>
> - Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> + Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> if ((Reg64 & B_IOTLB_REG_IVT) != 0) {
> - DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is
> set for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress));
> + DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is
> set for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress));
> return EFI_DEVICE_ERROR;
> }
>
> Reg64 &= ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK));
> Reg64 |= (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL);
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
> + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO *
> 16) + R_IOTLB_REG, Reg64);
>
> do {
> - Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> + Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
> } while ((Reg64 & B_IOTLB_REG_IVT) != 0);
> } else {
> //
> // Queued Invalidation
> //
> - ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo-
> >VtdUnitBaseAddress + R_ECAP_REG);
> + ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress +
> R_ECAP_REG);
> QiDesc.Low = QI_IOTLB_DID(0) |
> QI_IOTLB_DR(CAP_READ_DRAIN(ECapReg.Uint64)) |
> QI_IOTLB_DW(CAP_WRITE_DRAIN(ECapReg.Uint64)) | QI_IOTLB_GRAN(1) |
> QI_IOTLB_TYPE;
> QiDesc.High = QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0);
>
> @@ -392,14 +375,14 @@ InvalidateIOTLB (
> EFI_STATUS
> EnableDmarPreMem (
> IN UINTN VtdUnitBaseAddress,
> - IN UINTN RtaddrRegValue
> + IN UINT64 RtaddrRegValue
> )
> {
> UINT32 Reg32;
>
> DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n",
> VtdUnitBaseAddress));
>
> - DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue));
> + DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%016lx \n", RtaddrRegValue));
> MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)
> RtaddrRegValue);
>
> Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> @@ -452,30 +435,33 @@ EnableDmar (
> )
> {
> UINT32 Reg32;
> + UINTN VtdUnitBaseAddress;
>
> - DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n",
> VTdUnitInfo->VtdUnitBaseAddress));
> + VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
> +
> + DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n",
> VtdUnitBaseAddress));
>
> DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));
> - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_RTADDR_REG, (UINT64) (UINTN) RootEntryTable);
> + MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)
> RootEntryTable);
>
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 |
> B_GMCD_REG_SRTP);
>
> DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"));
> do {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while((Reg32 & B_GSTS_REG_RTPS) == 0);
> DEBUG ((DEBUG_INFO, "EnableDmar: R_GSTS_REG = 0x%x \n", Reg32));
>
> //
> // Init DMAr Fault Event and Data registers
> //
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_FEDATA_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);
>
> //
> // Write Buffer Flush before invalidation
> //
> - FlushWriteBuffer ((UINTN)VTdUnitInfo->VtdUnitBaseAddress);
> + FlushWriteBuffer (VtdUnitBaseAddress);
>
> //
> // Invalidate the context cache
> @@ -490,11 +476,11 @@ EnableDmar (
> //
> // Enable VTd
> //
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GCMD_REG, Reg32 | B_GMCD_REG_TE);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 |
> B_GMCD_REG_TE);
> DEBUG ((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
> do {
> - Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress +
> R_GSTS_REG);
> + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
> } while ((Reg32 & B_GSTS_REG_TE) == 0);
>
> DEBUG ((DEBUG_INFO, "VTD () enabled!<<<<<<\n"));
> @@ -566,139 +552,52 @@ DisableDmar (
> }
>
> /**
> - Dump VTd version registers.
> + Enable VTd translation table protection for block DMA
>
> - @param[in] VerReg The version register.
> -**/
> -VOID
> -DumpVtdVerRegs (
> - IN VTD_VER_REG *VerReg
> - )
> -{
> - DEBUG ((DEBUG_INFO, " VerReg:\n", VerReg->Uint32));
> - DEBUG ((DEBUG_INFO, " Major - 0x%x\n", VerReg->Bits.Major));
> - DEBUG ((DEBUG_INFO, " Minor - 0x%x\n", VerReg->Bits.Minor));
> -}
> -
> -/**
> - Dump VTd capability registers.
> -
> - @param[in] CapReg The capability register.
> -**/
> -VOID
> -DumpVtdCapRegs (
> - IN VTD_CAP_REG *CapReg
> - )
> -{
> - DEBUG ((DEBUG_INFO, " CapReg:\n", CapReg->Uint64));
> - DEBUG ((DEBUG_INFO, " ND - 0x%x\n", CapReg->Bits.ND));
> - DEBUG ((DEBUG_INFO, " AFL - 0x%x\n", CapReg->Bits.AFL));
> - DEBUG ((DEBUG_INFO, " RWBF - 0x%x\n", CapReg->Bits.RWBF));
> - DEBUG ((DEBUG_INFO, " PLMR - 0x%x\n", CapReg->Bits.PLMR));
> - DEBUG ((DEBUG_INFO, " PHMR - 0x%x\n", CapReg->Bits.PHMR));
> - DEBUG ((DEBUG_INFO, " CM - 0x%x\n", CapReg->Bits.CM));
> - DEBUG ((DEBUG_INFO, " SAGAW - 0x%x\n", CapReg->Bits.SAGAW));
> - DEBUG ((DEBUG_INFO, " MGAW - 0x%x\n", CapReg->Bits.MGAW));
> - DEBUG ((DEBUG_INFO, " ZLR - 0x%x\n", CapReg->Bits.ZLR));
> - DEBUG ((DEBUG_INFO, " FRO - 0x%x\n", CapReg->Bits.FRO));
> - DEBUG ((DEBUG_INFO, " SLLPS - 0x%x\n", CapReg->Bits.SLLPS));
> - DEBUG ((DEBUG_INFO, " PSI - 0x%x\n", CapReg->Bits.PSI));
> - DEBUG ((DEBUG_INFO, " NFR - 0x%x\n", CapReg->Bits.NFR));
> - DEBUG ((DEBUG_INFO, " MAMV - 0x%x\n", CapReg->Bits.MAMV));
> - DEBUG ((DEBUG_INFO, " DWD - 0x%x\n", CapReg->Bits.DWD));
> - DEBUG ((DEBUG_INFO, " DRD - 0x%x\n", CapReg->Bits.DRD));
> - DEBUG ((DEBUG_INFO, " FL1GP - 0x%x\n", CapReg->Bits.FL1GP));
> - DEBUG ((DEBUG_INFO, " PI - 0x%x\n", CapReg->Bits.PI));
> -}
> + @param[in] VtdUnitBaseAddress The base address of the VTd engine.
>
> -/**
> - Dump VTd extended capability registers.
> -
> - @param[in] ECapReg The extended capability register.
> + @retval EFI_SUCCESS DMAR translation is enabled.
> + @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
> **/
> -VOID
> -DumpVtdECapRegs (
> - IN VTD_ECAP_REG *ECapReg
> - )
> -{
> - DEBUG ((DEBUG_INFO, " ECapReg:\n", ECapReg->Uint64));
> - DEBUG ((DEBUG_INFO, " C - 0x%x\n", ECapReg->Bits.C));
> - DEBUG ((DEBUG_INFO, " QI - 0x%x\n", ECapReg->Bits.QI));
> - DEBUG ((DEBUG_INFO, " DT - 0x%x\n", ECapReg->Bits.DT));
> - DEBUG ((DEBUG_INFO, " IR - 0x%x\n", ECapReg->Bits.IR));
> - DEBUG ((DEBUG_INFO, " EIM - 0x%x\n", ECapReg->Bits.EIM));
> - DEBUG ((DEBUG_INFO, " PT - 0x%x\n", ECapReg->Bits.PT));
> - DEBUG ((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC));
> - DEBUG ((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO));
> - DEBUG ((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV));
> - DEBUG ((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS));
> - DEBUG ((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST));
> - DEBUG ((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID));
> - DEBUG ((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS));
> - DEBUG ((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS));
> - DEBUG ((DEBUG_INFO, " SRS - 0x%x\n", ECapReg->Bits.SRS));
> - DEBUG ((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS));
> - DEBUG ((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS));
> - DEBUG ((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS));
> - DEBUG ((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS));
> -}
> -
> -
> -/**
> - Enable VTd translation table protection for all.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] EngineMask The mask of the VTd engine to be accessed.
> -**/
> -VOID
> -EnableVTdTranslationProtectionAll (
> - IN VTD_INFO *VTdInfo,
> - IN UINT64 EngineMask
> +EFI_STATUS
> +EnableVTdTranslationProtectionBlockDma (
> + IN UINTN VtdUnitBaseAddress
> )
> {
> - EFI_STATUS Status;
> - EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable;
> - UINTN Index;
> + EFI_STATUS Status;
> + VTD_ECAP_REG ECapReg;
> + EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable;
>
> - DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n",
> EngineMask));
> + DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionBlockDma -
> 0x%08x\n", VtdUnitBaseAddress));
>
> - for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> - if ((EngineMask & LShiftU64(1, Index)) == 0) {
> - continue;
> - }
> + ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
> + DEBUG ((DEBUG_INFO, "ECapReg : 0%016lx\n", ECapReg.Uint64));
>
> - VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
> - DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
> - VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
> - DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
> - VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
> - DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
> -
> - if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS == 1) {
> - //
> - // Use Abort DMA Mode
> - //
> - Status = EnableDmarPreMem (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM);
> - } else {
> - //
> - // Use Null Root Entry Table
> - //
> - Status = PeiServicesLocatePpi (
> - &gEdkiiVTdNullRootEntryTableGuid,
> - 0,
> - NULL,
> - (VOID **)&RootEntryTable
> - );
> - if (EFI_ERROR(Status)) {
> - DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n",
> Status));
> - ASSERT (FALSE);
> - return;
> - }
> - EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress,
> (UINTN) *RootEntryTable);
> + if (ECapReg.Bits.ADMS == 1) {
> + //
> + // Use Abort DMA Mode
> + //
> + DEBUG ((DEBUG_INFO, "Enable abort DMA mode.\n"));
> + Status = EnableDmarPreMem (VtdUnitBaseAddress,
> V_RTADDR_REG_TTM_ADM);
> + } else {
> + //
> + // Use Null Root Entry Table
> + //
> + Status = PeiServicesLocatePpi (
> + &gEdkiiVTdNullRootEntryTableGuid,
> + 0,
> + NULL,
> + (VOID **)&RootEntryTable
> + );
> + if (EFI_ERROR(Status)) {
> + DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n",
> Status));
> + ASSERT (FALSE);
> + return EFI_DEVICE_ERROR;
> }
> + Status = EnableDmarPreMem (VtdUnitBaseAddress, (UINT64)
> (*RootEntryTable));
> }
>
> - return;
> + return Status;
> }
>
> /**
> @@ -715,18 +614,25 @@ EnableVTdTranslationProtection (
> )
> {
> EFI_STATUS Status;
> - UINTN VtdIndex;
> + UINTN Index;
> + VTD_UNIT_INFO *VtdUnitInfo;
>
> - for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> - if (VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable != 0) {
> - DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable
> 0x%x\n", VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable));
> - Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo-
> >VtdUnitInfo[VtdIndex].ExtRootEntryTable);
> + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> + VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> + if (VtdUnitInfo->Done) {
> + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) was enabled\n", Index));
> + continue;
> + }
> +
> + if (VtdUnitInfo->ExtRootEntryTable != 0) {
> + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable
> 0x%x\n", Index, VtdUnitInfo->ExtRootEntryTable));
> + Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable);
> } else {
> - DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n",
> VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable));
> - Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo-
> >VtdUnitInfo[VtdIndex].RootEntryTable);
> + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n",
> Index, VtdUnitInfo->RootEntryTable));
> + Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->RootEntryTable);
> }
> if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", VtdIndex));
> + DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", Index));
> return Status;
> }
> }
> @@ -737,23 +643,22 @@ EnableVTdTranslationProtection (
> Disable VTd translation table protection.
>
> @param[in] VTdInfo The VTd engine context information.
> - @param[in] EngineMask The mask of the VTd engine to be accessed.
> **/
> VOID
> DisableVTdTranslationProtection (
> - IN VTD_INFO *VTdInfo,
> - IN UINT64 EngineMask
> + IN VTD_INFO *VTdInfo
> )
> {
> UINTN Index;
>
> - DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - 0x%lx\n",
> EngineMask));
> + if (VTdInfo == NULL) {
> + return;
> + }
> +
> + DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - %d Vtd
> Engine\n", VTdInfo->VTdEngineCount));
>
> for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> - if ((EngineMask & LShiftU64(1, Index)) == 0) {
> - continue;
> - }
> - DisableDmar ((UINTN) VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress);
> + DisableDmar (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress);
>
> DisableQueuedInvalidationInterface(&VTdInfo->VtdUnitInfo[Index]);
> }
> @@ -786,6 +691,36 @@ PrepareVtdCacheInvalidationConfig (
> return EFI_SUCCESS;
> }
>
> +/**
> +
> +**/
> +EFI_STATUS
> +VtdCheckUsing5LevelPaging (
> + IN UINT8 HostAddressWidth,
> + IN VTD_UNIT_INFO *VtdUnitInfo,
> + OUT BOOLEAN *Is5LevelPaging
> + )
> +{
> + DEBUG((DEBUG_INFO, " CapReg SAGAW bits : 0x%02x\n", VtdUnitInfo-
> >CapReg.Bits.SAGAW));
> +
> + *Is5LevelPaging = FALSE;
> + if ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT3) != 0) {
> + *Is5LevelPaging = TRUE;
> + if ((HostAddressWidth <= 48) &&
> + ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT2) != 0)) {
> + *Is5LevelPaging = FALSE;
> + } else {
> + return EFI_UNSUPPORTED;
> + }
> + }
> + if ((VtdUnitInfo->CapReg.Bits.SAGAW & (BIT3 | BIT2)) == 0) {
> + return EFI_UNSUPPORTED;
> + }
> + DEBUG((DEBUG_INFO, " Using %d Level Paging\n", *Is5LevelPaging ? 5 :
> 4));
> + return EFI_SUCCESS;
> +}
> +
> +
> /**
> Prepare VTD configuration.
>
> @@ -798,43 +733,37 @@ PrepareVtdConfig (
> IN VTD_INFO *VTdInfo
> )
> {
> + EFI_STATUS Status;
> UINTN Index;
> - UINTN DomainNumber;
> + VTD_UNIT_INFO *VtdUnitInfo;
> + UINTN VtdUnitBaseAddress;
>
> for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> - DEBUG ((DEBUG_ERROR, "Dump VTd Capability (%d)\n", Index));
> - VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
> - DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
> - VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
> - DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
> - VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo-
> >VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
> - DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
> -
> - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
> - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0) {
> - DEBUG ((DEBUG_INFO, "Support 4-level page-table on VTD %d\n",
> Index));
> - }
> - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT3) != 0) {
> - DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n",
> Index));
> - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = TRUE;
> -
> - if ((VTdInfo->HostAddressWidth <= 48) &&
> - ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0)) {
> - DEBUG ((DEBUG_INFO, "Rollback to 4-level page-table on VTD %d\n",
> Index));
> - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
> - }
> + VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> + if (VtdUnitInfo->Done) {
> + continue;
> }
> - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) ==
> 0) {
> - DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on
> VTD %d !!!!\n", Index, VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW));
> - return EFI_UNSUPPORTED;
> + VtdUnitBaseAddress = VtdUnitInfo->VtdUnitBaseAddress;
> + DEBUG((DEBUG_INFO, "VTd Engine: 0x%08X\n", VtdUnitBaseAddress));
> +
> + VtdUnitInfo->VerReg.Uint32 = MmioRead32 (VtdUnitBaseAddress +
> R_VER_REG);
> + VtdUnitInfo->CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress +
> R_CAP_REG);
> + VtdUnitInfo->ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress +
> R_ECAP_REG);
> + DEBUG((DEBUG_INFO, " VerReg : 0x%08X\n", VtdUnitInfo-
> >VerReg.Uint32));
> + DEBUG((DEBUG_INFO, " CapReg : 0x%016lX\n", VtdUnitInfo-
> >CapReg.Uint64));
> + DEBUG((DEBUG_INFO, " ECapReg : 0x%016lX\n", VtdUnitInfo-
> >ECapReg.Uint64));
> +
> + Status = VtdCheckUsing5LevelPaging (VTdInfo->HostAddressWidth,
> VtdUnitInfo, &(VtdUnitInfo->Is5LevelPaging));
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not
> supported!!!!\n", VtdUnitInfo->CapReg.Bits.SAGAW));
> + return Status;
> }
>
> - DomainNumber = (UINTN)1 << (UINT8) ((UINTN) VTdInfo-
> >VtdUnitInfo[Index].CapReg.Bits.ND * 2 + 4);
> - if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber >=
> DomainNumber) {
> - DEBUG ((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >=
> DomainNumber(0x%x) !!!!\n", VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber, DomainNumber));
> - return EFI_UNSUPPORTED;
> + Status = PerpareCacheInvalidationInterface(VtdUnitInfo);
> + if (EFI_ERROR (Status)) {
> + return Status;
> }
> }
> +
> return EFI_SUCCESS;
> }
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> index a8f7bfee..ac91eac3 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> @@ -1,6 +1,6 @@
> /** @file
>
> - Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
>
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -50,20 +50,20 @@ typedef struct {
> the device driver need use SetAttribute() to update the IOMMU
> attribute to request DMA access (read and/or write).
>
> - @param[in] This The PPI instance pointer.
> - @param[in] DeviceHandle The device who initiates the DMA access
> request.
> - @param[in] Mapping The mapping value returned from Map().
> - @param[in] IoMmuAccess The IOMMU access.
> -
> - @retval EFI_SUCCESS The IoMmuAccess is set for the memory range
> specified by DeviceAddress and Length.
> - @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> - @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal
> combination of access.
> - @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> - @retval EFI_UNSUPPORTED The IOMMU does not support the memory
> range specified by Mapping.
> - @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to modify the IOMMU access.
> - @retval EFI_DEVICE_ERROR The IOMMU device reported an error while
> attempting the operation.
> - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> - not available to be allocated yet.
> + @param[in] This The PPI instance pointer.
> + @param[in] DeviceHandle The device who initiates the DMA access
> request.
> + @param[in] Mapping The mapping value returned from Map().
> + @param[in] IoMmuAccess The IOMMU access.
> +
> + @retval EFI_SUCCESS The IoMmuAccess is set for the memory
> range specified by DeviceAddress and Length.
> + @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal
> combination of access.
> + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not
> supported by the IOMMU.
> + @retval EFI_UNSUPPORTED The IOMMU does not support the
> memory range specified by Mapping.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to modify the IOMMU access.
> + @retval EFI_DEVICE_ERROR The IOMMU device reported an error
> while attempting the operation.
> + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled,
> but DMA buffer are
> + not available to be allocated yet.
> **/
> EFI_STATUS
> EFIAPI
> @@ -93,22 +93,22 @@ PeiIoMmuSetAttribute (
> Provides the controller-specific addresses required to access system
> memory from a
> DMA bus master.
>
> - @param This The PPI instance pointer.
> - @param Operation Indicates if the bus master is going to read or
> write to system memory.
> - @param HostAddress The system memory address to map to the PCI
> controller.
> - @param NumberOfBytes On input the number of bytes to map. On
> output the number of bytes
> - that were mapped.
> - @param DeviceAddress The resulting map address for the bus master
> PCI controller to use to
> - access the hosts HostAddress.
> - @param Mapping A resulting value to pass to Unmap().
> -
> - @retval EFI_SUCCESS The range was mapped for the returned
> NumberOfBytes.
> - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a
> common buffer.
> - @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> - @retval EFI_OUT_OF_RESOURCES The request could not be completed
> due to a lack of resources.
> - @retval EFI_DEVICE_ERROR The system hardware could not map the
> requested address.
> - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> - not available to be allocated yet.
> + @param [in] This The PPI instance pointer.
> + @param [in] Operation Indicates if the bus master is going to read or
> write to system memory.
> + @param [in] HostAddress The system memory address to map to the
> PCI controller.
> + @param [in] [out] NumberOfBytes On input the number of bytes to map.
> On output the number of bytes
> + that were mapped.
> + @param [out] DeviceAddress The resulting map address for the bus
> master PCI controller to use to
> + access the hosts HostAddress.
> + @param [out] Mapping A resulting value to pass to Unmap().
> +
> + @retval EFI_SUCCESS The range was mapped for the returned
> NumberOfBytes.
> + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a
> common buffer.
> + @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed
> due to a lack of resources.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the
> requested address.
> + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled,
> but DMA buffer are
> + not available to be allocated yet.
> **/
> EFI_STATUS
> EFIAPI
> @@ -140,7 +140,7 @@ PeiIoMmuMap (
>
> if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
> Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
> - *DeviceAddress = (UINTN)HostAddress;
> + *DeviceAddress = (UINTN) HostAddress;
> *Mapping = NULL;
> return EFI_SUCCESS;
> }
> @@ -184,14 +184,14 @@ PeiIoMmuMap (
> /**
> Completes the Map() operation and releases any corresponding resources.
>
> - @param This The PPI instance pointer.
> - @param Mapping The mapping value returned from Map().
> + @param [in] This The PPI instance pointer.
> + @param [in] Mapping The mapping value returned from Map().
>
> - @retval EFI_SUCCESS The range was unmapped.
> - @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> - @retval EFI_DEVICE_ERROR The data was not committed to the target
> system memory.
> - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> - not available to be allocated yet.
> + @retval EFI_SUCCESS The range was unmapped.
> + @retval EFI_INVALID_PARAMETER Mapping is not a value that was
> returned by Map().
> + @retval EFI_DEVICE_ERROR The data was not committed to the target
> system memory.
> + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled,
> but DMA buffer are
> + not available to be allocated yet.
> **/
> EFI_STATUS
> EFIAPI
> @@ -250,21 +250,21 @@ PeiIoMmuUnmap (
> Allocates pages that are suitable for an OperationBusMasterCommonBuffer
> or
> OperationBusMasterCommonBuffer64 mapping.
>
> - @param This The PPI instance pointer.
> - @param MemoryType The type of memory to allocate,
> EfiBootServicesData or
> - EfiRuntimeServicesData.
> - @param Pages The number of pages to allocate.
> - @param HostAddress A pointer to store the base system memory
> address of the
> - allocated range.
> - @param Attributes The requested bit mask of attributes for the
> allocated range.
> -
> - @retval EFI_SUCCESS The requested memory pages were allocated.
> - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
> attribute bits are
> - MEMORY_WRITE_COMBINE, MEMORY_CACHED and
> DUAL_ADDRESS_CYCLE.
> - @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> - @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> - not available to be allocated yet.
> + @param [in] This The PPI instance pointer.
> + @param [in] MemoryType The type of memory to allocate,
> EfiBootServicesData or
> + EfiRuntimeServicesData.
> + @param [in] Pages The number of pages to allocate.
> + @param [in] [out] HostAddress A pointer to store the base system
> memory address of the
> + allocated range.
> + @param [in] Attributes The requested bit mask of attributes for the
> allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were allocated.
> + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal
> attribute bits are
> + MEMORY_WRITE_COMBINE, MEMORY_CACHED and
> DUAL_ADDRESS_CYCLE.
> + @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled,
> but DMA buffer are
> + not available to be allocated yet.
> **/
> EFI_STATUS
> EFIAPI
> @@ -307,15 +307,15 @@ PeiIoMmuAllocateBuffer (
> /**
> Frees memory that was allocated with AllocateBuffer().
>
> - @param This The PPI instance pointer.
> - @param Pages The number of pages to free.
> - @param HostAddress The base system memory address of the
> allocated range.
> + @param [in] This The PPI instance pointer.
> + @param [in] Pages The number of pages to free.
> + @param [in] HostAddress The base system memory address of the
> allocated range.
>
> - @retval EFI_SUCCESS The requested memory pages were freed.
> - @retval EFI_INVALID_PARAMETER The memory range specified by
> HostAddress and Pages
> - was not allocated with AllocateBuffer().
> - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but
> DMA buffer are
> - not available to be allocated yet.
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory range specified by
> HostAddress and Pages
> + was not allocated with AllocateBuffer().
> + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled,
> but DMA buffer are
> + not available to be allocated yet.
> **/
> EFI_STATUS
> EFIAPI
> @@ -364,52 +364,114 @@ CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList
> = {
> };
>
> /**
> - Release the momery in the Intel VTd Info
> + Get ACPI DMAT Table from EdkiiVTdInfo PPI
>
> - @param[in] VTdInfo The VTd engine context information.
> + @retval Address ACPI DMAT Table address
> + @retval NULL Failed to get ACPI DMAT Table
> **/
> -VOID
> -ReleaseVTdInfo (
> - IN VTD_INFO *VTdInfo
> +EFI_ACPI_DMAR_HEADER * GetAcpiDmarTable (
> + VOID
> )
> {
> - UINTN Index;
> + EFI_STATUS Status;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
>
> - for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> - DEBUG ((DEBUG_INFO, "Release momery in VTdInfo[%d]\n", Index));
> + //
> + // Get the DMAR table
> + //
> + Status = PeiServicesLocatePpi (
> + &gEdkiiVTdInfoPpiGuid,
> + 0,
> + NULL,
> + (VOID **)&AcpiDmarTable
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Fail to get ACPI DMAR Table : %r\n", Status));
> + AcpiDmarTable = NULL;
> + } else {
> + DumpAcpiDMAR (AcpiDmarTable);
> + }
>
> - if (VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry) {
> - FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].FixedSecondLevelPagingEntry, 1);
> - VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry = 0;
> - }
> + return AcpiDmarTable;
> +}
>
> - if (VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry) {
> - FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].RmrrSecondLevelPagingEntry, 1);
> - VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry = 0;
> - }
> +/**
> + Get the VTd engine context information hob.
>
> - if (VTdInfo->VtdUnitInfo[Index].RootEntryTable) {
> - FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].RootEntryTable, VTdInfo-
> >VtdUnitInfo[Index].RootEntryTablePageSize);
> - VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
> - }
> + @retval The VTd engine context information.
>
> - if (VTdInfo->VtdUnitInfo[Index].ExtRootEntryTable) {
> - FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].ExtRootEntryTable, VTdInfo-
> >VtdUnitInfo[Index].ExtRootEntryTablePageSize);
> - VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
> - }
> +**/
> +VTD_INFO *
> +GetVTdInfoHob (
> + VOID
> + )
> +{
> + VOID *Hob;
> + VTD_INFO *VTdInfo;
>
> - if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData) {
> - FreePages ((VOID *) (UINTN) VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData, VTdInfo-
> >VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize);
> - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize = 0;
> - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData = 0;
> - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber = 0;
> - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataMaxNumber =
> 0;
> + Hob = GetFirstGuidHob (&mVTdInfoGuid);
> + if (Hob == NULL) {
> + VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO));
> + if (VTdInfo != NULL) {
> + ZeroMem (VTdInfo, sizeof (VTD_INFO));
> }
> + } else {
> + VTdInfo = GET_GUID_HOB_DATA(Hob);
> }
> + return VTdInfo;
> +}
> +
> +/**
> + Callback function of parse DMAR DRHD table in pre-memory phase.
> +
> + @param [in] [out] Context Callback function context.
> + @param [in] VTdIndex The VTd engine index.
> + @param [in] DmarDrhd The DRHD table.
> +
> +**/
> +VOID
> +ProcessDhrdPreMemory (
> + IN OUT VOID *Context,
> + IN UINT32 VTdIndex,
> + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
> + )
> +{
> + DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex,
> DmarDrhd->RegisterBaseAddress));
> +
> + EnableVTdTranslationProtectionBlockDma ((UINTN) DmarDrhd-
> >RegisterBaseAddress);
> }
>
> /**
> - Initializes the Intel VTd Info.
> + Callback function of parse DMAR DRHD table in post memory phase.
> +
> + @param [in] [out] Context Callback function context.
> + @param [in] VTdIndex The VTd engine index.
> + @param [in] DmarDrhd The DRHD table.
> +
> +**/
> +VOID
> +ProcessDrhdPostMemory (
> + IN OUT VOID *Context,
> + IN UINT32 VTdIndex,
> + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
> + )
> +{
> + VTD_UNIT_INFO *VtdUnitInfo;
> +
> + VtdUnitInfo = (VTD_UNIT_INFO *) Context;
> + VtdUnitInfo += VTdIndex;
> +
> + VtdUnitInfo->Done = FALSE;
> + VtdUnitInfo->VtdUnitBaseAddress = (UINTN) DmarDrhd-
> >RegisterBaseAddress;
> + VtdUnitInfo->Segment = DmarDrhd->SegmentNumber;
> + VtdUnitInfo->Flags = DmarDrhd->Flags;
> +
> + DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex,
> DmarDrhd->RegisterBaseAddress));
> + DEBUG ((DEBUG_INFO," Segment - %d, Flags - 0x%x\n", DmarDrhd-
> >SegmentNumber, DmarDrhd->Flags));
> +}
> +
> +/**
> + Initializes the Intel VTd Info in post memory phase.
>
> @retval EFI_SUCCESS Usb bot driver is successfully initialized.
> @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
> @@ -419,89 +481,103 @@ InitVTdInfo (
> VOID
> )
> {
> - EFI_STATUS Status;
> - EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> - VOID *Hob;
> VTD_INFO *VTdInfo;
> - UINT64 EngineMask;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> + UINTN VtdUnitNumber;
> + VTD_UNIT_INFO *VtdUnitInfo;
> + EFI_STATUS Status;
> + UINTN NewUnitIndex;
> + UINTN PreviousUnitIndex;
>
> - Status = PeiServicesLocatePpi (
> - &gEdkiiVTdInfoPpiGuid,
> - 0,
> - NULL,
> - (VOID **)&AcpiDmarTable
> - );
> - ASSERT_EFI_ERROR (Status);
> + VTdInfo = GetVTdInfoHob ();
> + ASSERT (VTdInfo != NULL);
>
> - DumpAcpiDMAR (AcpiDmarTable);
> + AcpiDmarTable = GetAcpiDmarTable ();
> + ASSERT (AcpiDmarTable != NULL);
>
> //
> - // Clear old VTdInfo Hob.
> + // Get VTd Unit Number
> //
> - Hob = GetFirstGuidHob (&mVTdInfoGuid);
> - if (Hob != NULL) {
> - DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
> -
> - VTdInfo = GET_GUID_HOB_DATA(Hob);
> - EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> - EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
> -
> - ReleaseVTdInfo (VTdInfo);
> - VTdInfo->VTdEngineCount = 0;
> + VtdUnitNumber = ParseDmarAcpiTableDrhd (AcpiDmarTable, NULL, NULL);
> + if (VtdUnitNumber == 0) {
> + return EFI_UNSUPPORTED;
> + }
>
> - ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
> + //
> + // Genrate a new Vtd Unit Info Table
> + //
> + VtdUnitInfo = AllocateZeroPages (EFI_SIZE_TO_PAGES (sizeof
> (VTD_UNIT_INFO) * VtdUnitNumber));
> + if (VtdUnitInfo == NULL) {
> + DEBUG ((DEBUG_ERROR, "InitVTdInfo - OUT_OF_RESOURCE\n"));
> + ASSERT (FALSE);
> + return EFI_OUT_OF_RESOURCES;
> }
>
> //
> - // Get DMAR information to local VTdInfo
> + // Parse the DMAR ACPI Table to the new Vtd Unit Info Table
> //
> - Status = ParseDmarAcpiTableDrhd (AcpiDmarTable);
> - if (EFI_ERROR(Status)) {
> - DEBUG ((DEBUG_ERROR, " ParseDmarAcpiTableDrhd : %r\n", Status));
> + Status = ParseDmarAcpiTableDrhd (AcpiDmarTable,
> ProcessDrhdPostMemory, VtdUnitInfo);
> + if (EFI_ERROR (Status)) {
> + ASSERT_EFI_ERROR (Status);
> return Status;
> }
>
> //
> - // NOTE: Do not parse RMRR here, because RMRR may cause DMAR
> programming.
> + // Check Host Address Width
> //
> + if (AcpiDmarTable->HostAddressWidth == VTdInfo->HostAddressWidth) {
> + //
> + // New Vtd Unit Info Table Loop
> + //
> + for (NewUnitIndex = 0; NewUnitIndex < VtdUnitNumber;
> NewUnitIndex++) {
> + //
> + // Previous Vtd Unit Info Table Loop
> + //
> + for (PreviousUnitIndex = 0; PreviousUnitIndex < VTdInfo-
> >VTdEngineCount; PreviousUnitIndex++) {
> + //
> + // Compare the new Vtd Unit with the previous VTd Unit
> + //
> + if (VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress == VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex].VtdUnitBaseAddress) {
> + DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n",
> VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress));
> + CopyMem (&VtdUnitInfo[NewUnitIndex], &VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex], sizeof (VTD_UNIT_INFO));
> + VtdUnitInfo[NewUnitIndex].Done = TRUE;
> +
> + break;
> + }
> + }
> + }
> + }
> + VTdInfo->AcpiDmarTable = AcpiDmarTable;
> + VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
> + VTdInfo->VTdEngineCount = VtdUnitNumber;
> + VTdInfo->VtdUnitInfo = VtdUnitInfo;
>
> return EFI_SUCCESS;
> }
>
> /**
> - Initializes the Intel VTd DMAR for all memory.
> + Initializes the Intel VTd DMAR for block all DMA.
>
> @retval EFI_SUCCESS Driver is successfully initialized.
> @retval RETURN_NOT_READY Fail to get VTdInfo Hob .
> **/
> EFI_STATUS
> -InitVTdDmarForAll (
> +InitVTdDmarBlockAll (
> VOID
> )
> {
> - VOID *Hob;
> - VTD_INFO *VTdInfo;
> - UINT64 EngineMask;
> - EFI_STATUS Status;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
>
> - Hob = GetFirstGuidHob (&mVTdInfoGuid);
> - if (Hob == NULL) {
> - DEBUG ((DEBUG_ERROR, "Fail to get VTdInfo Hob.\n"));
> - return RETURN_NOT_READY;
> - }
> - VTdInfo = GET_GUID_HOB_DATA (Hob);
> - EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> -
> - DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
> - Status = PrepareVtdConfig (VTdInfo);
> - if (EFI_ERROR (Status)) {
> - ASSERT_EFI_ERROR (Status);
> - return Status;
> - }
> -
> - EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
> + //
> + // Get the DMAR table
> + //
> + AcpiDmarTable = GetAcpiDmarTable ();
> + ASSERT (AcpiDmarTable != NULL);
>
> - return EFI_SUCCESS;
> + //
> + // Parse the DMAR table and block all DMA
> + //
> + return ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDhrdPreMemory,
> NULL);
> }
>
> /**
> @@ -524,8 +600,8 @@ InitDmaBuffer(
> DEBUG ((DEBUG_INFO, "InitDmaBuffer :\n"));
>
> Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
> + ASSERT(Hob != NULL);
> DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
> - VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
>
> /**
> When gVtdPmrInfoDataHobGuid exists, it means:
> @@ -535,7 +611,7 @@ InitDmaBuffer(
> 4. Protection regions will be conveyed through VTD_PMR_INFO_HOB
>
> When gVtdPmrInfoDataHobGuid dosen't exist, it means:
> - 1. IntelVTdDmar driver will calcuate the PMR memory alignment
> + 1. IntelVTdDmarPei driver will calcuate the protected memory alignment
> 2. Dma buffer is reserved by AllocateAlignedPages()
> **/
>
> @@ -545,33 +621,40 @@ InitDmaBuffer(
> return EFI_INVALID_PARAMETER;
> }
>
> - if (VtdPmrHobPtr == NULL) {
> - //
> - // Allocate memory for DMA buffer
> - //
> - DmaBufferInfo->DmaBufferBase = (UINT64) (UINTN)
> AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) DmaBufferInfo-
> >DmaBufferSize), 0);
> - if (DmaBufferInfo->DmaBufferBase == 0) {
> - DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
> - return EFI_OUT_OF_RESOURCES;
> + if (DmaBufferInfo->DmaBufferBase == 0) {
> + VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
> + if (VtdPmrHobPtr != NULL) {
> + //
> + // Get the protected memory ranges information from the VTd PMR hob
> + //
> + VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
> +
> + if ((VtdPmrHob->ProtectedHighBase - VtdPmrHob->ProtectedLowLimit)
> < DmaBufferInfo->DmaBufferSize) {
> + DEBUG ((DEBUG_ERROR, " DmaBufferSize not enough\n"));
> + return EFI_INVALID_PARAMETER;
> + }
> + DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
> + } else {
> + //
> + // Allocate memory for DMA buffer
> + //
> + DmaBufferInfo->DmaBufferBase = (UINTN) AllocateAlignedPages
> (EFI_SIZE_TO_PAGES (DmaBufferInfo->DmaBufferSize), 0);
> + if (DmaBufferInfo->DmaBufferBase == 0) {
> + DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> + DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
> }
> - DmaBufferInfo->DmaBufferLimit = DmaBufferInfo->DmaBufferBase +
> DmaBufferInfo->DmaBufferSize;
> - DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
> - } else {
> - //
> - // Get the PMR ranges information for the VTd PMR hob
> - //
> - VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
> - DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
> - DmaBufferInfo->DmaBufferLimit = VtdPmrHob->ProtectedHighBase;
> +
> + DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo-
> >DmaBufferBase + DmaBufferInfo->DmaBufferSize;
> + DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo-
> >DmaBufferBase;
> +
> + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo-
> >DmaBufferSize));
> + DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo-
> >DmaBufferBase));
> }
> - DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase
> + DmaBufferInfo->DmaBufferSize;
> - DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo-
> >DmaBufferBase;
>
> - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%lx\n", DmaBufferInfo-
> >DmaBufferSize));
> - DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%lx\n", DmaBufferInfo-
> >DmaBufferBase));
> - DEBUG ((DEBUG_INFO, " DmaBufferLimit : 0x%lx\n", DmaBufferInfo-
> >DmaBufferLimit));
> - DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%lx\n",
> DmaBufferInfo->DmaBufferCurrentTop));
> - DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%lx\n",
> DmaBufferInfo->DmaBufferCurrentBottom));
> + DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%x\n",
> DmaBufferInfo->DmaBufferCurrentTop));
> + DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%x\n",
> DmaBufferInfo->DmaBufferCurrentBottom));
>
> return EFI_SUCCESS;
> }
> @@ -588,14 +671,14 @@ InitVTdDmarForDma (
> VOID
> )
> {
> - VOID *Hob;
> VTD_INFO *VTdInfo;
> +
> EFI_STATUS Status;
> EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
> EDKII_IOMMU_PPI *OldIoMmuPpi;
>
> - Hob = GetFirstGuidHob (&mVTdInfoGuid);
> - VTdInfo = GET_GUID_HOB_DATA (Hob);
> + VTdInfo = GetVTdInfoHob ();
> + ASSERT (VTdInfo != NULL);
>
> DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
> Status = PrepareVtdConfig (VTdInfo);
> @@ -604,13 +687,6 @@ InitVTdDmarForDma (
> return Status;
> }
>
> - DEBUG ((DEBUG_INFO, "PrepareVtdCacheInvalidationConfig\n"));
> - Status = PrepareVtdCacheInvalidationConfig (VTdInfo);
> - if (EFI_ERROR (Status)) {
> - ASSERT_EFI_ERROR (Status);
> - return Status;
> - }
> -
> // create root entry table
> DEBUG ((DEBUG_INFO, "SetupTranslationTable\n"));
> Status = SetupTranslationTable (VTdInfo);
> @@ -619,10 +695,6 @@ InitVTdDmarForDma (
> return Status;
> }
>
> - // If there is RMRR memory, parse it here.
> - DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
> - ParseDmarAcpiTableRmrr (VTdInfo);
> -
> DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
> Status = EnableVTdTranslationProtection(VTdInfo);
> if (EFI_ERROR (Status)) {
> @@ -668,21 +740,10 @@ S3EndOfPeiNotify(
> IN VOID *Ppi
> )
> {
> - VOID *Hob;
> - VTD_INFO *VTdInfo;
> - UINT64 EngineMask;
> -
> DEBUG((DEBUG_INFO, "VTd DMAR PEI S3EndOfPeiNotify\n"));
>
> if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {
> - Hob = GetFirstGuidHob (&mVTdInfoGuid);
> - if (Hob == NULL) {
> - return EFI_SUCCESS;
> - }
> - VTdInfo = GET_GUID_HOB_DATA(Hob);
> -
> - EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> - DisableVTdTranslationProtection (VTdInfo, EngineMask);
> + DisableVTdTranslationProtection (GetVTdInfoHob ());
> }
> return EFI_SUCCESS;
> }
> @@ -733,18 +794,13 @@ VTdInfoNotify (
>
> DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized));
>
> - //
> - // NOTE: We need reinit VTdInfo because previous information might be
> overriden.
> - //
> - InitVTdInfo ();
> -
> if (!MemoryInitialized) {
> //
> // If the memory is not initialized,
> // Protect all system memory
> //
>
> - InitVTdDmarForAll ();
> + InitVTdDmarBlockAll ();
>
> //
> // Install PPI.
> @@ -758,9 +814,16 @@ VTdInfoNotify (
> //
>
> Status = InitDmaBuffer ();
> - ASSERT_EFI_ERROR(Status);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // NOTE: We need reinit VTdInfo because previous information might be
> overriden.
> + //
> + Status = InitVTdInfo ();
> + ASSERT_EFI_ERROR (Status);
>
> - InitVTdDmarForDma ();
> + Status = InitVTdDmarForDma ();
> + ASSERT_EFI_ERROR (Status);
> }
>
> return EFI_SUCCESS;
> @@ -826,4 +889,3 @@ IntelVTdDmarInitialize (
>
> return EFI_SUCCESS;
> }
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> index e23a6c8e..351a7810 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> @@ -9,68 +9,61 @@
> #ifndef __DMA_ACCESS_LIB_H__
> #define __DMA_ACCESS_LIB_H__
>
> -#define MAX_VTD_PCI_DATA_NUMBER 0x100
> -
> #define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))
>
> typedef struct {
> - UINT8 DeviceType;
> - VTD_SOURCE_ID PciSourceId;
> -} PEI_PCI_DEVICE_DATA;
> -
> -typedef struct {
> - BOOLEAN IncludeAllFlag;
> - UINT32 PciDeviceDataNumber;
> - UINT32 PciDeviceDataMaxNumber;
> - UINT32 PciDeviceDataPageSize;
> - UINT32 PciDeviceData;
> -} PEI_PCI_DEVICE_INFORMATION;
> -
> -typedef struct {
> - UINT32 VtdUnitBaseAddress;
> + BOOLEAN Done;
> + UINTN VtdUnitBaseAddress;
> UINT16 Segment;
> + UINT8 Flags;
> VTD_VER_REG VerReg;
> VTD_CAP_REG CapReg;
> VTD_ECAP_REG ECapReg;
> BOOLEAN Is5LevelPaging;
> - UINT32 FixedSecondLevelPagingEntry;
> - UINT32 RmrrSecondLevelPagingEntry;
> - UINT32 RootEntryTable;
> - UINT32 ExtRootEntryTable;
> - UINT16 RootEntryTablePageSize;
> - UINT16 ExtRootEntryTablePageSize;
> - PEI_PCI_DEVICE_INFORMATION PciDeviceInfo;
> UINT8 EnableQueuedInvalidation;
> - UINT16 QiDescLength;
> + UINT16 QueueSize;
> QI_DESC *QiDesc;
> UINT16 QiFreeHead;
> + UINTN FixedSecondLevelPagingEntry;
> + UINTN RootEntryTable;
> + UINTN ExtRootEntryTable;
> + UINTN RootEntryTablePageSize;
> + UINTN ExtRootEntryTablePageSize;
> } VTD_UNIT_INFO;
>
> typedef struct {
> - UINT32 AcpiDmarTable;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> UINT8 HostAddressWidth;
> - UINT32 VTdEngineCount;
> - VTD_UNIT_INFO VtdUnitInfo[1];
> + UINTN VTdEngineCount;
> + VTD_UNIT_INFO *VtdUnitInfo;
> } VTD_INFO;
>
> typedef struct {
> - UINT64 DmaBufferBase;
> - UINT64 DmaBufferSize;
> - UINT64 DmaBufferLimit;
> - UINT64 DmaBufferCurrentTop;
> - UINT64 DmaBufferCurrentBottom;
> + UINTN DmaBufferBase;
> + UINTN DmaBufferSize;
> + UINTN DmaBufferCurrentTop;
> + UINTN DmaBufferCurrentBottom;
> } DMA_BUFFER_INFO;
>
> +typedef
> +VOID
> +(*PROCESS_DRHD_CALLBACK_FUNC) (
> + IN OUT VOID *Context,
> + IN UINT32 VTdIndex,
> + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
> + );
> +
> /**
> - Enable VTd translation table protection.
> + Enable VTd translation table protection for block DMA
>
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] EngineMask The mask of the VTd engine to be accessed.
> + @param[in] VtdUnitBaseAddress The base address of the VTd engine.
> +
> + @retval EFI_SUCCESS DMAR translation is enabled.
> + @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
> **/
> -VOID
> -EnableVTdTranslationProtectionAll (
> - IN VTD_INFO *VTdInfo,
> - IN UINT64 EngineMask
> +EFI_STATUS
> +EnableVTdTranslationProtectionBlockDma (
> + IN UINTN VtdUnitBaseAddress
> );
>
> /**
> @@ -90,34 +83,27 @@ EnableVTdTranslationProtection (
> Disable VTd translation table protection.
>
> @param[in] VTdInfo The VTd engine context information.
> - @param[in] EngineMask The mask of the VTd engine to be accessed.
> **/
> VOID
> DisableVTdTranslationProtection (
> - IN VTD_INFO *VTdInfo,
> - IN UINT64 EngineMask
> + IN VTD_INFO *VTdInfo
> );
>
> /**
> Parse DMAR DRHD table.
>
> @param[in] AcpiDmarTable DMAR ACPI table
> + @param[in] Callback Callback function for handle DRHD
> + @param[in] Context Callback function Context
>
> - @return EFI_SUCCESS The DMAR DRHD table is parsed.
> -**/
> -EFI_STATUS
> -ParseDmarAcpiTableDrhd (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> - );
> -
> -/**
> - Parse DMAR DRHD table.
> + @return the VTd engine number.
>
> - @param[in] VTdInfo The VTd engine context information.
> **/
> -VOID
> -ParseDmarAcpiTableRmrr (
> - IN VTD_INFO *VTdInfo
> +UINTN
> +ParseDmarAcpiTableDrhd (
> + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
> + IN PROCESS_DRHD_CALLBACK_FUNC Callback,
> + IN VOID *Context
> );
>
> /**
> @@ -214,30 +200,7 @@ GetPciDataIndex (
> IN VTD_SOURCE_ID SourceId
> );
>
> -/**
> - Always enable the VTd page attribute for the device.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] Segment The Segment used to identify a VTd engine.
> - @param[in] SourceId The SourceId used to identify a VTd engine and
> table entry.
> - @param[in] MemoryBase The base of the memory.
> - @param[in] MemoryLimit The limit of the memory.
> - @param[in] IoMmuAccess The IOMMU access.
> -
> - @retval EFI_SUCCESS The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> - IN VTD_INFO *VTdInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT64 MemoryBase,
> - IN UINT64 MemoryLimit,
> - IN UINT64 IoMmuAccess
> - );
> -
> extern EFI_GUID mVTdInfoGuid;
> extern EFI_GUID mDmaBufferInfoGuid;
>
> #endif
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> index a309d566..c94f4a85 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> @@ -1,6 +1,7 @@
> /** @file
>
> Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
> +
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> **/
> @@ -129,12 +130,12 @@ CreateSecondLevelPagingEntryTable (
> FlushPageTableMemory (VTdUnitInfo, (UINTN) SecondLevelPagingEntry,
> EFI_PAGES_TO_SIZE (1));
> }
>
> - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n",
> SecondLevelPagingEntry));
> + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64)
> (UINTN) SecondLevelPagingEntry));
> //
> // If no access is needed, just create not present entry.
> //
> if (IoMmuAccess == 0) {
> - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN)
> SecondLevelPagingEntry));
> + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx Access 0\n",
> (UINT64) (UINTN) SecondLevelPagingEntry));
> return SecondLevelPagingEntry;
> }
>
> @@ -244,7 +245,7 @@ CreateSecondLevelPagingEntryTable (
> }
> FlushPageTableMemory (VTdUnitInfo, (UINTN) &Lvl5PtEntry[Lvl5Start],
> (UINTN) &Lvl5PtEntry[Lvl5End + 1] - (UINTN) &Lvl5PtEntry[Lvl5Start]);
>
> - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n",
> (UINTN)SecondLevelPagingEntry));
> + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64)
> (UINTN) SecondLevelPagingEntry));
> return SecondLevelPagingEntry;
> }
>
> @@ -276,6 +277,10 @@ CreateContextEntry (
> VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
> UINT64 Pt;
>
> + if (VTdUnitInfo->RootEntryTable != 0) {
> + return EFI_SUCCESS;
> + }
> +
> RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_ROOT_ENTRY) *
> VTD_ROOT_ENTRY_NUMBER);
> ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_CONTEXT_ENTRY) *
> VTD_CONTEXT_ENTRY_NUMBER);
> EntryTablePages = RootPages + ContextPages *
> (VTD_ROOT_ENTRY_NUMBER);
> @@ -286,8 +291,8 @@ CreateContextEntry (
> }
>
> DEBUG ((DEBUG_ERROR, "RootEntryTable address - 0x%x\n", Buffer));
> - VTdUnitInfo->RootEntryTable = (UINT32) (UINTN) Buffer;
> - VTdUnitInfo->RootEntryTablePageSize = (UINT16) EntryTablePages;
> + VTdUnitInfo->RootEntryTable = (UINTN) Buffer;
> + VTdUnitInfo->RootEntryTablePageSize = EntryTablePages;
> RootEntryBase = (VTD_ROOT_ENTRY *) Buffer;
> Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
>
> @@ -304,7 +309,7 @@ CreateContextEntry (
> RootEntry->Bits.ContextTablePointerHi = (UINT32) RShiftU64 ((UINT64)
> (UINTN) Buffer, 32);
> RootEntry->Bits.Present = 1;
> Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> - ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi) ;
> + ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi);
>
> for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
> SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -317,7 +322,7 @@ CreateContextEntry (
> ContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ? 0x3 :
> 0x2;
>
> if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> - SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
> + SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> VTdUnitInfo->FixedSecondLevelPagingEntry;
> Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
> ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
> ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64(Pt, 20);
> @@ -359,6 +364,10 @@ CreateExtContextEntry (
> VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
> UINT64 Pt;
>
> + if (VTdUnitInfo->ExtRootEntryTable != 0) {
> + return EFI_SUCCESS;
> + }
> +
> RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_ROOT_ENTRY) *
> VTD_ROOT_ENTRY_NUMBER);
> ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_CONTEXT_ENTRY) *
> VTD_CONTEXT_ENTRY_NUMBER);
> EntryTablePages = RootPages + ContextPages *
> (VTD_ROOT_ENTRY_NUMBER);
> @@ -369,8 +378,8 @@ CreateExtContextEntry (
> }
>
> DEBUG ((DEBUG_ERROR, "ExtRootEntryTable address - 0x%x\n", Buffer));
> - VTdUnitInfo->ExtRootEntryTable = (UINT32) (UINTN) Buffer;
> - VTdUnitInfo->ExtRootEntryTablePageSize = (UINT16) EntryTablePages;
> + VTdUnitInfo->ExtRootEntryTable = (UINTN) Buffer;
> + VTdUnitInfo->ExtRootEntryTablePageSize = EntryTablePages;
> ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) Buffer;
> Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
>
> @@ -390,7 +399,7 @@ CreateExtContextEntry (
> ExtRootEntry->Bits.UpperContextTablePointerHi = (UINT32) RShiftU64
> (RShiftU64 ((UINT64) (UINTN) Buffer, 12) + 1, 20);
> ExtRootEntry->Bits.UpperPresent = 1;
> Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> - ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi) ;
> + ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi);
>
> for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
> SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -403,7 +412,7 @@ CreateExtContextEntry (
> ExtContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ?
> 0x3 : 0x2;
>
> if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> - SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
> + SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> VTdUnitInfo->FixedSecondLevelPagingEntry;
> Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
>
> ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32)
> Pt;
> @@ -791,9 +800,6 @@ SetSecondLevelPagingAttribute (
> SplitAttribute = NeedSplitPage (BaseAddress, Length, PageAttribute);
> if (SplitAttribute == PageNone) {
> ConvertSecondLevelPageEntryAttribute (VTdUnitInfo, PageEntry,
> IoMmuAccess, &IsEntryModified);
> - if (IsEntryModified) {
> - //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
> - }
> //
> // Convert success, move to next
> //
> @@ -805,7 +811,6 @@ SetSecondLevelPagingAttribute (
> DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status));
> return RETURN_UNSUPPORTED;
> }
> - //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
> //
> // Just split current page
> // Convert success in next around
> @@ -837,7 +842,11 @@ CreateFixedSecondLevelPagingEntry (
> VOID *Hob;
> DMA_BUFFER_INFO *DmaBufferInfo;
>
> - VTdUnitInfo->FixedSecondLevelPagingEntry = (UINT32) (UINTN)
> CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
> + if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
> + return EFI_SUCCESS;
> + }
> +
> + VTdUnitInfo->FixedSecondLevelPagingEntry = (UINTN)
> CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
> if (VTdUnitInfo->FixedSecondLevelPagingEntry == 0) {
> DEBUG ((DEBUG_ERROR, "FixedSecondLevelPagingEntry is empty\n"));
> return EFI_OUT_OF_RESOURCES;
> @@ -846,14 +855,14 @@ CreateFixedSecondLevelPagingEntry (
> Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
> DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
> BaseAddress = DmaBufferInfo->DmaBufferBase;
> - Length = DmaBufferInfo->DmaBufferLimit - DmaBufferInfo-
> >DmaBufferBase;
> + Length = DmaBufferInfo->DmaBufferSize;
> IoMmuAccess = EDKII_IOMMU_ACCESS_READ |
> EDKII_IOMMU_ACCESS_WRITE;
>
> DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", BaseAddress));
> DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Length));
> DEBUG ((DEBUG_INFO, " IoMmuAccess = 0x%lx\n", IoMmuAccess));
>
> - Status = SetSecondLevelPagingAttribute (VTdUnitInfo,
> (VTD_SECOND_LEVEL_PAGING_ENTRY*) (UINTN) VTdUnitInfo-
> >FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
> + Status = SetSecondLevelPagingAttribute (VTdUnitInfo,
> (VTD_SECOND_LEVEL_PAGING_ENTRY*) VTdUnitInfo-
> >FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
>
> return Status;
> }
> @@ -877,6 +886,9 @@ SetupTranslationTable (
>
> for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
> VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
> + if (VtdUnitInfo->Done) {
> + continue;
> + }
>
> Status = CreateFixedSecondLevelPagingEntry (VtdUnitInfo);
> if (EFI_ERROR (Status)) {
> @@ -911,151 +923,3 @@ SetupTranslationTable (
> return EFI_SUCCESS;
> }
>
> -/**
> - Find the VTd index by the Segment and SourceId.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] Segment The segment of the source.
> - @param[in] SourceId The SourceId of the source.
> - @param[out] ExtContextEntry The ExtContextEntry of the source.
> - @param[out] ContextEntry The ContextEntry of the source.
> -
> - @return The index of the VTd engine.
> - @retval (UINTN)-1 The VTd engine is not found.
> -**/
> -UINTN
> -FindVtdIndexBySegmentSourceId (
> - IN VTD_INFO *VTdInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,
> - OUT VTD_CONTEXT_ENTRY **ContextEntry
> - )
> -{
> - UINTN VtdIndex;
> - VTD_ROOT_ENTRY *RootEntryBase;
> - VTD_ROOT_ENTRY *RootEntry;
> - VTD_CONTEXT_ENTRY *ContextEntryTable;
> - VTD_CONTEXT_ENTRY *ThisContextEntry;
> - VTD_EXT_ROOT_ENTRY *ExtRootEntryBase;
> - VTD_EXT_ROOT_ENTRY *ExtRootEntry;
> - VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable;
> - VTD_EXT_CONTEXT_ENTRY *ThisExtContextEntry;
> -
> - for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> - if (GetPciDataIndex (&VTdInfo->VtdUnitInfo[VtdIndex], Segment,
> SourceId) != (UINTN)-1) {
> - DEBUG ((DEBUG_INFO, "Find VtdIndex(0x%x) for S%04x B%02x D%02x
> F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> - break;
> - }
> - }
> - if (VtdIndex >= VTdInfo->VTdEngineCount) {
> - for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
> - if (Segment != VTdInfo->VtdUnitInfo[VtdIndex].Segment) {
> - continue;
> - }
> - if (VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag) {
> - DEBUG ((DEBUG_INFO, "Find IncludeAllFlag VtdIndex(0x%x) for S%04x
> B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> - break;
> - }
> - }
> - }
> -
> - if (VtdIndex < VTdInfo->VTdEngineCount) {
> - ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].ExtRootEntryTable;
> - if (ExtRootEntryBase != 0) {
> - ExtRootEntry = &ExtRootEntryBase[SourceId.Index.RootIndex];
> - ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi) ;
> - ThisExtContextEntry =
> &ExtContextEntryTable[SourceId.Index.ContextIndex];
> - if (ThisExtContextEntry->Bits.AddressWidth == 0) {
> - DEBUG ((DEBUG_INFO, "ExtContextEntry AddressWidth : 0x%x\n",
> ThisExtContextEntry->Bits.AddressWidth));
> - return (UINTN)-1;
> - }
> - *ExtContextEntry = ThisExtContextEntry;
> - *ContextEntry = NULL;
> - } else {
> - RootEntryBase = (VTD_ROOT_ENTRY*) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].RootEntryTable;
> - RootEntry = &RootEntryBase[SourceId.Index.RootIndex];
> - ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi) ;
> - ThisContextEntry = &ContextEntryTable[SourceId.Index.ContextIndex];
> - if (ThisContextEntry->Bits.AddressWidth == 0) {
> - DEBUG ((DEBUG_INFO, "ContextEntry AddressWidth : 0x%x\n",
> ThisContextEntry->Bits.AddressWidth));
> - return (UINTN)-1;
> - }
> - *ExtContextEntry = NULL;
> - *ContextEntry = ThisContextEntry;
> - }
> -
> - return VtdIndex;
> - }
> -
> - return (UINTN)-1;
> -}
> -
> -/**
> - Always enable the VTd page attribute for the device.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] Segment The Segment used to identify a VTd engine.
> - @param[in] SourceId The SourceId used to identify a VTd engine and
> table entry.
> - @param[in] MemoryBase The base of the memory.
> - @param[in] MemoryLimit The limit of the memory.
> - @param[in] IoMmuAccess The IOMMU access.
> -
> - @retval EFI_SUCCESS The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> - IN VTD_INFO *VTdInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT64 MemoryBase,
> - IN UINT64 MemoryLimit,
> - IN UINT64 IoMmuAccess
> - )
> -{
> - EFI_STATUS Status;
> - UINTN VtdIndex;
> - VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
> - VTD_CONTEXT_ENTRY *ContextEntry;
> - VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
> - UINT64 Pt;
> -
> - DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute (S%04x B%02x D%02x
> F%02x)\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device,
> SourceId.Bits.Function));
> -
> - VtdIndex = FindVtdIndexBySegmentSourceId (VTdInfo, Segment, SourceId,
> &ExtContextEntry, &ContextEntry);
> - if (VtdIndex == (UINTN)-1) {
> - DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute - Can not locate Pci
> device (S%04x B%02x D%02x F%02x) !\n", Segment, SourceId.Bits.Bus,
> SourceId.Bits.Device, SourceId.Bits.Function));
> - return EFI_DEVICE_ERROR;
> - }
> -
> - if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
> - DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n",
> VtdIndex));
> - VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry =
> (UINT32)(UINTN)CreateSecondLevelPagingEntryTable (&VTdInfo-
> >VtdUnitInfo[VtdIndex], NULL, 0, SIZE_4GB, 0);
> - if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
> - return EFI_OUT_OF_RESOURCES;
> - }
> -
> - Status =SetSecondLevelPagingAttribute (&VTdInfo-
> >VtdUnitInfo[VtdIndex],
> (VTD_SECOND_LEVEL_PAGING_ENTRY*)(UINTN)VTdInfo-
> >VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry, MemoryBase,
> MemoryLimit + 1 - MemoryBase, IoMmuAccess);
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> - }
> -
> - SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)
> (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry;
> - Pt = (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
> - if (ExtContextEntry != NULL) {
> - ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32)
> Pt;
> - ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64(Pt, 20);
> - ExtContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN)
> VTdInfo->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
> - ExtContextEntry->Bits.Present = 1;
> - FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN)
> ExtContextEntry, sizeof(*ExtContextEntry));
> - } else if (ContextEntry != NULL) {
> - ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
> - ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32)
> RShiftU64 (Pt, 20);
> - ContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
> - ContextEntry->Bits.Present = 1;
> - FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN)
> ContextEntry, sizeof (*ContextEntry));
> - }
> -
> - return EFI_SUCCESS;
> -}
> --
> 2.16.2.windows.1
next prev parent reply other threads:[~2022-01-24 2:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2022-01-18 8:31 ` Huang, Jenny
2022-01-19 8:26 ` Kowalewski, Robert
2022-01-18 8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
2022-01-21 8:24 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
2022-01-21 8:51 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
2022-01-21 8:35 ` Huang, Jenny
2022-01-24 2:44 ` Sheng Wei [this message]
2022-01-18 8:30 ` [PATCH v5 0/4] There are 4 patches for VTd drivers Huang, Jenny
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=PH0PR11MB4870E878BB06BAAC0CFE7621E15E9@PH0PR11MB4870.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox