IntelSiliconPkg/IntelVTdDxe: Move to feature dir.
Move IntelVTdDxe to Feature/VTd/IntelVTdDxe. Suggested-by: Star Zeng <star.zeng@intel.com> Cc: Star Zeng <star.zeng@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
562
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
Normal file
562
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
Normal file
@@ -0,0 +1,562 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
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 _DMAR_PROTECTION_H_
|
||||
#define _DMAR_PROTECTION_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PciSegmentLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/PerformanceLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/Acpi.h>
|
||||
|
||||
#include <Protocol/DxeSmmReadyToLock.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/PciEnumerationComplete.h>
|
||||
#include <Protocol/AcpiSystemDescriptionTable.h>
|
||||
#include <Protocol/PlatformVtdPolicy.h>
|
||||
#include <Protocol/IoMmu.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
|
||||
#define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))
|
||||
|
||||
#define ALIGN_VALUE_UP(Value, Alignment) (((Value) + (Alignment) - 1) & (~((Alignment) - 1)))
|
||||
#define ALIGN_VALUE_LOW(Value, Alignment) ((Value) & (~((Alignment) - 1)))
|
||||
|
||||
//
|
||||
// This is the initial max PCI DATA number.
|
||||
// The number may be enlarged later.
|
||||
//
|
||||
#define MAX_VTD_PCI_DATA_NUMBER 0x100
|
||||
|
||||
typedef struct {
|
||||
UINT8 DeviceType;
|
||||
VTD_SOURCE_ID PciSourceId;
|
||||
EDKII_PLATFORM_VTD_PCI_DEVICE_ID PciDeviceId;
|
||||
// for statistic analysis
|
||||
UINTN AccessCount;
|
||||
} PCI_DEVICE_DATA;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN IncludeAllFlag;
|
||||
UINTN PciDeviceDataNumber;
|
||||
UINTN PciDeviceDataMaxNumber;
|
||||
PCI_DEVICE_DATA *PciDeviceData;
|
||||
} PCI_DEVICE_INFORMATION;
|
||||
|
||||
typedef struct {
|
||||
UINTN VtdUnitBaseAddress;
|
||||
UINT16 Segment;
|
||||
VTD_CAP_REG CapReg;
|
||||
VTD_ECAP_REG ECapReg;
|
||||
VTD_ROOT_ENTRY *RootEntryTable;
|
||||
VTD_EXT_ROOT_ENTRY *ExtRootEntryTable;
|
||||
VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry;
|
||||
BOOLEAN HasDirtyContext;
|
||||
BOOLEAN HasDirtyPages;
|
||||
PCI_DEVICE_INFORMATION PciDeviceInfo;
|
||||
} VTD_UNIT_INFORMATION;
|
||||
|
||||
/**
|
||||
The scan bus callback function.
|
||||
|
||||
It is called in PCI bus scan for each PCI device under the bus.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The specific PCI device is processed in the callback.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *SCAN_BUS_FUNC_CALLBACK_FUNC) (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
);
|
||||
|
||||
extern EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;
|
||||
|
||||
extern UINT64 mVtdHostAddressWidthMask;
|
||||
extern UINTN mVtdUnitNumber;
|
||||
extern VTD_UNIT_INFORMATION *mVtdUnitInformation;
|
||||
|
||||
extern UINT64 mBelow4GMemoryLimit;
|
||||
extern UINT64 mAbove4GMemoryLimit;
|
||||
|
||||
extern EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;
|
||||
|
||||
/**
|
||||
Prepare VTD configuration.
|
||||
**/
|
||||
VOID
|
||||
PrepareVtdConfig (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Setup VTd translation table.
|
||||
|
||||
@retval EFI_SUCCESS Setup translation table successfully.
|
||||
@retval EFI_OUT_OF_RESOURCE Setup translation table fail.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetupTranslationTable (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Enable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is enabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not enabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnableDmar (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Disable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is disabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmar (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Invalid VTd global IOTLB.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS VTd global IOTLB is invalidated.
|
||||
@retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateVtdIOTLBGlobal (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegs (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers for all VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegsAll (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd capability registers.
|
||||
|
||||
@param[in] CapReg The capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdCapRegs (
|
||||
IN VTD_CAP_REG *CapReg
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd extended capability registers.
|
||||
|
||||
@param[in] ECapReg The extended capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdECapRegs (
|
||||
IN VTD_ECAP_REG *ECapReg
|
||||
);
|
||||
|
||||
/**
|
||||
Register PCI device to VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
@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 UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT8 DeviceType,
|
||||
IN BOOLEAN CheckExist
|
||||
);
|
||||
|
||||
/**
|
||||
The scan bus callback function to always enable page attribute.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ScanBusCallbackRegisterPciDevice (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
);
|
||||
|
||||
/**
|
||||
Scan PCI bus and invoke callback function for each PCI devices under the bus.
|
||||
|
||||
@param[in] Context The context of the callback function.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Callback The callback function in PCI scan.
|
||||
|
||||
@retval EFI_SUCCESS The PCI devices under the bus are scaned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScanPciBus (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback
|
||||
);
|
||||
|
||||
/**
|
||||
Dump the PCI device information managed by this VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpPciDeviceInfo (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Find the VTd index by the Segment and SourceId.
|
||||
|
||||
@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
|
||||
FindVtdIndexByPciDevice (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,
|
||||
OUT VTD_CONTEXT_ENTRY **ContextEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Get the DMAR ACPI table.
|
||||
|
||||
@retval EFI_SUCCESS The DMAR ACPI table is got.
|
||||
@retval EFI_NOT_FOUND The DMAR ACPI table is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDmarAcpiTable (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@return EFI_SUCCESS The DMAR DRHD table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableDrhd (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR RMRR table.
|
||||
|
||||
@return EFI_SUCCESS The DMAR RMRR table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableRmrr (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR context entry table.
|
||||
|
||||
@param[in] RootEntry DMAR root entry.
|
||||
**/
|
||||
VOID
|
||||
DumpDmarContextEntryTable (
|
||||
IN VTD_ROOT_ENTRY *RootEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR extended context entry table.
|
||||
|
||||
@param[in] ExtRootEntry DMAR extended root entry.
|
||||
**/
|
||||
VOID
|
||||
DumpDmarExtContextEntryTable (
|
||||
IN VTD_EXT_ROOT_ENTRY *ExtRootEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR second level paging entry.
|
||||
|
||||
@param[in] SecondLevelPagingEntry The second level paging entry.
|
||||
**/
|
||||
VOID
|
||||
DumpSecondLevelPagingEntry (
|
||||
IN VOID *SecondLevelPagingEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Set VTd attribute for a system memory.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] DomainIdentifier The domain ID of the source.
|
||||
@param[in] SecondLevelPagingEntry The second level paging entry in VTd table for the device.
|
||||
@param[in] BaseAddress 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.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@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 BaseAddress and Length.
|
||||
@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
|
||||
SetPageAttribute (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 DomainIdentifier,
|
||||
IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
/**
|
||||
Set VTd attribute for a system memory.
|
||||
|
||||
@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] BaseAddress 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.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@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 BaseAddress and Length.
|
||||
@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
|
||||
SetAccessAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
/**
|
||||
Return the index of PCI data.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@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 UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers if there is error.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdIfError (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize platform VTd policy.
|
||||
**/
|
||||
VOID
|
||||
InitializePlatformVTdPolicy (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Always enable the VTd page attribute for the device.
|
||||
|
||||
@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.
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AlwaysEnablePageAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
Convert the DeviceHandle to SourceId and Segment.
|
||||
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[out] Segment The Segment used to identify a VTd engine.
|
||||
@param[out] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@retval EFI_SUCCESS The Segment and SourceId are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
|
||||
@retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DeviceHandleToSourceId (
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
OUT UINT16 *Segment,
|
||||
OUT VTD_SOURCE_ID *SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize DMA protection.
|
||||
**/
|
||||
VOID
|
||||
InitializeDmaProtection (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Allocate zero pages.
|
||||
|
||||
@param[in] Pages the number of pages.
|
||||
|
||||
@return the page address.
|
||||
@retval NULL No resource to allocate pages.
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateZeroPages (
|
||||
IN UINTN Pages
|
||||
);
|
||||
|
||||
/**
|
||||
Flush VTD page table and context table memory.
|
||||
|
||||
This action is to make sure the IOMMU engine can get final data in memory.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] Base The base address of memory to be flushed.
|
||||
@param[in] Size The size of memory in bytes to be flushed.
|
||||
**/
|
||||
VOID
|
||||
FlushPageTableMemory (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINTN Base,
|
||||
IN UINTN Size
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user