From: Jiewen Yao Date: Sat, 16 Sep 2017 01:33:49 +0000 (+0800) Subject: IntelSiliconPkg/IntelVTdPmrPei: Move to feature dir. X-Git-Tag: edk2-stable201903~3393 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=db5c75863d17e9fc1e5b7081a7ec62dee8c6f177 IntelSiliconPkg/IntelVTdPmrPei: Move to feature dir. Move IntelVTdPmrPei to Feature/VTd/IntelVTdPmrPei. Suggested-by: Star Zeng Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jiewen Yao Reviewed-by: Star Zeng --- diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c new file mode 100644 index 0000000000..ef08e2991f --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c @@ -0,0 +1,314 @@ +/** @file + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License which accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "IntelVTdPmrPei.h" + +extern EDKII_VTD_INFO_PPI *mVTdInfoPpi; + +/** + Get protected low memory alignment. + + @param VtdUnitBaseAddress The base address of the VTd engine. + + @return protected low memory alignment. +**/ +UINT32 +GetPlmrAlignment ( + IN UINTN VtdUnitBaseAddress + ) +{ + UINT32 Data32; + + MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, 0xFFFFFFFF); + Data32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG); + Data32 = ~Data32 + 1; + + return Data32; +} + +/** + Get protected high memory alignment. + + @param VtdUnitBaseAddress The base address of the VTd engine. + + @return protected high memory alignment. +**/ +UINT64 +GetPhmrAlignment ( + IN UINTN VtdUnitBaseAddress + ) +{ + UINT64 Data64; + UINT8 HostAddressWidth; + + HostAddressWidth = mVTdInfoPpi->HostAddressWidth; + + MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF); + Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG); + Data64 = ~Data64 + 1; + Data64 = Data64 & (LShiftU64 (1, HostAddressWidth) - 1); + + return Data64; +} + +/** + Get protected low memory alignment. + + @return protected low memory alignment. +**/ +UINT32 +GetLowMemoryAlignment ( + VOID + ) +{ + UINTN Index; + UINT32 Alignment; + UINT32 FinalAlignment; + + FinalAlignment = 0; + for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { + Alignment = GetPlmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + if (FinalAlignment < Alignment) { + FinalAlignment = Alignment; + } + } + return FinalAlignment; +} + +/** + Get protected high memory alignment. + + @return protected high memory alignment. +**/ +UINT64 +GetHighMemoryAlignment ( + VOID + ) +{ + UINTN Index; + UINT64 Alignment; + UINT64 FinalAlignment; + + FinalAlignment = 0; + for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { + Alignment = GetPhmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + if (FinalAlignment < Alignment) { + FinalAlignment = Alignment; + } + } + return FinalAlignment; +} + +/** + Enable PMR in the VTd engine. + + @param VtdUnitBaseAddress The base address of the VTd engine. + + @retval EFI_SUCCESS The PMR is enabled. + @retval EFI_UNSUPPORTED The PMR is not supported. +**/ +EFI_STATUS +EnablePmr ( + IN UINTN VtdUnitBaseAddress + ) +{ + UINT32 Reg32; + VTD_CAP_REG CapReg; + + CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { + return EFI_UNSUPPORTED; + } + + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + if ((Reg32 & BIT0) == 0) { + MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31); + do { + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + } while((Reg32 & BIT0) == 0); + } + + return EFI_SUCCESS; +} + +/** + Disable PMR in the VTd engine. + + @param VtdUnitBaseAddress The base address of the VTd engine. + + @retval EFI_SUCCESS The PMR is disabled. + @retval EFI_UNSUPPORTED The PMR is not supported. +**/ +EFI_STATUS +DisablePmr ( + IN UINTN VtdUnitBaseAddress + ) +{ + UINT32 Reg32; + VTD_CAP_REG CapReg; + + CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { + return EFI_UNSUPPORTED; + } + + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + if ((Reg32 & BIT0) != 0) { + MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0); + do { + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + } while((Reg32 & BIT0) != 0); + } + + return EFI_SUCCESS; +} + +/** + Set PMR region in the VTd engine. + + @param VtdUnitBaseAddress The base address of the VTd engine. + @param LowMemoryBase The protected low memory region base. + @param LowMemoryLength The protected low memory region length. + @param HighMemoryBase The protected high memory region base. + @param HighMemoryLength The protected high memory region length. + + @retval EFI_SUCCESS The PMR is set to protected region. + @retval EFI_UNSUPPORTED The PMR is not supported. +**/ +EFI_STATUS +SetPmrRegion ( + IN UINTN VtdUnitBaseAddress, + IN UINT32 LowMemoryBase, + IN UINT32 LowMemoryLength, + IN UINT64 HighMemoryBase, + IN UINT64 HighMemoryLength + ) +{ + VTD_CAP_REG CapReg; + UINT32 PlmrAlignment; + UINT64 PhmrAlignment; + + DEBUG ((DEBUG_INFO, "VtdUnitBaseAddress - 0x%x\n", VtdUnitBaseAddress)); + + CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { + DEBUG ((DEBUG_ERROR, "PLMR/PHMR unsupported\n")); + return EFI_UNSUPPORTED; + } + + PlmrAlignment = GetPlmrAlignment (VtdUnitBaseAddress); + DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment)); + PhmrAlignment = GetPhmrAlignment (VtdUnitBaseAddress); + DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment)); + + if ((LowMemoryBase != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) || + (LowMemoryLength != ALIGN_VALUE(LowMemoryLength, PlmrAlignment)) || + (HighMemoryBase != ALIGN_VALUE(HighMemoryBase, PhmrAlignment)) || + (HighMemoryLength != ALIGN_VALUE(HighMemoryLength, PhmrAlignment))) { + DEBUG ((DEBUG_ERROR, "PLMR/PHMR alignment issue\n")); + return EFI_UNSUPPORTED; + } + + if (LowMemoryBase == 0 && LowMemoryLength == 0) { + LowMemoryBase = 0xFFFFFFFF; + } + if (HighMemoryBase == 0 && HighMemoryLength == 0) { + HighMemoryBase = 0xFFFFFFFFFFFFFFFF; + } + + MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, LowMemoryBase); + MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG, LowMemoryBase + LowMemoryLength - 1); + MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, HighMemoryBase); + MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1); + + return EFI_SUCCESS; +} + +/** + Set DMA protected region. + + @param LowMemoryBase The protected low memory region base. + @param LowMemoryLength The protected low memory region length. + @param HighMemoryBase The protected high memory region base. + @param HighMemoryLength The protected high memory region length. + + @retval EFI_SUCCESS The DMA protection is set. + @retval EFI_UNSUPPORTED The DMA protection is not set. +**/ +EFI_STATUS +SetDmaProtectedRange ( + IN UINT32 LowMemoryBase, + IN UINT32 LowMemoryLength, + IN UINT64 HighMemoryBase, + IN UINT64 HighMemoryLength + ) +{ + UINTN Index; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength)); + + for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { + DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + Status = SetPmrRegion ( + (UINTN)mVTdInfoPpi->VTdEngineAddress[Index], + LowMemoryBase, + LowMemoryLength, + HighMemoryBase, + HighMemoryLength + ); + if (EFI_ERROR(Status)) { + return Status; + } + Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + if (EFI_ERROR(Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + Diable DMA protection. + + @retval DMA protection is disabled. +**/ +EFI_STATUS +DisableDmaProtection ( + VOID + ) +{ + UINTN Index; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "DisableDmaProtection\n")); + + for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { + Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + if (EFI_ERROR(Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c new file mode 100644 index 0000000000..d118b7ef26 --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c @@ -0,0 +1,615 @@ +/** @file + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License which accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "IntelVTdPmrPei.h" + +#define TOTAL_DMA_BUFFER_SIZE SIZE_4MB + +EDKII_VTD_INFO_PPI *mVTdInfoPpi; +UINTN mDmaBufferBase; +UINTN mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE; +UINTN mDmaBufferCurrentTop; +UINTN mDmaBufferCurrentBottom; + +#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P') +typedef struct { + UINT32 Signature; + EDKII_IOMMU_OPERATION Operation; + UINTN NumberOfBytes; + EFI_PHYSICAL_ADDRESS HostAddress; + EFI_PHYSICAL_ADDRESS DeviceAddress; +} MAP_INFO; + +/** + + PEI Memory Layout: + + +------------------+ <------- EfiMemoryTop + | PEI allocated | + =========== +==================+ + ^ | Commom Buf | + | | -------------- | + DMA Buffer | * DMA FREE * | + | | -------------- | + V | Read/Write Buf | + =========== +==================+ + | PEI allocated | + | -------------- | <------- EfiFreeMemoryTop + | * PEI FREE * | + | -------------- | <------- EfiFreeMemoryBottom + | hob | + | -------------- | + | Stack | + +------------------+ <------- EfiMemoryBottom / Stack Bottom + + +------------------+ + | Mem Alloc Hob | + +------------------+ + +**/ + + +/** + Set IOMMU attribute for a system memory. + + If the IOMMU PPI exists, the system memory cannot be used + for DMA by default. + + When a device requests a DMA access for a system memory, + 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] 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. + +**/ +EFI_STATUS +EFIAPI +PeiIoMmuSetAttribute ( + IN EDKII_IOMMU_PPI *This, + IN VOID *Mapping, + IN UINT64 IoMmuAccess + ) +{ + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +EFIAPI +PeiIoMmuMap ( + IN EDKII_IOMMU_PPI *This, + IN EDKII_IOMMU_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + MAP_INFO *MapInfo; + UINTN Length; + + if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer || + Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) { + *DeviceAddress = (UINTN)HostAddress; + *Mapping = 0; + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + + Length = *NumberOfBytes + sizeof(MAP_INFO); + if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { + DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n")); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + *DeviceAddress = mDmaBufferCurrentBottom; + mDmaBufferCurrentBottom += Length; + + MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes); + MapInfo->Signature = MAP_INFO_SIGNATURE; + MapInfo->Operation = Operation; + MapInfo->NumberOfBytes = *NumberOfBytes; + MapInfo->HostAddress = (UINTN)HostAddress; + MapInfo->DeviceAddress = *DeviceAddress; + *Mapping = MapInfo; + DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation, (UINTN)*DeviceAddress, MapInfo)); + + // + // If this is a read operation from the Bus Master's point of view, + // then copy the contents of the real buffer into the mapped buffer + // so the Bus Master can read the contents of the real buffer. + // + if (Operation == EdkiiIoMmuOperationBusMasterRead || + Operation == EdkiiIoMmuOperationBusMasterRead64) { + CopyMem ( + (VOID *) (UINTN) MapInfo->DeviceAddress, + (VOID *) (UINTN) MapInfo->HostAddress, + MapInfo->NumberOfBytes + ); + } + + return EFI_SUCCESS; +} + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This The PPI instance pointer. + @param 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. +**/ +EFI_STATUS +EFIAPI +PeiIoMmuUnmap ( + IN EDKII_IOMMU_PPI *This, + IN VOID *Mapping + ) +{ + MAP_INFO *MapInfo; + UINTN Length; + + if (Mapping == NULL) { + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + + MapInfo = Mapping; + ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE); + DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes)); + + // + // If this is a write operation from the Bus Master's point of view, + // then copy the contents of the mapped buffer into the real buffer + // so the processor can read the contents of the real buffer. + // + if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite || + MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) { + CopyMem ( + (VOID *) (UINTN) MapInfo->HostAddress, + (VOID *) (UINTN) MapInfo->DeviceAddress, + MapInfo->NumberOfBytes + ); + } + + Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO); + if (mDmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) { + mDmaBufferCurrentBottom -= Length; + } + + return EFI_SUCCESS; +} + +/** + 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 and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +PeiIoMmuAllocateBuffer ( + IN EDKII_IOMMU_PPI *This, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT VOID **HostAddress, + IN UINT64 Attributes + ) +{ + UINTN Length; + + DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + + Length = EFI_PAGES_TO_SIZE(Pages); + if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { + DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n")); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + *HostAddress = (VOID *)(UINTN)(mDmaBufferCurrentTop - Length); + mDmaBufferCurrentTop -= Length; + + DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress)); + return EFI_SUCCESS; +} + +/** + 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. + + @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(). + +**/ +EFI_STATUS +EFIAPI +PeiIoMmuFreeBuffer ( + IN EDKII_IOMMU_PPI *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +{ + UINTN Length; + + DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + + Length = EFI_PAGES_TO_SIZE(Pages); + if ((UINTN)HostAddress == mDmaBufferCurrentTop) { + mDmaBufferCurrentTop += Length; + } + + return EFI_SUCCESS; +} + +EDKII_IOMMU_PPI mIoMmuPpi = { + EDKII_IOMMU_PPI_REVISION, + PeiIoMmuSetAttribute, + PeiIoMmuMap, + PeiIoMmuUnmap, + PeiIoMmuAllocateBuffer, + PeiIoMmuFreeBuffer, +}; + +CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEdkiiIoMmuPpiGuid, + (VOID *) &mIoMmuPpi +}; + +#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED | \ + EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \ + EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \ + EFI_RESOURCE_ATTRIBUTE_64_BIT_IO \ + ) + +#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED) + +#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED) + +#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT) + +GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mResourceTypeShortName[] = { + "Mem", + "MMIO", + "I/O", + "FD", + "MM Port I/O", + "Reserved Mem", + "Reserved I/O", +}; + +/** + Return the short name of resource type. + + @param Type resource type. + + @return the short name of resource type. +**/ +CHAR8 * +ShortNameOfResourceType ( + IN UINT32 Type + ) +{ + if (Type < sizeof(mResourceTypeShortName) / sizeof(mResourceTypeShortName[0])) { + return mResourceTypeShortName[Type]; + } else { + return "Unknown"; + } +} + +/** + Dump resource hob. + + @param HobList the HOB list. +**/ +VOID +DumpResourceHob ( + IN VOID *HobList + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + + DEBUG ((DEBUG_VERBOSE, "Resource Descriptor HOBs\n")); + for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + ResourceHob = Hob.ResourceDescriptor; + DEBUG ((DEBUG_VERBOSE, + " BA=%016lx L=%016lx Attr=%08x ", + ResourceHob->PhysicalStart, + ResourceHob->ResourceLength, + ResourceHob->ResourceAttribute + )); + DEBUG ((DEBUG_VERBOSE, ShortNameOfResourceType(ResourceHob->ResourceType))); + switch (ResourceHob->ResourceType) { + case EFI_RESOURCE_SYSTEM_MEMORY: + if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) != 0) { + DEBUG ((DEBUG_VERBOSE, " (Persistent)")); + } else if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) != 0) { + DEBUG ((DEBUG_VERBOSE, " (MoreReliable)")); + } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) { + DEBUG ((DEBUG_VERBOSE, " (Tested)")); + } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) { + DEBUG ((DEBUG_VERBOSE, " (Init)")); + } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) { + DEBUG ((DEBUG_VERBOSE, " (Present)")); + } else { + DEBUG ((DEBUG_VERBOSE, " (Unknown)")); + } + break; + default: + break; + } + DEBUG ((DEBUG_VERBOSE, "\n")); + } + } +} + +/** + Dump PHIT hob. + + @param HobList the HOB list. +**/ +VOID +DumpPhitHob ( + IN VOID *HobList + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; + + PhitHob = HobList; + ASSERT(GET_HOB_TYPE(HobList) == EFI_HOB_TYPE_HANDOFF); + DEBUG ((DEBUG_VERBOSE, "PHIT HOB\n")); + DEBUG ((DEBUG_VERBOSE, " PhitHob - 0x%x\n", PhitHob)); + DEBUG ((DEBUG_VERBOSE, " BootMode - 0x%x\n", PhitHob->BootMode)); + DEBUG ((DEBUG_VERBOSE, " EfiMemoryTop - 0x%016lx\n", PhitHob->EfiMemoryTop)); + DEBUG ((DEBUG_VERBOSE, " EfiMemoryBottom - 0x%016lx\n", PhitHob->EfiMemoryBottom)); + DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryTop - 0x%016lx\n", PhitHob->EfiFreeMemoryTop)); + DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryBottom - 0x%016lx\n", PhitHob->EfiFreeMemoryBottom)); + DEBUG ((DEBUG_VERBOSE, " EfiEndOfHobList - 0x%lx\n", PhitHob->EfiEndOfHobList)); +} + +/** + Get the highest memory. + + @param HobList the HOB list. + + @return the highest memory. +**/ +UINT64 +GetTopMemory ( + IN VOID *HobList + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + UINT64 TopMemory; + UINT64 ResourceTop; + + TopMemory = 0; + for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + ResourceHob = Hob.ResourceDescriptor; + switch (ResourceHob->ResourceType) { + case EFI_RESOURCE_SYSTEM_MEMORY: + ResourceTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength; + if (TopMemory < ResourceTop) { + TopMemory = ResourceTop; + } + break; + default: + break; + } + DEBUG ((DEBUG_VERBOSE, "\n")); + } + } + return TopMemory; +} + +/** + Initialize DMA protection. + + @param DmaBufferSize the DMA buffer size + @param DmaBufferBase the DMA buffer base + + @retval EFI_SUCCESS the DMA protection is initialized. + @retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection. +**/ +EFI_STATUS +InitDmaProtection ( + IN UINTN DmaBufferSize, + OUT UINTN *DmaBufferBase + ) +{ + EFI_STATUS Status; + VOID *HobList; + EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; + UINT32 LowMemoryAlignment; + UINT64 HighMemoryAlignment; + UINTN MemoryAlignment; + UINTN LowBottom; + UINTN LowTop; + UINTN HighBottom; + UINT64 HighTop; + + HobList = GetHobList (); + DumpPhitHob (HobList); + DumpResourceHob (HobList); + + PhitHob = HobList; + + ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop); + + LowMemoryAlignment = GetLowMemoryAlignment (); + HighMemoryAlignment = GetHighMemoryAlignment (); + if (LowMemoryAlignment < HighMemoryAlignment) { + MemoryAlignment = (UINTN)HighMemoryAlignment; + } else { + MemoryAlignment = LowMemoryAlignment; + } + ASSERT (DmaBufferSize == ALIGN_VALUE(DmaBufferSize, MemoryAlignment)); + *DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferSize), MemoryAlignment); + if (*DmaBufferBase == 0) { + DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n")); + return EFI_OUT_OF_RESOURCES; + } + + LowBottom = 0; + LowTop = *DmaBufferBase; + HighBottom = *DmaBufferBase + DmaBufferSize; + HighTop = GetTopMemory (HobList); + + Status = SetDmaProtectedRange ( + (UINT32)LowBottom, + (UINT32)(LowTop - LowBottom), + HighBottom, + HighTop - HighBottom + ); + + if (EFI_ERROR(Status)) { + FreePages ((VOID *)*DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferSize)); + } + + return Status; +} + +/** + Initializes the Intel VTd PMR PEIM. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS Usb bot driver is successfully initialized. + @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. + +**/ +EFI_STATUS +EFIAPI +IntelVTdPmrInitialize ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) { + return EFI_UNSUPPORTED; + } + + Status = PeiServicesLocatePpi ( + &gEdkiiVTdInfoPpiGuid, + 0, + NULL, + (VOID **)&mVTdInfoPpi + ); + ASSERT_EFI_ERROR(Status); + + // + // Find a pre-memory in resource hob as DMA buffer + // Mark PEI memory to be DMA protected. + // + Status = InitDmaProtection (mDmaBufferSize, &mDmaBufferBase); + if (EFI_ERROR(Status)) { + return Status; + } + + DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", mDmaBufferBase)); + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", mDmaBufferSize)); + + mDmaBufferCurrentTop = mDmaBufferBase + mDmaBufferSize; + mDmaBufferCurrentBottom = mDmaBufferBase; + + // + // Install PPI. + // + Status = PeiServicesInstallPpi (&mIoMmuPpiList); + ASSERT_EFI_ERROR(Status); + + return Status; +} + diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h new file mode 100644 index 0000000000..aa5926a766 --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h @@ -0,0 +1,68 @@ +/** @file + The definition for DMA access Library. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __DMA_ACCESS_LIB_H__ +#define __DMA_ACCESS_LIB_H__ + +/** + Set DMA protected region. + + @param LowMemoryBase The protected low memory region base. + @param LowMemoryLength The protected low memory region length. + @param HighMemoryBase The protected high memory region base. + @param HighMemoryLength The protected high memory region length. + + @retval EFI_SUCCESS The DMA protection is set. + @retval EFI_UNSUPPORTED The DMA protection is not set. +**/ +EFI_STATUS +SetDmaProtectedRange ( + IN UINT32 LowMemoryBase, + IN UINT32 LowMemoryLength, + IN UINT64 HighMemoryBase, + IN UINT64 HighMemoryLength + ); + +/** + Diable DMA protection. + + @retval DMA protection is disabled. +**/ +EFI_STATUS +DisableDmaProtection ( + VOID + ); + +/** + Get protected low memory alignment. + + @return protected low memory alignment. +**/ +UINT32 +GetLowMemoryAlignment ( + VOID + ); + +/** + Get protected high memory alignment. + + @return protected high memory alignment. +**/ +UINT64 +GetHighMemoryAlignment ( + VOID + ); + +#endif + diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf new file mode 100644 index 0000000000..86cd7d1618 --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf @@ -0,0 +1,59 @@ +## @file +# Component INF file for the Intel VTd PMR PEIM. +# +# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI +# and provide DMA protection in PEI. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = IntelVTdPmrPei + MODULE_UNI_FILE = IntelVTdPmrPei.uni + FILE_GUID = F906769F-4AED-4A0D-8C7C-FF21B9D1051A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = IntelVTdPmrInitialize + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelSiliconPkg/IntelSiliconPkg.dec + +[Sources] + IntelVTdPmrPei.c + IntelVTdPmrPei.h + IntelVTdPmr.c + +[LibraryClasses] + DebugLib + BaseMemoryLib + BaseLib + PeimEntryPoint + PeiServicesLib + HobLib + IoLib + +[Ppis] + gEdkiiIoMmuPpiGuid ## PRODUCES + gEdkiiVTdInfoPpiGuid ## CONSUMES + +[Pcd] + gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid AND + gEdkiiVTdInfoPpiGuid + +[UserExtensions.TianoCore."ExtraFiles"] + IntelVTdPmrPeiExtra.uni + diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.uni b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.uni new file mode 100644 index 0000000000..11508a4fd4 --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.uni @@ -0,0 +1,20 @@ +// /** @file +// IntelVTdPmrPei Module Localized Abstract and Description Content +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials are +// licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Intel VTd PMR PEI Driver." + +#string STR_MODULE_DESCRIPTION #language en-US "This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI and provide DMA protection to device in PEI." + diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni new file mode 100644 index 0000000000..c6b2dec9cd --- /dev/null +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni @@ -0,0 +1,20 @@ +// /** @file +// IntelVTdPmrPei Localized Strings and Content +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials are +// licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Intel VTd PMR PEI Driver" + + diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSiliconPkg.dsc index 091aea7654..10b67993ee 100644 --- a/IntelSiliconPkg/IntelSiliconPkg.dsc +++ b/IntelSiliconPkg/IntelSiliconPkg.dsc @@ -80,7 +80,7 @@ [Components] IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf - IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf + IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf IntelSiliconPkg/Feature/VTd/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf IntelSiliconPkg/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c deleted file mode 100644 index ef08e2991f..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmr.c +++ /dev/null @@ -1,314 +0,0 @@ -/** @file - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- - This program and the accompanying materials are licensed and made available under - the terms and conditions of the BSD License which accompanies this distribution. - The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include - -#include "IntelVTdPmrPei.h" - -extern EDKII_VTD_INFO_PPI *mVTdInfoPpi; - -/** - Get protected low memory alignment. - - @param VtdUnitBaseAddress The base address of the VTd engine. - - @return protected low memory alignment. -**/ -UINT32 -GetPlmrAlignment ( - IN UINTN VtdUnitBaseAddress - ) -{ - UINT32 Data32; - - MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, 0xFFFFFFFF); - Data32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG); - Data32 = ~Data32 + 1; - - return Data32; -} - -/** - Get protected high memory alignment. - - @param VtdUnitBaseAddress The base address of the VTd engine. - - @return protected high memory alignment. -**/ -UINT64 -GetPhmrAlignment ( - IN UINTN VtdUnitBaseAddress - ) -{ - UINT64 Data64; - UINT8 HostAddressWidth; - - HostAddressWidth = mVTdInfoPpi->HostAddressWidth; - - MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF); - Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG); - Data64 = ~Data64 + 1; - Data64 = Data64 & (LShiftU64 (1, HostAddressWidth) - 1); - - return Data64; -} - -/** - Get protected low memory alignment. - - @return protected low memory alignment. -**/ -UINT32 -GetLowMemoryAlignment ( - VOID - ) -{ - UINTN Index; - UINT32 Alignment; - UINT32 FinalAlignment; - - FinalAlignment = 0; - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Alignment = GetPlmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); - if (FinalAlignment < Alignment) { - FinalAlignment = Alignment; - } - } - return FinalAlignment; -} - -/** - Get protected high memory alignment. - - @return protected high memory alignment. -**/ -UINT64 -GetHighMemoryAlignment ( - VOID - ) -{ - UINTN Index; - UINT64 Alignment; - UINT64 FinalAlignment; - - FinalAlignment = 0; - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Alignment = GetPhmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); - if (FinalAlignment < Alignment) { - FinalAlignment = Alignment; - } - } - return FinalAlignment; -} - -/** - Enable PMR in the VTd engine. - - @param VtdUnitBaseAddress The base address of the VTd engine. - - @retval EFI_SUCCESS The PMR is enabled. - @retval EFI_UNSUPPORTED The PMR is not supported. -**/ -EFI_STATUS -EnablePmr ( - IN UINTN VtdUnitBaseAddress - ) -{ - UINT32 Reg32; - VTD_CAP_REG CapReg; - - CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); - if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { - return EFI_UNSUPPORTED; - } - - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); - if ((Reg32 & BIT0) == 0) { - MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); - } while((Reg32 & BIT0) == 0); - } - - return EFI_SUCCESS; -} - -/** - Disable PMR in the VTd engine. - - @param VtdUnitBaseAddress The base address of the VTd engine. - - @retval EFI_SUCCESS The PMR is disabled. - @retval EFI_UNSUPPORTED The PMR is not supported. -**/ -EFI_STATUS -DisablePmr ( - IN UINTN VtdUnitBaseAddress - ) -{ - UINT32 Reg32; - VTD_CAP_REG CapReg; - - CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); - if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { - return EFI_UNSUPPORTED; - } - - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); - if ((Reg32 & BIT0) != 0) { - MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); - } while((Reg32 & BIT0) != 0); - } - - return EFI_SUCCESS; -} - -/** - Set PMR region in the VTd engine. - - @param VtdUnitBaseAddress The base address of the VTd engine. - @param LowMemoryBase The protected low memory region base. - @param LowMemoryLength The protected low memory region length. - @param HighMemoryBase The protected high memory region base. - @param HighMemoryLength The protected high memory region length. - - @retval EFI_SUCCESS The PMR is set to protected region. - @retval EFI_UNSUPPORTED The PMR is not supported. -**/ -EFI_STATUS -SetPmrRegion ( - IN UINTN VtdUnitBaseAddress, - IN UINT32 LowMemoryBase, - IN UINT32 LowMemoryLength, - IN UINT64 HighMemoryBase, - IN UINT64 HighMemoryLength - ) -{ - VTD_CAP_REG CapReg; - UINT32 PlmrAlignment; - UINT64 PhmrAlignment; - - DEBUG ((DEBUG_INFO, "VtdUnitBaseAddress - 0x%x\n", VtdUnitBaseAddress)); - - CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); - if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { - DEBUG ((DEBUG_ERROR, "PLMR/PHMR unsupported\n")); - return EFI_UNSUPPORTED; - } - - PlmrAlignment = GetPlmrAlignment (VtdUnitBaseAddress); - DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment)); - PhmrAlignment = GetPhmrAlignment (VtdUnitBaseAddress); - DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment)); - - if ((LowMemoryBase != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) || - (LowMemoryLength != ALIGN_VALUE(LowMemoryLength, PlmrAlignment)) || - (HighMemoryBase != ALIGN_VALUE(HighMemoryBase, PhmrAlignment)) || - (HighMemoryLength != ALIGN_VALUE(HighMemoryLength, PhmrAlignment))) { - DEBUG ((DEBUG_ERROR, "PLMR/PHMR alignment issue\n")); - return EFI_UNSUPPORTED; - } - - if (LowMemoryBase == 0 && LowMemoryLength == 0) { - LowMemoryBase = 0xFFFFFFFF; - } - if (HighMemoryBase == 0 && HighMemoryLength == 0) { - HighMemoryBase = 0xFFFFFFFFFFFFFFFF; - } - - MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, LowMemoryBase); - MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG, LowMemoryBase + LowMemoryLength - 1); - MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, HighMemoryBase); - MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1); - - return EFI_SUCCESS; -} - -/** - Set DMA protected region. - - @param LowMemoryBase The protected low memory region base. - @param LowMemoryLength The protected low memory region length. - @param HighMemoryBase The protected high memory region base. - @param HighMemoryLength The protected high memory region length. - - @retval EFI_SUCCESS The DMA protection is set. - @retval EFI_UNSUPPORTED The DMA protection is not set. -**/ -EFI_STATUS -SetDmaProtectedRange ( - IN UINT32 LowMemoryBase, - IN UINT32 LowMemoryLength, - IN UINT64 HighMemoryBase, - IN UINT64 HighMemoryLength - ) -{ - UINTN Index; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength)); - - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); - Status = SetPmrRegion ( - (UINTN)mVTdInfoPpi->VTdEngineAddress[Index], - LowMemoryBase, - LowMemoryLength, - HighMemoryBase, - HighMemoryLength - ); - if (EFI_ERROR(Status)) { - return Status; - } - Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); - if (EFI_ERROR(Status)) { - return Status; - } - } - - return EFI_SUCCESS; -} - -/** - Diable DMA protection. - - @retval DMA protection is disabled. -**/ -EFI_STATUS -DisableDmaProtection ( - VOID - ) -{ - UINTN Index; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "DisableDmaProtection\n")); - - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); - if (EFI_ERROR(Status)) { - return Status; - } - } - - return EFI_SUCCESS; -} diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c deleted file mode 100644 index d118b7ef26..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.c +++ /dev/null @@ -1,615 +0,0 @@ -/** @file - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- - This program and the accompanying materials are licensed and made available under - the terms and conditions of the BSD License which accompanies this distribution. - The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "IntelVTdPmrPei.h" - -#define TOTAL_DMA_BUFFER_SIZE SIZE_4MB - -EDKII_VTD_INFO_PPI *mVTdInfoPpi; -UINTN mDmaBufferBase; -UINTN mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE; -UINTN mDmaBufferCurrentTop; -UINTN mDmaBufferCurrentBottom; - -#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P') -typedef struct { - UINT32 Signature; - EDKII_IOMMU_OPERATION Operation; - UINTN NumberOfBytes; - EFI_PHYSICAL_ADDRESS HostAddress; - EFI_PHYSICAL_ADDRESS DeviceAddress; -} MAP_INFO; - -/** - - PEI Memory Layout: - - +------------------+ <------- EfiMemoryTop - | PEI allocated | - =========== +==================+ - ^ | Commom Buf | - | | -------------- | - DMA Buffer | * DMA FREE * | - | | -------------- | - V | Read/Write Buf | - =========== +==================+ - | PEI allocated | - | -------------- | <------- EfiFreeMemoryTop - | * PEI FREE * | - | -------------- | <------- EfiFreeMemoryBottom - | hob | - | -------------- | - | Stack | - +------------------+ <------- EfiMemoryBottom / Stack Bottom - - +------------------+ - | Mem Alloc Hob | - +------------------+ - -**/ - - -/** - Set IOMMU attribute for a system memory. - - If the IOMMU PPI exists, the system memory cannot be used - for DMA by default. - - When a device requests a DMA access for a system memory, - 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] 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. - -**/ -EFI_STATUS -EFIAPI -PeiIoMmuSetAttribute ( - IN EDKII_IOMMU_PPI *This, - IN VOID *Mapping, - IN UINT64 IoMmuAccess - ) -{ - return EFI_SUCCESS; -} - -/** - 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. - -**/ -EFI_STATUS -EFIAPI -PeiIoMmuMap ( - IN EDKII_IOMMU_PPI *This, - IN EDKII_IOMMU_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - MAP_INFO *MapInfo; - UINTN Length; - - if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer || - Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) { - *DeviceAddress = (UINTN)HostAddress; - *Mapping = 0; - return EFI_SUCCESS; - } - - DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); - - Length = *NumberOfBytes + sizeof(MAP_INFO); - if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { - DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n")); - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - - *DeviceAddress = mDmaBufferCurrentBottom; - mDmaBufferCurrentBottom += Length; - - MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes); - MapInfo->Signature = MAP_INFO_SIGNATURE; - MapInfo->Operation = Operation; - MapInfo->NumberOfBytes = *NumberOfBytes; - MapInfo->HostAddress = (UINTN)HostAddress; - MapInfo->DeviceAddress = *DeviceAddress; - *Mapping = MapInfo; - DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation, (UINTN)*DeviceAddress, MapInfo)); - - // - // If this is a read operation from the Bus Master's point of view, - // then copy the contents of the real buffer into the mapped buffer - // so the Bus Master can read the contents of the real buffer. - // - if (Operation == EdkiiIoMmuOperationBusMasterRead || - Operation == EdkiiIoMmuOperationBusMasterRead64) { - CopyMem ( - (VOID *) (UINTN) MapInfo->DeviceAddress, - (VOID *) (UINTN) MapInfo->HostAddress, - MapInfo->NumberOfBytes - ); - } - - return EFI_SUCCESS; -} - -/** - Completes the Map() operation and releases any corresponding resources. - - @param This The PPI instance pointer. - @param 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. -**/ -EFI_STATUS -EFIAPI -PeiIoMmuUnmap ( - IN EDKII_IOMMU_PPI *This, - IN VOID *Mapping - ) -{ - MAP_INFO *MapInfo; - UINTN Length; - - if (Mapping == NULL) { - return EFI_SUCCESS; - } - - DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); - - MapInfo = Mapping; - ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE); - DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes)); - - // - // If this is a write operation from the Bus Master's point of view, - // then copy the contents of the mapped buffer into the real buffer - // so the processor can read the contents of the real buffer. - // - if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite || - MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) { - CopyMem ( - (VOID *) (UINTN) MapInfo->HostAddress, - (VOID *) (UINTN) MapInfo->DeviceAddress, - MapInfo->NumberOfBytes - ); - } - - Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO); - if (mDmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) { - mDmaBufferCurrentBottom -= Length; - } - - return EFI_SUCCESS; -} - -/** - 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 and MEMORY_CACHED. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - -**/ -EFI_STATUS -EFIAPI -PeiIoMmuAllocateBuffer ( - IN EDKII_IOMMU_PPI *This, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN OUT VOID **HostAddress, - IN UINT64 Attributes - ) -{ - UINTN Length; - - DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); - - Length = EFI_PAGES_TO_SIZE(Pages); - if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { - DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n")); - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - *HostAddress = (VOID *)(UINTN)(mDmaBufferCurrentTop - Length); - mDmaBufferCurrentTop -= Length; - - DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress)); - return EFI_SUCCESS; -} - -/** - 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. - - @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(). - -**/ -EFI_STATUS -EFIAPI -PeiIoMmuFreeBuffer ( - IN EDKII_IOMMU_PPI *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -{ - UINTN Length; - - DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); - - Length = EFI_PAGES_TO_SIZE(Pages); - if ((UINTN)HostAddress == mDmaBufferCurrentTop) { - mDmaBufferCurrentTop += Length; - } - - return EFI_SUCCESS; -} - -EDKII_IOMMU_PPI mIoMmuPpi = { - EDKII_IOMMU_PPI_REVISION, - PeiIoMmuSetAttribute, - PeiIoMmuMap, - PeiIoMmuUnmap, - PeiIoMmuAllocateBuffer, - PeiIoMmuFreeBuffer, -}; - -CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = { - EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEdkiiIoMmuPpiGuid, - (VOID *) &mIoMmuPpi -}; - -#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ - EFI_RESOURCE_ATTRIBUTE_TESTED | \ - EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \ - EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \ - EFI_RESOURCE_ATTRIBUTE_64_BIT_IO \ - ) - -#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED) - -#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED) - -#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT) - -GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mResourceTypeShortName[] = { - "Mem", - "MMIO", - "I/O", - "FD", - "MM Port I/O", - "Reserved Mem", - "Reserved I/O", -}; - -/** - Return the short name of resource type. - - @param Type resource type. - - @return the short name of resource type. -**/ -CHAR8 * -ShortNameOfResourceType ( - IN UINT32 Type - ) -{ - if (Type < sizeof(mResourceTypeShortName) / sizeof(mResourceTypeShortName[0])) { - return mResourceTypeShortName[Type]; - } else { - return "Unknown"; - } -} - -/** - Dump resource hob. - - @param HobList the HOB list. -**/ -VOID -DumpResourceHob ( - IN VOID *HobList - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - - DEBUG ((DEBUG_VERBOSE, "Resource Descriptor HOBs\n")); - for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - ResourceHob = Hob.ResourceDescriptor; - DEBUG ((DEBUG_VERBOSE, - " BA=%016lx L=%016lx Attr=%08x ", - ResourceHob->PhysicalStart, - ResourceHob->ResourceLength, - ResourceHob->ResourceAttribute - )); - DEBUG ((DEBUG_VERBOSE, ShortNameOfResourceType(ResourceHob->ResourceType))); - switch (ResourceHob->ResourceType) { - case EFI_RESOURCE_SYSTEM_MEMORY: - if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) != 0) { - DEBUG ((DEBUG_VERBOSE, " (Persistent)")); - } else if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) != 0) { - DEBUG ((DEBUG_VERBOSE, " (MoreReliable)")); - } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) { - DEBUG ((DEBUG_VERBOSE, " (Tested)")); - } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) { - DEBUG ((DEBUG_VERBOSE, " (Init)")); - } else if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) { - DEBUG ((DEBUG_VERBOSE, " (Present)")); - } else { - DEBUG ((DEBUG_VERBOSE, " (Unknown)")); - } - break; - default: - break; - } - DEBUG ((DEBUG_VERBOSE, "\n")); - } - } -} - -/** - Dump PHIT hob. - - @param HobList the HOB list. -**/ -VOID -DumpPhitHob ( - IN VOID *HobList - ) -{ - EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; - - PhitHob = HobList; - ASSERT(GET_HOB_TYPE(HobList) == EFI_HOB_TYPE_HANDOFF); - DEBUG ((DEBUG_VERBOSE, "PHIT HOB\n")); - DEBUG ((DEBUG_VERBOSE, " PhitHob - 0x%x\n", PhitHob)); - DEBUG ((DEBUG_VERBOSE, " BootMode - 0x%x\n", PhitHob->BootMode)); - DEBUG ((DEBUG_VERBOSE, " EfiMemoryTop - 0x%016lx\n", PhitHob->EfiMemoryTop)); - DEBUG ((DEBUG_VERBOSE, " EfiMemoryBottom - 0x%016lx\n", PhitHob->EfiMemoryBottom)); - DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryTop - 0x%016lx\n", PhitHob->EfiFreeMemoryTop)); - DEBUG ((DEBUG_VERBOSE, " EfiFreeMemoryBottom - 0x%016lx\n", PhitHob->EfiFreeMemoryBottom)); - DEBUG ((DEBUG_VERBOSE, " EfiEndOfHobList - 0x%lx\n", PhitHob->EfiEndOfHobList)); -} - -/** - Get the highest memory. - - @param HobList the HOB list. - - @return the highest memory. -**/ -UINT64 -GetTopMemory ( - IN VOID *HobList - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - UINT64 TopMemory; - UINT64 ResourceTop; - - TopMemory = 0; - for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - ResourceHob = Hob.ResourceDescriptor; - switch (ResourceHob->ResourceType) { - case EFI_RESOURCE_SYSTEM_MEMORY: - ResourceTop = ResourceHob->PhysicalStart + ResourceHob->ResourceLength; - if (TopMemory < ResourceTop) { - TopMemory = ResourceTop; - } - break; - default: - break; - } - DEBUG ((DEBUG_VERBOSE, "\n")); - } - } - return TopMemory; -} - -/** - Initialize DMA protection. - - @param DmaBufferSize the DMA buffer size - @param DmaBufferBase the DMA buffer base - - @retval EFI_SUCCESS the DMA protection is initialized. - @retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection. -**/ -EFI_STATUS -InitDmaProtection ( - IN UINTN DmaBufferSize, - OUT UINTN *DmaBufferBase - ) -{ - EFI_STATUS Status; - VOID *HobList; - EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; - UINT32 LowMemoryAlignment; - UINT64 HighMemoryAlignment; - UINTN MemoryAlignment; - UINTN LowBottom; - UINTN LowTop; - UINTN HighBottom; - UINT64 HighTop; - - HobList = GetHobList (); - DumpPhitHob (HobList); - DumpResourceHob (HobList); - - PhitHob = HobList; - - ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop); - - LowMemoryAlignment = GetLowMemoryAlignment (); - HighMemoryAlignment = GetHighMemoryAlignment (); - if (LowMemoryAlignment < HighMemoryAlignment) { - MemoryAlignment = (UINTN)HighMemoryAlignment; - } else { - MemoryAlignment = LowMemoryAlignment; - } - ASSERT (DmaBufferSize == ALIGN_VALUE(DmaBufferSize, MemoryAlignment)); - *DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferSize), MemoryAlignment); - if (*DmaBufferBase == 0) { - DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n")); - return EFI_OUT_OF_RESOURCES; - } - - LowBottom = 0; - LowTop = *DmaBufferBase; - HighBottom = *DmaBufferBase + DmaBufferSize; - HighTop = GetTopMemory (HobList); - - Status = SetDmaProtectedRange ( - (UINT32)LowBottom, - (UINT32)(LowTop - LowBottom), - HighBottom, - HighTop - HighBottom - ); - - if (EFI_ERROR(Status)) { - FreePages ((VOID *)*DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferSize)); - } - - return Status; -} - -/** - Initializes the Intel VTd PMR PEIM. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS Usb bot driver is successfully initialized. - @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. - -**/ -EFI_STATUS -EFIAPI -IntelVTdPmrInitialize ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_STATUS Status; - - if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) { - return EFI_UNSUPPORTED; - } - - Status = PeiServicesLocatePpi ( - &gEdkiiVTdInfoPpiGuid, - 0, - NULL, - (VOID **)&mVTdInfoPpi - ); - ASSERT_EFI_ERROR(Status); - - // - // Find a pre-memory in resource hob as DMA buffer - // Mark PEI memory to be DMA protected. - // - Status = InitDmaProtection (mDmaBufferSize, &mDmaBufferBase); - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", mDmaBufferBase)); - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", mDmaBufferSize)); - - mDmaBufferCurrentTop = mDmaBufferBase + mDmaBufferSize; - mDmaBufferCurrentBottom = mDmaBufferBase; - - // - // Install PPI. - // - Status = PeiServicesInstallPpi (&mIoMmuPpiList); - ASSERT_EFI_ERROR(Status); - - return Status; -} - diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h deleted file mode 100644 index aa5926a766..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - The definition for DMA access Library. - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __DMA_ACCESS_LIB_H__ -#define __DMA_ACCESS_LIB_H__ - -/** - Set DMA protected region. - - @param LowMemoryBase The protected low memory region base. - @param LowMemoryLength The protected low memory region length. - @param HighMemoryBase The protected high memory region base. - @param HighMemoryLength The protected high memory region length. - - @retval EFI_SUCCESS The DMA protection is set. - @retval EFI_UNSUPPORTED The DMA protection is not set. -**/ -EFI_STATUS -SetDmaProtectedRange ( - IN UINT32 LowMemoryBase, - IN UINT32 LowMemoryLength, - IN UINT64 HighMemoryBase, - IN UINT64 HighMemoryLength - ); - -/** - Diable DMA protection. - - @retval DMA protection is disabled. -**/ -EFI_STATUS -DisableDmaProtection ( - VOID - ); - -/** - Get protected low memory alignment. - - @return protected low memory alignment. -**/ -UINT32 -GetLowMemoryAlignment ( - VOID - ); - -/** - Get protected high memory alignment. - - @return protected high memory alignment. -**/ -UINT64 -GetHighMemoryAlignment ( - VOID - ); - -#endif - diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf deleted file mode 100644 index 86cd7d1618..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.inf +++ /dev/null @@ -1,59 +0,0 @@ -## @file -# Component INF file for the Intel VTd PMR PEIM. -# -# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI -# and provide DMA protection in PEI. -# -# Copyright (c) 2017, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010017 - BASE_NAME = IntelVTdPmrPei - MODULE_UNI_FILE = IntelVTdPmrPei.uni - FILE_GUID = F906769F-4AED-4A0D-8C7C-FF21B9D1051A - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - ENTRY_POINT = IntelVTdPmrInitialize - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - IntelSiliconPkg/IntelSiliconPkg.dec - -[Sources] - IntelVTdPmrPei.c - IntelVTdPmrPei.h - IntelVTdPmr.c - -[LibraryClasses] - DebugLib - BaseMemoryLib - BaseLib - PeimEntryPoint - PeiServicesLib - HobLib - IoLib - -[Ppis] - gEdkiiIoMmuPpiGuid ## PRODUCES - gEdkiiVTdInfoPpiGuid ## CONSUMES - -[Pcd] - gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND - gEdkiiVTdInfoPpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - IntelVTdPmrPeiExtra.uni - diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni deleted file mode 100644 index 11508a4fd4..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPei.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// IntelVTdPmrPei Module Localized Abstract and Description Content -// -// Copyright (c) 2017, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials are -// licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Intel VTd PMR PEI Driver." - -#string STR_MODULE_DESCRIPTION #language en-US "This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI and provide DMA protection to device in PEI." - diff --git a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni b/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni deleted file mode 100644 index c6b2dec9cd..0000000000 --- a/IntelSiliconPkg/IntelVTdPmrPei/IntelVTdPmrPeiExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// IntelVTdPmrPei Localized Strings and Content -// -// Copyright (c) 2017, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials are -// licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Intel VTd PMR PEI Driver" - -