30BOOLEAN mReservedSharedMemSupported =
FALSE;
36mBusMasterOperationName[EdkiiIoMmuOperationMaximum] = {
90 VOID *DecryptionSource;
94 "%a: Operation=%a Host=0x%p Bytes=0x%Lx\n",
97 Operation <
ARRAY_SIZE (mBusMasterOperationName)) ?
98 mBusMasterOperationName[Operation] :
101 (UINT64)((NumberOfBytes ==
NULL) ? 0 : *NumberOfBytes)
104 if ((HostAddress ==
NULL) || (NumberOfBytes ==
NULL) || (DeviceAddress ==
NULL) ||
107 return EFI_INVALID_PARAMETER;
117 if (MapInfo ==
NULL) {
118 Status = EFI_OUT_OF_RESOURCES;
125 ZeroMem (&MapInfo->Link,
sizeof MapInfo->Link);
126 MapInfo->Signature = MAP_INFO_SIG;
127 MapInfo->Operation = Operation;
128 MapInfo->NumberOfBytes = *NumberOfBytes;
130 MapInfo->CryptedAddress = (
UINTN)HostAddress;
131 MapInfo->ReservedMemBitmap = 0;
139 DecryptionSource = (VOID *)(
UINTN)MapInfo->CryptedAddress;
149 MapInfo->PlainTextAddress = BASE_4GB - 1;
164 if (EFI_ERROR (Status)) {
177 if ((MapInfo->CryptedAddress > BASE_4GB) ||
179 BASE_4GB - MapInfo->CryptedAddress))
186 Status = EFI_UNSUPPORTED;
197 MapInfo->PlainTextAddress = MapInfo->CryptedAddress;
202 (
UINTN)MapInfo->CryptedAddress - EFI_PAGE_SIZE
204 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
206 CommonBufferHeader->StashBuffer,
207 (VOID *)(
UINTN)MapInfo->CryptedAddress,
208 MapInfo->NumberOfBytes
214 DecryptionSource = CommonBufferHeader->StashBuffer;
215 MapInfo->ReservedMemBitmap = CommonBufferHeader->ReservedMemBitmap;
222 Status = EFI_INVALID_PARAMETER;
226 if (MapInfo->ReservedMemBitmap == 0) {
231 if (CC_GUEST_IS_SEV (
PcdGet64 (PcdConfidentialComputingGuestAttr))) {
237 MapInfo->PlainTextAddress,
238 MapInfo->NumberOfPages
240 }
else if (CC_GUEST_IS_TDX (
PcdGet64 (PcdConfidentialComputingGuestAttr))) {
246 MapInfo->PlainTextAddress,
247 MapInfo->NumberOfPages
255 if (EFI_ERROR (Status)) {
273 (VOID *)(
UINTN)MapInfo->PlainTextAddress,
275 MapInfo->NumberOfBytes
286 *DeviceAddress = MapInfo->PlainTextAddress;
291 "%a: Mapping=0x%p Device(PlainText)=0x%Lx Crypted=0x%Lx Pages=0x%Lx, ReservedMemBitmap=0x%Lx\n",
294 MapInfo->PlainTextAddress,
295 MapInfo->CryptedAddress,
296 (UINT64)MapInfo->NumberOfPages,
297 MapInfo->ReservedMemBitmap
334 IN BOOLEAN MemoryMapLocked
340 VOID *EncryptionTarget;
344 "%a: Mapping=0x%p MemoryMapLocked=%d\n",
350 if (Mapping ==
NULL) {
351 return EFI_INVALID_PARAMETER;
359 CommonBufferHeader =
NULL;
369 EncryptionTarget = (VOID *)(
UINTN)MapInfo->CryptedAddress;
371 switch (MapInfo->Operation) {
374 ASSERT (MapInfo->PlainTextAddress == MapInfo->CryptedAddress);
377 (
UINTN)MapInfo->PlainTextAddress - EFI_PAGE_SIZE
379 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
380 EncryptionTarget = CommonBufferHeader->StashBuffer;
389 (VOID *)(
UINTN)MapInfo->PlainTextAddress,
390 MapInfo->NumberOfBytes
401 if (MapInfo->ReservedMemBitmap == 0) {
402 if (CC_GUEST_IS_SEV (
PcdGet64 (PcdConfidentialComputingGuestAttr))) {
409 MapInfo->PlainTextAddress,
410 MapInfo->NumberOfPages
412 }
else if (CC_GUEST_IS_TDX (
PcdGet64 (PcdConfidentialComputingGuestAttr))) {
419 MapInfo->PlainTextAddress,
420 MapInfo->NumberOfPages
428 if (EFI_ERROR (Status)) {
444 (VOID *)(
UINTN)MapInfo->CryptedAddress,
445 CommonBufferHeader->StashBuffer,
446 MapInfo->NumberOfBytes
450 (VOID *)(
UINTN)MapInfo->PlainTextAddress,
454 if (!MemoryMapLocked) {
464 if (!MemoryMapLocked) {
526 IN OUT VOID **HostAddress,
533 UINTN CommonBufferPages;
535 UINT32 ReservedMemBitmap;
539 "%a: MemoryType=%u Pages=0x%Lx Attributes=0x%Lx\n",
549 if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
550 return EFI_UNSUPPORTED;
556 if (HostAddress ==
NULL) {
557 return EFI_INVALID_PARAMETER;
567 return EFI_INVALID_PARAMETER;
573 if (Pages > MAX_UINTN - 1) {
574 return EFI_OUT_OF_RESOURCES;
577 CommonBufferPages = Pages + 1;
593 if (StashBuffer ==
NULL) {
594 return EFI_OUT_OF_RESOURCES;
597 PhysicalAddress = (
UINTN)-1;
598 if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
602 PhysicalAddress = SIZE_4GB - 1;
612 if (EFI_ERROR (Status)) {
613 goto FreeStashBuffer;
616 CommonBufferHeader = (VOID *)(
UINTN)PhysicalAddress;
617 PhysicalAddress += EFI_PAGE_SIZE;
619 CommonBufferHeader->Signature = COMMON_BUFFER_SIG;
620 CommonBufferHeader->StashBuffer = StashBuffer;
621 CommonBufferHeader->ReservedMemBitmap = ReservedMemBitmap;
623 *HostAddress = (VOID *)(
UINTN)PhysicalAddress;
627 "%a: Host=0x%Lx Stash=0x%p\n",
660 UINTN CommonBufferPages;
665 "%a: Host=0x%p Pages=0x%Lx\n",
671 CommonBufferPages = Pages + 1;
673 (
UINTN)HostAddress - EFI_PAGE_SIZE
679 ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG);
680 if (CommonBufferHeader->Signature != COMMON_BUFFER_SIG) {
681 return EFI_INVALID_PARAMETER;
688 FreePages (CommonBufferHeader->StashBuffer, Pages);
751 IN UINT64 IoMmuAccess
757 DEBUG ((DEBUG_VERBOSE,
"%a: Mapping=0x%p Access=%lu\n", __func__, Mapping, IoMmuAccess));
759 if (Mapping ==
NULL) {
760 return EFI_INVALID_PARAMETER;
768 if (IoMmuAccess != 0) {
775 switch (MapInfo->Operation) {
778 if (IoMmuAccess != EDKII_IOMMU_ACCESS_READ) {
779 Status = EFI_INVALID_PARAMETER;
786 if (IoMmuAccess != EDKII_IOMMU_ACCESS_WRITE) {
787 Status = EFI_INVALID_PARAMETER;
794 if (IoMmuAccess != (EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE)) {
795 Status = EFI_INVALID_PARAMETER;
801 Status = EFI_UNSUPPORTED;
809 EDKII_IOMMU_PROTOCOL_REVISION,
842 IN VOID *EventToSignal
872 DEBUG ((DEBUG_VERBOSE,
"%a\n", __func__));
873 gBS->SignalEvent (EventToSignal);
901 DEBUG ((DEBUG_VERBOSE,
"%a\n", __func__));
907 for (Node =
GetFirstNode (&mMapInfos); Node != &mMapInfos; Node = NextNode) {
909 MapInfo =
CR (Node,
MAP_INFO, Link, MAP_INFO_SIG);
942 Status =
gBS->CreateEvent (
947 &UnmapAllMappingsEvent
949 if (EFI_ERROR (Status)) {
957 Status =
gBS->CreateEvent (
958 EVT_SIGNAL_EXIT_BOOT_SERVICES,
961 UnmapAllMappingsEvent,
964 if (EFI_ERROR (Status)) {
965 goto CloseUnmapAllMappingsEvent;
969 Status =
gBS->InstallMultipleProtocolInterfaces (
975 if (EFI_ERROR (Status)) {
976 goto CloseExitBootEvent;
982 mReservedSharedMemSupported =
TRUE;
984 if (EFI_ERROR (Status)) {
985 mReservedSharedMemSupported =
FALSE;
987 DEBUG ((DEBUG_INFO,
"%a: Feature of reserved memory for DMA is supported.\n", __func__));
993 gBS->CloseEvent (ExitBootEvent);
995CloseUnmapAllMappingsEvent:
996 gBS->CloseEvent (UnmapAllMappingsEvent);
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
VOID EFIAPI CpuDeadLoop(VOID)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
STATIC VOID EFIAPI IoMmuExitBoot(IN EFI_EVENT Event, IN VOID *EventToSignal)
EFI_STATUS EFIAPI IoMmuFreeBuffer(IN EDKII_IOMMU_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress)
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)
STATIC VOID EFIAPI IoMmuUnmapAllMappings(IN EFI_EVENT Event, IN VOID *Context)
STATIC EFI_STATUS EFIAPI IoMmuUnmapWorker(IN EDKII_IOMMU_PROTOCOL *This, IN VOID *Mapping, IN BOOLEAN MemoryMapLocked)
EFI_STATUS EFIAPI IoMmuUnmap(IN EDKII_IOMMU_PROTOCOL *This, IN VOID *Mapping)
EFI_STATUS EFIAPI InstallIoMmuProtocol(VOID)
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 EFIAPI IoMmuSetAttribute(IN EDKII_IOMMU_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN VOID *Mapping, IN UINT64 IoMmuAccess)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS IoMmuAllocateCommonBuffer(IN EFI_MEMORY_TYPE MemoryType, IN UINTN CommonBufferPages, OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress, OUT UINT32 *ReservedMemBitmap)
EFI_STATUS IoMmuFreeBounceBuffer(IN OUT MAP_INFO *MapInfo)
EFI_STATUS IoMmuFreeCommonBuffer(IN COMMON_BUFFER_HEADER *CommonBufferHeader, IN UINTN CommonBufferPages)
EFI_STATUS IoMmuInitReservedSharedMem(VOID)
EFI_STATUS IoMmuReleaseReservedSharedMem(BOOLEAN MemoryMapLocked)
EFI_STATUS IoMmuAllocateBounceBuffer(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN OUT MAP_INFO *MapInfo)
#define ARRAY_SIZE(Array)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define CR(Record, TYPE, Field, TestSignature)
RETURN_STATUS EFIAPI MemEncryptSevClearPageEncMask(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptSevSetPageEncMask(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptTdxSetPageSharedBit(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
RETURN_STATUS EFIAPI MemEncryptTdxClearPageSharedBit(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
#define PcdGet64(TokenName)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_GUID gEdkiiIoMmuProtocolGuid
@ EdkiiIoMmuOperationBusMasterWrite
@ EdkiiIoMmuOperationBusMasterWrite64
@ EdkiiIoMmuOperationBusMasterCommonBuffer
@ EdkiiIoMmuOperationBusMasterRead64
@ EdkiiIoMmuOperationBusMasterRead
@ EdkiiIoMmuOperationBusMasterCommonBuffer64
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)