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"
16 UINT64 mVtdHostAddressWidthMask
;
18 VTD_UNIT_INFORMATION
*mVtdUnitInformation
;
23 Flush VTD page table and context table memory.
25 This action is to make sure the IOMMU engine can get final data in memory.
27 @param[in] VtdIndex The index used to identify a VTd engine.
28 @param[in] Base The base address of memory to be flushed.
29 @param[in] Size The size of memory in bytes to be flushed.
32 FlushPageTableMemory (
38 if (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.C
== 0) {
39 WriteBackDataCacheRange ((VOID
*)Base
, Size
);
44 Flush VTd engine write buffer.
46 @param[in] VtdIndex The index used to identify a VTd engine.
55 if (mVtdUnitInformation
[VtdIndex
].CapReg
.Bits
.RWBF
!= 0) {
56 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
57 MmioWrite32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GCMD_REG
, Reg32
| B_GMCD_REG_WBF
);
59 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
60 } while ((Reg32
& B_GSTS_REG_WBF
) != 0);
65 Invalidate VTd context cache.
67 @param[in] VtdIndex The index used to identify a VTd engine.
70 InvalidateContextCache (
76 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
77 if ((Reg64
& B_CCMD_REG_ICC
) != 0) {
78 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex
));
79 return EFI_DEVICE_ERROR
;
82 Reg64
&= ((~B_CCMD_REG_ICC
) & (~B_CCMD_REG_CIRG_MASK
));
83 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_GLOBAL
);
84 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
, Reg64
);
87 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
88 } while ((Reg64
& B_CCMD_REG_ICC
) != 0);
96 @param[in] VtdIndex The index used to identify a VTd engine.
105 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
106 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
107 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex
));
108 return EFI_DEVICE_ERROR
;
111 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
112 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_GLOBAL
);
113 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
116 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
117 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
123 Invalid VTd global IOTLB.
125 @param[in] VtdIndex The index of VTd engine.
127 @retval EFI_SUCCESS VTd global IOTLB is invalidated.
128 @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
131 InvalidateVtdIOTLBGlobal (
139 DEBUG((DEBUG_VERBOSE
, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex
));
142 // Write Buffer Flush before invalidation
144 FlushWriteBuffer (VtdIndex
);
147 // Invalidate the context cache
149 if (mVtdUnitInformation
[VtdIndex
].HasDirtyContext
) {
150 InvalidateContextCache (VtdIndex
);
154 // Invalidate the IOTLB cache
156 if (mVtdUnitInformation
[VtdIndex
].HasDirtyContext
|| mVtdUnitInformation
[VtdIndex
].HasDirtyPages
) {
157 InvalidateIOTLB (VtdIndex
);
164 Prepare VTD configuration.
174 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
175 DEBUG ((DEBUG_INFO
, "Dump VTd Capability (%d)\n", Index
));
176 mVtdUnitInformation
[Index
].CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
177 DumpVtdCapRegs (&mVtdUnitInformation
[Index
].CapReg
);
178 mVtdUnitInformation
[Index
].ECapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_ECAP_REG
);
179 DumpVtdECapRegs (&mVtdUnitInformation
[Index
].ECapReg
);
181 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SLLPS
& BIT0
) == 0) {
182 DEBUG((DEBUG_WARN
, "!!!! 2MB super page is not supported on VTD %d !!!!\n", Index
));
184 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SAGAW
& BIT2
) == 0) {
185 DEBUG((DEBUG_ERROR
, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", Index
));
189 DomainNumber
= (UINTN
)1 << (UINT8
)((UINTN
)mVtdUnitInformation
[Index
].CapReg
.Bits
.ND
* 2 + 4);
190 if (mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
>= DomainNumber
) {
191 DEBUG((DEBUG_ERROR
, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
, DomainNumber
));
199 Disable PMR in all VTd engine.
210 DEBUG ((DEBUG_INFO
,"DisablePmr\n"));
211 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
212 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
213 if (CapReg
.Bits
.PLMR
== 0 || CapReg
.Bits
.PHMR
== 0) {
217 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
);
218 if ((Reg32
& BIT0
) != 0) {
219 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
, 0x0);
221 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_PMEN_ENABLE_REG
);
222 } while((Reg32
& BIT0
) != 0);
223 DEBUG ((DEBUG_INFO
,"Pmr(%d) disabled\n", Index
));
225 DEBUG ((DEBUG_INFO
,"Pmr(%d) not enabled\n", Index
));
232 Enable DMAR translation.
234 @retval EFI_SUCCESS DMAR translation is enabled.
235 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
245 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
246 DEBUG((DEBUG_INFO
, ">>>>>>EnableDmar() for engine [%d] \n", Index
));
248 if (mVtdUnitInformation
[Index
].ExtRootEntryTable
!= NULL
) {
249 DEBUG((DEBUG_INFO
, "ExtRootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].ExtRootEntryTable
));
250 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].ExtRootEntryTable
| BIT11
);
252 DEBUG((DEBUG_INFO
, "RootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].RootEntryTable
));
253 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].RootEntryTable
);
256 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
258 DEBUG((DEBUG_INFO
, "EnableDmar: waiting for RTPS bit to be set... \n"));
260 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
261 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
264 // Init DMAr Fault Event and Data registers
266 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
269 // Write Buffer Flush before invalidation
271 FlushWriteBuffer (Index
);
274 // Invalidate the context cache
276 InvalidateContextCache (Index
);
279 // Invalidate the IOTLB cache
281 InvalidateIOTLB (Index
);
286 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_TE
);
287 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
289 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
290 } while ((Reg32
& B_GSTS_REG_TE
) == 0);
292 DEBUG ((DEBUG_INFO
,"VTD (%d) enabled!<<<<<<\n",Index
));
296 // Need disable PMR, since we already setup translation table.
306 Disable DMAR translation.
308 @retval EFI_SUCCESS DMAR translation is disabled.
309 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.
320 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
321 DEBUG((DEBUG_INFO
, ">>>>>>DisableDmar() for engine [%d] \n", Index
));
324 // Write Buffer Flush before invalidation
326 FlushWriteBuffer (Index
);
331 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
333 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
334 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
336 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
337 DEBUG((DEBUG_INFO
, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32
));
339 DEBUG ((DEBUG_INFO
,"VTD (%d) Disabled!<<<<<<\n",Index
));
344 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
345 DEBUG((DEBUG_INFO
, "engine [%d] access\n", Index
));
346 for (SubIndex
= 0; SubIndex
< mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
; SubIndex
++) {
347 DEBUG ((DEBUG_INFO
, " PCI S%04X B%02x D%02x F%02x - %d\n",
348 mVtdUnitInformation
[Index
].Segment
,
349 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Bus
,
350 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Device
,
351 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Function
,
352 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].AccessCount
361 Dump VTd capability registers.
363 @param[in] CapReg The capability register.
367 IN VTD_CAP_REG
*CapReg
370 DEBUG((DEBUG_INFO
, " CapReg:\n", CapReg
->Uint64
));
371 DEBUG((DEBUG_INFO
, " ND - 0x%x\n", CapReg
->Bits
.ND
));
372 DEBUG((DEBUG_INFO
, " AFL - 0x%x\n", CapReg
->Bits
.AFL
));
373 DEBUG((DEBUG_INFO
, " RWBF - 0x%x\n", CapReg
->Bits
.RWBF
));
374 DEBUG((DEBUG_INFO
, " PLMR - 0x%x\n", CapReg
->Bits
.PLMR
));
375 DEBUG((DEBUG_INFO
, " PHMR - 0x%x\n", CapReg
->Bits
.PHMR
));
376 DEBUG((DEBUG_INFO
, " CM - 0x%x\n", CapReg
->Bits
.CM
));
377 DEBUG((DEBUG_INFO
, " SAGAW - 0x%x\n", CapReg
->Bits
.SAGAW
));
378 DEBUG((DEBUG_INFO
, " MGAW - 0x%x\n", CapReg
->Bits
.MGAW
));
379 DEBUG((DEBUG_INFO
, " ZLR - 0x%x\n", CapReg
->Bits
.ZLR
));
380 DEBUG((DEBUG_INFO
, " FRO - 0x%x\n", CapReg
->Bits
.FRO
));
381 DEBUG((DEBUG_INFO
, " SLLPS - 0x%x\n", CapReg
->Bits
.SLLPS
));
382 DEBUG((DEBUG_INFO
, " PSI - 0x%x\n", CapReg
->Bits
.PSI
));
383 DEBUG((DEBUG_INFO
, " NFR - 0x%x\n", CapReg
->Bits
.NFR
));
384 DEBUG((DEBUG_INFO
, " MAMV - 0x%x\n", CapReg
->Bits
.MAMV
));
385 DEBUG((DEBUG_INFO
, " DWD - 0x%x\n", CapReg
->Bits
.DWD
));
386 DEBUG((DEBUG_INFO
, " DRD - 0x%x\n", CapReg
->Bits
.DRD
));
387 DEBUG((DEBUG_INFO
, " FL1GP - 0x%x\n", CapReg
->Bits
.FL1GP
));
388 DEBUG((DEBUG_INFO
, " PI - 0x%x\n", CapReg
->Bits
.PI
));
392 Dump VTd extended capability registers.
394 @param[in] ECapReg The extended capability register.
398 IN VTD_ECAP_REG
*ECapReg
401 DEBUG((DEBUG_INFO
, " ECapReg:\n", ECapReg
->Uint64
));
402 DEBUG((DEBUG_INFO
, " C - 0x%x\n", ECapReg
->Bits
.C
));
403 DEBUG((DEBUG_INFO
, " QI - 0x%x\n", ECapReg
->Bits
.QI
));
404 DEBUG((DEBUG_INFO
, " DT - 0x%x\n", ECapReg
->Bits
.DT
));
405 DEBUG((DEBUG_INFO
, " IR - 0x%x\n", ECapReg
->Bits
.IR
));
406 DEBUG((DEBUG_INFO
, " EIM - 0x%x\n", ECapReg
->Bits
.EIM
));
407 DEBUG((DEBUG_INFO
, " PT - 0x%x\n", ECapReg
->Bits
.PT
));
408 DEBUG((DEBUG_INFO
, " SC - 0x%x\n", ECapReg
->Bits
.SC
));
409 DEBUG((DEBUG_INFO
, " IRO - 0x%x\n", ECapReg
->Bits
.IRO
));
410 DEBUG((DEBUG_INFO
, " MHMV - 0x%x\n", ECapReg
->Bits
.MHMV
));
411 DEBUG((DEBUG_INFO
, " ECS - 0x%x\n", ECapReg
->Bits
.ECS
));
412 DEBUG((DEBUG_INFO
, " MTS - 0x%x\n", ECapReg
->Bits
.MTS
));
413 DEBUG((DEBUG_INFO
, " NEST - 0x%x\n", ECapReg
->Bits
.NEST
));
414 DEBUG((DEBUG_INFO
, " DIS - 0x%x\n", ECapReg
->Bits
.DIS
));
415 DEBUG((DEBUG_INFO
, " PASID - 0x%x\n", ECapReg
->Bits
.PASID
));
416 DEBUG((DEBUG_INFO
, " PRS - 0x%x\n", ECapReg
->Bits
.PRS
));
417 DEBUG((DEBUG_INFO
, " ERS - 0x%x\n", ECapReg
->Bits
.ERS
));
418 DEBUG((DEBUG_INFO
, " SRS - 0x%x\n", ECapReg
->Bits
.SRS
));
419 DEBUG((DEBUG_INFO
, " NWFS - 0x%x\n", ECapReg
->Bits
.NWFS
));
420 DEBUG((DEBUG_INFO
, " EAFS - 0x%x\n", ECapReg
->Bits
.EAFS
));
421 DEBUG((DEBUG_INFO
, " PSS - 0x%x\n", ECapReg
->Bits
.PSS
));
427 @param[in] VtdIndex The index of VTd engine.
436 VTD_FRCD_REG FrcdReg
;
439 VTD_SOURCE_ID SourceId
;
441 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) Begin ####\n", VtdIndex
));
443 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_VER_REG
);
444 DEBUG((DEBUG_INFO
, " VER_REG - 0x%08x\n", Reg32
));
446 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CAP_REG
);
447 DEBUG((DEBUG_INFO
, " CAP_REG - 0x%016lx\n", CapReg
.Uint64
));
449 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_ECAP_REG
);
450 DEBUG((DEBUG_INFO
, " ECAP_REG - 0x%016lx\n", Reg64
));
452 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
453 DEBUG((DEBUG_INFO
, " GSTS_REG - 0x%08x \n", Reg32
));
455 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_RTADDR_REG
);
456 DEBUG((DEBUG_INFO
, " RTADDR_REG - 0x%016lx\n", Reg64
));
458 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
459 DEBUG((DEBUG_INFO
, " CCMD_REG - 0x%016lx\n", Reg64
));
461 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FSTS_REG
);
462 DEBUG((DEBUG_INFO
, " FSTS_REG - 0x%08x\n", Reg32
));
464 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FECTL_REG
);
465 DEBUG((DEBUG_INFO
, " FECTL_REG - 0x%08x\n", Reg32
));
467 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
468 DEBUG((DEBUG_INFO
, " FEDATA_REG - 0x%08x\n", Reg32
));
470 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEADDR_REG
);
471 DEBUG((DEBUG_INFO
, " FEADDR_REG - 0x%08x\n",Reg32
));
473 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEUADDR_REG
);
474 DEBUG((DEBUG_INFO
, " FEUADDR_REG - 0x%08x\n",Reg32
));
476 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
477 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
478 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
479 DEBUG((DEBUG_INFO
, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index
, FrcdReg
.Uint64
[1], FrcdReg
.Uint64
[0]));
480 if (FrcdReg
.Uint64
[1] != 0 || FrcdReg
.Uint64
[0] != 0) {
481 DEBUG((DEBUG_INFO
, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg
.Bits
.FILo
, FrcdReg
.Bits
.FIHi
)));
482 SourceId
.Uint16
= (UINT16
)FrcdReg
.Bits
.SID
;
483 DEBUG((DEBUG_INFO
, " Source - B%02x D%02x F%02x\n", SourceId
.Bits
.Bus
, SourceId
.Bits
.Device
, SourceId
.Bits
.Function
));
484 DEBUG((DEBUG_INFO
, " Type - %x (%a)\n", FrcdReg
.Bits
.T
, FrcdReg
.Bits
.T
? "read" : "write"));
485 DEBUG((DEBUG_INFO
, " Reason - %x\n", FrcdReg
.Bits
.FR
));
489 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IVA_REG
);
490 DEBUG((DEBUG_INFO
, " IVA_REG - 0x%016lx\n",Reg64
));
492 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
493 DEBUG((DEBUG_INFO
, " IOTLB_REG - 0x%016lx\n",Reg64
));
495 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) End ####\n", VtdIndex
));
499 Dump VTd registers for all VTd engine.
508 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
514 Dump VTd registers if there is error.
523 VTD_FRCD_REG FrcdReg
;
528 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
530 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
);
534 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FECTL_REG
);
535 if ((Reg32
& BIT30
) != 0) {
539 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_CAP_REG
);
540 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
541 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
542 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
543 if (FrcdReg
.Bits
.F
!= 0) {
549 DEBUG((DEBUG_INFO
, "\n#### ERROR ####\n"));
551 DEBUG((DEBUG_INFO
, "#### ERROR ####\n\n"));
555 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
556 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
557 if (FrcdReg
.Bits
.F
!= 0) {
559 MmioWrite64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)), FrcdReg
.Uint64
[1]);
561 MmioWrite32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
, MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
));