summaryrefslogtreecommitdiffstats
path: root/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c
diff options
context:
space:
mode:
Diffstat (limited to 'IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c')
-rw-r--r--IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c538
1 files changed, 0 insertions, 538 deletions
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c
deleted file mode 100644
index 0bd4e818ab..0000000000
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/** @file
- BmDma related function
-
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "DmaProtection.h"
-
-// TBD: May make it a policy
-#define DMA_MEMORY_TOP MAX_UINTN
-//#define DMA_MEMORY_TOP 0x0000000001FFFFFFULL
-
-#define MAP_HANDLE_INFO_SIGNATURE SIGNATURE_32 ('H', 'M', 'A', 'P')
-typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_HANDLE DeviceHandle;
- UINT64 IoMmuAccess;
-} MAP_HANDLE_INFO;
-#define MAP_HANDLE_INFO_FROM_LINK(a) CR (a, MAP_HANDLE_INFO, Link, MAP_HANDLE_INFO_SIGNATURE)
-
-#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
-typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EDKII_IOMMU_OPERATION Operation;
- UINTN NumberOfBytes;
- UINTN NumberOfPages;
- EFI_PHYSICAL_ADDRESS HostAddress;
- EFI_PHYSICAL_ADDRESS DeviceAddress;
- LIST_ENTRY HandleList;
-} MAP_INFO;
-#define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link, MAP_INFO_SIGNATURE)
-
-LIST_ENTRY gMaps = INITIALIZE_LIST_HEAD_VARIABLE(gMaps);
-
-/**
- This function fills DeviceHandle/IoMmuAccess to the MAP_HANDLE_INFO,
- based upon the DeviceAddress.
-
- @param[in] DeviceHandle The device who initiates the DMA access request.
- @param[in] DeviceAddress The base of device memory address to be used as the DMA memory.
- @param[in] Length The length of device memory address to be used as the DMA memory.
- @param[in] IoMmuAccess The IOMMU access.
-
-**/
-VOID
-SyncDeviceHandleToMapInfo (
- IN EFI_HANDLE DeviceHandle,
- IN EFI_PHYSICAL_ADDRESS DeviceAddress,
- IN UINT64 Length,
- IN UINT64 IoMmuAccess
- )
-{
- MAP_INFO *MapInfo;
- MAP_HANDLE_INFO *MapHandleInfo;
- LIST_ENTRY *Link;
- EFI_TPL OriginalTpl;
-
- //
- // Find MapInfo according to DeviceAddress
- //
- OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
- MapInfo = NULL;
- for (Link = GetFirstNode (&gMaps)
- ; !IsNull (&gMaps, Link)
- ; Link = GetNextNode (&gMaps, Link)
- ) {
- MapInfo = MAP_INFO_FROM_LINK (Link);
- if (MapInfo->DeviceAddress == DeviceAddress) {
- break;
- }
- }
- if ((MapInfo == NULL) || (MapInfo->DeviceAddress != DeviceAddress)) {
- DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: DeviceAddress(0x%lx) - not found\n", DeviceAddress));
- gBS->RestoreTPL (OriginalTpl);
- return ;
- }
-
- //
- // Find MapHandleInfo according to DeviceHandle
- //
- MapHandleInfo = NULL;
- for (Link = GetFirstNode (&MapInfo->HandleList)
- ; !IsNull (&MapInfo->HandleList, Link)
- ; Link = GetNextNode (&MapInfo->HandleList, Link)
- ) {
- MapHandleInfo = MAP_HANDLE_INFO_FROM_LINK (Link);
- if (MapHandleInfo->DeviceHandle == DeviceHandle) {
- break;
- }
- }
- if ((MapHandleInfo != NULL) && (MapHandleInfo->DeviceHandle == DeviceHandle)) {
- MapHandleInfo->IoMmuAccess = IoMmuAccess;
- gBS->RestoreTPL (OriginalTpl);
- return ;
- }
-
- //
- // No DeviceHandle
- // Initialize and insert the MAP_HANDLE_INFO structure
- //
- MapHandleInfo = AllocatePool (sizeof (MAP_HANDLE_INFO));
- if (MapHandleInfo == NULL) {
- DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: %r\n", EFI_OUT_OF_RESOURCES));
- gBS->RestoreTPL (OriginalTpl);
- return ;
- }
-
- MapHandleInfo->Signature = MAP_HANDLE_INFO_SIGNATURE;
- MapHandleInfo->DeviceHandle = DeviceHandle;
- MapHandleInfo->IoMmuAccess = IoMmuAccess;
-
- InsertTailList (&MapInfo->HandleList, &MapHandleInfo->Link);
- gBS->RestoreTPL (OriginalTpl);
-
- return ;
-}
-
-/**
- Provides the controller-specific addresses required to access system memory from a
- DMA bus master.
-
- @param This The protocol 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
-IoMmuMap (
- IN EDKII_IOMMU_PROTOCOL *This,
- IN EDKII_IOMMU_OPERATION Operation,
- IN VOID *HostAddress,
- IN OUT UINTN *NumberOfBytes,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
- OUT VOID **Mapping
- )
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
- MAP_INFO *MapInfo;
- EFI_PHYSICAL_ADDRESS DmaMemoryTop;
- BOOLEAN NeedRemap;
- EFI_TPL OriginalTpl;
-
- if (NumberOfBytes == NULL || DeviceAddress == NULL ||
- Mapping == NULL) {
- DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((DEBUG_VERBOSE, "IoMmuMap: ==> 0x%08x - 0x%08x (%x)\n", HostAddress, *NumberOfBytes, Operation));
-
- //
- // Make sure that Operation is valid
- //
- if ((UINT32) Operation >= EdkiiIoMmuOperationMaximum) {
- DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
- NeedRemap = FALSE;
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
-
- DmaMemoryTop = DMA_MEMORY_TOP;
-
- //
- // Alignment check
- //
- if ((*NumberOfBytes != ALIGN_VALUE(*NumberOfBytes, SIZE_4KB)) ||
- (PhysicalAddress != ALIGN_VALUE(PhysicalAddress, SIZE_4KB))) {
- if ((Operation == EdkiiIoMmuOperationBusMasterCommonBuffer) ||
- (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64)) {
- //
- // The input buffer might be a subset from IoMmuAllocateBuffer.
- // Skip the check.
- //
- } else {
- NeedRemap = TRUE;
- }
- }
-
- if ((PhysicalAddress + *NumberOfBytes) >= DMA_MEMORY_TOP) {
- NeedRemap = TRUE;
- }
-
- if (((Operation != EdkiiIoMmuOperationBusMasterRead64 &&
- Operation != EdkiiIoMmuOperationBusMasterWrite64 &&
- Operation != EdkiiIoMmuOperationBusMasterCommonBuffer64)) &&
- ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
- //
- // If the root bridge or the device cannot handle performing DMA above
- // 4GB but any part of the DMA transfer being mapped is above 4GB, then
- // map the DMA transfer to a buffer below 4GB.
- //
- NeedRemap = TRUE;
- DmaMemoryTop = MIN (DmaMemoryTop, SIZE_4GB - 1);
- }
-
- if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
- Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
- if (NeedRemap) {
- //
- // Common Buffer operations can not be remapped. If the common buffer
- // is above 4GB, then it is not possible to generate a mapping, so return
- // an error.
- //
- DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_UNSUPPORTED));
- return EFI_UNSUPPORTED;
- }
- }
-
- //
- // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
- // called later.
- //
- MapInfo = AllocatePool (sizeof (MAP_INFO));
- if (MapInfo == NULL) {
- *NumberOfBytes = 0;
- DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_OUT_OF_RESOURCES));
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Initialize the MAP_INFO structure
- //
- MapInfo->Signature = MAP_INFO_SIGNATURE;
- MapInfo->Operation = Operation;
- MapInfo->NumberOfBytes = *NumberOfBytes;
- MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
- MapInfo->HostAddress = PhysicalAddress;
- MapInfo->DeviceAddress = DmaMemoryTop;
- InitializeListHead(&MapInfo->HandleList);
-
- //
- // Allocate a buffer below 4GB to map the transfer to.
- //
- if (NeedRemap) {
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiBootServicesData,
- MapInfo->NumberOfPages,
- &MapInfo->DeviceAddress
- );
- if (EFI_ERROR (Status)) {
- FreePool (MapInfo);
- *NumberOfBytes = 0;
- DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", Status));
- return Status;
- }
-
- //
- // 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
- );
- }
- } else {
- MapInfo->DeviceAddress = MapInfo->HostAddress;
- }
-
- OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
- InsertTailList (&gMaps, &MapInfo->Link);
- gBS->RestoreTPL (OriginalTpl);
-
- //
- // The DeviceAddress is the address of the maped buffer below 4GB
- //
- *DeviceAddress = MapInfo->DeviceAddress;
- //
- // Return a pointer to the MAP_INFO structure in Mapping
- //
- *Mapping = MapInfo;
-
- DEBUG ((DEBUG_VERBOSE, "IoMmuMap: 0x%08x - 0x%08x <==\n", *DeviceAddress, *Mapping));
-
- return EFI_SUCCESS;
-}
-
-/**
- Completes the Map() operation and releases any corresponding resources.
-
- @param This The protocol 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
-IoMmuUnmap (
- IN EDKII_IOMMU_PROTOCOL *This,
- IN VOID *Mapping
- )
-{
- MAP_INFO *MapInfo;
- MAP_HANDLE_INFO *MapHandleInfo;
- LIST_ENTRY *Link;
- EFI_TPL OriginalTpl;
-
- DEBUG ((DEBUG_VERBOSE, "IoMmuUnmap: 0x%08x\n", Mapping));
-
- if (Mapping == NULL) {
- DEBUG ((DEBUG_ERROR, "IoMmuUnmap: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
-
- OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
- MapInfo = NULL;
- for (Link = GetFirstNode (&gMaps)
- ; !IsNull (&gMaps, Link)
- ; Link = GetNextNode (&gMaps, Link)
- ) {
- MapInfo = MAP_INFO_FROM_LINK (Link);
- if (MapInfo == Mapping) {
- break;
- }
- }
- //
- // Mapping is not a valid value returned by Map()
- //
- if (MapInfo != Mapping) {
- gBS->RestoreTPL (OriginalTpl);
- DEBUG ((DEBUG_ERROR, "IoMmuUnmap: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
- RemoveEntryList (&MapInfo->Link);
- gBS->RestoreTPL (OriginalTpl);
-
- //
- // remove all nodes in MapInfo->HandleList
- //
- while (!IsListEmpty (&MapInfo->HandleList)) {
- MapHandleInfo = MAP_HANDLE_INFO_FROM_LINK (MapInfo->HandleList.ForwardLink);
- RemoveEntryList (&MapHandleInfo->Link);
- FreePool (MapHandleInfo);
- }
-
- if (MapInfo->DeviceAddress != MapInfo->HostAddress) {
- //
- // 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
- );
- }
-
- //
- // Free the mapped buffer and the MAP_INFO structure.
- //
- gBS->FreePages (MapInfo->DeviceAddress, MapInfo->NumberOfPages);
- }
-
- FreePool (Mapping);
- return EFI_SUCCESS;
-}
-
-/**
- Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
- OperationBusMasterCommonBuffer64 mapping.
-
- @param This The protocol instance pointer.
- @param Type This parameter is not used and must be ignored.
- @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.
-
-**/
-EFI_STATUS
-EFIAPI
-IoMmuAllocateBuffer (
- IN EDKII_IOMMU_PROTOCOL *This,
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- IN OUT VOID **HostAddress,
- IN UINT64 Attributes
- )
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
-
- DEBUG ((DEBUG_VERBOSE, "IoMmuAllocateBuffer: ==> 0x%08x\n", Pages));
-
- //
- // Validate Attributes
- //
- if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
- DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_UNSUPPORTED));
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check for invalid inputs
- //
- if (HostAddress == NULL) {
- DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // The only valid memory types are EfiBootServicesData and
- // EfiRuntimeServicesData
- //
- if (MemoryType != EfiBootServicesData &&
- MemoryType != EfiRuntimeServicesData) {
- DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_INVALID_PARAMETER));
- return EFI_INVALID_PARAMETER;
- }
-
- PhysicalAddress = DMA_MEMORY_TOP;
- if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
- //
- // Limit allocations to memory below 4GB
- //
- PhysicalAddress = MIN (PhysicalAddress, SIZE_4GB - 1);
- }
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- MemoryType,
- Pages,
- &PhysicalAddress
- );
- if (!EFI_ERROR (Status)) {
- *HostAddress = (VOID *) (UINTN) PhysicalAddress;
- }
-
- DEBUG ((DEBUG_VERBOSE, "IoMmuAllocateBuffer: 0x%08x <==\n", *HostAddress));
-
- return Status;
-}
-
-/**
- Frees memory that was allocated with AllocateBuffer().
-
- @param This The protocol 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
-IoMmuFreeBuffer (
- IN EDKII_IOMMU_PROTOCOL *This,
- IN UINTN Pages,
- IN VOID *HostAddress
- )
-{
- DEBUG ((DEBUG_VERBOSE, "IoMmuFreeBuffer: 0x%\n", Pages));
- return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
-}
-
-/**
- Get device information from mapping.
-
- @param[in] Mapping The mapping.
- @param[out] DeviceAddress The device address of the mapping.
- @param[out] NumberOfPages The number of pages of the mapping.
-
- @retval EFI_SUCCESS The device information is returned.
- @retval EFI_INVALID_PARAMETER The mapping is invalid.
-**/
-EFI_STATUS
-GetDeviceInfoFromMapping (
- IN VOID *Mapping,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
- OUT UINTN *NumberOfPages
- )
-{
- MAP_INFO *MapInfo;
- LIST_ENTRY *Link;
-
- if (Mapping == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- MapInfo = NULL;
- for (Link = GetFirstNode (&gMaps)
- ; !IsNull (&gMaps, Link)
- ; Link = GetNextNode (&gMaps, Link)
- ) {
- MapInfo = MAP_INFO_FROM_LINK (Link);
- if (MapInfo == Mapping) {
- break;
- }
- }
- //
- // Mapping is not a valid value returned by Map()
- //
- if (MapInfo != Mapping) {
- return EFI_INVALID_PARAMETER;
- }
-
- *DeviceAddress = MapInfo->DeviceAddress;
- *NumberOfPages = MapInfo->NumberOfPages;
- return EFI_SUCCESS;
-}
-