* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: N2_MemErrDetector.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
#ifndef _N2_MEMERRDETECTOR_H
#define _N2_MEMERRDETECTOR_H
/************************************************************************
** Copyright (C) 2005, Sun Microsystems, Inc.
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy.
*************************************************************************/
#include "MemoryTransaction.h"
#include "SS_MemErrDetector.h"
#include "SS_CsrAccess.h"
#include "BL_CKSyndrome.h"
#include "BL_HammingEcc.h"
#include "BL_Hamming_32_7_Synd.h"
#include "N2_L2AddressingFields.h"
#include "N2_L2CacheFlushAddrFields.h"
#include "N2_L2DiagDataAddressingFields.h"
#include "N2_L2ErrorEnMem.h"
#include "N2_L2ErrorStatusReg.h"
#include "N2_L2ControlReg.h"
#include "N2_L2ErrorAddressReg.h"
#include "N2_L2DiagDataMem.h"
#include "N2_L2DiagTagMem.h"
#include "N2_L2DiagVdMem.h"
#include "N2_L2DiagUaMem.h"
#include "N2_L2NotdataErrorReg.h"
#include "N2_DramErrorStatusMem.h"
#include "N2_DramErrorInjectMem.h"
#include "N2_DramErrorCounterMem.h"
#include "N2_DramErrorLocMem.h"
#include "N2_DramFbdInjectedErrSrcReg.h"
#include "N2_DramFbdCountReg.h"
#include "N2_DramFbdErrorSyndromeReg.h"
#include "N2_SocErrorInjectReg.h"
#include "N2_SocErrorStatusReg.h"
#include "N2_SocPendingErrStatusReg.h"
#include "N2_SocErrorLogEnableReg.h"
#include "N2_SocErrorIntrEnReg.h"
#include "N2_SocFatalErrorEnableReg.h"
#include "N2_SocErrorSteeringReg.h"
* The N2_MemErrDetector class is used to detect injected RAS errors
* associated with the memory hierarchy. In particular, it models and
* detects errors in the primary and secondary caches and DRAM.
#define RAS_OSTR debugOutput_ && cerr
// Memory Error Detector for RAS
// Detects RAS error related to memory access: primary cache,
// secondary cache, DRAM and FBDIMM errors.
class N2_MemErrDetector
: public SS_MemErrDetector
{
// Extend class to include update() method which guarantees (or rather,
// approximates) writing to the L2 Error Status Register.
class N2_CheckedL2ESRAccess
: public SS_CsrAccess
<N2_L2ErrorStatusReg
> {
N2_CheckedL2ESRAccess(SS_Csr
& csr
):
SS_CsrAccess
<N2_L2ErrorStatusReg
>(csr
) {}
~N2_CheckedL2ESRAccess() {}
const N2_CheckedL2ESRAccess
&
operator=( const N2_CheckedL2ESRAccess
&rhs
) {
fprintf(stderr
, "Unimplemented function." );
// add update checking to insure the MEC, MEU, etc. bits are set
// correctly. Returns true if the N2_L2ErrorAddressReg associated
// with the error should also be updated.
bool access(uint64_t ndx
, N2_L2ErrorStatusReg
&csr
, bool isRead
);
// Extend N2_L2DiagVdMem class to include ECC and syndrome calculators
class N2_L2DiagVdMemWithECC
: public N2_L2DiagVdMem
{
N2_L2DiagVdMemWithECC() {}
N2_L2DiagVdMemWithECC( const N2_L2DiagVdMemWithECC
& obj
) :
~N2_L2DiagVdMemWithECC() {}
// Shifts used to convert VD diag data into dirty and valid bits with ECC
static const N2_L2_DIAG_VD_ACCESS_VALID_SHIFT
= 16;
static const N2_L2_DIAG_VD_ACCESS_DIRTY_SHIFT
= 0;
static const N2_L2_DIAG_VD_ACCESS_ECC_SHIFT
= 0;
return (getVALID() << N2_L2_DIAG_VD_ACCESS_VALID_SHIFT
) |
setVALID(vd
>> N2_L2_DIAG_VD_ACCESS_VALID_SHIFT
);
uint32_t calcECC(void) const
return (BL_Hamming_32_7_Synd::calc_check_bits(getVD())).get();
BL_Hamming_32_7_Synd
getSyndrome(void) const
return BL_Hamming_32_7_Synd(getVD(), getVDECC());
struct N2_L2VaudSyndrome
{
N2_L2VaudSyndrome(uint32_t vdSyndrome
,uint32_t uaSyndrome
) :
uaSyndrome_(uaSyndrome
){}
BL_Hamming_32_7_Synd vdSyndrome_
;
BL_Hamming_32_7_Synd uaSyndrome_
;
// Extend N2_L2DiagUaMem class to include ECC and syndrome calculators
class N2_L2DiagUaMemWithECC
: public N2_L2DiagUaMem
{
N2_L2DiagUaMemWithECC() {}
N2_L2DiagUaMemWithECC( const N2_L2DiagUaMemWithECC
& obj
) :
~N2_L2DiagUaMemWithECC() {}
// Shifts used to convert VD diag data into dirty and valid bits with ECC
static const N2_L2_DIAG_UA_ACCESS_USED_SHIFT
= 16;
static const N2_L2_DIAG_UA_ACCESS_ALLOC_SHIFT
= 0;
static const N2_L2_DIAG_UA_ACCESS_ECC_SHIFT
= 0;
return (getUSED() << N2_L2_DIAG_UA_ACCESS_USED_SHIFT
) |
setUSED(vd
>> N2_L2_DIAG_UA_ACCESS_USED_SHIFT
);
uint32_t calcECC(void) const
return (BL_Hamming_32_7_Synd::calc_check_bits(getUA())).get();
BL_Hamming_32_7_Synd
getSyndrome(void) const
return BL_Hamming_32_7_Synd(getUA(), getUAECC());
// Extend N2_L2DiagDataMem class to include ECC and syndrome calculators
class N2_L2DiagDataMemWithECC
: public N2_L2DiagDataMem
{
N2_L2DiagDataMemWithECC() {}
N2_L2DiagDataMemWithECC( const N2_L2DiagDataMemWithECC
& obj
) :
~N2_L2DiagDataMemWithECC() {}
uint32_t calcECC(void) const
return (BL_Hamming_32_7_Synd::calc_check_bits(getDATA())).get();
BL_Hamming_32_7_Synd
getSyndrome(void) const
return BL_Hamming_32_7_Synd(getDATA(), getECC());
static const uint64_t L2_NOT_DATA
= 0x7f;
// This class captures the error status of an L2 cache data quarter
// The ECC syndromes for 4 32-bit words are captured in the
// qLineSyndrome_ field and the physical address corresponding to the
// ECC error, if any, is in the errorPaddr_ field.
class N2_L2CacheLineError
{
N2_L2CacheLineError(uint64_t errorPaddr
) :
virtual ~N2_L2CacheLineError() {}
* @param rhs The right hand side of the assignment operator.
* @return The lvalue of the assignment.
const N2_L2CacheLineError
&
operator=( const N2_L2CacheLineError
&rhs
)
errorType_
= rhs
.errorType_
;
qLineSyndrome_
= rhs
.qLineSyndrome_
;
errorPaddr_
= rhs
.errorPaddr_
;
// if qLineSyndrome, not qLineSyndrome_, compiler bug?!?
bool isError() const { return qLineSyndrome_
!= 0; }
uint32_t qLineSyndrome() const { return qLineSyndrome_
; }
uint64_t errorPaddr() const { return errorPaddr_
; }
bool isCorrectable() const { return isError() &&
errorType_
== CORRECTABLE_ERROR
; }
bool isUncorrectable() const { return isError() &&
(errorType_
== UNCORRECTABLE_ERROR
||
errorType_
== NOT_DATA
); }
bool isNotData() const { return isError() &&
errorType_
== NOT_DATA
; }
void addQuarterLine(BL_Hamming_32_7_Synd wordSyndrome
) {
qLineSyndrome_
|= (wordSyndrome
.getSyndrome() << ( 7 * wordNdx_
++));
// dispatch on current worst cache line error type.
// Incorportate error from current word into quarter line's
case NO_ERROR
: // any new error bad
if (!wordSyndrome
.noError()) {
errorType_
= CORRECTABLE_ERROR
;
/* consider NotData or uncorrectable possibility by
case CORRECTABLE_ERROR
: // is new uncorrectable?
if (wordSyndrome
.isUncorrectableError()) {
errorType_
= UNCORRECTABLE_ERROR
;
/* consider NotData possibility by falling through */
case UNCORRECTABLE_ERROR
: // only NOT_DATA is worse
if (wordSyndrome
.getSyndrome() ==
N2_L2DiagDataMemWithECC::L2_NOT_DATA
) {
case NOT_DATA
: // can't get any worse than this
fprintf(stderr
, "N2_L2CacheLineError::addQuarterLine "
"bad errorType_ 0x%x", errorType_
);
class N2_CererWithBitMux
: public N2_Cerer
{
N2_CererWithBitMux(const N2_CererWithBitMux
&obj
) :
N2_CererWithBitMux(const N2_Cerer
&obj
) :
bool checkOneL2Cbit(const MemoryTransaction
&memXact
) {
(this->l2c_socc() && memXact
.tablewalk()) ||
memXact
.referenceType() == MemoryTransaction::INSTR
) ||
memXact
.referenceType() == MemoryTransaction::DATA
);
return icl2c() || dcl2c();
N2_MemErrDetector(SS_Model
*model
) :
L2ControlRegAccess_(((N2_Model
*)n2_model
)->csr
),
L2ErrorStatusRegAccess_(((N2_Model
*)n2_model
)->csr
),
L2ErrorAddressRegAccess_(((N2_Model
*)n2_model
)->csr
),
L2ErrorEnMemAccess_(((N2_Model
*)n2_model
)->csr
),
L2DiagDataMemAccess_(((N2_Model
*)n2_model
)->csr
),
L2DiagTagMemAccess_(((N2_Model
*)n2_model
)->csr
),
L2DiagVdMemAccess_(((N2_Model
*)n2_model
)->csr
),
L2DiagUaMemAccess_(((N2_Model
*)n2_model
)->csr
),
L2NotdataErrorRegAccess_(((N2_Model
*)n2_model
)->csr
),
DramErrorStatusMemAccess_(((N2_Model
*)n2_model
)->csr
),
DramErrorInjectMemAccess_(((N2_Model
*)n2_model
)->csr
),
DramErrorCounterMemAccess_(((N2_Model
*)n2_model
)->csr
),
DramErrorLocMemAccess_(((N2_Model
*)n2_model
)->csr
),
DramFbdInjectedErrSrcRegAccess_(((N2_Model
*)n2_model
)->csr
),
DramFbdCountRegAccess_(((N2_Model
*)n2_model
)->csr
),
DramFbdErrorSyndromeRegAccess_(((N2_Model
*)n2_model
)->csr
),
socErrorInjectRegAccess_(((N2_Model
*)n2_model
)->csr
),
socErrorStatusRegAccess_(((N2_Model
*)n2_model
)->csr
),
socPendingErrStatusRegAccess_(((N2_Model
*)n2_model
)->csr
),
socErrorLogEnableRegAccess_(((N2_Model
*)n2_model
)->csr
),
socErrorIntrEnRegAccess_(((N2_Model
*)n2_model
)->csr
),
socFatalErrorEnableRegAccess_(((N2_Model
*)n2_model
)->csr
),
socErrorSteeringRegAccess_(((N2_Model
*)n2_model
)->csr
),
debugOutput_(getenv("RAS_DEBUG") != NULL
),
debugChipKill_(getenv("CHIPKILL_DEBUG") != NULL
)
for (int bank
= 0; bank
< N2_L2_CACHE_NR_BANKS
; ++bank
) {
L2CacheWaysNRUPtr_
[bank
] = 0;
step_hook
= n2_step_hook
;
//tick_err_detector = n2_tick_cmpr_disrupting_err_detector;
* @param orig The MemErrDetector object to copy.
N2_MemErrDetector( const N2_MemErrDetector
&orig
) :
L2ControlRegAccess_(orig
.L2ControlRegAccess_
),
L2ErrorStatusRegAccess_(orig
.L2ErrorStatusRegAccess_
),
L2ErrorAddressRegAccess_(orig
.L2ErrorAddressRegAccess_
),
L2ErrorEnMemAccess_(orig
.L2ErrorEnMemAccess_
),
L2DiagDataMemAccess_(orig
.L2DiagDataMemAccess_
),
L2DiagTagMemAccess_(orig
.L2DiagTagMemAccess_
),
L2DiagVdMemAccess_(orig
.L2DiagVdMemAccess_
),
L2DiagUaMemAccess_(orig
.L2DiagUaMemAccess_
),
L2NotdataErrorRegAccess_(orig
.L2NotdataErrorRegAccess_
),
DramErrorStatusMemAccess_(orig
.DramErrorStatusMemAccess_
),
DramErrorInjectMemAccess_(orig
.DramErrorInjectMemAccess_
),
DramErrorCounterMemAccess_(orig
.DramErrorCounterMemAccess_
),
DramErrorLocMemAccess_(orig
.DramErrorLocMemAccess_
),
DramFbdInjectedErrSrcRegAccess_(orig
.DramFbdInjectedErrSrcRegAccess_
),
DramFbdCountRegAccess_(orig
.DramFbdCountRegAccess_
),
DramFbdErrorSyndromeRegAccess_(orig
.DramFbdErrorSyndromeRegAccess_
),
socErrorInjectRegAccess_(orig
.socErrorInjectRegAccess_
),
socErrorStatusRegAccess_(orig
.socErrorStatusRegAccess_
),
socPendingErrStatusRegAccess_(orig
.socPendingErrStatusRegAccess_
),
socErrorLogEnableRegAccess_(orig
.socErrorLogEnableRegAccess_
),
socErrorIntrEnRegAccess_(orig
.socErrorIntrEnRegAccess_
),
socFatalErrorEnableRegAccess_(orig
.socFatalErrorEnableRegAccess_
),
socErrorSteeringRegAccess_(orig
.socErrorSteeringRegAccess_
),
debugOutput_(orig
.debugOutput_
),
debugChipKill_(orig
.debugChipKill_
)
for (int bank
= 0; bank
< N2_L2_CACHE_NR_BANKS
; ++bank
) {
L2CacheWaysNRUPtr_
[bank
] = orig
.L2CacheWaysNRUPtr_
[bank
] ;
virtual ~N2_MemErrDetector() {}
* @param rhs The right hand side of the equality operator
* @return Return true if this objec and rhs are equal,
bool operator==( const N2_MemErrDetector
&rhs
) const;
* @param rhs The right hand side of the assignment operator.
* @return The lvalue of the assignment.
const N2_MemErrDetector
& operator=( const N2_MemErrDetector
&rhs
);
SS_Trap::Type
detect_fetch_err( MemoryLevel level
,
SS_Vaddr npc
, SS_Strand
* s
, SS_Paddr pa
) ;
SS_Trap::Type
detect_load_err( MemoryLevel level
,
SS_Vaddr pc
, SS_Vaddr npc
,
SS_Strand
* s
, SS_Instr
* line
,
SS_Trap::Type
inject_store_err( MemoryLevel level
,
SS_Vaddr pc
, SS_Vaddr npc
,
SS_Strand
* s
, SS_Instr
* line
,
BL_EccBits
N2_MemErrDetector::n2_tick_cmpr_err_injector(SS_Strand
* s
,
SS_Trap::Type
N2_MemErrDetector::n2_tick_cmpr_precise_err_detector(SS_Strand
* s
,
N2_TickAccess::TickAccessIndex array_index
);
static bool n2_tick_cmpr_disrupting_err_detector(SS_Strand
* s
);
// Returns whether an prefetch instruction is a prefetchICE
bool is_prefetchICE(SS_Opcode
& opc
)
return opc
.get_fcn() == 0x18;
// Routine to flush L2 cache
void prefetchICE(SS_Paddr pa
);
SS_Trap::Type
ras_flush( SS_Vaddr pc
, SS_Vaddr npc
,
{ return SS_Trap::NO_TRAP
; }
void ras_flush( SS_Strand
*s
, SS_Strand
* requesting_strand
, SS_Paddr pa
, uint64_t size
, CacheType type
);
static SS_Trap::Type
n2_step_hook(SS_Strand
* s
);
* detectErr() throws traps and furballs when an RAS error
* has been injected in the memory hierarchy.
SS_Trap::Type
detectErr(const MemoryTransaction
&memXact
);
* L2CacheFill takes a memory transaction and fills the
* L-cache as needed with data used by the transaction.
SS_Trap::Type
L2CacheFill(const MemoryTransaction
&memXact
);
void L2CacheFlush(N2_L2CacheFlushAddrFields flushAddr
);
// In cache look-up routines, setting the way to this value
// means a miss or "no way" matched
const static int NO_WAY
= -1;
// SWIG routines for controlling debugging output
void startDebugOutput() { debugOutput_
= true; }
void stopDebugOutput() { debugOutput_
= false; }
// N2 PRM Rev 1.1 Sect B.5.1
// Basic L2 cache size parameters
// The number of sets per bank is:
// 4MB/8s = 512K bytes per bank
// 512K/64B = 8K lines per bank
// 8K/16 = 512 sets per bank
static const N2_L2_CACHE_LINE_SIZE
= 64;
static const N2_L2_CACHE_NR_BANKS
= 8;
static const N2_L2_CACHE_NR_SETS_PER_BANK
= 512;
uint32_t L2CacheWaysNRUPtr_
[N2_L2_CACHE_NR_BANKS
];
std::map
<uint64_t,uint64_t> dramECCMap_
;
void L2FixTags(N2_L2AddressingFields paddr
);
void L2FixTagsAndTrap(N2_Strand
*strand
,
N2_L2AddressingFields paddr
,
const MemoryTransaction
&memXact
);
bool L2FixTag(uint32_t diagNdx
);
N2_L2VaudSyndrome
L2FixVUAD(N2_L2AddressingFields paddr
,
N2_L2DiagVdMemWithECC
&diagVD
);
N2_L2DiagVdMemWithECC
L2FixVUADAndTrap(N2_Strand
*strand
,
N2_L2AddressingFields paddr
,
const MemoryTransaction
&memXact
);
int L2FindWay(N2_L2AddressingFields paddr
,
N2_L2DiagVdMemWithECC diagVD
);
SS_Trap::Type
L2CacheMiss(N2_Strand
*strand
,
const MemoryTransaction
&memXact
,
N2_L2DiagVdMemWithECC
&diagVD
);
SS_Trap::Type
L2CacheHit(N2_Strand
*strand
,
const MemoryTransaction
&memXact
,
N2_L2DiagVdMemWithECC
&diagVD
,
N2_L2CacheLineError
L2ProcessCacheLine(N2_L2AddressingFields paddr
,
N2_L2CacheLineError
L2ProcessQuarterLine(N2_L2AddressingFields paddr
,
SS_Trap::Type
ThrowL2DataTrap(const MemoryTransaction
&memXact
,
N2_L2CacheLineError lineError
);
void ThrowL2DataCorrectableTrap(const MemoryTransaction
&memXact
,
N2_L2CacheLineError lineError
);
SS_Trap::Type
ThrowL2DataUncorrectableTrap(const MemoryTransaction
&memXact
,
N2_L2CacheLineError lineError
);
void ThrowL2DataWriteBackTrap(const MemoryTransaction
&memXact
,
N2_L2CacheLineError lineError
);
void poisonL2Line(N2_L2AddressingFields paddr
, int way
);
// Diagnostic access and modification routines.
typedef void (N2_L2ErrorStatusReg::*ErrorStatusRegBitSetFn
)(uint64_t);
void setL2ErrorStatusReg(uint32_t bank
,
ErrorStatusRegBitSetFn bitSetFunction
,
void setL2NotdataErrorReg(uint32_t bank
,
// trapToErrorSteer() posts a trap to the ERRORSTEER core/strand
void trapToErrorSteer(N2_Strand
*strand
, uint32_t bank
,
SS_Interrupt::Bit trapNr
) {
N2_Strand
*target_strand
= (N2_Strand
*)n2_model
->cpu
[0]->strand
[getErrorSteer(bank
)];
// Figure out which strand gets the trap from the L2 Control
// Register's ERRORSTEER field.
if(trapNr
== SS_Interrupt::BIT_HW_CORRECTED_ERROR
){
if(!strand
->seter
.dhcce())
else if(trapNr
== SS_Interrupt::BIT_SW_RECOVERABLE_ERROR
){
strand
->irq
.raise(target_strand
,trapNr
);
void setDESR(uint_t strandId
,bool sw_recoverable_trap
,
uint32_t errorType
, uint32_t errorAddr
)
N2_Strand
*strand
= (N2_Strand
*)n2_model
->cpu
[0]->strand
[strandId
];
N2_Desr
*desr
= &(strand
->desr
);
// sets the Strand's desr; not a copy
// S <- 1 for SW_recoverable_trap
// S <- 0 for HW_corrected_error
desr
->s(sw_recoverable_trap
);
desr
->errtype(errorType
); // error code
desr
->erraddr(errorAddr
); // error address
{ // set multiple error bit
// Get the CEEN bit from the L2$ error enable register
uint32_t getCEEN(uint32_t bank
) {
N2_L2ErrorEnMem L2ErrorEnableReg
;
L2ErrorEnMemAccess_
.access(bank
, L2ErrorEnableReg
, true);
return L2ErrorEnableReg
.getCEEN();
// Get the NCEEN bit from the L2$ error enable register
bool getNCEEN(uint32_t bank
) {
N2_L2ErrorEnMem L2ErrorEnableReg
;
L2ErrorEnMemAccess_
.access(bank
, L2ErrorEnableReg
, true);
return L2ErrorEnableReg
.getNCEEN();
// Get the ERRORSTEER core/strand id from the L2$ error control reg
uint_t
getErrorSteer(uint32_t bank
) {
N2_L2ControlReg L2ControlReg
;
L2ControlRegAccess_
.access(bank
, L2ControlReg
, true);
return L2ControlReg
.getERRORSTEER();
// get a set-bank index into a diagnostic csr array from a
static uint64_t paddrToSetBankNdx(N2_L2AddressingFields paddr
)
uint64_t diagNdx
= paddr
.getSET();
diagNdx
<<= N2_L2AddressingFields::bitSizeBANK
;
return (diagNdx
| paddr
.getBANK());
// get a way-set-bank index into a diagnostic csr array from a
static uint64_t paddrToWaySetBankNdx(N2_L2AddressingFields paddr
,
diagNdx
<<= N2_L2AddressingFields::bitSizeSET
;
diagNdx
|= paddr
.getSET();
diagNdx
<<= N2_L2AddressingFields::bitSizeBANK
;
return (diagNdx
| paddr
.getBANK());
void DramThrowCorrectableTrap(N2_Strand
*strand
,
const MemoryTransaction
&memXact
,
SS_Trap::Type
DramThrowUncorrectableTrap(N2_Strand
*strand
,
const MemoryTransaction
&memXact
,
static const uint64_t N2_DRAM_PADDR_MCU_SHIFT
= 6;
static const uint64_t N2_DRAM_PADDR_NR_MCU_LOG2
= 2;
static const uint64_t N2_DRAM_PADDR_NR_MCU
=
(1<< N2_DRAM_PADDR_NR_MCU_LOG2
);
// Diagnostic access and modification routines.
SS_Trap::Type
dramProcessMemOp(N2_Strand
*strand
,
const MemoryTransaction
&memXact
,
N2_L2AddressingFields paddr
,bool &);
void dramUpdateECC(N2_L2AddressingFields paddr
, bool isNotData
);
// Soc Error Detection and Correction Routines
void processSocFbdError(N2_Strand
&strand
,
N2_L2AddressingFields paddress
,
N2_SocErrorReg::SocErrRegBitGetFn getFBR
);
// Accessor Templates for L2$ Control Registers and Diag Access
SS_CsrAccess
<N2_L2ControlReg
> L2ControlRegAccess_
;
N2_CheckedL2ESRAccess L2ErrorStatusRegAccess_
;
SS_CsrAccess
<N2_L2ErrorAddressReg
> L2ErrorAddressRegAccess_
;
SS_CsrAccess
<N2_L2ErrorEnMem
> L2ErrorEnMemAccess_
;
SS_CsrAccess
<N2_L2DiagDataMem
> L2DiagDataMemAccess_
;
SS_CsrAccess
<N2_L2DiagTagMem
> L2DiagTagMemAccess_
;
SS_CsrAccess
<N2_L2DiagVdMemWithECC
> L2DiagVdMemAccess_
;
SS_CsrAccess
<N2_L2DiagUaMemWithECC
> L2DiagUaMemAccess_
;
SS_CsrAccess
<N2_L2NotdataErrorReg
> L2NotdataErrorRegAccess_
;
// Accessor Templates for Dram Control Registers
SS_CsrAccess
<N2_DramErrorStatusMem
> DramErrorStatusMemAccess_
;
SS_CsrAccess
<N2_DramErrorInjectMem
> DramErrorInjectMemAccess_
;
SS_CsrAccess
<N2_DramErrorCounterMem
> DramErrorCounterMemAccess_
;
SS_CsrAccess
<N2_DramErrorLocMem
> DramErrorLocMemAccess_
;
SS_CsrAccess
<N2_DramFbdInjectedErrSrcReg
>
DramFbdInjectedErrSrcRegAccess_
;
SS_CsrAccess
<N2_DramFbdCountReg
> DramFbdCountRegAccess_
;
SS_CsrAccess
<N2_DramFbdErrorSyndromeReg
>
DramFbdErrorSyndromeRegAccess_
;
// Accessor Templates for Soc Error Control Registers
SS_CsrAccess
<N2_SocErrorInjectReg
> socErrorInjectRegAccess_
;
SS_CsrAccess
<N2_SocErrorStatusReg
> socErrorStatusRegAccess_
;
SS_CsrAccess
<N2_SocPendingErrStatusReg
> socPendingErrStatusRegAccess_
;
SS_CsrAccess
<N2_SocErrorLogEnableReg
> socErrorLogEnableRegAccess_
;
SS_CsrAccess
<N2_SocErrorIntrEnReg
> socErrorIntrEnRegAccess_
;
SS_CsrAccess
<N2_SocFatalErrorEnableReg
> socFatalErrorEnableRegAccess_
;
SS_CsrAccess
<N2_SocErrorSteeringReg
> socErrorSteeringRegAccess_
;
// set to artificially inject Chip-Kill errors. Note that this
// can't be used with "real" CK error injection because it
// could result in uncorrectable double nibble errors.
#endif /* _N2_MEMERRDETECTOR_H */