3 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #include "DmaProtection.h"
19 EFI_ACPI_DESCRIPTION_HEADER Header
;
24 EFI_ACPI_DESCRIPTION_HEADER Header
;
30 EFI_ACPI_DMAR_HEADER
*mAcpiDmarTable
= NULL
;
33 Dump DMAR DeviceScopeEntry.
35 @param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry
38 DumpDmarDeviceScopeEntry (
39 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
44 EFI_ACPI_DMAR_PCI_PATH
*PciPath
;
46 if (DmarDeviceScopeEntry
== NULL
) {
51 " *************************************************************************\n"
54 " * DMA-Remapping Device Scope Entry Structure *\n"
57 " *************************************************************************\n"
60 (sizeof(UINTN
) == sizeof(UINT64
)) ?
61 " DMAR Device Scope Entry address ...................... 0x%016lx\n" :
62 " DMAR Device Scope Entry address ...................... 0x%08x\n",
66 " Device Scope Entry Type ............................ 0x%02x\n",
67 DmarDeviceScopeEntry
->Type
69 switch (DmarDeviceScopeEntry
->Type
) {
70 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
72 " PCI Endpoint Device\n"
75 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
80 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
85 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
90 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
92 " ACPI Namespace Device\n"
99 " Length ............................................. 0x%02x\n",
100 DmarDeviceScopeEntry
->Length
103 " Enumeration ID ..................................... 0x%02x\n",
104 DmarDeviceScopeEntry
->EnumerationId
107 " Starting Bus Number ................................ 0x%02x\n",
108 DmarDeviceScopeEntry
->StartBusNumber
111 PciPathNumber
= (DmarDeviceScopeEntry
->Length
- sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
)) / sizeof(EFI_ACPI_DMAR_PCI_PATH
);
112 PciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)(DmarDeviceScopeEntry
+ 1);
113 for (PciPathIndex
= 0; PciPathIndex
< PciPathNumber
; PciPathIndex
++) {
115 " Device ............................................. 0x%02x\n",
116 PciPath
[PciPathIndex
].Device
119 " Function ........................................... 0x%02x\n",
120 PciPath
[PciPathIndex
].Function
125 " *************************************************************************\n\n"
132 Dump DMAR ANDD table.
134 @param[in] Andd DMAR ANDD table
138 IN EFI_ACPI_DMAR_ANDD_HEADER
*Andd
146 " ***************************************************************************\n"
149 " * ACPI Name-space Device Declaration Structure *\n"
152 " ***************************************************************************\n"
155 (sizeof(UINTN
) == sizeof(UINT64
)) ?
156 " ANDD address ........................................... 0x%016lx\n" :
157 " ANDD address ........................................... 0x%08x\n",
161 " Type ................................................. 0x%04x\n",
165 " Length ............................................... 0x%04x\n",
169 " ACPI Device Number ................................... 0x%02x\n",
170 Andd
->AcpiDeviceNumber
173 " ACPI Object Name ..................................... '%a'\n",
178 " ***************************************************************************\n\n"
185 Dump DMAR RHSA table.
187 @param[in] Rhsa DMAR RHSA table
191 IN EFI_ACPI_DMAR_RHSA_HEADER
*Rhsa
199 " ***************************************************************************\n"
202 " * Remapping Hardware Status Affinity Structure *\n"
205 " ***************************************************************************\n"
208 (sizeof(UINTN
) == sizeof(UINT64
)) ?
209 " RHSA address ........................................... 0x%016lx\n" :
210 " RHSA address ........................................... 0x%08x\n",
214 " Type ................................................. 0x%04x\n",
218 " Length ............................................... 0x%04x\n",
222 " Register Base Address ................................ 0x%016lx\n",
223 Rhsa
->RegisterBaseAddress
226 " Proximity Domain ..................................... 0x%08x\n",
227 Rhsa
->ProximityDomain
231 " ***************************************************************************\n\n"
238 Dump DMAR ATSR table.
240 @param[in] Atsr DMAR ATSR table
244 IN EFI_ACPI_DMAR_ATSR_HEADER
*Atsr
247 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
255 " ***************************************************************************\n"
258 " * Root Port ATS Capability Reporting Structure *\n"
261 " ***************************************************************************\n"
264 (sizeof(UINTN
) == sizeof(UINT64
)) ?
265 " ATSR address ........................................... 0x%016lx\n" :
266 " ATSR address ........................................... 0x%08x\n",
270 " Type ................................................. 0x%04x\n",
274 " Length ............................................... 0x%04x\n",
278 " Flags ................................................ 0x%02x\n",
282 " ALL_PORTS .......................................... 0x%02x\n",
283 Atsr
->Flags
& EFI_ACPI_DMAR_ATSR_FLAGS_ALL_PORTS
286 " Segment Number ....................................... 0x%04x\n",
290 AtsrLen
= Atsr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_ATSR_HEADER
);
291 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Atsr
+ 1);
292 while (AtsrLen
> 0) {
293 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
294 AtsrLen
-= DmarDeviceScopeEntry
->Length
;
295 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
299 " ***************************************************************************\n\n"
306 Dump DMAR RMRR table.
308 @param[in] Rmrr DMAR RMRR table
312 IN EFI_ACPI_DMAR_RMRR_HEADER
*Rmrr
315 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
323 " ***************************************************************************\n"
326 " * Reserved Memory Region Reporting Structure *\n"
329 " ***************************************************************************\n"
332 (sizeof(UINTN
) == sizeof(UINT64
)) ?
333 " RMRR address ........................................... 0x%016lx\n" :
334 " RMRR address ........................................... 0x%08x\n",
338 " Type ................................................. 0x%04x\n",
342 " Length ............................................... 0x%04x\n",
346 " Segment Number ....................................... 0x%04x\n",
350 " Reserved Memory Region Base Address .................. 0x%016lx\n",
351 Rmrr
->ReservedMemoryRegionBaseAddress
354 " Reserved Memory Region Limit Address ................. 0x%016lx\n",
355 Rmrr
->ReservedMemoryRegionLimitAddress
358 RmrrLen
= Rmrr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_RMRR_HEADER
);
359 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Rmrr
+ 1);
360 while (RmrrLen
> 0) {
361 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
362 RmrrLen
-= DmarDeviceScopeEntry
->Length
;
363 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
367 " ***************************************************************************\n\n"
374 Dump DMAR DRHD table.
376 @param[in] Drhd DMAR DRHD table
380 IN EFI_ACPI_DMAR_DRHD_HEADER
*Drhd
383 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
391 " ***************************************************************************\n"
394 " * DMA-Remapping Hardware Definition Structure *\n"
397 " ***************************************************************************\n"
400 (sizeof(UINTN
) == sizeof(UINT64
)) ?
401 " DRHD address ........................................... 0x%016lx\n" :
402 " DRHD address ........................................... 0x%08x\n",
406 " Type ................................................. 0x%04x\n",
410 " Length ............................................... 0x%04x\n",
414 " Flags ................................................ 0x%02x\n",
418 " INCLUDE_PCI_ALL .................................... 0x%02x\n",
419 Drhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
422 " Segment Number ....................................... 0x%04x\n",
426 " Register Base Address ................................ 0x%016lx\n",
427 Drhd
->RegisterBaseAddress
430 DrhdLen
= Drhd
->Header
.Length
- sizeof(EFI_ACPI_DMAR_DRHD_HEADER
);
431 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Drhd
+ 1);
432 while (DrhdLen
> 0) {
433 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
434 DrhdLen
-= DmarDeviceScopeEntry
->Length
;
435 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
439 " ***************************************************************************\n\n"
446 Dump DMAR ACPI table.
448 @param[in] Dmar DMAR ACPI table
452 IN EFI_ACPI_DMAR_HEADER
*Dmar
455 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
466 "*****************************************************************************\n"
472 "*****************************************************************************\n"
476 (sizeof(UINTN
) == sizeof(UINT64
)) ?
477 "DMAR address ............................................. 0x%016lx\n" :
478 "DMAR address ............................................. 0x%08x\n",
486 " Host Address Width ................................... 0x%02x\n",
487 Dmar
->HostAddressWidth
490 " Flags ................................................ 0x%02x\n",
494 " INTR_REMAP ......................................... 0x%02x\n",
495 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_INTR_REMAP
498 " X2APIC_OPT_OUT_SET ................................. 0x%02x\n",
499 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT
502 DmarLen
= Dmar
->Header
.Length
- sizeof(EFI_ACPI_DMAR_HEADER
);
503 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)(Dmar
+ 1);
504 while (DmarLen
> 0) {
505 switch (DmarHeader
->Type
) {
506 case EFI_ACPI_DMAR_TYPE_DRHD
:
507 DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
509 case EFI_ACPI_DMAR_TYPE_RMRR
:
510 DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
512 case EFI_ACPI_DMAR_TYPE_ATSR
:
513 DumpDmarAtsr ((EFI_ACPI_DMAR_ATSR_HEADER
*)DmarHeader
);
515 case EFI_ACPI_DMAR_TYPE_RHSA
:
516 DumpDmarRhsa ((EFI_ACPI_DMAR_RHSA_HEADER
*)DmarHeader
);
518 case EFI_ACPI_DMAR_TYPE_ANDD
:
519 DumpDmarAndd ((EFI_ACPI_DMAR_ANDD_HEADER
*)DmarHeader
);
524 DmarLen
-= DmarHeader
->Length
;
525 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
529 "*****************************************************************************\n\n"
536 Dump DMAR ACPI table.
543 DumpAcpiDMAR ((EFI_ACPI_DMAR_HEADER
*)(UINTN
)mAcpiDmarTable
);
547 Get PCI device information from DMAR DevScopeEntry.
549 @param[in] Segment The segment number.
550 @param[in] DmarDevScopeEntry DMAR DevScopeEntry
551 @param[out] Bus The bus number.
552 @param[out] Device The device number.
553 @param[out] Function The function number.
555 @retval EFI_SUCCESS The PCI device information is returned.
558 GetPciBusDeviceFunction (
560 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
,
566 EFI_ACPI_DMAR_PCI_PATH
*DmarPciPath
;
571 DmarPciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)((UINTN
)(DmarDevScopeEntry
+ 1));
572 MyBus
= DmarDevScopeEntry
->StartBusNumber
;
573 MyDevice
= DmarPciPath
->Device
;
574 MyFunction
= DmarPciPath
->Function
;
576 switch (DmarDevScopeEntry
->Type
) {
577 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
578 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
579 while ((UINTN
)DmarPciPath
+ sizeof(EFI_ACPI_DMAR_PCI_PATH
) < (UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
) {
580 MyBus
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment
, MyBus
, MyDevice
, MyFunction
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
582 MyDevice
= DmarPciPath
->Device
;
583 MyFunction
= DmarPciPath
->Function
;
586 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
587 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
588 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
594 *Function
= MyFunction
;
600 Process DMAR DHRD table.
602 @param[in] VtdIndex The index of VTd engine.
603 @param[in] DmarDrhd The DRHD table.
605 @retval EFI_SUCCESS The DRHD table is processed.
610 IN EFI_ACPI_DMAR_DRHD_HEADER
*DmarDrhd
613 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
617 UINT8 SecondaryBusNumber
;
619 VTD_SOURCE_ID SourceId
;
621 mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
= (UINTN
)DmarDrhd
->RegisterBaseAddress
;
622 DEBUG ((DEBUG_INFO
," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex
, DmarDrhd
->RegisterBaseAddress
));
624 mVtdUnitInformation
[VtdIndex
].Segment
= DmarDrhd
->SegmentNumber
;
626 if ((DmarDrhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
) != 0) {
627 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= TRUE
;
628 DEBUG ((DEBUG_INFO
," ProcessDhrd: with INCLUDE ALL\n"));
630 Status
= ScanPciBus((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, 0, ScanBusCallbackRegisterPciDevice
);
631 if (EFI_ERROR (Status
)) {
635 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= FALSE
;
636 DEBUG ((DEBUG_INFO
," ProcessDhrd: without INCLUDE ALL\n"));
639 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarDrhd
+ 1));
640 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarDrhd
+ DmarDrhd
->Header
.Length
) {
642 Status
= GetPciBusDeviceFunction (DmarDrhd
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
643 if (EFI_ERROR (Status
)) {
647 DEBUG ((DEBUG_INFO
," ProcessDhrd: "));
648 switch (DmarDevScopeEntry
->Type
) {
649 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
650 DEBUG ((DEBUG_INFO
,"PCI Endpoint"));
652 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
653 DEBUG ((DEBUG_INFO
,"PCI-PCI bridge"));
655 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
656 DEBUG ((DEBUG_INFO
,"IOAPIC"));
658 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
659 DEBUG ((DEBUG_INFO
,"MSI Capable HPET"));
661 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
662 DEBUG ((DEBUG_INFO
,"ACPI Namespace Device"));
665 DEBUG ((DEBUG_INFO
," S%04x B%02x D%02x F%02x\n", DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
));
667 SourceId
.Bits
.Bus
= Bus
;
668 SourceId
.Bits
.Device
= Device
;
669 SourceId
.Bits
.Function
= Function
;
671 Status
= RegisterPciDevice (VtdIndex
, DmarDrhd
->SegmentNumber
, SourceId
, DmarDevScopeEntry
->Type
, TRUE
);
672 if (EFI_ERROR (Status
)) {
674 // There might be duplication for special device other than standard PCI device.
676 switch (DmarDevScopeEntry
->Type
) {
677 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
678 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
683 switch (DmarDevScopeEntry
->Type
) {
684 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
685 SecondaryBusNumber
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
686 Status
= ScanPciBus ((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, SecondaryBusNumber
, ScanBusCallbackRegisterPciDevice
);
687 if (EFI_ERROR (Status
)) {
695 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
702 Process DMAR RMRR table.
704 @param[in] DmarRmrr The RMRR table.
706 @retval EFI_SUCCESS The RMRR table is processed.
710 IN EFI_ACPI_DMAR_RMRR_HEADER
*DmarRmrr
713 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
718 VTD_SOURCE_ID SourceId
;
720 DEBUG ((DEBUG_INFO
," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr
->ReservedMemoryRegionBaseAddress
, DmarRmrr
->ReservedMemoryRegionLimitAddress
));
722 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarRmrr
+ 1));
723 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarRmrr
+ DmarRmrr
->Header
.Length
) {
724 if (DmarDevScopeEntry
->Type
!= EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
) {
725 DEBUG ((DEBUG_INFO
,"RMRR DevScopeEntryType is not endpoint, type[0x%x] \n", DmarDevScopeEntry
->Type
));
726 return EFI_DEVICE_ERROR
;
729 Status
= GetPciBusDeviceFunction (DmarRmrr
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
730 if (EFI_ERROR (Status
)) {
734 DEBUG ((DEBUG_INFO
,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr
->SegmentNumber
, Bus
, Device
, Function
));
736 SourceId
.Bits
.Bus
= Bus
;
737 SourceId
.Bits
.Device
= Device
;
738 SourceId
.Bits
.Function
= Function
;
739 Status
= SetAccessAttribute (
740 DmarRmrr
->SegmentNumber
,
742 DmarRmrr
->ReservedMemoryRegionBaseAddress
,
743 DmarRmrr
->ReservedMemoryRegionLimitAddress
+ 1 - DmarRmrr
->ReservedMemoryRegionBaseAddress
,
744 EDKII_IOMMU_ACCESS_READ
| EDKII_IOMMU_ACCESS_WRITE
746 if (EFI_ERROR (Status
)) {
750 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
757 Get VTd engine number.
764 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
768 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
769 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
770 switch (DmarHeader
->Type
) {
771 case EFI_ACPI_DMAR_TYPE_DRHD
:
777 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
783 Parse DMAR DRHD table.
785 @return EFI_SUCCESS The DMAR DRHD table is parsed.
788 ParseDmarAcpiTableDrhd (
792 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
796 mVtdUnitNumber
= GetVtdEngineNumber ();
797 DEBUG ((DEBUG_INFO
," VtdUnitNumber - %d\n", mVtdUnitNumber
));
798 ASSERT (mVtdUnitNumber
> 0);
799 if (mVtdUnitNumber
== 0) {
800 return EFI_DEVICE_ERROR
;
803 mVtdUnitInformation
= AllocateZeroPool (sizeof(*mVtdUnitInformation
) * mVtdUnitNumber
);
804 ASSERT (mVtdUnitInformation
!= NULL
);
805 if (mVtdUnitInformation
== NULL
) {
806 return EFI_OUT_OF_RESOURCES
;
810 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
811 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
812 switch (DmarHeader
->Type
) {
813 case EFI_ACPI_DMAR_TYPE_DRHD
:
814 ASSERT (VtdIndex
< mVtdUnitNumber
);
815 Status
= ProcessDhrd (VtdIndex
, (EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
816 if (EFI_ERROR (Status
)) {
826 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
828 ASSERT (VtdIndex
== mVtdUnitNumber
);
830 for (VtdIndex
= 0; VtdIndex
< mVtdUnitNumber
; VtdIndex
++) {
831 DumpPciDeviceInfo (VtdIndex
);
837 Parse DMAR DRHD table.
839 @return EFI_SUCCESS The DMAR DRHD table is parsed.
842 ParseDmarAcpiTableRmrr (
846 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
849 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
850 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
851 switch (DmarHeader
->Type
) {
852 case EFI_ACPI_DMAR_TYPE_RMRR
:
853 Status
= ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
854 if (EFI_ERROR (Status
)) {
861 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
867 This function scan ACPI table in RSDT.
869 @param[in] Rsdt ACPI RSDT
870 @param[in] Signature ACPI table signature
883 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
885 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
887 EntryPtr
= &Rsdt
->Entry
;
888 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
889 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
890 if ((Table
!= NULL
) && (Table
->Signature
== Signature
)) {
899 This function scan ACPI table in XSDT.
901 @param[in] Xsdt ACPI XSDT
902 @param[in] Signature ACPI table signature
916 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
918 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
920 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
921 for (Index
= 0; Index
< EntryCount
; Index
++) {
922 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
923 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
924 if ((Table
!= NULL
) && (Table
->Signature
== Signature
)) {
933 This function scan ACPI table in RSDP.
935 @param[in] Rsdp ACPI RSDP
936 @param[in] Signature ACPI table signature
942 IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
946 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
953 // Check ACPI2.0 table
955 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
957 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
958 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
964 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
969 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
970 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
977 Get the DMAR ACPI table.
979 @retval EFI_SUCCESS The DMAR ACPI table is got.
980 @retval EFI_ALREADY_STARTED The DMAR ACPI table has been got previously.
981 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.
991 if (mAcpiDmarTable
!= NULL
) {
992 return EFI_ALREADY_STARTED
;
996 Status
= EfiGetSystemConfigurationTable (
997 &gEfiAcpi20TableGuid
,
1000 if (EFI_ERROR (Status
)) {
1001 Status
= EfiGetSystemConfigurationTable (
1002 &gEfiAcpi10TableGuid
,
1006 if (EFI_ERROR (Status
)) {
1007 return EFI_NOT_FOUND
;
1009 ASSERT (AcpiTable
!= NULL
);
1011 mAcpiDmarTable
= FindAcpiPtr (
1012 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
1013 EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE
1015 if (mAcpiDmarTable
== NULL
) {
1016 return EFI_NOT_FOUND
;
1018 DEBUG ((DEBUG_INFO
,"DMAR Table - 0x%08x\n", mAcpiDmarTable
));