3 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License which accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PeiServicesLib.h>
23 #include <Library/HobLib.h>
24 #include <IndustryStandard/Vtd.h>
25 #include <Ppi/IoMmu.h>
26 #include <Ppi/VtdInfo.h>
27 #include <Ppi/MemoryDiscovered.h>
28 #include <Ppi/EndOfPeiPhase.h>
30 #include "IntelVTdPmrPei.h"
32 EFI_GUID mVTdInfoGuid
= {
33 0x222f5e30, 0x5cd, 0x49c6, { 0x8a, 0xc, 0x36, 0xd6, 0x58, 0x41, 0xe0, 0x82 }
36 EFI_GUID mDmaBufferInfoGuid
= {
37 0x7b624ec7, 0xfb67, 0x4f9c, { 0xb6, 0xb0, 0x4d, 0xfa, 0x9c, 0x88, 0x20, 0x39 }
43 UINTN DmaBufferCurrentTop
;
44 UINTN DmaBufferCurrentBottom
;
47 #define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
50 EDKII_IOMMU_OPERATION Operation
;
52 EFI_PHYSICAL_ADDRESS HostAddress
;
53 EFI_PHYSICAL_ADDRESS DeviceAddress
;
60 +------------------+ <=============== PHMR.Limit (+ alignment) (1 << (HostAddressWidth + 1))
64 +------------------+ <------- EfiMemoryTop
66 =========== +==================+ <=============== PHMR.Base
69 DMA Buffer | * DMA FREE * |
72 =========== +==================+ <=============== PLMR.Limit (+ alignment)
74 | -------------- | <------- EfiFreeMemoryTop
76 | -------------- | <------- EfiFreeMemoryBottom
80 +------------------+ <------- EfiMemoryBottom / Stack Bottom
88 +------------------+ <=============== PLMR.Base (0)
92 Set IOMMU attribute for a system memory.
94 If the IOMMU PPI exists, the system memory cannot be used
97 When a device requests a DMA access for a system memory,
98 the device driver need use SetAttribute() to update the IOMMU
99 attribute to request DMA access (read and/or write).
101 @param[in] This The PPI instance pointer.
102 @param[in] Mapping The mapping value returned from Map().
103 @param[in] IoMmuAccess The IOMMU access.
105 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
106 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
107 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
108 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
109 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
110 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
111 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
112 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
113 not available to be allocated yet.
118 PeiIoMmuSetAttribute (
119 IN EDKII_IOMMU_PPI
*This
,
121 IN UINT64 IoMmuAccess
125 DMA_BUFFER_INFO
*DmaBufferInfo
;
127 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
128 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
130 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
131 return EFI_NOT_AVAILABLE_YET
;
138 Provides the controller-specific addresses required to access system memory from a
141 @param This The PPI instance pointer.
142 @param Operation Indicates if the bus master is going to read or write to system memory.
143 @param HostAddress The system memory address to map to the PCI controller.
144 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
146 @param DeviceAddress The resulting map address for the bus master PCI controller to use to
147 access the hosts HostAddress.
148 @param Mapping A resulting value to pass to Unmap().
150 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
151 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
152 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
153 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
154 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
155 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
156 not available to be allocated yet.
162 IN EDKII_IOMMU_PPI
*This
,
163 IN EDKII_IOMMU_OPERATION Operation
,
164 IN VOID
*HostAddress
,
165 IN OUT UINTN
*NumberOfBytes
,
166 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
173 DMA_BUFFER_INFO
*DmaBufferInfo
;
175 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
176 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
178 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress
, *NumberOfBytes
));
179 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
180 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
182 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
183 return EFI_NOT_AVAILABLE_YET
;
186 if (Operation
== EdkiiIoMmuOperationBusMasterCommonBuffer
||
187 Operation
== EdkiiIoMmuOperationBusMasterCommonBuffer64
) {
188 *DeviceAddress
= (UINTN
)HostAddress
;
193 Length
= *NumberOfBytes
+ sizeof(MAP_INFO
);
194 if (Length
> DmaBufferInfo
->DmaBufferCurrentTop
- DmaBufferInfo
->DmaBufferCurrentBottom
) {
195 DEBUG ((DEBUG_ERROR
, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));
197 return EFI_OUT_OF_RESOURCES
;
200 *DeviceAddress
= DmaBufferInfo
->DmaBufferCurrentBottom
;
201 DmaBufferInfo
->DmaBufferCurrentBottom
+= Length
;
203 MapInfo
= (VOID
*)(UINTN
)(*DeviceAddress
+ *NumberOfBytes
);
204 MapInfo
->Signature
= MAP_INFO_SIGNATURE
;
205 MapInfo
->Operation
= Operation
;
206 MapInfo
->NumberOfBytes
= *NumberOfBytes
;
207 MapInfo
->HostAddress
= (UINTN
)HostAddress
;
208 MapInfo
->DeviceAddress
= *DeviceAddress
;
210 DEBUG ((DEBUG_VERBOSE
, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation
, (UINTN
)*DeviceAddress
, MapInfo
));
213 // If this is a read operation from the Bus Master's point of view,
214 // then copy the contents of the real buffer into the mapped buffer
215 // so the Bus Master can read the contents of the real buffer.
217 if (Operation
== EdkiiIoMmuOperationBusMasterRead
||
218 Operation
== EdkiiIoMmuOperationBusMasterRead64
) {
220 (VOID
*) (UINTN
) MapInfo
->DeviceAddress
,
221 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
222 MapInfo
->NumberOfBytes
230 Completes the Map() operation and releases any corresponding resources.
232 @param This The PPI instance pointer.
233 @param Mapping The mapping value returned from Map().
235 @retval EFI_SUCCESS The range was unmapped.
236 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
237 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
238 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
239 not available to be allocated yet.
245 IN EDKII_IOMMU_PPI
*This
,
252 DMA_BUFFER_INFO
*DmaBufferInfo
;
254 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
255 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
257 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuUnmap - Mapping - %x\n", Mapping
));
258 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
259 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
261 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
262 return EFI_NOT_AVAILABLE_YET
;
265 if (Mapping
== NULL
) {
270 ASSERT (MapInfo
->Signature
== MAP_INFO_SIGNATURE
);
271 DEBUG ((DEBUG_VERBOSE
, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo
->Operation
, (UINTN
)MapInfo
->DeviceAddress
, MapInfo
->NumberOfBytes
));
274 // If this is a write operation from the Bus Master's point of view,
275 // then copy the contents of the mapped buffer into the real buffer
276 // so the processor can read the contents of the real buffer.
278 if (MapInfo
->Operation
== EdkiiIoMmuOperationBusMasterWrite
||
279 MapInfo
->Operation
== EdkiiIoMmuOperationBusMasterWrite64
) {
281 (VOID
*) (UINTN
) MapInfo
->HostAddress
,
282 (VOID
*) (UINTN
) MapInfo
->DeviceAddress
,
283 MapInfo
->NumberOfBytes
287 Length
= MapInfo
->NumberOfBytes
+ sizeof(MAP_INFO
);
288 if (DmaBufferInfo
->DmaBufferCurrentBottom
== MapInfo
->DeviceAddress
+ Length
) {
289 DmaBufferInfo
->DmaBufferCurrentBottom
-= Length
;
296 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
297 OperationBusMasterCommonBuffer64 mapping.
299 @param This The PPI instance pointer.
300 @param MemoryType The type of memory to allocate, EfiBootServicesData or
301 EfiRuntimeServicesData.
302 @param Pages The number of pages to allocate.
303 @param HostAddress A pointer to store the base system memory address of the
305 @param Attributes The requested bit mask of attributes for the allocated range.
307 @retval EFI_SUCCESS The requested memory pages were allocated.
308 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
309 MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
310 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
311 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
312 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
313 not available to be allocated yet.
318 PeiIoMmuAllocateBuffer (
319 IN EDKII_IOMMU_PPI
*This
,
320 IN EFI_MEMORY_TYPE MemoryType
,
322 IN OUT VOID
**HostAddress
,
328 DMA_BUFFER_INFO
*DmaBufferInfo
;
330 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
331 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
333 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuAllocateBuffer - page - %x\n", Pages
));
334 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
335 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
337 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
338 return EFI_NOT_AVAILABLE_YET
;
341 Length
= EFI_PAGES_TO_SIZE(Pages
);
342 if (Length
> DmaBufferInfo
->DmaBufferCurrentTop
- DmaBufferInfo
->DmaBufferCurrentBottom
) {
343 DEBUG ((DEBUG_ERROR
, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));
345 return EFI_OUT_OF_RESOURCES
;
347 *HostAddress
= (VOID
*)(UINTN
)(DmaBufferInfo
->DmaBufferCurrentTop
- Length
);
348 DmaBufferInfo
->DmaBufferCurrentTop
-= Length
;
350 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress
));
355 Frees memory that was allocated with AllocateBuffer().
357 @param This The PPI instance pointer.
358 @param Pages The number of pages to free.
359 @param HostAddress The base system memory address of the allocated range.
361 @retval EFI_SUCCESS The requested memory pages were freed.
362 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
363 was not allocated with AllocateBuffer().
364 @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
365 not available to be allocated yet.
371 IN EDKII_IOMMU_PPI
*This
,
378 DMA_BUFFER_INFO
*DmaBufferInfo
;
380 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
381 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
383 DEBUG ((DEBUG_VERBOSE
, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages
, HostAddress
));
384 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentTop - %x\n", DmaBufferInfo
->DmaBufferCurrentTop
));
385 DEBUG ((DEBUG_VERBOSE
, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo
->DmaBufferCurrentBottom
));
387 if (DmaBufferInfo
->DmaBufferCurrentTop
== 0) {
388 return EFI_NOT_AVAILABLE_YET
;
391 Length
= EFI_PAGES_TO_SIZE(Pages
);
392 if ((UINTN
)HostAddress
== DmaBufferInfo
->DmaBufferCurrentTop
) {
393 DmaBufferInfo
->DmaBufferCurrentTop
+= Length
;
399 EDKII_IOMMU_PPI mIoMmuPpi
= {
400 EDKII_IOMMU_PPI_REVISION
,
401 PeiIoMmuSetAttribute
,
404 PeiIoMmuAllocateBuffer
,
408 CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList
= {
409 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
415 Initialize DMA protection.
417 @param VTdInfo The VTd engine context information.
419 @retval EFI_SUCCESS the DMA protection is initialized.
420 @retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection.
428 UINT32 LowMemoryAlignment
;
429 UINT64 HighMemoryAlignment
;
430 UINTN MemoryAlignment
;
435 DMA_BUFFER_INFO
*DmaBufferInfo
;
437 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
438 EDKII_IOMMU_PPI
*OldIoMmuPpi
;
440 Hob
= GetFirstGuidHob (&mDmaBufferInfoGuid
);
441 DmaBufferInfo
= GET_GUID_HOB_DATA(Hob
);
443 DEBUG ((DEBUG_INFO
, " DmaBufferSize : 0x%x\n", DmaBufferInfo
->DmaBufferSize
));
445 LowMemoryAlignment
= GetLowMemoryAlignment (VTdInfo
, VTdInfo
->EngineMask
);
446 HighMemoryAlignment
= GetHighMemoryAlignment (VTdInfo
, VTdInfo
->EngineMask
);
447 if (LowMemoryAlignment
< HighMemoryAlignment
) {
448 MemoryAlignment
= (UINTN
)HighMemoryAlignment
;
450 MemoryAlignment
= LowMemoryAlignment
;
452 ASSERT (DmaBufferInfo
->DmaBufferSize
== ALIGN_VALUE(DmaBufferInfo
->DmaBufferSize
, MemoryAlignment
));
453 DmaBufferInfo
->DmaBufferBase
= (UINTN
)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo
->DmaBufferSize
), MemoryAlignment
);
454 ASSERT (DmaBufferInfo
->DmaBufferBase
!= 0);
455 if (DmaBufferInfo
->DmaBufferBase
== 0) {
456 DEBUG ((DEBUG_INFO
, " InitDmaProtection : OutOfResource\n"));
457 return EFI_OUT_OF_RESOURCES
;
460 DEBUG ((DEBUG_INFO
, " DmaBufferBase : 0x%x\n", DmaBufferInfo
->DmaBufferBase
));
462 DmaBufferInfo
->DmaBufferCurrentTop
= DmaBufferInfo
->DmaBufferBase
+ DmaBufferInfo
->DmaBufferSize
;
463 DmaBufferInfo
->DmaBufferCurrentBottom
= DmaBufferInfo
->DmaBufferBase
;
468 Status
= PeiServicesLocatePpi (
472 (VOID
**) &OldIoMmuPpi
474 if (!EFI_ERROR (Status
)) {
475 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mIoMmuPpiList
);
477 Status
= PeiServicesInstallPpi (&mIoMmuPpiList
);
479 ASSERT_EFI_ERROR (Status
);
482 LowTop
= DmaBufferInfo
->DmaBufferBase
;
483 HighBottom
= DmaBufferInfo
->DmaBufferBase
+ DmaBufferInfo
->DmaBufferSize
;
484 HighTop
= LShiftU64 (1, VTdInfo
->HostAddressWidth
+ 1);
486 Status
= SetDmaProtectedRange (
490 (UINT32
)(LowTop
- LowBottom
),
495 if (EFI_ERROR(Status
)) {
496 FreePages ((VOID
*)DmaBufferInfo
->DmaBufferBase
, EFI_SIZE_TO_PAGES(DmaBufferInfo
->DmaBufferSize
));
503 Initializes the Intel VTd Info.
505 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
506 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
515 EFI_ACPI_DMAR_HEADER
*AcpiDmarTable
;
518 Status
= PeiServicesLocatePpi (
519 &gEdkiiVTdInfoPpiGuid
,
522 (VOID
**)&AcpiDmarTable
524 ASSERT_EFI_ERROR(Status
);
526 DumpAcpiDMAR (AcpiDmarTable
);
529 // Clear old VTdInfo Hob.
531 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
533 ZeroMem (&((EFI_HOB_GUID_TYPE
*)Hob
)->Name
, sizeof(EFI_GUID
));
537 // Get DMAR information to local VTdInfo
539 Status
= ParseDmarAcpiTableDrhd (AcpiDmarTable
);
540 if (EFI_ERROR(Status
)) {
545 // NOTE: Do not parse RMRR here, because RMRR may cause PMR programming.
552 Initializes the Intel VTd PMR for all memory.
554 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
555 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
571 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
572 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
577 HighTop
= LShiftU64 (1, VTdInfo
->HostAddressWidth
+ 1);
579 Status
= SetDmaProtectedRange (
583 (UINT32
)(LowTop
- LowBottom
),
592 Initializes the Intel VTd PMR for DMA buffer.
594 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
595 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
607 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
608 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
611 // If there is RMRR memory, parse it here.
613 ParseDmarAcpiTableRmrr (VTdInfo
);
616 // Allocate a range in PEI memory as DMA buffer
617 // Mark others to be DMA protected.
619 Status
= InitDmaProtection (VTdInfo
);
625 This function handles S3 resume task at the end of PEI
627 @param[in] PeiServices Pointer to PEI Services Table.
628 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
629 caused this function to execute.
630 @param[in] Ppi Pointer to the PPI data associated with this function.
632 @retval EFI_STATUS Always return EFI_SUCCESS
637 IN EFI_PEI_SERVICES
**PeiServices
,
638 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDesc
,
646 DEBUG((DEBUG_INFO
, "VTdPmr S3EndOfPeiNotify\n"));
648 if ((PcdGet8(PcdVTdPolicyPropertyMask
) & BIT1
) == 0) {
649 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
653 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
655 EngineMask
= LShiftU64 (1, VTdInfo
->VTdEngineCount
) - 1;
656 DisableDmaProtection (VTdInfo
, EngineMask
);
661 EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc
= {
662 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
663 &gEfiEndOfPeiSignalPpiGuid
,
668 This function handles VTd engine setup
670 @param[in] PeiServices Pointer to PEI Services Table.
671 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
672 caused this function to execute.
673 @param[in] Ppi Pointer to the PPI data associated with this function.
675 @retval EFI_STATUS Always return EFI_SUCCESS
680 IN EFI_PEI_SERVICES
**PeiServices
,
681 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDesc
,
686 VOID
*MemoryDiscovered
;
687 UINT64 EnabledEngineMask
;
690 BOOLEAN MemoryInitialized
;
692 DEBUG ((DEBUG_INFO
, "VTdInfoNotify\n"));
695 // Check if memory is initialized.
697 MemoryInitialized
= FALSE
;
698 Status
= PeiServicesLocatePpi (
699 &gEfiPeiMemoryDiscoveredPpiGuid
,
704 if (!EFI_ERROR(Status
)) {
705 MemoryInitialized
= TRUE
;
708 DEBUG ((DEBUG_INFO
, "MemoryInitialized - %x\n", MemoryInitialized
));
710 if (!MemoryInitialized
) {
712 // If the memory is not initialized,
713 // Protect all system memory
721 Status
= PeiServicesInstallPpi (&mIoMmuPpiList
);
722 ASSERT_EFI_ERROR(Status
);
725 // If the memory is initialized,
726 // Allocate DMA buffer and protect rest system memory
730 // NOTE: We need reinit VTdInfo because previous information might be overriden.
734 Hob
= GetFirstGuidHob (&mVTdInfoGuid
);
735 VTdInfo
= GET_GUID_HOB_DATA(Hob
);
738 // NOTE: We need check if PMR is enabled or not.
740 EnabledEngineMask
= GetDmaProtectionEnabledEngineMask (VTdInfo
, VTdInfo
->EngineMask
);
741 if (EnabledEngineMask
!= 0) {
742 EnableVTdTranslationProtection (VTdInfo
, EnabledEngineMask
);
743 DisableDmaProtection (VTdInfo
, EnabledEngineMask
);
746 if (EnabledEngineMask
!= 0) {
747 DisableVTdTranslationProtection (VTdInfo
, EnabledEngineMask
);
755 EFI_PEI_NOTIFY_DESCRIPTOR mVTdInfoNotifyDesc
= {
756 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
757 &gEdkiiVTdInfoPpiGuid
,
762 Initializes the Intel VTd PMR PEIM.
764 @param FileHandle Handle of the file being invoked.
765 @param PeiServices Describes the list of possible PEI Services.
767 @retval EFI_SUCCESS Usb bot driver is successfully initialized.
768 @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
773 IntelVTdPmrInitialize (
774 IN EFI_PEI_FILE_HANDLE FileHandle
,
775 IN CONST EFI_PEI_SERVICES
**PeiServices
779 EFI_BOOT_MODE BootMode
;
780 DMA_BUFFER_INFO
*DmaBufferInfo
;
782 DEBUG ((DEBUG_INFO
, "IntelVTdPmrInitialize\n"));
784 if ((PcdGet8(PcdVTdPolicyPropertyMask
) & BIT0
) == 0) {
785 return EFI_UNSUPPORTED
;
788 DmaBufferInfo
= BuildGuidHob (&mDmaBufferInfoGuid
, sizeof(DMA_BUFFER_INFO
));
789 ASSERT(DmaBufferInfo
!= NULL
);
790 if (DmaBufferInfo
== NULL
) {
791 return EFI_OUT_OF_RESOURCES
;
793 ZeroMem (DmaBufferInfo
, sizeof(DMA_BUFFER_INFO
));
795 PeiServicesGetBootMode (&BootMode
);
797 if (BootMode
== BOOT_ON_S3_RESUME
) {
798 DmaBufferInfo
->DmaBufferSize
= PcdGet32 (PcdVTdPeiDmaBufferSizeS3
);
800 DmaBufferInfo
->DmaBufferSize
= PcdGet32 (PcdVTdPeiDmaBufferSize
);
803 Status
= PeiServicesNotifyPpi (&mVTdInfoNotifyDesc
);
804 ASSERT_EFI_ERROR (Status
);
807 // Register EndOfPei Notify for S3
809 if (BootMode
== BOOT_ON_S3_RESUME
) {
810 Status
= PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc
);
811 ASSERT_EFI_ERROR (Status
);