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 " DMA_CTRL_PLATFORM_OPT_IN_FLAG ...................... 0x%02x\n",
503 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_DMA_CTRL_PLATFORM_OPT_IN_FLAG
506 DmarLen
= Dmar
->Header
.Length
- sizeof(EFI_ACPI_DMAR_HEADER
);
507 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)(Dmar
+ 1);
508 while (DmarLen
> 0) {
509 switch (DmarHeader
->Type
) {
510 case EFI_ACPI_DMAR_TYPE_DRHD
:
511 DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
513 case EFI_ACPI_DMAR_TYPE_RMRR
:
514 DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
516 case EFI_ACPI_DMAR_TYPE_ATSR
:
517 DumpDmarAtsr ((EFI_ACPI_DMAR_ATSR_HEADER
*)DmarHeader
);
519 case EFI_ACPI_DMAR_TYPE_RHSA
:
520 DumpDmarRhsa ((EFI_ACPI_DMAR_RHSA_HEADER
*)DmarHeader
);
522 case EFI_ACPI_DMAR_TYPE_ANDD
:
523 DumpDmarAndd ((EFI_ACPI_DMAR_ANDD_HEADER
*)DmarHeader
);
528 DmarLen
-= DmarHeader
->Length
;
529 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
533 "*****************************************************************************\n\n"
540 Dump DMAR ACPI table.
547 DumpAcpiDMAR ((EFI_ACPI_DMAR_HEADER
*)(UINTN
)mAcpiDmarTable
);
551 Get PCI device information from DMAR DevScopeEntry.
553 @param[in] Segment The segment number.
554 @param[in] DmarDevScopeEntry DMAR DevScopeEntry
555 @param[out] Bus The bus number.
556 @param[out] Device The device number.
557 @param[out] Function The function number.
559 @retval EFI_SUCCESS The PCI device information is returned.
562 GetPciBusDeviceFunction (
564 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
,
570 EFI_ACPI_DMAR_PCI_PATH
*DmarPciPath
;
575 DmarPciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)((UINTN
)(DmarDevScopeEntry
+ 1));
576 MyBus
= DmarDevScopeEntry
->StartBusNumber
;
577 MyDevice
= DmarPciPath
->Device
;
578 MyFunction
= DmarPciPath
->Function
;
580 switch (DmarDevScopeEntry
->Type
) {
581 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
582 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
583 while ((UINTN
)DmarPciPath
+ sizeof(EFI_ACPI_DMAR_PCI_PATH
) < (UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
) {
584 MyBus
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment
, MyBus
, MyDevice
, MyFunction
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
586 MyDevice
= DmarPciPath
->Device
;
587 MyFunction
= DmarPciPath
->Function
;
590 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
591 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
592 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
598 *Function
= MyFunction
;
604 Process DMAR DHRD table.
606 @param[in] VtdIndex The index of VTd engine.
607 @param[in] DmarDrhd The DRHD table.
609 @retval EFI_SUCCESS The DRHD table is processed.
614 IN EFI_ACPI_DMAR_DRHD_HEADER
*DmarDrhd
617 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
621 UINT8 SecondaryBusNumber
;
623 VTD_SOURCE_ID SourceId
;
625 mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
= (UINTN
)DmarDrhd
->RegisterBaseAddress
;
626 DEBUG ((DEBUG_INFO
," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex
, DmarDrhd
->RegisterBaseAddress
));
628 mVtdUnitInformation
[VtdIndex
].Segment
= DmarDrhd
->SegmentNumber
;
630 if ((DmarDrhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
) != 0) {
631 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= TRUE
;
632 DEBUG ((DEBUG_INFO
," ProcessDhrd: with INCLUDE ALL\n"));
634 Status
= ScanPciBus((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, 0, ScanBusCallbackRegisterPciDevice
);
635 if (EFI_ERROR (Status
)) {
639 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= FALSE
;
640 DEBUG ((DEBUG_INFO
," ProcessDhrd: without INCLUDE ALL\n"));
643 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarDrhd
+ 1));
644 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarDrhd
+ DmarDrhd
->Header
.Length
) {
646 Status
= GetPciBusDeviceFunction (DmarDrhd
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
647 if (EFI_ERROR (Status
)) {
651 DEBUG ((DEBUG_INFO
," ProcessDhrd: "));
652 switch (DmarDevScopeEntry
->Type
) {
653 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
654 DEBUG ((DEBUG_INFO
,"PCI Endpoint"));
656 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
657 DEBUG ((DEBUG_INFO
,"PCI-PCI bridge"));
659 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
660 DEBUG ((DEBUG_INFO
,"IOAPIC"));
662 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
663 DEBUG ((DEBUG_INFO
,"MSI Capable HPET"));
665 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
666 DEBUG ((DEBUG_INFO
,"ACPI Namespace Device"));
669 DEBUG ((DEBUG_INFO
," S%04x B%02x D%02x F%02x\n", DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
));
671 SourceId
.Bits
.Bus
= Bus
;
672 SourceId
.Bits
.Device
= Device
;
673 SourceId
.Bits
.Function
= Function
;
675 Status
= RegisterPciDevice (VtdIndex
, DmarDrhd
->SegmentNumber
, SourceId
, DmarDevScopeEntry
->Type
, TRUE
);
676 if (EFI_ERROR (Status
)) {
678 // There might be duplication for special device other than standard PCI device.
680 switch (DmarDevScopeEntry
->Type
) {
681 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
682 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
687 switch (DmarDevScopeEntry
->Type
) {
688 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
689 SecondaryBusNumber
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
690 Status
= ScanPciBus ((VOID
*)VtdIndex
, DmarDrhd
->SegmentNumber
, SecondaryBusNumber
, ScanBusCallbackRegisterPciDevice
);
691 if (EFI_ERROR (Status
)) {
699 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
706 Process DMAR RMRR table.
708 @param[in] DmarRmrr The RMRR table.
710 @retval EFI_SUCCESS The RMRR table is processed.
714 IN EFI_ACPI_DMAR_RMRR_HEADER
*DmarRmrr
717 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
722 VTD_SOURCE_ID SourceId
;
724 DEBUG ((DEBUG_INFO
," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr
->ReservedMemoryRegionBaseAddress
, DmarRmrr
->ReservedMemoryRegionLimitAddress
));
726 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarRmrr
+ 1));
727 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarRmrr
+ DmarRmrr
->Header
.Length
) {
728 if (DmarDevScopeEntry
->Type
!= EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
) {
729 DEBUG ((DEBUG_INFO
,"RMRR DevScopeEntryType is not endpoint, type[0x%x] \n", DmarDevScopeEntry
->Type
));
730 return EFI_DEVICE_ERROR
;
733 Status
= GetPciBusDeviceFunction (DmarRmrr
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
734 if (EFI_ERROR (Status
)) {
738 DEBUG ((DEBUG_INFO
,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr
->SegmentNumber
, Bus
, Device
, Function
));
740 SourceId
.Bits
.Bus
= Bus
;
741 SourceId
.Bits
.Device
= Device
;
742 SourceId
.Bits
.Function
= Function
;
743 Status
= SetAccessAttribute (
744 DmarRmrr
->SegmentNumber
,
746 DmarRmrr
->ReservedMemoryRegionBaseAddress
,
747 DmarRmrr
->ReservedMemoryRegionLimitAddress
+ 1 - DmarRmrr
->ReservedMemoryRegionBaseAddress
,
748 EDKII_IOMMU_ACCESS_READ
| EDKII_IOMMU_ACCESS_WRITE
750 if (EFI_ERROR (Status
)) {
754 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
761 Get VTd engine number.
768 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
772 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
773 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
774 switch (DmarHeader
->Type
) {
775 case EFI_ACPI_DMAR_TYPE_DRHD
:
781 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
787 Parse DMAR DRHD table.
789 @return EFI_SUCCESS The DMAR DRHD table is parsed.
792 ParseDmarAcpiTableDrhd (
796 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
800 mVtdUnitNumber
= GetVtdEngineNumber ();
801 DEBUG ((DEBUG_INFO
," VtdUnitNumber - %d\n", mVtdUnitNumber
));
802 ASSERT (mVtdUnitNumber
> 0);
803 if (mVtdUnitNumber
== 0) {
804 return EFI_DEVICE_ERROR
;
807 mVtdUnitInformation
= AllocateZeroPool (sizeof(*mVtdUnitInformation
) * mVtdUnitNumber
);
808 ASSERT (mVtdUnitInformation
!= NULL
);
809 if (mVtdUnitInformation
== NULL
) {
810 return EFI_OUT_OF_RESOURCES
;
814 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
815 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
816 switch (DmarHeader
->Type
) {
817 case EFI_ACPI_DMAR_TYPE_DRHD
:
818 ASSERT (VtdIndex
< mVtdUnitNumber
);
819 Status
= ProcessDhrd (VtdIndex
, (EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
820 if (EFI_ERROR (Status
)) {
830 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
832 ASSERT (VtdIndex
== mVtdUnitNumber
);
834 for (VtdIndex
= 0; VtdIndex
< mVtdUnitNumber
; VtdIndex
++) {
835 DumpPciDeviceInfo (VtdIndex
);
841 Parse DMAR DRHD table.
843 @return EFI_SUCCESS The DMAR DRHD table is parsed.
846 ParseDmarAcpiTableRmrr (
850 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
853 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
854 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
855 switch (DmarHeader
->Type
) {
856 case EFI_ACPI_DMAR_TYPE_RMRR
:
857 Status
= ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
858 if (EFI_ERROR (Status
)) {
865 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
871 This function scan ACPI table in RSDT.
873 @param[in] Rsdt ACPI RSDT
874 @param[in] Signature ACPI table signature
887 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
889 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
891 EntryPtr
= &Rsdt
->Entry
;
892 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
893 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
894 if ((Table
!= NULL
) && (Table
->Signature
== Signature
)) {
903 This function scan ACPI table in XSDT.
905 @param[in] Xsdt ACPI XSDT
906 @param[in] Signature ACPI table signature
920 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
922 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
924 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
925 for (Index
= 0; Index
< EntryCount
; Index
++) {
926 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
927 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
928 if ((Table
!= NULL
) && (Table
->Signature
== Signature
)) {
937 This function scan ACPI table in RSDP.
939 @param[in] Rsdp ACPI RSDP
940 @param[in] Signature ACPI table signature
946 IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
950 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
957 // Check ACPI2.0 table
959 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
961 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
962 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
968 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
973 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
974 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
981 Get the DMAR ACPI table.
983 @retval EFI_SUCCESS The DMAR ACPI table is got.
984 @retval EFI_ALREADY_STARTED The DMAR ACPI table has been got previously.
985 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.
995 if (mAcpiDmarTable
!= NULL
) {
996 return EFI_ALREADY_STARTED
;
1000 Status
= EfiGetSystemConfigurationTable (
1001 &gEfiAcpi20TableGuid
,
1004 if (EFI_ERROR (Status
)) {
1005 Status
= EfiGetSystemConfigurationTable (
1006 &gEfiAcpi10TableGuid
,
1010 if (EFI_ERROR (Status
)) {
1011 return EFI_NOT_FOUND
;
1013 ASSERT (AcpiTable
!= NULL
);
1015 mAcpiDmarTable
= FindAcpiPtr (
1016 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
1017 EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE
1019 if (mAcpiDmarTable
== NULL
) {
1020 return EFI_NOT_FOUND
;
1022 DEBUG ((DEBUG_INFO
,"DMAR Table - 0x%08x\n", mAcpiDmarTable
));