bc9f427a36863ac17890a913d0c683a32dcacc30
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"
17 VTD_UNIT_INFORMATION
*mVtdUnitInformation
;
22 Flush VTD page table and context table memory.
24 This action is to make sure the IOMMU engine can get final data in memory.
26 @param[in] VtdIndex The index used to identify a VTd engine.
27 @param[in] Base The base address of memory to be flushed.
28 @param[in] Size The size of memory in bytes to be flushed.
31 FlushPageTableMemory (
37 if (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.C
== 0) {
38 WriteBackDataCacheRange ((VOID
*)Base
, Size
);
43 Flush VTd engine write buffer.
45 @param[in] VtdIndex The index used to identify a VTd engine.
54 if (mVtdUnitInformation
[VtdIndex
].CapReg
.Bits
.RWBF
!= 0) {
55 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
56 MmioWrite32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GCMD_REG
, Reg32
| B_GMCD_REG_WBF
);
58 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
59 } while ((Reg32
& B_GSTS_REG_WBF
) != 0);
64 Invalidate VTd context cache.
66 @param[in] VtdIndex The index used to identify a VTd engine.
69 InvalidateContextCache (
75 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
76 if ((Reg64
& B_CCMD_REG_ICC
) != 0) {
77 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex
));
78 return EFI_DEVICE_ERROR
;
81 Reg64
&= ((~B_CCMD_REG_ICC
) & (~B_CCMD_REG_CIRG_MASK
));
82 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_GLOBAL
);
83 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
, Reg64
);
86 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
87 } while ((Reg64
& B_CCMD_REG_ICC
) != 0);
95 @param[in] VtdIndex The index used to identify a VTd engine.
104 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
105 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
106 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex
));
107 return EFI_DEVICE_ERROR
;
110 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
111 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_GLOBAL
);
112 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
115 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
116 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
122 Invalid VTd global IOTLB.
124 @param[in] VtdIndex The index of VTd engine.
126 @retval EFI_SUCCESS VTd global IOTLB is invalidated.
127 @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
130 InvalidateVtdIOTLBGlobal (
138 DEBUG((DEBUG_VERBOSE
, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex
));
141 // Write Buffer Flush before invalidation
143 FlushWriteBuffer (VtdIndex
);
146 // Invalidate the context cache
148 if (mVtdUnitInformation
[VtdIndex
].HasDirtyContext
) {
149 InvalidateContextCache (VtdIndex
);
153 // Invalidate the IOTLB cache
155 if (mVtdUnitInformation
[VtdIndex
].HasDirtyContext
|| mVtdUnitInformation
[VtdIndex
].HasDirtyPages
) {
156 InvalidateIOTLB (VtdIndex
);
163 Prepare VTD configuration.
173 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
174 DEBUG ((DEBUG_INFO
, "Dump VTd Capability (%d)\n", Index
));
175 mVtdUnitInformation
[Index
].CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
176 DumpVtdCapRegs (&mVtdUnitInformation
[Index
].CapReg
);
177 mVtdUnitInformation
[Index
].ECapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_ECAP_REG
);
178 DumpVtdECapRegs (&mVtdUnitInformation
[Index
].ECapReg
);
180 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SLLPS
& BIT0
) == 0) {
181 DEBUG((DEBUG_WARN
, "!!!! 2MB super page is not supported on VTD %d !!!!\n", Index
));
183 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SAGAW
& BIT2
) == 0) {
184 DEBUG((DEBUG_ERROR
, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", Index
));
188 DomainNumber
= (UINTN
)1 << (UINT8
)((UINTN
)mVtdUnitInformation
[Index
].CapReg
.Bits
.ND
* 2 + 4);
189 if (mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
>= DomainNumber
) {
190 DEBUG((DEBUG_ERROR
, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
, DomainNumber
));
198 Disable PMR in all VTd engine.
209 DEBUG ((DEBUG_INFO
,"DisablePmr\n"));
210 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
211 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
212 if (CapReg
.Bits
.PLMR
== 0 || CapReg
.Bits
.PHMR
== 0) {
216 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
);
217 if ((Reg32
& BIT0
) != 0) {
218 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
, 0x0);
220 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
);
221 } while((Reg32
& BIT0
) != 0);
222 DEBUG ((DEBUG_INFO
,"Pmr(%d) disabled\n", Index
));
224 DEBUG ((DEBUG_INFO
,"Pmr(%d) not enabled\n", Index
));
231 Enable DMAR translation.
233 @retval EFI_SUCCESS DMAR translation is enabled.
234 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
244 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
245 DEBUG((DEBUG_INFO
, ">>>>>>EnableDmar() for engine [%d] \n", Index
));
247 if (mVtdUnitInformation
[Index
].ExtRootEntryTable
!= NULL
) {
248 DEBUG((DEBUG_INFO
, "ExtRootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].ExtRootEntryTable
));
249 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].ExtRootEntryTable
| BIT11
);
251 DEBUG((DEBUG_INFO
, "RootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].RootEntryTable
));
252 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].RootEntryTable
);
255 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
257 DEBUG((DEBUG_INFO
, "EnableDmar: waiting for RTPS bit to be set... \n"));
259 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
260 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
263 // Init DMAr Fault Event and Data registers
265 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
268 // Write Buffer Flush before invalidation
270 FlushWriteBuffer (Index
);
273 // Invalidate the context cache
275 InvalidateContextCache (Index
);
278 // Invalidate the IOTLB cache
280 InvalidateIOTLB (Index
);
285 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_TE
);
286 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
288 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
289 } while ((Reg32
& B_GSTS_REG_TE
) == 0);
291 DEBUG ((DEBUG_INFO
,"VTD (%d) enabled!<<<<<<\n",Index
));
295 // Need disable PMR, since we already setup translation table.
305 Disable DMAR translation.
307 @retval EFI_SUCCESS DMAR translation is disabled.
308 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.
319 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
320 DEBUG((DEBUG_INFO
, ">>>>>>DisableDmar() for engine [%d] \n", Index
));
323 // Write Buffer Flush before invalidation
325 FlushWriteBuffer (Index
);
330 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
332 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
333 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
335 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
336 DEBUG((DEBUG_INFO
, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32
));
338 DEBUG ((DEBUG_INFO
,"VTD (%d) Disabled!<<<<<<\n",Index
));
343 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
344 DEBUG((DEBUG_INFO
, "engine [%d] access\n", Index
));
345 for (SubIndex
= 0; SubIndex
< mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
; SubIndex
++) {
346 DEBUG ((DEBUG_INFO
, " PCI S%04X B%02x D%02x F%02x - %d\n",
347 mVtdUnitInformation
[Index
].Segment
,
348 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Bus
,
349 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Device
,
350 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Function
,
351 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].AccessCount
360 Dump VTd capability registers.
362 @param[in] CapReg The capability register.
366 IN VTD_CAP_REG
*CapReg
369 DEBUG((DEBUG_INFO
, " CapReg:\n", CapReg
->Uint64
));
370 DEBUG((DEBUG_INFO
, " ND - 0x%x\n", CapReg
->Bits
.ND
));
371 DEBUG((DEBUG_INFO
, " AFL - 0x%x\n", CapReg
->Bits
.AFL
));
372 DEBUG((DEBUG_INFO
, " RWBF - 0x%x\n", CapReg
->Bits
.RWBF
));
373 DEBUG((DEBUG_INFO
, " PLMR - 0x%x\n", CapReg
->Bits
.PLMR
));
374 DEBUG((DEBUG_INFO
, " PHMR - 0x%x\n", CapReg
->Bits
.PHMR
));
375 DEBUG((DEBUG_INFO
, " CM - 0x%x\n", CapReg
->Bits
.CM
));
376 DEBUG((DEBUG_INFO
, " SAGAW - 0x%x\n", CapReg
->Bits
.SAGAW
));
377 DEBUG((DEBUG_INFO
, " MGAW - 0x%x\n", CapReg
->Bits
.MGAW
));
378 DEBUG((DEBUG_INFO
, " ZLR - 0x%x\n", CapReg
->Bits
.ZLR
));
379 DEBUG((DEBUG_INFO
, " FRO - 0x%x\n", CapReg
->Bits
.FRO
));
380 DEBUG((DEBUG_INFO
, " SLLPS - 0x%x\n", CapReg
->Bits
.SLLPS
));
381 DEBUG((DEBUG_INFO
, " PSI - 0x%x\n", CapReg
->Bits
.PSI
));
382 DEBUG((DEBUG_INFO
, " NFR - 0x%x\n", CapReg
->Bits
.NFR
));
383 DEBUG((DEBUG_INFO
, " MAMV - 0x%x\n", CapReg
->Bits
.MAMV
));
384 DEBUG((DEBUG_INFO
, " DWD - 0x%x\n", CapReg
->Bits
.DWD
));
385 DEBUG((DEBUG_INFO
, " DRD - 0x%x\n", CapReg
->Bits
.DRD
));
386 DEBUG((DEBUG_INFO
, " FL1GP - 0x%x\n", CapReg
->Bits
.FL1GP
));
387 DEBUG((DEBUG_INFO
, " PI - 0x%x\n", CapReg
->Bits
.PI
));
391 Dump VTd extended capability registers.
393 @param[in] ECapReg The extended capability register.
397 IN VTD_ECAP_REG
*ECapReg
400 DEBUG((DEBUG_INFO
, " ECapReg:\n", ECapReg
->Uint64
));
401 DEBUG((DEBUG_INFO
, " C - 0x%x\n", ECapReg
->Bits
.C
));
402 DEBUG((DEBUG_INFO
, " QI - 0x%x\n", ECapReg
->Bits
.QI
));
403 DEBUG((DEBUG_INFO
, " DT - 0x%x\n", ECapReg
->Bits
.DT
));
404 DEBUG((DEBUG_INFO
, " IR - 0x%x\n", ECapReg
->Bits
.IR
));
405 DEBUG((DEBUG_INFO
, " EIM - 0x%x\n", ECapReg
->Bits
.EIM
));
406 DEBUG((DEBUG_INFO
, " PT - 0x%x\n", ECapReg
->Bits
.PT
));
407 DEBUG((DEBUG_INFO
, " SC - 0x%x\n", ECapReg
->Bits
.SC
));
408 DEBUG((DEBUG_INFO
, " IRO - 0x%x\n", ECapReg
->Bits
.IRO
));
409 DEBUG((DEBUG_INFO
, " MHMV - 0x%x\n", ECapReg
->Bits
.MHMV
));
410 DEBUG((DEBUG_INFO
, " ECS - 0x%x\n", ECapReg
->Bits
.ECS
));
411 DEBUG((DEBUG_INFO
, " MTS - 0x%x\n", ECapReg
->Bits
.MTS
));
412 DEBUG((DEBUG_INFO
, " NEST - 0x%x\n", ECapReg
->Bits
.NEST
));
413 DEBUG((DEBUG_INFO
, " DIS - 0x%x\n", ECapReg
->Bits
.DIS
));
414 DEBUG((DEBUG_INFO
, " PASID - 0x%x\n", ECapReg
->Bits
.PASID
));
415 DEBUG((DEBUG_INFO
, " PRS - 0x%x\n", ECapReg
->Bits
.PRS
));
416 DEBUG((DEBUG_INFO
, " ERS - 0x%x\n", ECapReg
->Bits
.ERS
));
417 DEBUG((DEBUG_INFO
, " SRS - 0x%x\n", ECapReg
->Bits
.SRS
));
418 DEBUG((DEBUG_INFO
, " NWFS - 0x%x\n", ECapReg
->Bits
.NWFS
));
419 DEBUG((DEBUG_INFO
, " EAFS - 0x%x\n", ECapReg
->Bits
.EAFS
));
420 DEBUG((DEBUG_INFO
, " PSS - 0x%x\n", ECapReg
->Bits
.PSS
));
426 @param[in] VtdIndex The index of VTd engine.
435 VTD_FRCD_REG FrcdReg
;
438 VTD_SOURCE_ID SourceId
;
440 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) Begin ####\n", VtdIndex
));
442 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_VER_REG
);
443 DEBUG((DEBUG_INFO
, " VER_REG - 0x%08x\n", Reg32
));
445 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CAP_REG
);
446 DEBUG((DEBUG_INFO
, " CAP_REG - 0x%016lx\n", CapReg
.Uint64
));
448 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_ECAP_REG
);
449 DEBUG((DEBUG_INFO
, " ECAP_REG - 0x%016lx\n", Reg64
));
451 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
452 DEBUG((DEBUG_INFO
, " GSTS_REG - 0x%08x \n", Reg32
));
454 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_RTADDR_REG
);
455 DEBUG((DEBUG_INFO
, " RTADDR_REG - 0x%016lx\n", Reg64
));
457 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
458 DEBUG((DEBUG_INFO
, " CCMD_REG - 0x%016lx\n", Reg64
));
460 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FSTS_REG
);
461 DEBUG((DEBUG_INFO
, " FSTS_REG - 0x%08x\n", Reg32
));
463 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FECTL_REG
);
464 DEBUG((DEBUG_INFO
, " FECTL_REG - 0x%08x\n", Reg32
));
466 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
467 DEBUG((DEBUG_INFO
, " FEDATA_REG - 0x%08x\n", Reg32
));
469 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEADDR_REG
);
470 DEBUG((DEBUG_INFO
, " FEADDR_REG - 0x%08x\n",Reg32
));
472 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEUADDR_REG
);
473 DEBUG((DEBUG_INFO
, " FEUADDR_REG - 0x%08x\n",Reg32
));
475 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
476 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
477 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
478 DEBUG((DEBUG_INFO
, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index
, FrcdReg
.Uint64
[1], FrcdReg
.Uint64
[0]));
479 if (FrcdReg
.Uint64
[1] != 0 || FrcdReg
.Uint64
[0] != 0) {
480 DEBUG((DEBUG_INFO
, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg
.Bits
.FILo
, FrcdReg
.Bits
.FIHi
)));
481 SourceId
.Uint16
= (UINT16
)FrcdReg
.Bits
.SID
;
482 DEBUG((DEBUG_INFO
, " Source - B%02x D%02x F%02x\n", SourceId
.Bits
.Bus
, SourceId
.Bits
.Device
, SourceId
.Bits
.Function
));
483 DEBUG((DEBUG_INFO
, " Type - %x (%a)\n", FrcdReg
.Bits
.T
, FrcdReg
.Bits
.T
? "read" : "write"));
484 DEBUG((DEBUG_INFO
, " Reason - %x\n", FrcdReg
.Bits
.FR
));
488 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IVA_REG
);
489 DEBUG((DEBUG_INFO
, " IVA_REG - 0x%016lx\n",Reg64
));
491 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
492 DEBUG((DEBUG_INFO
, " IOTLB_REG - 0x%016lx\n",Reg64
));
494 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) End ####\n", VtdIndex
));
498 Dump VTd registers for all VTd engine.
507 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
513 Dump VTd registers if there is error.
522 VTD_FRCD_REG FrcdReg
;
527 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
529 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
);
533 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FECTL_REG
);
534 if ((Reg32
& BIT30
) != 0) {
538 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_CAP_REG
);
539 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
540 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
541 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
542 if (FrcdReg
.Bits
.F
!= 0) {
548 DEBUG((DEBUG_INFO
, "\n#### ERROR ####\n"));
550 DEBUG((DEBUG_INFO
, "#### ERROR ####\n\n"));
554 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
555 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
556 if (FrcdReg
.Bits
.F
!= 0) {
558 MmioWrite64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)), FrcdReg
.Uint64
[1]);
560 MmioWrite32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
, MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
));