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 Invalid VTd global IOTLB.
25 @param[in] VtdIndex The index of VTd engine.
27 @retval EFI_SUCCESS VTd global IOTLB is invalidated.
28 @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
31 InvalidateVtdIOTLBGlobal (
42 DEBUG((DEBUG_VERBOSE
, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex
));
47 // Write Buffer Flush before invalidation
49 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CAP_REG
);
50 if ((Reg32
& B_CAP_REG_RWBF
) != 0) {
51 MmioWrite32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_WBF
);
55 // Invalidate the context cache
57 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
58 if ((Reg64
& B_CCMD_REG_ICC
) != 0) {
59 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateVtdIOTLBGlobal: B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex
));
60 return EFI_DEVICE_ERROR
;
63 Reg64
&= ((~B_CCMD_REG_ICC
) & (~B_CCMD_REG_CIRG_MASK
));
64 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_GLOBAL
);
65 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
, Reg64
);
68 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
69 } while ((Reg64
& B_CCMD_REG_ICC
) != 0);
72 // Invalidate the IOTLB cache
75 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
76 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
77 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateVtdIOTLBGlobal: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex
));
78 return EFI_DEVICE_ERROR
;
81 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
82 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_GLOBAL
);
83 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
86 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
87 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
92 MmioWrite32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
94 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
95 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
100 MmioWrite32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_TE
);
102 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
103 } while ((Reg32
& B_GSTS_REG_TE
) == 0);
109 Invalid VTd IOTLB domain.
111 @param[in] VtdIndex The index of VTd engine.
112 @param[in] DomainIdentifier The domain ID of the source.
114 @retval EFI_SUCCESS VTd IOTLB domain is invalidated.
115 @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated.
118 InvalidateVtdIOTLBDomain (
120 IN UINT16 DomainIdentifier
129 DEBUG((DEBUG_VERBOSE
, "InvalidateVtdIOTLBDomain(%d): 0x%016lx (0x%04x)\n", VtdIndex
, DomainIdentifier
));
132 // Invalidate the context cache
134 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
135 if ((Reg64
& B_CCMD_REG_ICC
) != 0) {
136 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateVtdIOTLBDomain: B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex
));
137 return EFI_DEVICE_ERROR
;
140 Reg64
&= ((~B_CCMD_REG_ICC
) & (~B_CCMD_REG_CIRG_MASK
));
141 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_DOMAIN
);
142 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_DOMAIN
);
143 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
, Reg64
);
146 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
147 } while ((Reg64
& B_CCMD_REG_ICC
) != 0);
150 // Invalidate the IOTLB cache
153 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
154 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
155 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateVtdIOTLBDomain: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex
));
156 return EFI_DEVICE_ERROR
;
159 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
160 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_DOMAIN
);
161 Reg64
|= LShiftU64 (DomainIdentifier
, 32);
162 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
165 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
166 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
172 Invalid VTd IOTLB page.
174 @param[in] VtdIndex The index of VTd engine.
175 @param[in] Address The address of IOTLB page.
176 @param[in] AddressMode The address mode of IOTLB page.
177 @param[in] DomainIdentifier The domain ID of the source.
179 @retval EFI_SUCCESS VTd IOTLB page is invalidated.
180 @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated.
183 InvalidateVtdIOTLBPage (
186 IN UINT8 AddressMode
,
187 IN UINT16 DomainIdentifier
197 DEBUG((DEBUG_VERBOSE
, "InvalidateVtdIOTLBPage(%d): 0x%016lx (0x%02x)\n", VtdIndex
, Address
, AddressMode
));
199 if (mVtdUnitInformation
[VtdIndex
].CapReg
.Bits
.PSI
!= 0) {
200 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
201 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
202 DEBUG ((DEBUG_ERROR
,"ERROR: InvalidateVtdIOTLBPage: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex
));
203 return EFI_DEVICE_ERROR
;
206 Data64
= Address
| AddressMode
;
207 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IVA_REG
, Data64
);
209 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
210 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_PAGE
);
211 Reg64
|= LShiftU64 (DomainIdentifier
, 32);
212 MmioWrite64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
215 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
216 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
218 InvalidateVtdIOTLBGlobal (VtdIndex
);
225 Prepare VTD configuration.
235 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
236 DEBUG ((DEBUG_INFO
, "Dump VTd Capability (%d)\n", Index
));
237 mVtdUnitInformation
[Index
].CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
238 DumpVtdCapRegs (&mVtdUnitInformation
[Index
].CapReg
);
239 mVtdUnitInformation
[Index
].ECapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_ECAP_REG
);
240 DumpVtdECapRegs (&mVtdUnitInformation
[Index
].ECapReg
);
242 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SLLPS
& BIT0
) == 0) {
243 DEBUG((DEBUG_WARN
, "!!!! 2MB super page is not supported on VTD %d !!!!\n", Index
));
245 if ((mVtdUnitInformation
[Index
].CapReg
.Bits
.SAGAW
& BIT2
) == 0) {
246 DEBUG((DEBUG_ERROR
, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", Index
));
250 DomainNumber
= (UINTN
)1 << (UINT8
)((UINTN
)mVtdUnitInformation
[Index
].CapReg
.Bits
.ND
* 2 + 4);
251 if (mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDescriptorNumber
>= DomainNumber
) {
252 DEBUG((DEBUG_ERROR
, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDescriptorNumber
, DomainNumber
));
260 Enable DMAR translation.
262 @retval EFI_SUCCESS DMAR translation is enabled.
263 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
276 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
277 DEBUG((DEBUG_INFO
, ">>>>>>EnableDmar() for engine [%d] \n", Index
));
279 if (mVtdUnitInformation
[Index
].ExtRootEntryTable
!= NULL
) {
280 DEBUG((DEBUG_INFO
, "ExtRootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].ExtRootEntryTable
));
281 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].ExtRootEntryTable
| BIT11
);
283 DEBUG((DEBUG_INFO
, "RootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].RootEntryTable
));
284 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].RootEntryTable
);
287 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
289 DEBUG((DEBUG_INFO
, "EnableDmar: waiting for RTPS bit to be set... \n"));
291 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
292 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
295 // Init DMAr Fault Event and Data registers
297 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
300 // Write Buffer Flush before invalidation
302 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
303 if ((Reg32
& B_CAP_REG_RWBF
) != 0) {
304 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_WBF
);
308 // Invalidate the context cache
310 Reg64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CCMD_REG
);
311 if ((Reg64
& B_CCMD_REG_ICC
) != 0) {
312 DEBUG ((DEBUG_INFO
,"ERROR: EnableDmar: B_CCMD_REG_ICC is set for VTD(%d)\n",Index
));
313 return EFI_DEVICE_ERROR
;
316 Reg64
&= ((~B_CCMD_REG_ICC
) & (~B_CCMD_REG_CIRG_MASK
));
317 Reg64
|= (B_CCMD_REG_ICC
| V_CCMD_REG_CIRG_GLOBAL
);
318 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CCMD_REG
, Reg64
);
320 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_CCMD_REG_ICC ...\n"));
322 Reg64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CCMD_REG
);
323 } while ((Reg64
& B_CCMD_REG_ICC
) != 0);
326 // Invalidate the IOTLB cache
328 DEBUG((DEBUG_INFO
, "EnableDmar: IRO 0x%x\n", mVtdUnitInformation
[Index
].ECapReg
.Bits
.IRO
));
330 Reg64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[Index
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
331 if ((Reg64
& B_IOTLB_REG_IVT
) != 0) {
332 DEBUG ((DEBUG_INFO
,"ERROR: EnableDmar: B_IOTLB_REG_IVT is set for VTD(%d)\n", Index
));
333 return EFI_DEVICE_ERROR
;
336 Reg64
&= ((~B_IOTLB_REG_IVT
) & (~B_IOTLB_REG_IIRG_MASK
));
337 Reg64
|= (B_IOTLB_REG_IVT
| V_IOTLB_REG_IIRG_GLOBAL
);
338 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[Index
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
, Reg64
);
340 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_IOTLB_REG_IVT ...\n"));
342 Reg64
= MmioRead64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[Index
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
343 } while ((Reg64
& B_IOTLB_REG_IVT
) != 0);
348 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_TE
);
349 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
351 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
352 } while ((Reg32
& B_GSTS_REG_TE
) == 0);
354 DEBUG ((DEBUG_INFO
,"VTD (%d) enabled!<<<<<<\n",Index
));
363 Disable DMAR translation.
365 @retval EFI_SUCCESS DMAR translation is disabled.
366 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.
378 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
379 DEBUG((DEBUG_INFO
, ">>>>>>DisableDmar() for engine [%d] \n", Index
));
382 // Write Buffer Flush before invalidation
384 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_CAP_REG
);
385 if ((Reg32
& B_CAP_REG_RWBF
) != 0) {
386 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_WBF
);
392 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
394 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
395 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
397 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
398 DEBUG((DEBUG_INFO
, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32
));
400 DEBUG ((DEBUG_INFO
,"VTD (%d) Disabled!<<<<<<\n",Index
));
409 Dump VTd capability registers.
411 @param[in] CapReg The capability register.
415 IN VTD_CAP_REG
*CapReg
418 DEBUG((DEBUG_INFO
, " CapReg:\n", CapReg
->Uint64
));
419 DEBUG((DEBUG_INFO
, " ND - 0x%x\n", CapReg
->Bits
.ND
));
420 DEBUG((DEBUG_INFO
, " AFL - 0x%x\n", CapReg
->Bits
.AFL
));
421 DEBUG((DEBUG_INFO
, " RWBF - 0x%x\n", CapReg
->Bits
.RWBF
));
422 DEBUG((DEBUG_INFO
, " PLMR - 0x%x\n", CapReg
->Bits
.PLMR
));
423 DEBUG((DEBUG_INFO
, " PHMR - 0x%x\n", CapReg
->Bits
.PHMR
));
424 DEBUG((DEBUG_INFO
, " CM - 0x%x\n", CapReg
->Bits
.CM
));
425 DEBUG((DEBUG_INFO
, " SAGAW - 0x%x\n", CapReg
->Bits
.SAGAW
));
426 DEBUG((DEBUG_INFO
, " MGAW - 0x%x\n", CapReg
->Bits
.MGAW
));
427 DEBUG((DEBUG_INFO
, " ZLR - 0x%x\n", CapReg
->Bits
.ZLR
));
428 DEBUG((DEBUG_INFO
, " FRO - 0x%x\n", CapReg
->Bits
.FRO
));
429 DEBUG((DEBUG_INFO
, " SLLPS - 0x%x\n", CapReg
->Bits
.SLLPS
));
430 DEBUG((DEBUG_INFO
, " PSI - 0x%x\n", CapReg
->Bits
.PSI
));
431 DEBUG((DEBUG_INFO
, " NFR - 0x%x\n", CapReg
->Bits
.NFR
));
432 DEBUG((DEBUG_INFO
, " MAMV - 0x%x\n", CapReg
->Bits
.MAMV
));
433 DEBUG((DEBUG_INFO
, " DWD - 0x%x\n", CapReg
->Bits
.DWD
));
434 DEBUG((DEBUG_INFO
, " DRD - 0x%x\n", CapReg
->Bits
.DRD
));
435 DEBUG((DEBUG_INFO
, " FL1GP - 0x%x\n", CapReg
->Bits
.FL1GP
));
436 DEBUG((DEBUG_INFO
, " PI - 0x%x\n", CapReg
->Bits
.PI
));
440 Dump VTd extended capability registers.
442 @param[in] ECapReg The extended capability register.
446 IN VTD_ECAP_REG
*ECapReg
449 DEBUG((DEBUG_INFO
, " ECapReg:\n", ECapReg
->Uint64
));
450 DEBUG((DEBUG_INFO
, " C - 0x%x\n", ECapReg
->Bits
.C
));
451 DEBUG((DEBUG_INFO
, " QI - 0x%x\n", ECapReg
->Bits
.QI
));
452 DEBUG((DEBUG_INFO
, " DT - 0x%x\n", ECapReg
->Bits
.DT
));
453 DEBUG((DEBUG_INFO
, " IR - 0x%x\n", ECapReg
->Bits
.IR
));
454 DEBUG((DEBUG_INFO
, " EIM - 0x%x\n", ECapReg
->Bits
.EIM
));
455 DEBUG((DEBUG_INFO
, " PT - 0x%x\n", ECapReg
->Bits
.PT
));
456 DEBUG((DEBUG_INFO
, " SC - 0x%x\n", ECapReg
->Bits
.SC
));
457 DEBUG((DEBUG_INFO
, " IRO - 0x%x\n", ECapReg
->Bits
.IRO
));
458 DEBUG((DEBUG_INFO
, " MHMV - 0x%x\n", ECapReg
->Bits
.MHMV
));
459 DEBUG((DEBUG_INFO
, " ECS - 0x%x\n", ECapReg
->Bits
.ECS
));
460 DEBUG((DEBUG_INFO
, " MTS - 0x%x\n", ECapReg
->Bits
.MTS
));
461 DEBUG((DEBUG_INFO
, " NEST - 0x%x\n", ECapReg
->Bits
.NEST
));
462 DEBUG((DEBUG_INFO
, " DIS - 0x%x\n", ECapReg
->Bits
.DIS
));
463 DEBUG((DEBUG_INFO
, " PASID - 0x%x\n", ECapReg
->Bits
.PASID
));
464 DEBUG((DEBUG_INFO
, " PRS - 0x%x\n", ECapReg
->Bits
.PRS
));
465 DEBUG((DEBUG_INFO
, " ERS - 0x%x\n", ECapReg
->Bits
.ERS
));
466 DEBUG((DEBUG_INFO
, " SRS - 0x%x\n", ECapReg
->Bits
.SRS
));
467 DEBUG((DEBUG_INFO
, " NWFS - 0x%x\n", ECapReg
->Bits
.NWFS
));
468 DEBUG((DEBUG_INFO
, " EAFS - 0x%x\n", ECapReg
->Bits
.EAFS
));
469 DEBUG((DEBUG_INFO
, " PSS - 0x%x\n", ECapReg
->Bits
.PSS
));
475 @param[in] VtdIndex The index of VTd engine.
484 VTD_FRCD_REG FrcdReg
;
487 VTD_SOURCE_ID SourceId
;
489 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) Begin ####\n", VtdIndex
));
491 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_VER_REG
);
492 DEBUG((DEBUG_INFO
, " VER_REG - 0x%08x\n", Reg32
));
494 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CAP_REG
);
495 DEBUG((DEBUG_INFO
, " CAP_REG - 0x%016lx\n", CapReg
.Uint64
));
497 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_ECAP_REG
);
498 DEBUG((DEBUG_INFO
, " ECAP_REG - 0x%016lx\n", Reg64
));
500 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
501 DEBUG((DEBUG_INFO
, " GSTS_REG - 0x%08x \n", Reg32
));
503 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_RTADDR_REG
);
504 DEBUG((DEBUG_INFO
, " RTADDR_REG - 0x%016lx\n", Reg64
));
506 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
507 DEBUG((DEBUG_INFO
, " CCMD_REG - 0x%016lx\n", Reg64
));
509 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FSTS_REG
);
510 DEBUG((DEBUG_INFO
, " FSTS_REG - 0x%08x\n", Reg32
));
512 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FECTL_REG
);
513 DEBUG((DEBUG_INFO
, " FECTL_REG - 0x%08x\n", Reg32
));
515 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
516 DEBUG((DEBUG_INFO
, " FEDATA_REG - 0x%08x\n", Reg32
));
518 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEADDR_REG
);
519 DEBUG((DEBUG_INFO
, " FEADDR_REG - 0x%08x\n",Reg32
));
521 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEUADDR_REG
);
522 DEBUG((DEBUG_INFO
, " FEUADDR_REG - 0x%08x\n",Reg32
));
524 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
525 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
526 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
527 DEBUG((DEBUG_INFO
, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index
, FrcdReg
.Uint64
[1], FrcdReg
.Uint64
[0]));
528 if (FrcdReg
.Uint64
[1] != 0 || FrcdReg
.Uint64
[0] != 0) {
529 DEBUG((DEBUG_INFO
, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg
.Bits
.FILo
, FrcdReg
.Bits
.FIHi
)));
530 SourceId
.Uint16
= (UINT16
)FrcdReg
.Bits
.SID
;
531 DEBUG((DEBUG_INFO
, " Source - B%02x D%02x F%02x\n", SourceId
.Bits
.Bus
, SourceId
.Bits
.Device
, SourceId
.Bits
.Function
));
532 DEBUG((DEBUG_INFO
, " Type - %x (%a)\n", FrcdReg
.Bits
.T
, FrcdReg
.Bits
.T
? "read" : "write"));
533 DEBUG((DEBUG_INFO
, " Reason - %x\n", FrcdReg
.Bits
.FR
));
537 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IVA_REG
);
538 DEBUG((DEBUG_INFO
, " IVA_REG - 0x%016lx\n",Reg64
));
540 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
541 DEBUG((DEBUG_INFO
, " IOTLB_REG - 0x%016lx\n",Reg64
));
543 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) End ####\n", VtdIndex
));
547 Dump VTd registers for all VTd engine.
556 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
562 Dump VTd registers if there is error.
571 VTD_FRCD_REG FrcdReg
;
576 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
578 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
);
582 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FECTL_REG
);
583 if ((Reg32
& BIT30
) != 0) {
587 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_CAP_REG
);
588 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
589 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
590 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
591 if ((FrcdReg
.Uint64
[0] != 0) || (FrcdReg
.Uint64
[1] != 0)) {
597 DEBUG((DEBUG_INFO
, "#### ERROR ####\n"));
599 DEBUG((DEBUG_INFO
, "#### ERROR ####\n"));