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 Enable DMAR translation.
201 @retval EFI_SUCCESS DMAR translation is enabled.
202 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
212 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
213 DEBUG((DEBUG_INFO
, ">>>>>>EnableDmar() for engine [%d] \n", Index
));
215 if (mVtdUnitInformation
[Index
].ExtRootEntryTable
!= NULL
) {
216 DEBUG((DEBUG_INFO
, "ExtRootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].ExtRootEntryTable
));
217 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].ExtRootEntryTable
| BIT11
);
219 DEBUG((DEBUG_INFO
, "RootEntryTable 0x%x \n", mVtdUnitInformation
[Index
].RootEntryTable
));
220 MmioWrite64 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_RTADDR_REG
, (UINT64
)(UINTN
)mVtdUnitInformation
[Index
].RootEntryTable
);
223 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
225 DEBUG((DEBUG_INFO
, "EnableDmar: waiting for RTPS bit to be set... \n"));
227 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
228 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
231 // Init DMAr Fault Event and Data registers
233 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
236 // Write Buffer Flush before invalidation
238 FlushWriteBuffer (Index
);
241 // Invalidate the context cache
243 InvalidateContextCache (Index
);
246 // Invalidate the IOTLB cache
248 InvalidateIOTLB (Index
);
253 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_TE
);
254 DEBUG((DEBUG_INFO
, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
256 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
257 } while ((Reg32
& B_GSTS_REG_TE
) == 0);
259 DEBUG ((DEBUG_INFO
,"VTD (%d) enabled!<<<<<<\n",Index
));
268 Disable DMAR translation.
270 @retval EFI_SUCCESS DMAR translation is disabled.
271 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.
282 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
283 DEBUG((DEBUG_INFO
, ">>>>>>DisableDmar() for engine [%d] \n", Index
));
286 // Write Buffer Flush before invalidation
288 FlushWriteBuffer (Index
);
293 MmioWrite32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GCMD_REG
, B_GMCD_REG_SRTP
);
295 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
296 } while((Reg32
& B_GSTS_REG_RTPS
) == 0);
298 Reg32
= MmioRead32 (mVtdUnitInformation
[Index
].VtdUnitBaseAddress
+ R_GSTS_REG
);
299 DEBUG((DEBUG_INFO
, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32
));
301 DEBUG ((DEBUG_INFO
,"VTD (%d) Disabled!<<<<<<\n",Index
));
306 for (Index
= 0; Index
< mVtdUnitNumber
; Index
++) {
307 DEBUG((DEBUG_INFO
, "engine [%d] access\n", Index
));
308 for (SubIndex
= 0; SubIndex
< mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceDataNumber
; SubIndex
++) {
309 DEBUG ((DEBUG_INFO
, " PCI S%04X B%02x D%02x F%02x - %d\n",
310 mVtdUnitInformation
[Index
].Segment
,
311 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Bus
,
312 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Device
,
313 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].PciSourceId
.Bits
.Function
,
314 mVtdUnitInformation
[Index
].PciDeviceInfo
.PciDeviceData
[Index
].AccessCount
323 Dump VTd capability registers.
325 @param[in] CapReg The capability register.
329 IN VTD_CAP_REG
*CapReg
332 DEBUG((DEBUG_INFO
, " CapReg:\n", CapReg
->Uint64
));
333 DEBUG((DEBUG_INFO
, " ND - 0x%x\n", CapReg
->Bits
.ND
));
334 DEBUG((DEBUG_INFO
, " AFL - 0x%x\n", CapReg
->Bits
.AFL
));
335 DEBUG((DEBUG_INFO
, " RWBF - 0x%x\n", CapReg
->Bits
.RWBF
));
336 DEBUG((DEBUG_INFO
, " PLMR - 0x%x\n", CapReg
->Bits
.PLMR
));
337 DEBUG((DEBUG_INFO
, " PHMR - 0x%x\n", CapReg
->Bits
.PHMR
));
338 DEBUG((DEBUG_INFO
, " CM - 0x%x\n", CapReg
->Bits
.CM
));
339 DEBUG((DEBUG_INFO
, " SAGAW - 0x%x\n", CapReg
->Bits
.SAGAW
));
340 DEBUG((DEBUG_INFO
, " MGAW - 0x%x\n", CapReg
->Bits
.MGAW
));
341 DEBUG((DEBUG_INFO
, " ZLR - 0x%x\n", CapReg
->Bits
.ZLR
));
342 DEBUG((DEBUG_INFO
, " FRO - 0x%x\n", CapReg
->Bits
.FRO
));
343 DEBUG((DEBUG_INFO
, " SLLPS - 0x%x\n", CapReg
->Bits
.SLLPS
));
344 DEBUG((DEBUG_INFO
, " PSI - 0x%x\n", CapReg
->Bits
.PSI
));
345 DEBUG((DEBUG_INFO
, " NFR - 0x%x\n", CapReg
->Bits
.NFR
));
346 DEBUG((DEBUG_INFO
, " MAMV - 0x%x\n", CapReg
->Bits
.MAMV
));
347 DEBUG((DEBUG_INFO
, " DWD - 0x%x\n", CapReg
->Bits
.DWD
));
348 DEBUG((DEBUG_INFO
, " DRD - 0x%x\n", CapReg
->Bits
.DRD
));
349 DEBUG((DEBUG_INFO
, " FL1GP - 0x%x\n", CapReg
->Bits
.FL1GP
));
350 DEBUG((DEBUG_INFO
, " PI - 0x%x\n", CapReg
->Bits
.PI
));
354 Dump VTd extended capability registers.
356 @param[in] ECapReg The extended capability register.
360 IN VTD_ECAP_REG
*ECapReg
363 DEBUG((DEBUG_INFO
, " ECapReg:\n", ECapReg
->Uint64
));
364 DEBUG((DEBUG_INFO
, " C - 0x%x\n", ECapReg
->Bits
.C
));
365 DEBUG((DEBUG_INFO
, " QI - 0x%x\n", ECapReg
->Bits
.QI
));
366 DEBUG((DEBUG_INFO
, " DT - 0x%x\n", ECapReg
->Bits
.DT
));
367 DEBUG((DEBUG_INFO
, " IR - 0x%x\n", ECapReg
->Bits
.IR
));
368 DEBUG((DEBUG_INFO
, " EIM - 0x%x\n", ECapReg
->Bits
.EIM
));
369 DEBUG((DEBUG_INFO
, " PT - 0x%x\n", ECapReg
->Bits
.PT
));
370 DEBUG((DEBUG_INFO
, " SC - 0x%x\n", ECapReg
->Bits
.SC
));
371 DEBUG((DEBUG_INFO
, " IRO - 0x%x\n", ECapReg
->Bits
.IRO
));
372 DEBUG((DEBUG_INFO
, " MHMV - 0x%x\n", ECapReg
->Bits
.MHMV
));
373 DEBUG((DEBUG_INFO
, " ECS - 0x%x\n", ECapReg
->Bits
.ECS
));
374 DEBUG((DEBUG_INFO
, " MTS - 0x%x\n", ECapReg
->Bits
.MTS
));
375 DEBUG((DEBUG_INFO
, " NEST - 0x%x\n", ECapReg
->Bits
.NEST
));
376 DEBUG((DEBUG_INFO
, " DIS - 0x%x\n", ECapReg
->Bits
.DIS
));
377 DEBUG((DEBUG_INFO
, " PASID - 0x%x\n", ECapReg
->Bits
.PASID
));
378 DEBUG((DEBUG_INFO
, " PRS - 0x%x\n", ECapReg
->Bits
.PRS
));
379 DEBUG((DEBUG_INFO
, " ERS - 0x%x\n", ECapReg
->Bits
.ERS
));
380 DEBUG((DEBUG_INFO
, " SRS - 0x%x\n", ECapReg
->Bits
.SRS
));
381 DEBUG((DEBUG_INFO
, " NWFS - 0x%x\n", ECapReg
->Bits
.NWFS
));
382 DEBUG((DEBUG_INFO
, " EAFS - 0x%x\n", ECapReg
->Bits
.EAFS
));
383 DEBUG((DEBUG_INFO
, " PSS - 0x%x\n", ECapReg
->Bits
.PSS
));
389 @param[in] VtdIndex The index of VTd engine.
398 VTD_FRCD_REG FrcdReg
;
401 VTD_SOURCE_ID SourceId
;
403 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) Begin ####\n", VtdIndex
));
405 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_VER_REG
);
406 DEBUG((DEBUG_INFO
, " VER_REG - 0x%08x\n", Reg32
));
408 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CAP_REG
);
409 DEBUG((DEBUG_INFO
, " CAP_REG - 0x%016lx\n", CapReg
.Uint64
));
411 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_ECAP_REG
);
412 DEBUG((DEBUG_INFO
, " ECAP_REG - 0x%016lx\n", Reg64
));
414 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_GSTS_REG
);
415 DEBUG((DEBUG_INFO
, " GSTS_REG - 0x%08x \n", Reg32
));
417 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_RTADDR_REG
);
418 DEBUG((DEBUG_INFO
, " RTADDR_REG - 0x%016lx\n", Reg64
));
420 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_CCMD_REG
);
421 DEBUG((DEBUG_INFO
, " CCMD_REG - 0x%016lx\n", Reg64
));
423 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FSTS_REG
);
424 DEBUG((DEBUG_INFO
, " FSTS_REG - 0x%08x\n", Reg32
));
426 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FECTL_REG
);
427 DEBUG((DEBUG_INFO
, " FECTL_REG - 0x%08x\n", Reg32
));
429 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEDATA_REG
);
430 DEBUG((DEBUG_INFO
, " FEDATA_REG - 0x%08x\n", Reg32
));
432 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEADDR_REG
);
433 DEBUG((DEBUG_INFO
, " FEADDR_REG - 0x%08x\n",Reg32
));
435 Reg32
= MmioRead32 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ R_FEUADDR_REG
);
436 DEBUG((DEBUG_INFO
, " FEUADDR_REG - 0x%08x\n",Reg32
));
438 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
439 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
440 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
441 DEBUG((DEBUG_INFO
, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index
, FrcdReg
.Uint64
[1], FrcdReg
.Uint64
[0]));
442 if (FrcdReg
.Uint64
[1] != 0 || FrcdReg
.Uint64
[0] != 0) {
443 DEBUG((DEBUG_INFO
, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg
.Bits
.FILo
, FrcdReg
.Bits
.FIHi
)));
444 SourceId
.Uint16
= (UINT16
)FrcdReg
.Bits
.SID
;
445 DEBUG((DEBUG_INFO
, " Source - B%02x D%02x F%02x\n", SourceId
.Bits
.Bus
, SourceId
.Bits
.Device
, SourceId
.Bits
.Function
));
446 DEBUG((DEBUG_INFO
, " Type - %x (%a)\n", FrcdReg
.Bits
.T
, FrcdReg
.Bits
.T
? "read" : "write"));
447 DEBUG((DEBUG_INFO
, " Reason - %x\n", FrcdReg
.Bits
.FR
));
451 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IVA_REG
);
452 DEBUG((DEBUG_INFO
, " IVA_REG - 0x%016lx\n",Reg64
));
454 Reg64
= MmioRead64 (mVtdUnitInformation
[VtdIndex
].VtdUnitBaseAddress
+ (mVtdUnitInformation
[VtdIndex
].ECapReg
.Bits
.IRO
* 16) + R_IOTLB_REG
);
455 DEBUG((DEBUG_INFO
, " IOTLB_REG - 0x%016lx\n",Reg64
));
457 DEBUG((DEBUG_INFO
, "#### DumpVtdRegs(%d) End ####\n", VtdIndex
));
461 Dump VTd registers for all VTd engine.
470 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
476 Dump VTd registers if there is error.
485 VTD_FRCD_REG FrcdReg
;
490 for (Num
= 0; Num
< mVtdUnitNumber
; Num
++) {
492 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FSTS_REG
);
496 Reg32
= MmioRead32 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_FECTL_REG
);
497 if ((Reg32
& BIT30
) != 0) {
501 CapReg
.Uint64
= MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ R_CAP_REG
);
502 for (Index
= 0; Index
< (UINTN
)CapReg
.Bits
.NFR
+ 1; Index
++) {
503 FrcdReg
.Uint64
[0] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
));
504 FrcdReg
.Uint64
[1] = MmioRead64 (mVtdUnitInformation
[Num
].VtdUnitBaseAddress
+ ((CapReg
.Bits
.FRO
* 16) + (Index
* 16) + R_FRCD_REG
+ sizeof(UINT64
)));
505 if ((FrcdReg
.Uint64
[0] != 0) || (FrcdReg
.Uint64
[1] != 0)) {
511 DEBUG((DEBUG_INFO
, "#### ERROR ####\n"));
513 DEBUG((DEBUG_INFO
, "#### ERROR ####\n"));