3 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "DmaProtection.h"
13 EFI_ACPI_DESCRIPTION_HEADER Header
;
18 EFI_ACPI_DESCRIPTION_HEADER Header
;
24 EFI_ACPI_DMAR_HEADER
*mAcpiDmarTable
= NULL
;
27 Dump DMAR DeviceScopeEntry.
29 @param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry
32 DumpDmarDeviceScopeEntry (
33 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
38 EFI_ACPI_DMAR_PCI_PATH
*PciPath
;
40 if (DmarDeviceScopeEntry
== NULL
) {
45 " *************************************************************************\n"
48 " * DMA-Remapping Device Scope Entry Structure *\n"
51 " *************************************************************************\n"
54 (sizeof(UINTN
) == sizeof(UINT64
)) ?
55 " DMAR Device Scope Entry address ...................... 0x%016lx\n" :
56 " DMAR Device Scope Entry address ...................... 0x%08x\n",
60 " Device Scope Entry Type ............................ 0x%02x\n",
61 DmarDeviceScopeEntry
->Type
63 switch (DmarDeviceScopeEntry
->Type
) {
64 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
66 " PCI Endpoint Device\n"
69 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
74 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
79 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
84 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
86 " ACPI Namespace Device\n"
93 " Length ............................................. 0x%02x\n",
94 DmarDeviceScopeEntry
->Length
97 " Enumeration ID ..................................... 0x%02x\n",
98 DmarDeviceScopeEntry
->EnumerationId
101 " Starting Bus Number ................................ 0x%02x\n",
102 DmarDeviceScopeEntry
->StartBusNumber
105 PciPathNumber
= (DmarDeviceScopeEntry
->Length
- sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
)) / sizeof(EFI_ACPI_DMAR_PCI_PATH
);
106 PciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)(DmarDeviceScopeEntry
+ 1);
107 for (PciPathIndex
= 0; PciPathIndex
< PciPathNumber
; PciPathIndex
++) {
109 " Device ............................................. 0x%02x\n",
110 PciPath
[PciPathIndex
].Device
113 " Function ........................................... 0x%02x\n",
114 PciPath
[PciPathIndex
].Function
119 " *************************************************************************\n\n"
126 Dump DMAR ANDD table.
128 @param[in] Andd DMAR ANDD table
132 IN EFI_ACPI_DMAR_ANDD_HEADER
*Andd
140 " ***************************************************************************\n"
143 " * ACPI Name-space Device Declaration Structure *\n"
146 " ***************************************************************************\n"
149 (sizeof(UINTN
) == sizeof(UINT64
)) ?
150 " ANDD address ........................................... 0x%016lx\n" :
151 " ANDD address ........................................... 0x%08x\n",
155 " Type ................................................. 0x%04x\n",
159 " Length ............................................... 0x%04x\n",
163 " ACPI Device Number ................................... 0x%02x\n",
164 Andd
->AcpiDeviceNumber
167 " ACPI Object Name ..................................... '%a'\n",
172 " ***************************************************************************\n\n"
179 Dump DMAR RHSA table.
181 @param[in] Rhsa DMAR RHSA table
185 IN EFI_ACPI_DMAR_RHSA_HEADER
*Rhsa
193 " ***************************************************************************\n"
196 " * Remapping Hardware Status Affinity Structure *\n"
199 " ***************************************************************************\n"
202 (sizeof(UINTN
) == sizeof(UINT64
)) ?
203 " RHSA address ........................................... 0x%016lx\n" :
204 " RHSA address ........................................... 0x%08x\n",
208 " Type ................................................. 0x%04x\n",
212 " Length ............................................... 0x%04x\n",
216 " Register Base Address ................................ 0x%016lx\n",
217 Rhsa
->RegisterBaseAddress
220 " Proximity Domain ..................................... 0x%08x\n",
221 Rhsa
->ProximityDomain
225 " ***************************************************************************\n\n"
232 Dump DMAR ATSR table.
234 @param[in] Atsr DMAR ATSR table
238 IN EFI_ACPI_DMAR_ATSR_HEADER
*Atsr
241 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
249 " ***************************************************************************\n"
252 " * Root Port ATS Capability Reporting Structure *\n"
255 " ***************************************************************************\n"
258 (sizeof(UINTN
) == sizeof(UINT64
)) ?
259 " ATSR address ........................................... 0x%016lx\n" :
260 " ATSR address ........................................... 0x%08x\n",
264 " Type ................................................. 0x%04x\n",
268 " Length ............................................... 0x%04x\n",
272 " Flags ................................................ 0x%02x\n",
276 " ALL_PORTS .......................................... 0x%02x\n",
277 Atsr
->Flags
& EFI_ACPI_DMAR_ATSR_FLAGS_ALL_PORTS
280 " Segment Number ....................................... 0x%04x\n",
284 AtsrLen
= Atsr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_ATSR_HEADER
);
285 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Atsr
+ 1);
286 while (AtsrLen
> 0) {
287 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
288 AtsrLen
-= DmarDeviceScopeEntry
->Length
;
289 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
293 " ***************************************************************************\n\n"
300 Dump DMAR RMRR table.
302 @param[in] Rmrr DMAR RMRR table
306 IN EFI_ACPI_DMAR_RMRR_HEADER
*Rmrr
309 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
317 " ***************************************************************************\n"
320 " * Reserved Memory Region Reporting Structure *\n"
323 " ***************************************************************************\n"
326 (sizeof(UINTN
) == sizeof(UINT64
)) ?
327 " RMRR address ........................................... 0x%016lx\n" :
328 " RMRR address ........................................... 0x%08x\n",
332 " Type ................................................. 0x%04x\n",
336 " Length ............................................... 0x%04x\n",
340 " Segment Number ....................................... 0x%04x\n",
344 " Reserved Memory Region Base Address .................. 0x%016lx\n",
345 Rmrr
->ReservedMemoryRegionBaseAddress
348 " Reserved Memory Region Limit Address ................. 0x%016lx\n",
349 Rmrr
->ReservedMemoryRegionLimitAddress
352 RmrrLen
= Rmrr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_RMRR_HEADER
);
353 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Rmrr
+ 1);
354 while (RmrrLen
> 0) {
355 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
356 RmrrLen
-= DmarDeviceScopeEntry
->Length
;
357 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
361 " ***************************************************************************\n\n"
368 Dump DMAR DRHD table.
370 @param[in] Drhd DMAR DRHD table
374 IN EFI_ACPI_DMAR_DRHD_HEADER
*Drhd
377 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
385 " ***************************************************************************\n"
388 " * DMA-Remapping Hardware Definition Structure *\n"
391 " ***************************************************************************\n"
394 (sizeof(UINTN
) == sizeof(UINT64
)) ?
395 " DRHD address ........................................... 0x%016lx\n" :
396 " DRHD address ........................................... 0x%08x\n",
400 " Type ................................................. 0x%04x\n",
404 " Length ............................................... 0x%04x\n",
408 " Flags ................................................ 0x%02x\n",
412 " INCLUDE_PCI_ALL .................................... 0x%02x\n",
413 Drhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
416 " Segment Number ....................................... 0x%04x\n",
420 " Register Base Address ................................ 0x%016lx\n",
421 Drhd
->RegisterBaseAddress
424 DrhdLen
= Drhd
->Header
.Length
- sizeof(EFI_ACPI_DMAR_DRHD_HEADER
);
425 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Drhd
+ 1);
426 while (DrhdLen
> 0) {
427 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
428 DrhdLen
-= DmarDeviceScopeEntry
->Length
;
429 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
433 " ***************************************************************************\n\n"
440 Dump DMAR ACPI table.
442 @param[in] Dmar DMAR ACPI table
446 IN EFI_ACPI_DMAR_HEADER
*Dmar
449 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
460 "*****************************************************************************\n"
466 "*****************************************************************************\n"
470 (sizeof(UINTN
) == sizeof(UINT64
)) ?
471 "DMAR address ............................................. 0x%016lx\n" :
472 "DMAR address ............................................. 0x%08x\n",
480 " Host Address Width ................................... 0x%02x\n",
481 Dmar
->HostAddressWidth
484 " Flags ................................................ 0x%02x\n",
488 " INTR_REMAP ......................................... 0x%02x\n",
489 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_INTR_REMAP
492 " X2APIC_OPT_OUT_SET ................................. 0x%02x\n",
493 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT
496 " DMA_CTRL_PLATFORM_OPT_IN_FLAG ...................... 0x%02x\n",
497 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_DMA_CTRL_PLATFORM_OPT_IN_FLAG
500 DmarLen
= Dmar
->Header
.Length
- sizeof(EFI_ACPI_DMAR_HEADER
);
501 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)(Dmar
+ 1);
502 while (DmarLen
> 0) {
503 switch (DmarHeader
->Type
) {
504 case EFI_ACPI_DMAR_TYPE_DRHD
:
505 DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
507 case EFI_ACPI_DMAR_TYPE_RMRR
:
508 DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
510 case EFI_ACPI_DMAR_TYPE_ATSR
:
511 DumpDmarAtsr ((EFI_ACPI_DMAR_ATSR_HEADER
*)DmarHeader
);
513 case EFI_ACPI_DMAR_TYPE_RHSA
:
514 DumpDmarRhsa ((EFI_ACPI_DMAR_RHSA_HEADER
*)DmarHeader
);
516 case EFI_ACPI_DMAR_TYPE_ANDD
:
517 DumpDmarAndd ((EFI_ACPI_DMAR_ANDD_HEADER
*)DmarHeader
);
522 DmarLen
-= DmarHeader
->Length
;
523 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
527 "*****************************************************************************\n\n"
534 Dump DMAR ACPI table.
541 DumpAcpiDMAR ((EFI_ACPI_DMAR_HEADER
*)(UINTN
)mAcpiDmarTable
);
545 Get PCI device information from DMAR DevScopeEntry.
547 @param[in] Segment The segment number.
548 @param[in] DmarDevScopeEntry DMAR DevScopeEntry
549 @param[out] Bus The bus number.
550 @param[out] Device The device number.
551 @param[out] Function The function number.
553 @retval EFI_SUCCESS The PCI device information is returned.
556 GetPciBusDeviceFunction (
558 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
,
564 EFI_ACPI_DMAR_PCI_PATH
*DmarPciPath
;
569 DmarPciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)((UINTN
)(DmarDevScopeEntry
+ 1));
570 MyBus
= DmarDevScopeEntry
->StartBusNumber
;
571 MyDevice
= DmarPciPath
->Device
;
572 MyFunction
= DmarPciPath
->Function
;
574 switch (DmarDevScopeEntry
->Type
) {
575 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
576 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
577 while ((UINTN
)DmarPciPath
+ sizeof(EFI_ACPI_DMAR_PCI_PATH
) < (UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
) {
578 MyBus
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment
, MyBus
, MyDevice
, MyFunction
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
580 MyDevice
= DmarPciPath
->Device
;
581 MyFunction
= DmarPciPath
->Function
;
584 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
585 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
586 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
592 *Function
= MyFunction
;
598 Process DMAR DHRD table.
600 @param[in] VtdIndex The index of VTd engine.
601 @param[in] DmarDrhd The DRHD table.
603 @retval EFI_SUCCESS The DRHD table is processed.
608 IN EFI_ACPI_DMAR_DRHD_HEADER
*DmarDrhd
611 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
615 UINT8 SecondaryBusNumber
;
617 VTD_SOURCE_ID SourceId
;
619 mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
= (UINTN
)DmarDrhd
->RegisterBaseAddress
;
620 DEBUG ((DEBUG_INFO
," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex
, DmarDrhd
->RegisterBaseAddress
));
622 mVtdUnitInformation
[VtdIndex
].Segment
= DmarDrhd
->SegmentNumber
;
624 if ((DmarDrhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
) != 0) {
625 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= TRUE
;
626 DEBUG ((DEBUG_INFO
," ProcessDhrd: with INCLUDE ALL\n"));
628 Status
= ScanPciBus((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, 0, ScanBusCallbackRegisterPciDevice
);
629 if (EFI_ERROR (Status
)) {
633 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= FALSE
;
634 DEBUG ((DEBUG_INFO
," ProcessDhrd: without INCLUDE ALL\n"));
637 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarDrhd
+ 1));
638 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarDrhd
+ DmarDrhd
->Header
.Length
) {
640 Status
= GetPciBusDeviceFunction (DmarDrhd
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
641 if (EFI_ERROR (Status
)) {
645 DEBUG ((DEBUG_INFO
," ProcessDhrd: "));
646 switch (DmarDevScopeEntry
->Type
) {
647 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
648 DEBUG ((DEBUG_INFO
,"PCI Endpoint"));
650 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
651 DEBUG ((DEBUG_INFO
,"PCI-PCI bridge"));
653 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
654 DEBUG ((DEBUG_INFO
,"IOAPIC"));
656 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
657 DEBUG ((DEBUG_INFO
,"MSI Capable HPET"));
659 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
660 DEBUG ((DEBUG_INFO
,"ACPI Namespace Device"));
663 DEBUG ((DEBUG_INFO
," S%04x B%02x D%02x F%02x\n", DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
));
665 SourceId
.Bits
.Bus
= Bus
;
666 SourceId
.Bits
.Device
= Device
;
667 SourceId
.Bits
.Function
= Function
;
669 Status
= RegisterPciDevice (VtdIndex
, DmarDrhd
->SegmentNumber
, SourceId
, DmarDevScopeEntry
->Type
, TRUE
);
670 if (EFI_ERROR (Status
)) {
672 // There might be duplication for special device other than standard PCI device.
674 switch (DmarDevScopeEntry
->Type
) {
675 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
676 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
681 switch (DmarDevScopeEntry
->Type
) {
682 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
683 SecondaryBusNumber
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
684 Status
= ScanPciBus ((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, SecondaryBusNumber
, ScanBusCallbackRegisterPciDevice
);
685 if (EFI_ERROR (Status
)) {
693 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
700 Process DMAR RMRR table.
702 @param[in] DmarRmrr The RMRR table.
704 @retval EFI_SUCCESS The RMRR table is processed.
708 IN EFI_ACPI_DMAR_RMRR_HEADER
*DmarRmrr
711 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
716 VTD_SOURCE_ID SourceId
;
718 DEBUG ((DEBUG_INFO
," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr
->ReservedMemoryRegionBaseAddress
, DmarRmrr
->ReservedMemoryRegionLimitAddress
));
720 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarRmrr
+ 1));
721 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarRmrr
+ DmarRmrr
->Header
.Length
) {
722 if (DmarDevScopeEntry
->Type
!= EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
) {
723 DEBUG ((DEBUG_INFO
,"RMRR DevScopeEntryType is not endpoint, type[0x%x] \n", DmarDevScopeEntry
->Type
));
724 return EFI_DEVICE_ERROR
;
727 Status
= GetPciBusDeviceFunction (DmarRmrr
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
728 if (EFI_ERROR (Status
)) {
732 DEBUG ((DEBUG_INFO
,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr
->SegmentNumber
, Bus
, Device
, Function
));
734 SourceId
.Bits
.Bus
= Bus
;
735 SourceId
.Bits
.Device
= Device
;
736 SourceId
.Bits
.Function
= Function
;
737 Status
= SetAccessAttribute (
738 DmarRmrr
->SegmentNumber
,
740 DmarRmrr
->ReservedMemoryRegionBaseAddress
,
741 DmarRmrr
->ReservedMemoryRegionLimitAddress
+ 1 - DmarRmrr
->ReservedMemoryRegionBaseAddress
,
742 EDKII_IOMMU_ACCESS_READ
| EDKII_IOMMU_ACCESS_WRITE
744 if (EFI_ERROR (Status
)) {
748 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
755 Get VTd engine number.
762 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
766 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
767 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
768 switch (DmarHeader
->Type
) {
769 case EFI_ACPI_DMAR_TYPE_DRHD
:
775 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
781 Parse DMAR DRHD table.
783 @return EFI_SUCCESS The DMAR DRHD table is parsed.
786 ParseDmarAcpiTableDrhd (
790 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
794 mVtdUnitNumber
= GetVtdEngineNumber ();
795 DEBUG ((DEBUG_INFO
," VtdUnitNumber - %d\n", mVtdUnitNumber
));
796 ASSERT (mVtdUnitNumber
> 0);
797 if (mVtdUnitNumber
== 0) {
798 return EFI_DEVICE_ERROR
;
801 mVtdUnitInformation
= AllocateZeroPool (sizeof(*mVtdUnitInformation
) * mVtdUnitNumber
);
802 ASSERT (mVtdUnitInformation
!= NULL
);
803 if (mVtdUnitInformation
== NULL
) {
804 return EFI_OUT_OF_RESOURCES
;
808 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
809 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
810 switch (DmarHeader
->Type
) {
811 case EFI_ACPI_DMAR_TYPE_DRHD
:
812 ASSERT (VtdIndex
< mVtdUnitNumber
);
813 Status
= ProcessDhrd (VtdIndex
, (EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
814 if (EFI_ERROR (Status
)) {
824 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
826 ASSERT (VtdIndex
== mVtdUnitNumber
);
828 for (VtdIndex
= 0; VtdIndex
< mVtdUnitNumber
; VtdIndex
++) {
829 DumpPciDeviceInfo (VtdIndex
);
835 Parse DMAR DRHD table.
837 @return EFI_SUCCESS The DMAR DRHD table is parsed.
840 ParseDmarAcpiTableRmrr (
844 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
847 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
848 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
849 switch (DmarHeader
->Type
) {
850 case EFI_ACPI_DMAR_TYPE_RMRR
:
851 Status
= ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
852 if (EFI_ERROR (Status
)) {
859 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
865 Get the DMAR ACPI table.
867 @retval EFI_SUCCESS The DMAR ACPI table is got.
868 @retval EFI_ALREADY_STARTED The DMAR ACPI table has been got previously.
869 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.
876 if (mAcpiDmarTable
!= NULL
) {
877 return EFI_ALREADY_STARTED
;
880 mAcpiDmarTable
= (EFI_ACPI_DMAR_HEADER
*) EfiLocateFirstAcpiTable (
881 EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE
883 if (mAcpiDmarTable
== NULL
) {
884 return EFI_NOT_FOUND
;
886 DEBUG ((DEBUG_INFO
,"DMAR Table - 0x%08x\n", mAcpiDmarTable
));