* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: BL_CKSyndrome.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 ============================================
/************************************************************************
** Copyright (C) 2007, 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.
*************************************************************************/
#ifndef __BL_CKSyndrome_h__
#define __BL_CKSyndrome_h__
// Syndrome class for BL Chip-kill ECC
// Class provides basic routines to determine whether there is an
// ECC error, whether it is single, double, or multiple bit, and, if
// it is a single bit error, is it a data bit or check bit error.
BL_CKSyndrome(BL_CKEccFile::ChipKillLine line
, uint64_t savedECC
) :
syndrome_(generateChipkillECC(line
) ^ savedECC
),
badDataNibblePosition_(0),
badCheckNibblePosition_(0),
fprintf(stderr
,"BL_CKSyndrome::BL_CKSyndrome: bad syndrome");
bool isUncorrectableError()
!isCorrectableDataBitError() &&
!isCorrectableCheckBitError();
// Implemented based on Table A-10 in N2 PRM rev1.1
bool isCorrectableDataBitError()
bool correctableDataBitError
= false;
uint32_t s3
= bit_shift(syndrome_
,0,4);
uint32_t s2
= bit_shift(syndrome_
,4,4);
uint32_t s1
= bit_shift(syndrome_
,8,4);
uint32_t s0
= bit_shift(syndrome_
,12,4);
// If nibble s0 == 0 - Row 4 of Table A-10
// The remaining three nibble should be non zero
if ((s1
!= 0) && (s2
!= 0) && (s3
!= 0))
if ((s1
== s2
) && (s1
== s3
))
// For it to be a valid single-bit correctable
correctableDataBitError
= true;
badDataNibblePosition_
= 30;
// Mask to be XOR'ed with Nibble 30 to fix data
dataCorrectionMask_
= s1
;
// If nibble s1 == 0 - Case ab0c - Row 3 of Table A-10
// The remaining three nibble should be non zero
if ((s0
!= 0) && (s2
!= 0) && (s3
!= 0))
// And the value of syndrome nibble 3 should be
// the same as the value in the matrix of synd0
if (ab0cErrorValidationMatrix
[s2
][s0
] == s3
)
// For it to be a valid single-bit correctable
correctableDataBitError
= true;
ab0cErrorNibbleIdentityMatrix
[s2
][s0
];
// Mask to be XOR'ed with the nibble indexed
// by badDataNibblePosition_ to fix data
dataCorrectionMask_
= s2
;
// If nibble s2 == 0 - Case a0bc - Row 2 of Table A-10
// The remaining three nibble should be non zero
if ((s0
!= 0) && (s1
!= 0) && (s3
!= 0))
// And the value of syndrome nibble 3 should be
// the same as the value in the matrix of synd0
if (a0bcErrorValidationMatrix
[s1
][s0
] == s3
)
// For it to be a valid single-bit correctable
correctableDataBitError
= true;
a0bcErrorNibbleIdentityMatrix
[s1
][s0
];
// Mask to be XOR'ed with nibble in
// badDataNibblePosition_ above to fix data
dataCorrectionMask_
= s1
;
// If nibble s3 == 0 - Row 5 of Table A-10
// The remaining three nibble should be non zero
if ((s0
!= 0) && (s1
!= 0) && (s2
!= 0))
if ((s0
== s1
) && (s0
== s2
))
// For it to be a valid single-bit correctable
correctableDataBitError
= true;
badDataNibblePosition_
= 31;
// Mask to be XOR'ed with Nibble 31 to fix data
dataCorrectionMask_
= s0
;
return correctableDataBitError
;
// Implemented based on Table A-10 in N2 PRM rev1.1
bool isCorrectableCheckBitError()
bool correctableCheckBitError
= false;
uint32_t s3
= bit_shift(syndrome_
,0,4);
uint32_t s2
= bit_shift(syndrome_
,4,4);
uint32_t s1
= bit_shift(syndrome_
,8,4);
uint32_t s0
= bit_shift(syndrome_
,12,4);
// If nibble s0 != 0 - Row 6 of Table A-10
// The remaining three nibble should be zero
if ((s1
== 0) && (s2
== 0) && (s3
== 0))
// For it to be a valid single-bit correctable
correctableCheckBitError
= true;
// use big endian to index nibble position
badCheckNibblePosition_
= 3;
// This mask has to be XOR'ed with check nibble
// identified above to restore valid ECC
checkCorrectionMask_
= s0
;
// If nibble s1 != 0 - Row 7 of Table A-10
// The remaining three nibble should be zero
if ((s0
== 0) && (s2
== 0) && (s3
== 0))
// For it to be a valid single-bit correctable
correctableCheckBitError
= true;
// use big endian to index nibble position
badCheckNibblePosition_
= 2;
checkCorrectionMask_
= s1
;
// This mask has to be XOR'ed with check nibble
// identified above to restore valid ECC
// If nibble s2 != 0 - Row 8 of Table A-10
// The remaining three nibble should be zero
if ((s0
== 0) && (s1
== 0) && (s3
== 0))
// For it to be a valid single-bit correctable
correctableCheckBitError
= true;
// use big endian to index nibble position
badCheckNibblePosition_
= 1;
// This mask has to be XOR'ed with check nibble
// identified above to restore valid ECC
checkCorrectionMask_
= s2
;
// If nibble s3 != 0 - Row 9 of Table A-10
// The remaining three nibble should be zero
if ((s0
== 0) && (s1
== 0) && (s2
== 0))
// For it to be a valid single-bit correctable
correctableCheckBitError
= true;
// use big endian to index nibble position
badCheckNibblePosition_
= 0;
// This mask has to be XOR'ed with check nibble
// identified above to restore valid ECC
checkCorrectionMask_
= s3
;
return correctableCheckBitError
;
uint64_t getSyndrome() const { return syndrome_
; }
uint32_t getBadDataNibblePosition()
if (!isCorrectableDataBitError())
fprintf(stderr
,"BL_CKSyndrome::"
"getBadDataNibblePosition(): "
"not correctable data error");
return badDataNibblePosition_
;
uint32_t getBadCheckNibblePosition()
if (!isCorrectableCheckBitError())
fprintf(stderr
,"BL_CKSyndrome::"
"getBadCheckNibblePosition(): "
"not correctable check error");
return badCheckNibblePosition_
;
uint64_t getDataCorrectionMask()
if (!isCorrectableDataBitError())
fprintf(stderr
,"BL_CKSyndrome::"
"getDataCorrectionMask(): "
"not correctable data error");
return dataCorrectionMask_
;
uint64_t getCheckCorrectionMask()
if (!isCorrectableCheckBitError())
fprintf(stderr
,"BL_CKSyndrome::"
"getCheckCorrectionMask(): "
"not correctable check error");
return checkCorrectionMask_
;
bool correctChipKillLine(BL_CKEccFile::ChipKillLine
&line
)
if (!isCorrectableDataBitError())
uint32_t nibbleNdx
= getBadDataNibblePosition();
uint64_t nibbleMask
= getDataCorrectionMask();
line
.lsdw
^= nibbleMask
<< (4 * nibbleNdx
);
line
.msdw
^= nibbleMask
<< (4 * (nibbleNdx
- 16));
bool correctChipKillECC(uint64_t &ecc
)
if (!isCorrectableCheckBitError())
uint32_t nibbleNdx
= getBadCheckNibblePosition();
uint64_t nibbleMask
= getCheckCorrectionMask();
ecc
^= nibbleMask
<< (4 * nibbleNdx
);
uint32_t badDataNibblePosition_
;
uint32_t badCheckNibblePosition_
;
uint64_t dataCorrectionMask_
;
uint64_t checkCorrectionMask_
;
// The following 2 Dimensional Matrix implements Table A-12 of
// N2 PRM rev1.1 First dimension is Syndrome0. Second
// dimension is Syndrome1 The values contained in the matrix
// are the possible values for Syndrome3 in hexadecimal for a
// given [synd0,synd1], the value of synd3 should exactly
// match the value present in this table for the data bit
// error to be correctable (single bit) otherwise it is an
// uncorrectable (multibit) error
static const uint32_t a0bcErrorValidationMatrix
[16][16];
// The following 2 Dimensional Matrix implements Table A-11 of
// N2 PRM rev1.1 First dimension is Syndrome0. Second
// dimension is Syndrome1 // The data present at the
// intersection [synd0,synd1], represents the Data Nibble that
// has the correctable error! // The correction mask is the
static const uint32_t a0bcErrorNibbleIdentityMatrix
[16][16];
// The following 2 Dimensional Matrix implements Table A-14 of
// N2 PRM rev1.1 First dimension is Syndrome0. Second
// dimension is Syndrome2 The values contained in the matrix
// are the possible values for Syndrome3 in hexadecimal for a
// given [synd0,synd2], the value of synd3 should exactly
// match the value present in this table for the data bit
// error to be correctable (single bit) otherwise it is an
// uncorrectable (multibit) error
static const uint32_t ab0cErrorValidationMatrix
[16][16];
// The following 2 Dimensional Matrix implements Table A-13 of
// N2 PRM rev1.1 First dimension is Syndrome0. Second
// dimension is Syndrome2 // The data present at the
// intersection [synd0,synd2], represents the Data Nibble that
// has the correctable error!
// The correction mask is the value of Syndrome2
static const uint32_t ab0cErrorNibbleIdentityMatrix
[16][16];
#endif //__BL_CKSyndrome_h__