3 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/MemoryAllocationLib.h>
14 #include <Library/IoLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/PeiServicesLib.h>
17 #include <Library/HobLib.h>
18 #include <IndustryStandard/Vtd.h>
19 #include <Ppi/IoMmu.h>
20 #include <Ppi/VtdInfo.h>
21 #include <Ppi/MemoryDiscovered.h>
22 #include <Ppi/EndOfPeiPhase.h>
24 #include "IntelVTdPmrPei.h"
26 EFI_GUID mVTdInfoGuid
= {
27 0x222f5e30, 0x5cd, 0x49c6, { 0x8a, 0xc, 0x36, 0xd6, 0x58, 0x41, 0xe0, 0x82 }
30 EFI_GUID mDmaBufferInfoGuid
= {
31 0x7b624ec7, 0xfb67, 0x4f9c, { 0xb6, 0xb0, 0x4d, 0xfa, 0x9c, 0x88, 0x20, 0x39 }
37 UINTN DmaBufferCurrentTop
;
38 UINTN DmaBufferCurrentBottom
;
41 #define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
44 EDKII_IOMMU_OPERATION Operation
;
46 EFI_PHYSICAL_ADDRESS HostAddress
;
47 EFI_PHYSICAL_ADDRESS DeviceAddress
;
54 +------------------+ <=============== PHMR.Limit (+ alignment) (1 << (HostAddressWidth + 1))
58 +------------------+ <------- EfiMemoryTop
60 =========== +==================+ <=============== PHMR.Base
63 DMA Buffer | * DMA FREE * |
66 =========== +==================+ <=============== PLMR.Limit (+ alignment)
68 | -------------- | <------- EfiFreeMemoryTop
70 | -------------- | <------- EfiFreeMemoryBottom
74 +------------------+ <------- EfiMemoryBottom / Stack Bottom
82 +------------------+ <=============== PLMR.Base (0)
86 Set IOMMU attribute for a system memory.
88 If the IOMMU PPI exists, the system memory cannot be used
91 When a device requests a DMA access for a system memory,
92 the device driver need use SetAttribute() to update the IOMMU
93 attribute to request DMA access (read and/or write).
95 @param[in] This The PPI instance pointer.
96 @param[in] Mapping The mapping value returned from Map().
97 @param[in] IoMmuAccess The IOMMU access.
99 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
100 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
101 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
102 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
103 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
104 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
105 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
106 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
107 not available to be allocated yet.
112 PeiIoMmuSetAttribute (
113 IN EDKII_IOMMU_PPI
*This
,
115 IN UINT64 IoMmuAccess
119 DMA_BUFFER_INFO
*DmaBufferInfo
;
121 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
122 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
124 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
125 return EFI_NOT_AVAILABLE_YET
;
132 Provides the controller-specific addresses required to access system memory from a
135 @param This The PPI instance pointer.
136 @param Operation Indicates if the bus master is going to read or write to system memory.
137 @param HostAddress The system memory address to map to the PCI controller.
138 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
140 @param DeviceAddress The resulting map address for the bus master PCI controller to use to
141 access the hosts HostAddress.
142 @param Mapping A resulting value to pass to Unmap().
144 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
145 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
146 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
147 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
148 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
149 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
150 not available to be allocated yet.
156 IN EDKII_IOMMU_PPI
*This
,
157 IN EDKII_IOMMU_OPERATION Operation
,
158 IN VOID
*HostAddress
,
159 IN OUT UINTN
*NumberOfBytes
,
160 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
167 DMA_BUFFER_INFO
*DmaBufferInfo
;
169 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
170 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
172 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress
, *NumberOfBytes
));
173 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
174 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
176 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
177 return EFI_NOT_AVAILABLE_YET
;
180 if (Operation
== EdkiiIoMmuOperationBusMasterCommonBuffer
||
181 Operation
== EdkiiIoMmuOperationBusMasterCommonBuffer64
) {
182 *DeviceAddress
= (UINTN
)HostAddress
;
187 Length
= *NumberOfBytes
+ sizeof(MAP_INFO
);
188 if (Length
> DmaBufferInfo
->DmaBufferCurrentTop
- DmaBufferInfo
->DmaBufferCurrentBottom
) {
189 DEBUG ((DEBUG_ERROR
, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));
191 return EFI_OUT_OF_RESOURCES
;
194 *DeviceAddress
= DmaBufferInfo
->DmaBufferCurrentBottom
;
195 DmaBufferInfo
->DmaBufferCurrentBottom
+= Length
;
197 MapInfo
= (VOID
*)(UINTN
)(*DeviceAddress
+ *NumberOfBytes
);
198 MapInfo
->Signature
= MAP_INFO_SIGNATURE
;
199 MapInfo
->Operation
= Operation
;
200 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
201 MapInfo
->HostAddress
= (UINTN
)HostAddress
;
202 MapInfo
->DeviceAddress
= *DeviceAddress
;
204 DEBUG ((DEBUG_VERBOSE
, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation
, (UINTN
)*DeviceAddress
, MapInfo
));
207 // If this is a read operation from the Bus Master's point of view,
208 // then copy the contents of the real buffer into the mapped buffer
209 // so the Bus Master can read the contents of the real buffer.
211 if (Operation
== EdkiiIoMmuOperationBusMasterRead
||
212 Operation
== EdkiiIoMmuOperationBusMasterRead64
) {
214 (VOID
*) (UINTN
) MapInfo
->DeviceAddress
,
215 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
216 MapInfo
->NumberOfBytes
224 Completes the Map() operation and releases any corresponding resources.
226 @param This The PPI instance pointer.
227 @param Mapping The mapping value returned from Map().
229 @retval EFI_SUCCESS The range was unmapped.
230 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
231 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
232 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
233 not available to be allocated yet.
239 IN EDKII_IOMMU_PPI
*This
,
246 DMA_BUFFER_INFO
*DmaBufferInfo
;
248 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
249 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
251 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuUnmap - Mapping - %x\n", Mapping
));
252 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
253 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
255 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
256 return EFI_NOT_AVAILABLE_YET
;
259 if (Mapping
== NULL
) {
264 ASSERT (MapInfo
->Signature
== MAP_INFO_SIGNATURE
);
265 DEBUG ((DEBUG_VERBOSE
, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo
->Operation
, (UINTN
)MapInfo
->DeviceAddress
, MapInfo
->NumberOfBytes
));
268 // If this is a write operation from the Bus Master's point of view,
269 // then copy the contents of the mapped buffer into the real buffer
270 // so the processor can read the contents of the real buffer.
272 if (MapInfo
->Operation
== EdkiiIoMmuOperationBusMasterWrite
||
273 MapInfo
->Operation
== EdkiiIoMmuOperationBusMasterWrite64
) {
275 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
276 (VOID
*) (UINTN
) MapInfo
->DeviceAddress
,
277 MapInfo
->NumberOfBytes
281 Length
= MapInfo
->NumberOfBytes
+ sizeof(MAP_INFO
);
282 if (DmaBufferInfo
->DmaBufferCurrentBottom
== MapInfo
->DeviceAddress
+ Length
) {
283 DmaBufferInfo
->DmaBufferCurrentBottom
-= Length
;
290 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
291 OperationBusMasterCommonBuffer64 mapping.
293 @param This The PPI instance pointer.
294 @param MemoryType The type of memory to allocate, EfiBootServicesData or
295 EfiRuntimeServicesData.
296 @param Pages The number of pages to allocate.
297 @param HostAddress A pointer to store the base system memory address of the
299 @param Attributes The requested bit mask of attributes for the allocated range.
301 @retval EFI_SUCCESS The requested memory pages were allocated.
302 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
303 MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
304 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
305 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
306 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
307 not available to be allocated yet.
312 PeiIoMmuAllocateBuffer (
313 IN EDKII_IOMMU_PPI
*This
,
314 IN EFI_MEMORY_TYPE MemoryType
,
316 IN OUT VOID
**HostAddress
,
322 DMA_BUFFER_INFO
*DmaBufferInfo
;
324 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
325 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
327 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuAllocateBuffer - page - %x\n", Pages
));
328 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
329 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
331 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
332 return EFI_NOT_AVAILABLE_YET
;
335 Length
= EFI_PAGES_TO_SIZE(Pages
);
336 if (Length
> DmaBufferInfo
->DmaBufferCurrentTop
- DmaBufferInfo
->DmaBufferCurrentBottom
) {
337 DEBUG ((DEBUG_ERROR
, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));
339 return EFI_OUT_OF_RESOURCES
;
341 *HostAddress
= (VOID
*)(UINTN
)(DmaBufferInfo
->DmaBufferCurrentTop
- Length
);
342 DmaBufferInfo
->DmaBufferCurrentTop
-= Length
;
344 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress
));
349 Frees memory that was allocated with AllocateBuffer().
351 @param This The PPI instance pointer.
352 @param Pages The number of pages to free.
353 @param HostAddress The base system memory address of the allocated range.
355 @retval EFI_SUCCESS The requested memory pages were freed.
356 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
357 was not allocated with AllocateBuffer().
358 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
359 not available to be allocated yet.
365 IN EDKII_IOMMU_PPI
*This
,
372 DMA_BUFFER_INFO
*DmaBufferInfo
;
374 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
375 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
377 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages
, HostAddress
));
378 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
379 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
381 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
382 return EFI_NOT_AVAILABLE_YET
;
385 Length
= EFI_PAGES_TO_SIZE(Pages
);
386 if ((UINTN
)HostAddress
== DmaBufferInfo
->DmaBufferCurrentTop
) {
387 DmaBufferInfo
->DmaBufferCurrentTop
+= Length
;
393 EDKII_IOMMU_PPI mIoMmuPpi
= {
394 EDKII_IOMMU_PPI_REVISION
,
395 PeiIoMmuSetAttribute
,
398 PeiIoMmuAllocateBuffer
,
402 CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList
= {
403 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
409 Initialize DMA protection.
411 @param VTdInfo The VTd engine context information.
413 @retval EFI_SUCCESS the DMA protection is initialized.
414 @retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection.
422 UINT32 LowMemoryAlignment
;
423 UINT64 HighMemoryAlignment
;
424 UINTN MemoryAlignment
;
429 DMA_BUFFER_INFO
*DmaBufferInfo
;
431 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
432 EDKII_IOMMU_PPI
*OldIoMmuPpi
;
434 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
435 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
437 DEBUG ((DEBUG_INFO
, " DmaBufferSize : 0x%x\n", DmaBufferInfo
->DmaBufferSize
));
439 LowMemoryAlignment
= GetLowMemoryAlignment (VTdInfo
, VTdInfo
->EngineMask
);
440 HighMemoryAlignment
= GetHighMemoryAlignment (VTdInfo
, VTdInfo
->EngineMask
);
441 if (LowMemoryAlignment
< HighMemoryAlignment
) {
442 MemoryAlignment
= (UINTN
)HighMemoryAlignment
;
444 MemoryAlignment
= LowMemoryAlignment
;
446 ASSERT (DmaBufferInfo
->DmaBufferSize
== ALIGN_VALUE(DmaBufferInfo
->DmaBufferSize
, MemoryAlignment
));
447 DmaBufferInfo
->DmaBufferBase
= (UINTN
)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo
->DmaBufferSize
), MemoryAlignment
);
448 ASSERT (DmaBufferInfo
->DmaBufferBase
!= 0);
449 if (DmaBufferInfo
->DmaBufferBase
== 0) {
450 DEBUG ((DEBUG_INFO
, " InitDmaProtection : OutOfResource\n"));
451 return EFI_OUT_OF_RESOURCES
;
454 DEBUG ((DEBUG_INFO
, " DmaBufferBase : 0x%x\n", DmaBufferInfo
->DmaBufferBase
));
456 DmaBufferInfo
->DmaBufferCurrentTop
= DmaBufferInfo
->DmaBufferBase
+ DmaBufferInfo
->DmaBufferSize
;
457 DmaBufferInfo
->DmaBufferCurrentBottom
= DmaBufferInfo
->DmaBufferBase
;
462 Status
= PeiServicesLocatePpi (
466 (VOID
**) &OldIoMmuPpi
468 if (!EFI_ERROR (Status
)) {
469 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mIoMmuPpiList
);
471 Status
= PeiServicesInstallPpi (&mIoMmuPpiList
);
473 ASSERT_EFI_ERROR (Status
);
476 LowTop
= DmaBufferInfo
->DmaBufferBase
;
477 HighBottom
= DmaBufferInfo
->DmaBufferBase
+ DmaBufferInfo
->DmaBufferSize
;
478 HighTop
= LShiftU64 (1, VTdInfo
->HostAddressWidth
+ 1);
480 Status
= SetDmaProtectedRange (
484 (UINT32
)(LowTop
- LowBottom
),
489 if (EFI_ERROR(Status
)) {
490 FreePages ((VOID
*)DmaBufferInfo
->DmaBufferBase
, EFI_SIZE_TO_PAGES(DmaBufferInfo
->DmaBufferSize
));
497 Initializes the Intel VTd Info.
499 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
500 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
509 EFI_ACPI_DMAR_HEADER
*AcpiDmarTable
;
512 Status
= PeiServicesLocatePpi (
513 &gEdkiiVTdInfoPpiGuid
,
516 (VOID
**)&AcpiDmarTable
518 ASSERT_EFI_ERROR(Status
);
520 DumpAcpiDMAR (AcpiDmarTable
);
523 // Clear old VTdInfo Hob.
525 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
527 ZeroMem (&((EFI_HOB_GUID_TYPE
*)Hob
)->Name
, sizeof(EFI_GUID
));
531 // Get DMAR information to local VTdInfo
533 Status
= ParseDmarAcpiTableDrhd (AcpiDmarTable
);
534 if (EFI_ERROR(Status
)) {
539 // NOTE: Do not parse RMRR here, because RMRR may cause PMR programming.
546 Initializes the Intel VTd PMR for all memory.
548 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
549 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
565 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
566 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
571 HighTop
= LShiftU64 (1, VTdInfo
->HostAddressWidth
+ 1);
573 Status
= SetDmaProtectedRange (
577 (UINT32
)(LowTop
- LowBottom
),
586 Initializes the Intel VTd PMR for DMA buffer.
588 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
589 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
601 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
602 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
605 // If there is RMRR memory, parse it here.
607 ParseDmarAcpiTableRmrr (VTdInfo
);
610 // Allocate a range in PEI memory as DMA buffer
611 // Mark others to be DMA protected.
613 Status
= InitDmaProtection (VTdInfo
);
619 This function handles S3 resume task at the end of PEI
621 @param[in] PeiServices Pointer to PEI Services Table.
622 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
623 caused this function to execute.
624 @param[in] Ppi Pointer to the PPI data associated with this function.
626 @retval EFI_STATUS Always return EFI_SUCCESS
631 IN EFI_PEI_SERVICES
**PeiServices
,
632 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDesc
,
640 DEBUG((DEBUG_INFO
, "VTdPmr S3EndOfPeiNotify\n"));
642 if ((PcdGet8(PcdVTdPolicyPropertyMask
) & BIT1
) == 0) {
643 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
647 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
649 EngineMask
= LShiftU64 (1, VTdInfo
->VTdEngineCount
) - 1;
650 DisableDmaProtection (VTdInfo
, EngineMask
);
655 EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc
= {
656 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
657 &gEfiEndOfPeiSignalPpiGuid
,
662 This function handles VTd engine setup
664 @param[in] PeiServices Pointer to PEI Services Table.
665 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
666 caused this function to execute.
667 @param[in] Ppi Pointer to the PPI data associated with this function.
669 @retval EFI_STATUS Always return EFI_SUCCESS
674 IN EFI_PEI_SERVICES
**PeiServices
,
675 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDesc
,
680 VOID
*MemoryDiscovered
;
681 UINT64 EnabledEngineMask
;
684 BOOLEAN MemoryInitialized
;
686 DEBUG ((DEBUG_INFO
, "VTdInfoNotify\n"));
689 // Check if memory is initialized.
691 MemoryInitialized
= FALSE
;
692 Status
= PeiServicesLocatePpi (
693 &gEfiPeiMemoryDiscoveredPpiGuid
,
698 if (!EFI_ERROR(Status
)) {
699 MemoryInitialized
= TRUE
;
702 DEBUG ((DEBUG_INFO
, "MemoryInitialized - %x\n", MemoryInitialized
));
704 if (!MemoryInitialized
) {
706 // If the memory is not initialized,
707 // Protect all system memory
715 Status
= PeiServicesInstallPpi (&mIoMmuPpiList
);
716 ASSERT_EFI_ERROR(Status
);
719 // If the memory is initialized,
720 // Allocate DMA buffer and protect rest system memory
724 // NOTE: We need reinit VTdInfo because previous information might be overriden.
728 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
729 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
732 // NOTE: We need check if PMR is enabled or not.
734 EnabledEngineMask
= GetDmaProtectionEnabledEngineMask (VTdInfo
, VTdInfo
->EngineMask
);
735 if (EnabledEngineMask
!= 0) {
736 EnableVTdTranslationProtection (VTdInfo
, EnabledEngineMask
);
737 DisableDmaProtection (VTdInfo
, EnabledEngineMask
);
740 if (EnabledEngineMask
!= 0) {
741 DisableVTdTranslationProtection (VTdInfo
, EnabledEngineMask
);
749 EFI_PEI_NOTIFY_DESCRIPTOR mVTdInfoNotifyDesc
= {
750 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
751 &gEdkiiVTdInfoPpiGuid
,
756 Initializes the Intel VTd PMR PEIM.
758 @param FileHandle Handle of the file being invoked.
759 @param PeiServices Describes the list of possible PEI Services.
761 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
762 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
767 IntelVTdPmrInitialize (
768 IN EFI_PEI_FILE_HANDLE FileHandle
,
769 IN CONST EFI_PEI_SERVICES
**PeiServices
773 EFI_BOOT_MODE BootMode
;
774 DMA_BUFFER_INFO
*DmaBufferInfo
;
776 DEBUG ((DEBUG_INFO
, "IntelVTdPmrInitialize\n"));
778 if ((PcdGet8(PcdVTdPolicyPropertyMask
) & BIT0
) == 0) {
779 return EFI_UNSUPPORTED
;
782 DmaBufferInfo
= BuildGuidHob (&mDmaBufferInfoGuid
, sizeof(DMA_BUFFER_INFO
));
783 ASSERT(DmaBufferInfo
!= NULL
);
784 if (DmaBufferInfo
== NULL
) {
785 return EFI_OUT_OF_RESOURCES
;
787 ZeroMem (DmaBufferInfo
, sizeof(DMA_BUFFER_INFO
));
789 PeiServicesGetBootMode (&BootMode
);
791 if (BootMode
== BOOT_ON_S3_RESUME
) {
792 DmaBufferInfo
->DmaBufferSize
= PcdGet32 (PcdVTdPeiDmaBufferSizeS3
);
794 DmaBufferInfo
->DmaBufferSize
= PcdGet32 (PcdVTdPeiDmaBufferSize
);
797 Status
= PeiServicesNotifyPpi (&mVTdInfoNotifyDesc
);
798 ASSERT_EFI_ERROR (Status
);
801 // Register EndOfPei Notify for S3
803 if (BootMode
== BOOT_ON_S3_RESUME
) {
804 Status
= PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc
);
805 ASSERT_EFI_ERROR (Status
);