3 Copyright (c) 2017, 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
;
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"
52 " * DMA-Remapping Device Scope Entry Structure *\n"
53 " *************************************************************************\n"
56 (sizeof(UINTN
) == sizeof(UINT64
)) ?
57 " DMAR Device Scope Entry address ...................... 0x%016lx\n" :
58 " DMAR Device Scope Entry address ...................... 0x%08x\n",
62 " Device Scope Entry Type ............................ 0x%02x\n",
63 DmarDeviceScopeEntry
->Type
65 switch (DmarDeviceScopeEntry
->Type
) {
66 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
68 " PCI Endpoint Device\n"
71 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
76 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
81 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
86 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
88 " ACPI Namespace Device\n"
95 " Length ............................................. 0x%02x\n",
96 DmarDeviceScopeEntry
->Length
99 " Enumeration ID ..................................... 0x%02x\n",
100 DmarDeviceScopeEntry
->EnumerationId
103 " Starting Bus Number ................................ 0x%02x\n",
104 DmarDeviceScopeEntry
->StartBusNumber
107 PciPathNumber
= (DmarDeviceScopeEntry
->Length
- sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
)) / sizeof(EFI_ACPI_DMAR_PCI_PATH
);
108 PciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)(DmarDeviceScopeEntry
+ 1);
109 for (PciPathIndex
= 0; PciPathIndex
< PciPathNumber
; PciPathIndex
++) {
111 " Device ............................................. 0x%02x\n",
112 PciPath
[PciPathIndex
].Device
115 " Function ........................................... 0x%02x\n",
116 PciPath
[PciPathIndex
].Function
121 " *************************************************************************\n\n"
128 Dump DMAR ANDD table.
130 @param[in] Andd DMAR ANDD table
134 IN EFI_ACPI_DMAR_ANDD_HEADER
*Andd
142 " ***************************************************************************\n"
143 " * ACPI Name-space Device Declaration Structure *\n"
144 " ***************************************************************************\n"
147 (sizeof(UINTN
) == sizeof(UINT64
)) ?
148 " ANDD address ........................................... 0x%016lx\n" :
149 " ANDD address ........................................... 0x%08x\n",
153 " Type ................................................. 0x%04x\n",
157 " Length ............................................... 0x%04x\n",
161 " ACPI Device Number ................................... 0x%02x\n",
162 Andd
->AcpiDeviceNumber
165 " ACPI Object Name ..................................... '%a'\n",
170 " ***************************************************************************\n\n"
177 Dump DMAR RHSA table.
179 @param[in] Rhsa DMAR RHSA table
183 IN EFI_ACPI_DMAR_RHSA_HEADER
*Rhsa
191 " ***************************************************************************\n"
192 " * Remapping Hardware Status Affinity Structure *\n"
193 " ***************************************************************************\n"
196 (sizeof(UINTN
) == sizeof(UINT64
)) ?
197 " RHSA address ........................................... 0x%016lx\n" :
198 " RHSA address ........................................... 0x%08x\n",
202 " Type ................................................. 0x%04x\n",
206 " Length ............................................... 0x%04x\n",
210 " Register Base Address ................................ 0x%016lx\n",
211 Rhsa
->RegisterBaseAddress
214 " Proximity Domain ..................................... 0x%08x\n",
215 Rhsa
->ProximityDomain
219 " ***************************************************************************\n\n"
226 Dump DMAR ATSR table.
228 @param[in] Atsr DMAR ATSR table
232 IN EFI_ACPI_DMAR_ATSR_HEADER
*Atsr
235 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
243 " ***************************************************************************\n"
244 " * Root Port ATS Capability Reporting Structure *\n"
245 " ***************************************************************************\n"
248 (sizeof(UINTN
) == sizeof(UINT64
)) ?
249 " ATSR address ........................................... 0x%016lx\n" :
250 " ATSR address ........................................... 0x%08x\n",
254 " Type ................................................. 0x%04x\n",
258 " Length ............................................... 0x%04x\n",
262 " Flags ................................................ 0x%02x\n",
266 " ALL_PORTS .......................................... 0x%02x\n",
267 Atsr
->Flags
& EFI_ACPI_DMAR_ATSR_FLAGS_ALL_PORTS
270 " Segment Number ....................................... 0x%04x\n",
274 AtsrLen
= Atsr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_ATSR_HEADER
);
275 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Atsr
+ 1);
276 while (AtsrLen
> 0) {
277 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
278 AtsrLen
-= DmarDeviceScopeEntry
->Length
;
279 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
283 " ***************************************************************************\n\n"
290 Dump DMAR RMRR table.
292 @param[in] Rmrr DMAR RMRR table
296 IN EFI_ACPI_DMAR_RMRR_HEADER
*Rmrr
299 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
307 " ***************************************************************************\n"
308 " * Reserved Memory Region Reporting Structure *\n"
309 " ***************************************************************************\n"
312 (sizeof(UINTN
) == sizeof(UINT64
)) ?
313 " RMRR address ........................................... 0x%016lx\n" :
314 " RMRR address ........................................... 0x%08x\n",
318 " Type ................................................. 0x%04x\n",
322 " Length ............................................... 0x%04x\n",
326 " Segment Number ....................................... 0x%04x\n",
330 " Reserved Memory Region Base Address .................. 0x%016lx\n",
331 Rmrr
->ReservedMemoryRegionBaseAddress
334 " Reserved Memory Region Limit Address ................. 0x%016lx\n",
335 Rmrr
->ReservedMemoryRegionLimitAddress
338 RmrrLen
= Rmrr
->Header
.Length
- sizeof(EFI_ACPI_DMAR_RMRR_HEADER
);
339 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Rmrr
+ 1);
340 while (RmrrLen
> 0) {
341 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
342 RmrrLen
-= DmarDeviceScopeEntry
->Length
;
343 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
347 " ***************************************************************************\n\n"
354 Dump DMAR DRHD table.
356 @param[in] Drhd DMAR DRHD table
360 IN EFI_ACPI_DMAR_DRHD_HEADER
*Drhd
363 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDeviceScopeEntry
;
371 " ***************************************************************************\n"
372 " * DMA-Remapping Hardware Definition Structure *\n"
373 " ***************************************************************************\n"
376 (sizeof(UINTN
) == sizeof(UINT64
)) ?
377 " DRHD address ........................................... 0x%016lx\n" :
378 " DRHD address ........................................... 0x%08x\n",
382 " Type ................................................. 0x%04x\n",
386 " Length ............................................... 0x%04x\n",
390 " Flags ................................................ 0x%02x\n",
394 " INCLUDE_PCI_ALL .................................... 0x%02x\n",
395 Drhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
398 " Segment Number ....................................... 0x%04x\n",
402 " Register Base Address ................................ 0x%016lx\n",
403 Drhd
->RegisterBaseAddress
406 DrhdLen
= Drhd
->Header
.Length
- sizeof(EFI_ACPI_DMAR_DRHD_HEADER
);
407 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)(Drhd
+ 1);
408 while (DrhdLen
> 0) {
409 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry
);
410 DrhdLen
-= DmarDeviceScopeEntry
->Length
;
411 DmarDeviceScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDeviceScopeEntry
+ DmarDeviceScopeEntry
->Length
);
415 " ***************************************************************************\n\n"
422 Dump DMAR ACPI table.
424 @param[in] Dmar DMAR ACPI table
428 IN EFI_ACPI_DMAR_HEADER
*Dmar
431 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
442 "*****************************************************************************\n"
444 "*****************************************************************************\n"
448 (sizeof(UINTN
) == sizeof(UINT64
)) ?
449 "DMAR address ............................................. 0x%016lx\n" :
450 "DMAR address ............................................. 0x%08x\n",
458 " Host Address Width ................................... 0x%02x\n",
459 Dmar
->HostAddressWidth
462 " Flags ................................................ 0x%02x\n",
466 " INTR_REMAP ......................................... 0x%02x\n",
467 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_INTR_REMAP
470 " X2APIC_OPT_OUT_SET ................................. 0x%02x\n",
471 Dmar
->Flags
& EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT
474 DmarLen
= Dmar
->Header
.Length
- sizeof(EFI_ACPI_DMAR_HEADER
);
475 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)(Dmar
+ 1);
476 while (DmarLen
> 0) {
477 switch (DmarHeader
->Type
) {
478 case EFI_ACPI_DMAR_TYPE_DRHD
:
479 DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
481 case EFI_ACPI_DMAR_TYPE_RMRR
:
482 DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
484 case EFI_ACPI_DMAR_TYPE_ATSR
:
485 DumpDmarAtsr ((EFI_ACPI_DMAR_ATSR_HEADER
*)DmarHeader
);
487 case EFI_ACPI_DMAR_TYPE_RHSA
:
488 DumpDmarRhsa ((EFI_ACPI_DMAR_RHSA_HEADER
*)DmarHeader
);
490 case EFI_ACPI_DMAR_TYPE_ANDD
:
491 DumpDmarAndd ((EFI_ACPI_DMAR_ANDD_HEADER
*)DmarHeader
);
496 DmarLen
-= DmarHeader
->Length
;
497 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
501 "*****************************************************************************\n\n"
508 Dump DMAR ACPI table.
515 DumpAcpiDMAR ((EFI_ACPI_DMAR_HEADER
*)(UINTN
)mAcpiDmarTable
);
519 Get PCI device information from DMAR DevScopeEntry.
521 @param[in] Segment The segment number.
522 @param[in] DmarDevScopeEntry DMAR DevScopeEntry
523 @param[out] Bus The bus number.
524 @param[out] Device The device number.
525 @param[out] Function The function number.
527 @retval EFI_SUCCESS The PCI device information is returned.
530 GetPciBusDeviceFunction (
532 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
,
538 EFI_ACPI_DMAR_PCI_PATH
*DmarPciPath
;
543 DmarPciPath
= (EFI_ACPI_DMAR_PCI_PATH
*)((UINTN
)(DmarDevScopeEntry
+ 1));
544 MyBus
= DmarDevScopeEntry
->StartBusNumber
;
545 MyDevice
= DmarPciPath
->Device
;
546 MyFunction
= DmarPciPath
->Function
;
548 switch (DmarDevScopeEntry
->Type
) {
549 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
550 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
551 while ((UINTN
)DmarPciPath
< (UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
) {
552 MyBus
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment
, MyBus
, MyDevice
, MyFunction
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
553 MyDevice
= DmarPciPath
->Device
;
554 MyFunction
= DmarPciPath
->Function
;
558 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
559 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
560 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
566 *Function
= MyFunction
;
572 Process DMAR DHRD table.
574 @param[in] VtdIndex The index of VTd engine.
575 @param[in] DmarDrhd The DRHD table.
577 @retval EFI_SUCCESS The DRHD table is processed.
582 IN EFI_ACPI_DMAR_DRHD_HEADER
*DmarDrhd
585 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
589 UINT8 SecondaryBusNumber
;
591 VTD_SOURCE_ID SourceId
;
592 BOOLEAN IsRealPciDevice
;
594 mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
= (UINTN
)DmarDrhd
->RegisterBaseAddress
;
595 DEBUG ((DEBUG_INFO
," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex
, DmarDrhd
->RegisterBaseAddress
));
597 mVtdUnitInformation
[VtdIndex
].Segment
= DmarDrhd
->SegmentNumber
;
599 if ((DmarDrhd
->Flags
& EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
) != 0) {
600 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= TRUE
;
601 DEBUG ((DEBUG_INFO
," ProcessDhrd: with INCLUDE ALL\n"));
603 Status
= ScanPciBus(VtdIndex
, DmarDrhd
->SegmentNumber
, 0);
604 if (EFI_ERROR (Status
)) {
608 mVtdUnitInformation
[VtdIndex
].PciDeviceInfo
.IncludeAllFlag
= FALSE
;
609 DEBUG ((DEBUG_INFO
," ProcessDhrd: without INCLUDE ALL\n"));
612 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarDrhd
+ 1));
613 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarDrhd
+ DmarDrhd
->Header
.Length
) {
615 Status
= GetPciBusDeviceFunction (DmarDrhd
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
616 if (EFI_ERROR (Status
)) {
619 switch (DmarDevScopeEntry
->Type
) {
620 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
621 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
622 IsRealPciDevice
= TRUE
;
625 IsRealPciDevice
= FALSE
;
629 DEBUG ((DEBUG_INFO
," ProcessDhrd: "));
630 switch (DmarDevScopeEntry
->Type
) {
631 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
632 DEBUG ((DEBUG_INFO
,"PCI Endpoint"));
634 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
635 DEBUG ((DEBUG_INFO
,"PCI-PCI bridge"));
637 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC
:
638 DEBUG ((DEBUG_INFO
,"IOAPIC"));
640 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET
:
641 DEBUG ((DEBUG_INFO
,"MSI Capable HPET"));
643 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE
:
644 DEBUG ((DEBUG_INFO
,"ACPI Namespace Device"));
647 DEBUG ((DEBUG_INFO
," S%04x B%02x D%02x F%02x\n", DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
));
649 SourceId
.Bits
.Bus
= Bus
;
650 SourceId
.Bits
.Device
= Device
;
651 SourceId
.Bits
.Function
= Function
;
653 Status
= RegisterPciDevice (VtdIndex
, DmarDrhd
->SegmentNumber
, SourceId
, IsRealPciDevice
, TRUE
);
654 if (EFI_ERROR (Status
)) {
656 // There might be duplication for special device other than standard PCI device.
658 switch (DmarDevScopeEntry
->Type
) {
659 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
:
660 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
665 switch (DmarDevScopeEntry
->Type
) {
666 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE
:
667 SecondaryBusNumber
= PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DmarDrhd
->SegmentNumber
, Bus
, Device
, Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
668 Status
= ScanPciBus (VtdIndex
, DmarDrhd
->SegmentNumber
, SecondaryBusNumber
);
669 if (EFI_ERROR (Status
)) {
677 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
684 Process DMAR RMRR table.
686 @param[in] DmarRmrr The RMRR table.
688 @retval EFI_SUCCESS The RMRR table is processed.
692 IN EFI_ACPI_DMAR_RMRR_HEADER
*DmarRmrr
695 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*DmarDevScopeEntry
;
700 VTD_SOURCE_ID SourceId
;
702 DEBUG ((DEBUG_INFO
," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr
->ReservedMemoryRegionBaseAddress
, DmarRmrr
->ReservedMemoryRegionLimitAddress
));
704 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)(DmarRmrr
+ 1));
705 while ((UINTN
)DmarDevScopeEntry
< (UINTN
)DmarRmrr
+ DmarRmrr
->Header
.Length
) {
706 if (DmarDevScopeEntry
->Type
!= EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT
) {
707 DEBUG ((DEBUG_INFO
,"RMRR DevScopeEntryType is not endpoint, type[0x%x] \n", DmarDevScopeEntry
->Type
));
708 return EFI_DEVICE_ERROR
;
711 Status
= GetPciBusDeviceFunction (DmarRmrr
->SegmentNumber
, DmarDevScopeEntry
, &Bus
, &Device
, &Function
);
712 if (EFI_ERROR (Status
)) {
716 DEBUG ((DEBUG_INFO
,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr
->SegmentNumber
, Bus
, Device
, Function
));
718 SourceId
.Bits
.Bus
= Bus
;
719 SourceId
.Bits
.Device
= Device
;
720 SourceId
.Bits
.Function
= Function
;
721 Status
= SetAccessAttribute (
722 DmarRmrr
->SegmentNumber
,
724 DmarRmrr
->ReservedMemoryRegionBaseAddress
,
725 DmarRmrr
->ReservedMemoryRegionLimitAddress
+ 1 - DmarRmrr
->ReservedMemoryRegionBaseAddress
,
726 EDKII_IOMMU_ACCESS_READ
| EDKII_IOMMU_ACCESS_WRITE
728 if (EFI_ERROR (Status
)) {
732 DmarDevScopeEntry
= (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
*)((UINTN
)DmarDevScopeEntry
+ DmarDevScopeEntry
->Length
);
739 Get VTd engine number.
746 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
750 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
751 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
752 switch (DmarHeader
->Type
) {
753 case EFI_ACPI_DMAR_TYPE_DRHD
:
759 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
765 Parse DMAR DRHD table.
767 @return EFI_SUCCESS The DMAR DRHD table is parsed.
770 ParseDmarAcpiTableDrhd (
774 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
778 mVtdUnitNumber
= GetVtdEngineNumber ();
779 DEBUG ((DEBUG_INFO
," VtdUnitNumber - %d\n", mVtdUnitNumber
));
780 ASSERT (mVtdUnitNumber
> 0);
781 if (mVtdUnitNumber
== 0) {
782 return EFI_DEVICE_ERROR
;
785 mVtdUnitInformation
= AllocateZeroPool (sizeof(*mVtdUnitInformation
) * mVtdUnitNumber
);
786 ASSERT (mVtdUnitInformation
!= NULL
);
787 if (mVtdUnitInformation
== NULL
) {
788 return EFI_OUT_OF_RESOURCES
;
791 mVtdHostAddressWidthMask
= LShiftU64 (1ull, mAcpiDmarTable
->HostAddressWidth
) - 1;
794 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
795 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
796 switch (DmarHeader
->Type
) {
797 case EFI_ACPI_DMAR_TYPE_DRHD
:
798 ASSERT (VtdIndex
< mVtdUnitNumber
);
799 Status
= ProcessDhrd (VtdIndex
, (EFI_ACPI_DMAR_DRHD_HEADER
*)DmarHeader
);
800 if (EFI_ERROR (Status
)) {
810 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
812 ASSERT (VtdIndex
== mVtdUnitNumber
);
814 for (VtdIndex
= 0; VtdIndex
< mVtdUnitNumber
; VtdIndex
++) {
815 DumpPciDeviceInfo (VtdIndex
);
821 Parse DMAR DRHD table.
823 @return EFI_SUCCESS The DMAR DRHD table is parsed.
826 ParseDmarAcpiTableRmrr (
830 EFI_ACPI_DMAR_STRUCTURE_HEADER
*DmarHeader
;
833 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)(mAcpiDmarTable
+ 1));
834 while ((UINTN
)DmarHeader
< (UINTN
)mAcpiDmarTable
+ mAcpiDmarTable
->Header
.Length
) {
835 switch (DmarHeader
->Type
) {
836 case EFI_ACPI_DMAR_TYPE_RMRR
:
837 Status
= ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER
*)DmarHeader
);
838 if (EFI_ERROR (Status
)) {
845 DmarHeader
= (EFI_ACPI_DMAR_STRUCTURE_HEADER
*)((UINTN
)DmarHeader
+ DmarHeader
->Length
);
851 This function scan ACPI table in RSDT.
853 @param[in] Rsdt ACPI RSDT
854 @param[in] Signature ACPI table signature
867 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
869 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
871 EntryPtr
= &Rsdt
->Entry
;
872 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
873 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
874 if (Table
->Signature
== Signature
) {
883 This function scan ACPI table in XSDT.
885 @param[in] Xsdt ACPI XSDT
886 @param[in] Signature ACPI table signature
900 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
902 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
904 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
905 for (Index
= 0; Index
< EntryCount
; Index
++) {
906 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
907 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
908 if (Table
->Signature
== Signature
) {
917 This function scan ACPI table in RSDP.
919 @param[in] Rsdp ACPI RSDP
920 @param[in] Signature ACPI table signature
926 IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
930 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
937 // Check ACPI2.0 table
939 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
941 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
942 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
948 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
953 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
954 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
961 Get the DMAR ACPI table.
963 @retval EFI_SUCCESS The DMAR ACPI table is got.
964 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.
975 Status
= EfiGetSystemConfigurationTable (
976 &gEfiAcpi20TableGuid
,
979 if (EFI_ERROR (Status
)) {
980 Status
= EfiGetSystemConfigurationTable (
985 ASSERT (AcpiTable
!= NULL
);
987 mAcpiDmarTable
= FindAcpiPtr (
988 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
989 EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE
991 DEBUG ((DEBUG_INFO
,"DMAR Table - 0x%08x\n", mAcpiDmarTable
));
992 if (mAcpiDmarTable
== NULL
) {
993 return EFI_UNSUPPORTED
;