* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: l2warm.c
* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
* This 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 program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For the avoidance of doubt, and except that if any non-GPL license
* choice is available it will apply instead, Sun elects to use only
* the General Public License version 2 (GPLv2) at this time for any
* software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later version
* may be used, or where a choice of which version of the GPL is applied is
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* ========== Copyright Header End ============================================
/*--------------------------------------------
initialize scoreboard to hold the info of
slam, it will be used to select the slam line.
--------------------------------------------*/
for( i
= 0; i
< L2WAY
; i
++){
for( j
= 0; j
< 16; j
++){
l2warm_vars
.blackboard
[0][i
][j
] = 0;
l2warm_vars
.blackboard
[1][i
][j
] = 0;
l2warm_vars
.blackboard
[2][i
][j
] = 0;
l2warm_vars
.blackboard
[3][i
][j
] = 0;
l2warm_vars
.blackboard
[4][i
][j
] = 0;
l2warm_vars
.blackboard
[5][i
][j
] = 0;
l2warm_vars
.blackboard
[6][i
][j
] = 0;
l2warm_vars
.blackboard
[7][i
][j
] = 0;
for(idx
= 0;idx
< MAX_BANK
;idx
++)l2warm_vars
.round_robin
[idx
] = 0;
//get bank mode default 8 bank
l2warm_vars
.l2mask
= 0xf;
l2warm_vars
.bank_type
= 4;
pargs
= mc_scan_plusargs ("bank_set_mask=");
l2warm_vars
.l2mask
= atoi(pargs
);
if(*pargs
== 'a')l2warm_vars
.l2mask
= 10;
else if(*pargs
== 'b')l2warm_vars
.l2mask
= 11;
else if(*pargs
== 'c')l2warm_vars
.l2mask
= 12;
l2warm_vars
.bank_type
= 0;
for(idx
= 0; idx
< 4;idx
++){
if( l2warm_vars
.l2mask
& (1 << idx
))l2warm_vars
.bank_type
++;
int t_mask
= l2warm_vars
.l2mask
;
if(t_mask
& (1 << i
))type
+= 2;
io_printf("Info: L2 bank MASK(%x) %d bank mode selected\n", l2warm_vars
.l2mask
, type
);
l2warm_vars
.l1mask
= 0xf;
l2warm_vars
.core_type
= 4;
pargs
= mc_scan_plusargs ("core_set_mask=");
l2warm_vars
.l1mask
= atoi(pargs
);
if(*pargs
== 'a')l2warm_vars
.l1mask
= 10;
else if(*pargs
== 'b')l2warm_vars
.l1mask
= 11;
else if(*pargs
== 'c')l2warm_vars
.l1mask
= 12;
l2warm_vars
.core_type
= 0;
for(idx
= 0; idx
< 4;idx
++){
if( l2warm_vars
.l1mask
& (1 << idx
))l2warm_vars
.core_type
++;
t_mask
= l2warm_vars
.l1mask
;
if(t_mask
& (1 << i
))type
+= 2;
io_printf("Info: L1 bank MASK(%x) %d bank mode selected\n", l2warm_vars
.l1mask
, type
);
pargs
= mc_scan_plusargs ("l2valid=");
if(pargs
!= (char *) 0)l2warm_vars
.turn_on_valid
= 1;
pargs
= mc_scan_plusargs ("l2dirty=");
if(pargs
!= (char *) 0)l2warm_vars
.turn_on_dirty
= 1;
pargs
= mc_scan_plusargs ("l2dirty_off=");
if(pargs
!= (char *) 0)l2warm_vars
.turn_off_dirty
= 1;
pargs
= mc_scan_plusargs ("err_enjection_on");
if(pargs
!= (char *) 0)l2warm_vars
.err_enjection
= 1;
pargs
= mc_scan_plusargs ("l2warm_round_robin=");
if(pargs
!= (char *) 0)l2warm_vars
.replace
= 1;
//warm all the cache line.
pargs
= mc_scan_plusargs ("warm_all=");
if(pargs
!= (char *) 0)l2warm_vars
.warm_all
= 1;
pargs
= mc_scan_plusargs ("uncorrectable_err=");
if(pargs
!= (char *) 0)l2warm_vars
.uncorrect_err
= atoi(pargs
);
if(l2warm_vars
.uncorrect_err
)l2warm_vars
.err_enjection
= 1;
pargs
= mc_scan_plusargs ("l2range=");
l2warm_vars
.check_range
= 0;
l2warm_vars
.check_range
= 1;
idx
= l2warm_copy(pargs
, cbuf
, 0);
l2warm_vars
.up_bound
= l2warm_getEight(cbuf
);
l2warm_copy(pargs
, cbuf
, idx
);
l2warm_vars
.low_bound
= l2warm_getEight(cbuf
);
io_printf("Info:L2warm range %llx:%llx\n", l2warm_vars
.up_bound
, l2warm_vars
.low_bound
);
pargs
= mc_scan_plusargs ("l2run_error=");
if(pargs
!= (char *) 0)l2warm_vars
.l2run_error
= 1;
pargs
= mc_scan_plusargs ("l2run_percent=");
l2warm_vars
.l2run_percent
= atoi(pargs
);
io_printf("Info: L2 runtime percent %d\n", l2warm_vars
.l2run_percent
);
pargs
= mc_scan_plusargs ("l2run_range=");
l2warm_vars
.rcheck_range
= 1;
idx
= l2warm_copy(pargs
, cbuf
, 0);
l2warm_vars
.rup_bound
= l2warm_getEight(cbuf
);
l2warm_copy(pargs
, cbuf
, idx
);
l2warm_vars
.rlow_bound
= l2warm_getEight(cbuf
);
io_printf("Info:L2run_error range %llx:%llx\n", l2warm_vars
.rup_bound
, l2warm_vars
.rlow_bound
);
l2warm_vars
.wayLayout
[0] = 0;
l2warm_vars
.wayLayout
[1] = 4;
l2warm_vars
.wayLayout
[2] = 1;
l2warm_vars
.wayLayout
[3] = 5;
l2warm_vars
.wayLayout
[4] = 8;
l2warm_vars
.wayLayout
[5] = 12;
l2warm_vars
.wayLayout
[6] = 9;
l2warm_vars
.wayLayout
[7] = 13;
l2warm_vars
.wayLayout
[8] = 2;
l2warm_vars
.wayLayout
[9] = 6;
l2warm_vars
.wayLayout
[10] = 3;
l2warm_vars
.wayLayout
[11] = 7;
l2warm_vars
.wayLayout
[12] = 10;
l2warm_vars
.wayLayout
[13] = 14;
l2warm_vars
.wayLayout
[14] = 11;
l2warm_vars
.wayLayout
[15] = 15;
//ssign way3[3:0] = {wrway[15:14],wrway[11:10]};
//assign way2[3:0] = {wrway[7:6],wrway[3:2]};
//assign way1[3:0] = {wrway[13:12],wrway[9:8]};
//assign way0[3:0] = {wrway[5:4],wrway[1:0]};
//assign way_a0[1:0] = {way[2], way[0]};
//assign way_a1[1:0] = {way[3], way[1]};
l2warm_vars
.tagWay
[0] = 0;l2warm_vars
.tagPos
[0] = 0;
l2warm_vars
.tagWay
[4] = 0;l2warm_vars
.tagPos
[4] = 1;
l2warm_vars
.tagWay
[1] = 2;l2warm_vars
.tagPos
[1] = 0;
l2warm_vars
.tagWay
[5] = 2;l2warm_vars
.tagPos
[5] = 1;
l2warm_vars
.tagWay
[8] = 4;l2warm_vars
.tagPos
[8] = 0;
l2warm_vars
.tagWay
[12] = 4;l2warm_vars
.tagPos
[12]= 1;
l2warm_vars
.tagWay
[9] = 6;l2warm_vars
.tagPos
[9] = 0;
l2warm_vars
.tagWay
[13] = 6;l2warm_vars
.tagPos
[13] = 1;
l2warm_vars
.tagWay
[2] = 8;l2warm_vars
.tagPos
[2] = 0;
l2warm_vars
.tagWay
[6] = 8;l2warm_vars
.tagPos
[6] = 1;
l2warm_vars
.tagWay
[3] = 10;l2warm_vars
.tagPos
[3] = 0;
l2warm_vars
.tagWay
[7] = 10;l2warm_vars
.tagPos
[7] = 1;
l2warm_vars
.tagWay
[10] = 12;l2warm_vars
.tagPos
[10] = 0;
l2warm_vars
.tagWay
[14] = 12;l2warm_vars
.tagPos
[14] = 1;
l2warm_vars
.tagWay
[11] = 14;l2warm_vars
.tagPos
[11] = 0;
l2warm_vars
.tagWay
[15] = 14;l2warm_vars
.tagPos
[15] = 1;
/*--------------------------------------------
bind caller's argments to pointer table.
--------------------------------------------*/
void l2warm_setRdancy(int value
){
l2warm_vars
.redundancy
= value
;
io_printf("Info: Which mod of Tag(%x)\n", value
);
/*--------------------------------------------
bind caller's argments to pointer table.
--------------------------------------------*/
int loc
= 1;//argment should be 1.
l2warm_vars
.vuad_num
= 0;
l2warm_vars
.data_num
= 0;
for(bank
= 0; bank
< MAX_BANK
; bank
++){
for(idx
= bank
* TAG
; idx
< (bank
+ 1) * TAG
; idx
++){//get tag
tf_nodeinfo(loc
, &node_info
);
if(l2warm_vars
.tag_num
== 0)l2warm_vars
.tag_num
= node_info
.node_ngroups
;
l2warm_vars
.tag_avalPtr
[idx
] = node_info
.node_value
.memoryval_p
;
for(idx
= (bank
* VUAD
); idx
< (bank
+ 1) * VUAD
; idx
++){//get vuad
tf_nodeinfo(loc
, &node_info
);
if(l2warm_vars
.vuad_num
== 0)l2warm_vars
.vuad_num
= node_info
.node_ngroups
;
l2warm_vars
.vuad_avalPtr
[idx
] = node_info
.node_value
.memoryval_p
;
for(idx
= (bank
* DDATA
); idx
< (bank
+ 1) * DDATA
; idx
++){//get data
tf_nodeinfo(loc
, &node_info
);
if(l2warm_vars
.data_num
== 0)l2warm_vars
.data_num
= node_info
.node_ngroups
;
l2warm_vars
.data_avalPtr
[idx
] = node_info
.node_value
.memoryval_p
;
/*-------------------------------------------------------------------------------
convert ascii to hex array.
--------------------------------------------------------------------------------*/
int l2warm_copy(char* buf
, char* cbuf
, int idx
)
while((buf
[idx
] != '\0') &&
(buf
[idx
] != ' '))cbuf
[ind
++] = buf
[idx
++];
/*-------------------------------------------------------------------------------
check the address symbol that is "@".
if symbol there, return address.
--------------------------------------------------------------------------------*/
long long l2warm_getEight(char *buf
)
for(i
= 0; buf
[i
] != '\0';i
++){
key
|= buf
[i
] > '9' ? ((buf
[i
] & 0xf) + 9) : buf
[i
] & 0xf;
/*--------------------------------------------
not valid, not dirty, not used and not alloc.
--------------------------------------------*/
void l2warm_l2_clear_vuad(int bank
)
int vuad
, size
, idx
, groups
;
//for(int bank = 0; bank < BANK; bank++){
for(vuad
= 0; vuad
< VUAD
;vuad
++){
idx
= bank
* VUAD
+ vuad
;
for(size
= 0; size
< 32;size
++){
avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
] + size
* l2warm_vars
.vuad_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.vuad_num
;
for(groups
= 0; groups
< l2warm_vars
.vuad_num
;groups
++){
/*--------------------------------------------
--------------------------------------------*/
int l2warm_even_parity(int data
, int num
)
/*--------------------------------------------
--------------------------------------------*/
int l2warm_range(int max
)
int num
= random() & 0xff;
/*--------------------------------------------
--------------------------------------------*/
void l2warm_error_enject_three(char* bits
, int low
, int high
, int parity
)
if(l2warm_vars
.err_enjection
){
num
= l2warm_range(high
- low
);
if(num
== parity
)num
= 0;
bits
[low
+num
] ^= 1;//flip bit
/*--------------------------------------------
--------------------------------------------*/
void l2warm_error_enject_two(int* bits
, int low
, int high
)
if(l2warm_vars
.err_enjection
){
num
= l2warm_range(high
- low
);
*bits
^= (1 << num
);//flip bit
/*--------------------------------------------
--------------------------------------------*/
int l2warm_error_enject_one(int bits
)
int num
= l2warm_range(28);
bits
^= (1 << num
);//flip bit
/*--------------------------------------------
--------------------------------------------*/
long long l2warm_error_enject_long(long long bits
)
int num
= l2warm_range(38);
bits
^= (1 << num
);//flip bit
/*--------------------------------------------
--------------------------------------------*/
int l2warm_check_parity_two(long long bits
, int num
)
for(i
= 0; i
< num
; i
++){
/*--------------------------------------------
--------------------------------------------*/
int l2warm_check_parity()
ch
= l2warm_vars
.slam_data
[j
];
ch
= l2warm_vars
.slam_data
[19];
/*--------------------------------------------
// This task generates the 7b ECC for a 32b data segment.
// The input is a 32b data segment.
// The output is {1b_parity, 6b_ecc}.
--------------------------------------------*/
int l2warm_decc(int data
){
for(i
= 0; i
< 32;i
++){//unpack
dcc
[6] = d
[0] ^ d
[1] ^ d
[2] ^ d
[4] ^ d
[5] ^ d
[7] ^ d
[10] ^
d
[11] ^ d
[12] ^ d
[14] ^ d
[17] ^ d
[18] ^ d
[21] ^ d
[23] ^
d
[24] ^ d
[26] ^ d
[27] ^ d
[29];
dcc
[5] = d
[31] ^ d
[30] ^ d
[29] ^ d
[28] ^ d
[27] ^ d
[26];
dcc
[4] = d
[25] ^ d
[24] ^ d
[23] ^ d
[22] ^ d
[21] ^ d
[20] ^
d
[19] ^ d
[18] ^ d
[17] ^ d
[16] ^ d
[15] ^ d
[14] ^
dcc
[3] = d
[25] ^ d
[24] ^ d
[23] ^ d
[22] ^ d
[21] ^ d
[20] ^
d
[19] ^ d
[18] ^ d
[10] ^ d
[9] ^ d
[8] ^ d
[7] ^
dcc
[2] = d
[31] ^ d
[30] ^ d
[29] ^ d
[25] ^ d
[24] ^ d
[23] ^ d
[22] ^
d
[17] ^ d
[16] ^ d
[15] ^ d
[14] ^ d
[10] ^ d
[9] ^ d
[8] ^
d
[7] ^ d
[3] ^ d
[2] ^ d
[1];
dcc
[1] = d
[0] ^ d
[2] ^ d
[3] ^ d
[5] ^ d
[6] ^ d
[9] ^ d
[10] ^
d
[12] ^ d
[13] ^ d
[16] ^ d
[17] ^ d
[20] ^ d
[21] ^ d
[24] ^
d
[25] ^ d
[27] ^ d
[28] ^ d
[31];
dcc
[0] = d
[0] ^ d
[1] ^ d
[3] ^ d
[4] ^ d
[6] ^ d
[8] ^ d
[10] ^
d
[11] ^ d
[13] ^ d
[15] ^ d
[17] ^ d
[19] ^ d
[21] ^ d
[23] ^
d
[25] ^ d
[26] ^ d
[28] ^ d
[30];
/*--------------------------------------------
// This function generates the 6b ECC for a 22b tag.
// The input is a 22b tag.
// The output is {5b_ecc, 1b_parity}.
--------------------------------------------*/
int l2warm_tecc(int tag
){
tcc
[0] = t
[0] ^ t
[1] ^ t
[2] ^ t
[4] ^ t
[5] ^ t
[7] ^ t
[10] ^
t
[11] ^ t
[12] ^ t
[14] ^ t
[17] ^ t
[18] ^ t
[21];
tcc
[1] = t
[0] ^ t
[1] ^ t
[3] ^ t
[4] ^ t
[6] ^ t
[8] ^ t
[10] ^
t
[11] ^ t
[13] ^ t
[15] ^ t
[17] ^ t
[19] ^ t
[21];
tcc
[2] = t
[0] ^ t
[2] ^ t
[3] ^ t
[5] ^ t
[6] ^ t
[9] ^ t
[10] ^
t
[12] ^ t
[13] ^ t
[16] ^ t
[17] ^ t
[20] ^ t
[21];
tcc
[3] = t
[17] ^ t
[16] ^ t
[15] ^ t
[14] ^ t
[10] ^ t
[9] ^ t
[8] ^
t
[7] ^ t
[3] ^ t
[2] ^ t
[1];
tcc
[4] = t
[21] ^ t
[20] ^ t
[19] ^ t
[18] ^ t
[10] ^ t
[9] ^ t
[8] ^
t
[7] ^ t
[6] ^ t
[5] ^ t
[4];
tcc
[5] = t
[21] ^ t
[20] ^ t
[19] ^ t
[18] ^ t
[17] ^ t
[16] ^ t
[15] ^
t
[14] ^ t
[13] ^ t
[12] ^ t
[11];
/*--------------------------------------------
initilally, used bit reseted.
--------------------------------------------*/
void l2warm_slam_value(int num
)
for(groups
= 0; groups
< num
;groups
++){
l2warm_vars
.avalPtr
[groups
] = l2warm_vars
.slam_data
[groups
];
l2warm_vars
.bvalPtr
[groups
] = 0;
/*--------------------------------------------
initilally, used bit reseted.
--------------------------------------------*/
int l2warm_used(int vuad
)
vuad
|= (l2warm_even_parity(vuad
, 12) << 12);
/*--------------------------------------------
initilally, alloc bit reseted.
--------------------------------------------*/
int l2warm_alloc(int vuad
)
vuad
|= (l2warm_even_parity(vuad
, 12) << 12);
/*--------------------------------------------
turn on the valid bit used the way index.
--------------------------------------------*/
int l2warm_valid(int vuad
)
vuad
|= (l2warm_vars
.valid_bit
<< l2warm_vars
.way
);
/*--------------------------------------------
initilally, alloc bit reseted.
--------------------------------------------*/
int l2warm_dirty(int vuad
)
vuad
|= (l2warm_vars
.dirty_bit
<< l2warm_vars
.way
);
/*--------------------------------------------
unpack char array into binary format.
--------------------------------------------*/
for(i
= 0; i
< l2warm_vars
.vuad_num
- 1;i
++){
ch
= l2warm_vars
.slam_data
[i
];
l2warm_vars
.vuad_unpk
[idx
++] = ch
& 1;
//process the last 4 bits.
ch
= l2warm_vars
.slam_data
[i
];
l2warm_vars
.vuad_unpk
[idx
++] = ch
& 1;
/*--------------------------------------------
pack binary format to char foramy.
--------------------------------------------*/
for(i
= 0; i
< l2warm_vars
.vuad_num
;i
++){
for(j
= 0; j
< 8;j
++)ch
|= (l2warm_vars
.vuad_unpk
[idx
++] << j
);
l2warm_vars
.slam_data
[i
] = ch
;
/*--------------------------------------------
N1:{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
.din0 ({vd_ecc_wr_data_c4[6:0], valid_c4[15:0], dirty_c4[15:0]}),
--------------------------------------------*/
void l2warm_extract_vuad(int vuad_idx
)
l2warm_vars
.low_vuad
= 0;
for(i
= 60; i
>= 0;i
-= 4){//get alloc and dirty.
l2warm_vars
.low_vuad
<<= 1;
l2warm_vars
.low_vuad
|= l2warm_vars
.vuad_unpk
[i
+ vuad_idx
];
for(i
= 124; i
>= 64;i
-= 4){//get used and valid
l2warm_vars
.up_vuad
<<= 1;
l2warm_vars
.up_vuad
|= l2warm_vars
.vuad_unpk
[i
+ vuad_idx
];
/*--------------------------------------------
{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
--------------------------------------------*/
void l2warm_integrate_vuad(int vuad_idx
, int ecc
)
for(i
= 0; i
< 64;i
+= 4){//get alloc and dirty.
l2warm_vars
.vuad_unpk
[i
+ vuad_idx
] = l2warm_vars
.low_vuad
& 1;
l2warm_vars
.low_vuad
>>= 1;
for(i
= 64; i
< 128;i
+= 4){//get used and valid
l2warm_vars
.vuad_unpk
[i
+ vuad_idx
] = l2warm_vars
.up_vuad
& 1;
l2warm_vars
.up_vuad
>>= 1;
for(i
= 128; i
< 156;i
+= 4){
l2warm_vars
.vuad_unpk
[i
+ vuad_idx
] = ecc
& 1;
/*--------------------------------------------
initilally, used bit reseted.
--------------------------------------------*/
void l2warm_updated_ua(int idx
, int vuadarray
, int vuad
)
l2warm_vars
.avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
] + vuadarray
* l2warm_vars
.vuad_num
* 2;
l2warm_vars
.bvalPtr
= l2warm_vars
.avalPtr
+ l2warm_vars
.vuad_num
;
//used and alloc data field
for(groups
= 0; groups
< l2warm_vars
.vuad_num
;groups
++)l2warm_vars
.slam_data
[groups
] = l2warm_vars
.avalPtr
[groups
];
l2warm_extract_vuad(vuad
);
l2warm_vars
.up_vuad
= l2warm_used(l2warm_vars
.up_vuad
);
l2warm_vars
.low_vuad
= l2warm_alloc(l2warm_vars
.low_vuad
);
ecc
= l2warm_decc((l2warm_vars
.up_vuad
<< 16) | l2warm_vars
.low_vuad
);
l2warm_integrate_vuad(vuad
, ecc
);
l2warm_slam_value(l2warm_vars
.vuad_num
);
/*--------------------------------------------
set valid/dirty bit randomly.
vuadarray is index of 32 array.
vuad contain index of word.
--------------------------------------------*/
void l2warm_updated_vd(int idx
, int vuadarray
, int vuad
)
//valid and dirty data field
l2warm_vars
.avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
+4] + vuadarray
* l2warm_vars
.vuad_num
* 2;
l2warm_vars
.bvalPtr
= l2warm_vars
.avalPtr
+ l2warm_vars
.vuad_num
;
for(groups
= 0; groups
< l2warm_vars
.vuad_num
;groups
++)l2warm_vars
.slam_data
[groups
] = l2warm_vars
.avalPtr
[groups
];
l2warm_unpack();//unpack hexa to binary
l2warm_extract_vuad(vuad
);
l2warm_vars
.up_vuad
= l2warm_valid(l2warm_vars
.up_vuad
);
l2warm_vars
.low_vuad
= l2warm_dirty(l2warm_vars
.low_vuad
);
ecc
= l2warm_decc((l2warm_vars
.up_vuad
<< 16) | l2warm_vars
.low_vuad
);
l2warm_integrate_vuad(vuad
, ecc
);
l2warm_slam_value(l2warm_vars
.vuad_num
);
/*--------------------------------------------
{cache_data_out_c5[31:0], cache_ecc_out_c5[6:0]} = cache_decc_out_c5[38:0];[38:7]
{cache_data_out_c5[63:32], cache_ecc_out_c5[13:7]} = cache_decc_out_c5[77:39];[77:46]
{cache_data_out_c5[95:64], cache_ecc_out_c5[20:14]} = cache_decc_out_c5[116:78];[116:85]
{cache_data_out_c5[127:96], cache_ecc_out_c5[27:21]} = cache_decc_out_c5[155:117];[155:124]
{cache_data_out_c5[159:128], cache_ecc_out_c5[34:28]} = cache_decc_out_c5[194:156];[194:163]
{cache_data_out_c5[191:160], cache_ecc_out_c5[41:35]} = cache_decc_out_c5[233:195];[233:202]
{cache_data_out_c5[223:192], cache_ecc_out_c5[48:42]} = cache_decc_out_c5[272:234];[272:241]
{cache_data_out_c5[255:224], cache_ecc_out_c5[55:49]} = cache_decc_out_c5[311:273];[311:280]
{cache_data_out_c5[287:256], cache_ecc_out_c5[62:56]} = cache_decc_out_c5[350:312];[350:329]
{cache_data_out_c5[319:288], cache_ecc_out_c5[69:63]} = cache_decc_out_c5[389:351];[389:358]
{cache_data_out_c5[351:320], cache_ecc_out_c5[76:70]} = cache_decc_out_c5[428:390];[428:397]
{cache_data_out_c5[383:352], cache_ecc_out_c5[83:77]} = cache_decc_out_c5[467:429];[467:436]
{cache_data_out_c5[415:384], cache_ecc_out_c5[90:84]} = cache_decc_out_c5[506:468];[506:475]
{cache_data_out_c5[447:416], cache_ecc_out_c5[97:91]} = cache_decc_out_c5[545:507];[545:514]
{cache_data_out_c5[479:448], cache_ecc_out_c5[104:98]} = cache_decc_out_c5[584:546];[584:553]
{cache_data_out_c5[511:480], cache_ecc_out_c5[111:105]} = cache_decc_out_c5[623:585];[623:592]
data:unpack ascending order.
--------------------------------------------*/
void l2warm_adjust_data(int which_shift
)
char ch
, unpk
[156], temp
[128];
for(i
= 15; i
>= 0; i
--){
ch
= l2warm_vars
.l1line
[i
];
//insert ecc into data array.
ch
= l2warm_vars
.ecc
[0];//first four bytes
for(i
= 96;i
< 128;i
++)unpk
[idx
++] = temp
[i
];
for(i
= 117; i
< 124;i
++){
for(i
= 64;i
< 96;i
++)unpk
[idx
++] = temp
[i
];
for(i
= 32;i
< 64;i
++)unpk
[idx
++] = temp
[i
];
for(i
= 0;i
< 32;i
++)unpk
[idx
++] = temp
[i
];
//pack binaray data to hexa
//we need to adjust this routine.
for(j
= 0; j
< 3;j
++)l2warm_vars
.parts
[i
][j
] = 0;
for(j
= 0;j
< 8;j
++)ch
|= unpk
[idx
++] << j
;
l2warm_parts(7, 4, unpk
); //19
l2warm_parts(6, 3, unpk
); //20
l2warm_parts(5, 4, unpk
); //19
l2warm_parts(4, 3, unpk
);//20
l2warm_parts(3, 4, unpk
);
l2warm_parts(2, 3, unpk
);
l2warm_parts(1, 4, unpk
);
l2warm_parts(0, 3, unpk
);
l2warm_parts(7, 3, unpk
); //20
l2warm_parts(6, 4, unpk
); //19
l2warm_parts(5, 3, unpk
); //20
l2warm_parts(4, 4, unpk
);//19
l2warm_parts(3, 3, unpk
);
l2warm_parts(2, 4, unpk
);
l2warm_parts(1, 3, unpk
);
l2warm_parts(0, 4, unpk
);
/*--------------------------------------------
slam data into data array.
--------------------------------------------*/
void l2warm_parts(int row
, int etc
, char* unpk
)
l2warm_vars
.parts
[row
][i
] |= unpk
[l2warm_vars
.idx
++] << j
;
for(j
= 0; j
< etc
; j
++){
l2warm_vars
.parts
[row
][i
] |= unpk
[l2warm_vars
.idx
++] << j
;
/*--------------------------------------------
--------------------------------------------*/
void l2warm_slam_data(int row
)
l2warm_vars
.bvalPtr
= l2warm_vars
.avalPtr
+ l2warm_vars
.data_num
;
for(groups
= 0; groups
< 3;groups
++){
l2warm_vars
.avalPtr
[groups
] = l2warm_vars
.parts
[row
][groups
];
l2warm_vars
.bvalPtr
[groups
] = 0;
/*--------------------------------------------
slam data into data array.
sub bank select:address<5:4>->the same as l1 cache size
-------------------------------------------*/
void l2warm_slam_real_data(char* data
, int subbank
)
int l1bank
, fbyte
[4], i
, sub
, l2index
, l2high
, ind
, pointer
;
int idx
= l2warm_vars
.bank
* DDATA
;//place the pointer on the target bank.
int didx
= 0;//start from the first byte
l2index
= l2warm_vars
.l2_index
& 0xff;
l2high
= l2warm_vars
.l2_index
& 0x100 ? 0 : 4;
for(l1bank
= 3; l1bank
>= 0;l1bank
--){//process data by l1 cache size
l2warm_vars
.l1line
[i
] = data
[didx
++];
fbyte
[i
/ 4] |= l2warm_vars
.l1line
[i
] & 0xff;
for(i
= 0; i
< 4;i
++)l2warm_vars
.ecc
[i
] = l2warm_decc(fbyte
[i
]);
l2warm_adjust_data(subbank
);
sub
= subbank
== 0 || subbank
== 2 ? 0 : 1;//deceide top or bottom based on addr[5:4]
ind
= idx
+ sub
* QUAD
* 2 + l2warm_vars
.way
* 8 + l2high
;
pointer
= l2index
* l2warm_vars
.data_num
* 2;
if(subbank
== 0 || subbank
== 1){
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 128+1] + pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 3] + pointer
;//1hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 128 +1] + pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 3] + pointer
;//1hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 128] + pointer
;//0hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 2] + pointer
;//1lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 128] + pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 2]+ pointer
;//1hi
else if(subbank
== 2 ||subbank
== 3 ){
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 128 + 3]+ pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 1]+ pointer
;//1hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 128 + 3]+ pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 1]+ pointer
;//1hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 128 + 2]+ pointer
;//0hi
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
]+ pointer
;//1lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256 + 128+2]+ pointer
;//0lo
l2warm_vars
.avalPtr
= l2warm_vars
.data_avalPtr
[ind
+ 256]+ pointer
;//1hi
if(subbank
== 4)subbank
= 0;
/*--------------------------------------------
slam vuad into vuad array.
vuad memory:[107:0] vuad [31:0]
<51-39> <38-26> <25-13> <12-0>
{parity, 11-0} {parity, 11-0} {parity, 11- 0} {parity, 11- 0}
index[9:8] ->be used as an index of vuad.
index[14:10]->be used as an index of vuad array.
index[17:15]->be used as an index of subarray.
{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
reg [159:0] inq_ary [31:0];
<135-119> <118-102> <101-85> <84-68> <67-51> <50-34> <33-17> <16-0>
--------------------------------------------*/
//generate the subsript for vuad access based on index.
int subarray
= (l2warm_vars
.l2_index
>> 7) & 0x3;//4 inq_arry
int vuadarray
= (l2warm_vars
.l2_index
>> 2) & 0x1f;//32 array
int vuad
= l2warm_vars
.l2_index
& 0x3;//4 words
int idx
= l2warm_vars
.bank
* VUAD
+ subarray
;
l2warm_vars
.valid_bit
= 1;
l2warm_vars
.dirty_bit
= 0;
l2warm_updated_vd(idx
, vuadarray
, vuad
);
/*--------------------------------------------
// 29 27 25 |23 21 19 17|15 13 11 9|7 5 3 1
--------------------------------------------*/
void l2warm_fillerOdd(char* aval
, char*bval
, int cval
, int num
)
val
|= ((cval
& 1) << (2*i
+ 1));
aval
[j
] &= 0x55;//0101_0101
bval
[j
] &= 0x55;//0101_0101
val
|= ((cval
& 1) << (2*i
+ 1));
aval
[3] &= 0x55;//0101_0101
bval
[3] &= 0x55;//0101_0101
/*--------------------------------------------
30 28 26 24 |22 20 18 16 |14 12 10 8 |6 4 2
--------------------------------------------*/
void l2warm_fillerEven(char* aval
, char*bval
, int cval
, int add
)
val
|= ((cval
& 1) << (2*i
+ 2 + add
));
aval
[0] &= 0xaa;//1010 1010
bval
[0] &= 0xaa;//1010 1010
val
|= ((cval
& 1) << (2*i
));
aval
[j
] &= 0xaa;//0101_0101
bval
[j
] &= 0xaa;//0101_0101
/*--------------------------------------------
2 | 4 6 8 10 | 12 14 16 18 | 20 22 24 26
--------------------------------------------*/
void l2warm_filler13(char* aval
, char* bval
, int cval
, int num
)
val
|= (cval
& 1) ? 1 << idx
: 0 ;
aval
[j
] &= 0xaa;//0101_0101
bval
[j
] &= 0xaa;//0101_0101
val
|= (cval
& 1) ? 1 << idx
: 0;
aval
[3] &= 0xaa;//0101_0101
bval
[3] &= 0xaa;//0101_0101
/*--------------------------------------------
0 2 | 4 6 8 10 | 12 14 16 18 | 20 22 24
--------------------------------------------*/
void l2warm_filler13o(char* aval
, char* bval
, int cval
)
val
|= ((cval
& 1) << (2*i
+ 2));
aval
[0] &= 0xaa;//0101 0101
bval
[0] &= 0xaa;//0101 0101
val
|= (cval
& 1) ? 1 << idx
: 0 ;
aval
[j
] &= 0xaa;//0101_0101
bval
[j
] &= 0xaa;//0101_0101
val
|= (cval
& 1) ? 1 << idx
: 0;
aval
[3] &= 0xaa;//0101_0101
bval
[3] &= 0xaa;//0101_0101
/*--------------------------------------------
// The input is a 22b tag.
// The output is {5b_ecc, 1b_parity}.
--------------------------------------------*/
int way
, up_half
, low_half
;
int groups
, tag_data
, idx
, even
;
tag_data
= l2warm_vars
.tag
<< 6 | l2warm_tecc(l2warm_vars
.tag
);
low_half
= tag_data
& 0x1fff;
up_half
= (tag_data
>> 13) & 0x7fff;
// way = l2warm_varsl2warm_vars.way % 2 ? l2warm_vars.way - 1 : l2warm_vars.way;//need even number
way
= l2warm_vars
.tagWay
[l2warm_vars
.way
];
even
= l2warm_vars
.tagPos
[l2warm_vars
.way
];
idx
= l2warm_vars
.bank
* TAG
+ way
;
//io_printf("TAG = %x low = %x up = %x\n", tag_data, low_half, up_half);
avalPtr
= l2warm_vars
.tag_avalPtr
[idx
] + l2warm_vars
.l2_index
* l2warm_vars
.tag_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.tag_num
;
//io_printf("read up = ");
for(groups
= 0; groups
< l2warm_vars
.tag_num
;groups
++){
aval
[groups
] = avalPtr
[groups
];
bval
[groups
] = bvalPtr
[groups
];
//io_printf("%02x",avalPtr[groups] & 0xff);
if(l2warm_vars
.redundancy
)
even
? l2warm_fillerEven(aval
, bval
, up_half
, 0): l2warm_fillerOdd(aval
, bval
, up_half
, 3);
//even ? l2warm_fillerOdd(aval, bval, up_half, 3) : l2warm_fillerEven(aval, bval, up_half, -2);
even
? l2warm_fillerOdd(aval
, bval
, up_half
, 3) :l2warm_filler13(aval
, bval
, up_half
, 3);
//io_printf(" write up = ");
for(groups
= 0; groups
< l2warm_vars
.tag_num
;groups
++){
avalPtr
[groups
] = aval
[groups
];
bvalPtr
[groups
] = bval
[groups
];
//io_printf("%02x",avalPtr[groups] & 0xff);
avalPtr
= l2warm_vars
.tag_avalPtr
[idx
+1] + l2warm_vars
.l2_index
* l2warm_vars
.tag_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.tag_num
;
//io_printf("read low = ");
for(groups
= 0; groups
< l2warm_vars
.tag_num
;groups
++){
aval
[groups
] = avalPtr
[groups
];
bval
[groups
] = bvalPtr
[groups
];
//io_printf("%02x",avalPtr[groups] & 0xff);
if(l2warm_vars
.redundancy
)
even
? l2warm_filler13(aval
, bval
, low_half
,1) : l2warm_fillerOdd(aval
, bval
, low_half
, 1);
even
? l2warm_fillerOdd(aval
, bval
, low_half
, 1) : l2warm_filler13o(aval
, bval
, low_half
);
//io_printf(" write low = ");
for(groups
= 0; groups
< l2warm_vars
.tag_num
;groups
++){
avalPtr
[groups
] = aval
[groups
];
bvalPtr
[groups
] = bval
[groups
];
//io_printf("%02x",avalPtr[groups] & 0xff);
/*------------------------------------------
mask out address and get index, tag and bank
--------------------------------------------*/
void l2warm_get_Mode(KeyType
* addr
)
//generate the variables, index, bank, tag of l2 cache.
if(l2warm_vars
.bank_type
== 4){
l2warm_vars
.bank
= (int)((*addr
>> 6) & 0x7);//l2bank
l2warm_vars
.l2_index
= (int)((*addr
>> 9) & 0x1ff);//9 bits 512
l2warm_vars
.tag
= (int)((*addr
>> 18) & 0x3fffff);//22 bit
l2warm_vars
.selected
= (l2warm_vars
.l2_index
& 0x3) | (((l2warm_vars
.l2_index
>> 7) & 0x3) << 2);
else if(l2warm_vars
.bank_type
== 2){
bank
= (int)((*addr
>> 6) & 0x3);//l2bank
l2warm_vars
.l2_index
= (int)((*addr
>> 8) & 0x1ff);//9 bits 512
l2warm_vars
.tag
= (int)((*addr
>> 17) & 0x3fffff);//22 bit
l2warm_vars
.selected
= (l2warm_vars
.l2_index
& 0x3) | (((l2warm_vars
.l2_index
>> 7) & 0x3) << 2);
// io_printf("Info:address(%llx) bank(%x) ", *addr, l2warm_vars.bank);
if(bank
>= 2){//looking for high bit
for(idx
= 0;idx
< 4;idx
++){
if(l2warm_vars
.l2mask
& (1 << idx
)){
l2warm_vars
.bank
= idx
* 2;
l2warm_vars
.bank
+= bank
% 2;
// io_printf("inside %d", idx);
else{//looking for low bit
for(idx
= 0;idx
< 4;idx
++){
if(l2warm_vars
.l2mask
& (1 << idx
)){
l2warm_vars
.bank
= idx
* 2;
l2warm_vars
.bank
+= bank
% 2;
// io_printf("after(%x)\n", l2warm_vars.bank);
else if(l2warm_vars
.bank_type
== 1){
bank
= (int)((*addr
>> 6) & 0x1);//l2bank
l2warm_vars
.l2_index
= (int)((*addr
>> 7) & 0x1ff);//9 bits 512
l2warm_vars
.tag
= (int)((*addr
>> 16) & 0x3fffff);//22 bit
l2warm_vars
.selected
= (l2warm_vars
.l2_index
& 0x3) | (((l2warm_vars
.l2_index
>> 7) & 0x3) << 2);
for(idx
= 0;idx
< 4;idx
++){
if(l2warm_vars
.l2mask
& (1 << idx
)){
l2warm_vars
.bank
= idx
* 2 + bank
;
/*------------------------------------------
slam tag, data, vuad into rtl.
`define L2T_ARR_D_WIDTH 28
`define L2T_ARR_DEPTH 512
reg [`L2T_ARR_D_WIDTH + 1:0] way0[`L2T_ARR_DEPTH - 1 :0]; //one extra bit for redundancy
reg [`L2T_ARR_D_WIDTH - 1:0] way1[`L2T_ARR_DEPTH - 1:0];
--------------------------------------------*/
bool l2warm_slam(KeyType addr
, char* data
)
// if(addr < 0x100)return 0;// 0x40040)return;
subbank
= (int)((addr
>> 4) & 0x3); //l1 bank common for every bank type.
l2warm_get_Mode(&addr
);//generate the variables, index, bank, tag of l2 cache.
if((l2warm_vars
.check_range
== 0) ||
(l2warm_vars
.check_range
&& (addr
< l2warm_vars
.up_bound
) && (addr
>= l2warm_vars
.low_bound
))){
// subbank = (int)((addr >> 4) & 0x3); //l1 bank common for every bank type.
if(l2warm_vars
.replace
|| l2warm_vars
.check_range
){
l2warm_vars
.way
=l2warm_vars
.round_robin
[l2warm_vars
.bank
];
while(l2warm_vars
.blackboard
[l2warm_vars
.bank
][l2warm_vars
.way
][l2warm_vars
.selected
]){
l2warm_vars
.round_robin
[l2warm_vars
.bank
]++;
l2warm_vars
.way
= l2warm_vars
.round_robin
[l2warm_vars
.bank
];
if(l2warm_vars
.way
> (L2WAY
-1)){
l2warm_vars
.round_robin
[l2warm_vars
.bank
] = 0;
if(finite
> (L2WAY
- 1))return 0;//no available way for this address
l2warm_vars
.way
= random() & 0xf;
while(l2warm_vars
.blackboard
[l2warm_vars
.bank
][l2warm_vars
.way
][l2warm_vars
.selected
]){
l2warm_vars
.way
= random() & 0xf;
// if(l2warm_vars.way >0 && l2warm_vars.way <4 || l2warm_vars.way >7 && l2warm_vars.way <12)return 0;
// io_printf("ADDRESS %llx way = %x bank = %d index = %x\n", addr, l2warm_vars.way, l2warm_vars.bank, l2warm_vars.l2_index);
l2warm_vars
.blackboard
[l2warm_vars
.bank
][l2warm_vars
.way
][l2warm_vars
.selected
] = 1;
l2warm_slam_tag(); //process tag
l2warm_slam_vuad();//process vuad
l2warm_slam_real_data(data
, subbank
);//process data
return (l2warm_vars
.way
<< 1 | 1);
/*------------------------------------------
warm cache line which is not in mem.image
--------------------------------------------*/
void l2warm_warm_all_cache(b_tree_node_ptr
* mem
)
b_tree_atom_ptr data
;//b-tree node.
// variables for warm_all
last_addr
[i
] += (KeyType
)1 << 18;
mask_addr
= (last_addr
[i
] >> 6) & 0x3ffffffff;
data
= b_Find(mem
, &mask_addr
);
warm_tag
[i
] = (int)((last_addr
[i
] >> 18) & 0x3fffff);
l2warm_vars
.turn_on_dirty
= 1;//on dirty bit.
for(l2warm_vars
.bank
= 0; l2warm_vars
.bank
< 4;l2warm_vars
. bank
++){
l2warm_vars
.tag
= warm_tag
[l2warm_vars
.bank
];
for(l2warm_vars
.way
= 0; l2warm_vars
.way
< L2WAY
;l2warm_vars
.way
++){
for(l2warm_vars
.l2_index
= 0; l2warm_vars
.l2_index
< 1024; l2warm_vars
.l2_index
++){
if(l2warm_vars
.blackboard
[l2warm_vars
.bank
][l2warm_vars
.way
][l2warm_vars
.l2_index
])continue;
for(i
= 0; i
< 64;i
++)rdata
[i
] = random() & 0xff;
l2warm_slam_tag(); //process tag
l2warm_slam_vuad();//process vuad
l2warm_slam_real_data(rdata
, subbank
);//process data
/*------------------------------------------
--------------------------------------------*/
int l2warm_percent(int* taken
, int* not_taken
)
if(l2warm_vars
.l2run_percent
== 0)return 1;
if(num
> l2warm_vars
.l2run_percent
){//not taken
if(*not_taken
== (100 - l2warm_vars
.l2run_percent
)){
if(*taken
== l2warm_vars
.l2run_percent
){
if((*taken
+ *not_taken
) == 100){
/*------------------------------------------
dynamically inject error int l2 tag or data.
3). tag way ->2'b10:way0, 2'b10:way1 2bits
--------------------------------------------*/
void l2warm_l2_tag_update( int loc
)
if(l2warm_percent(&l2warm_vars
.taken_t
, &l2warm_vars
.not_taken_t
)){
for(idx
= 0; idx
< 6;idx
++){
if((l2warm_vars
.wren
& 1) && (l2warm_vars
.way
& 3))break;
pos
= l2warm_get_long(loc
+1);//arg 2 index
tidx
= (pos
>> (idx
* 10)) & 0x3ff;//get memory index
l2warm_vars
.tag_pend
|= (1 << l2warm_vars
.bank
);
l2warm_vars
.tag_pidx
[l2warm_vars
.bank
] = tidx
;
l2warm_vars
.tag_pos
[l2warm_vars
.bank
] = (idx
<< 1) + loc
+ 3;//arg 4
if(l2warm_vars
.way
& 2)l2warm_vars
.tag_pos
[l2warm_vars
.bank
]++;
if((l2warm_vars
.tag_pend_now
& (1 << l2warm_vars
.bank
)) &&
(l2warm_vars
.tag_pidx
[l2warm_vars
.bank
] == l2warm_vars
.tag_pidx_now
[l2warm_vars
.bank
])&&
(l2warm_vars
.tag_pos
[l2warm_vars
.bank
] == l2warm_vars
.tag_pos_now
[l2warm_vars
.bank
] ))l2warm_vars
.tag_pend_now
^= (1 << l2warm_vars
.bank
);
/*--------------------------------------------
slam tag into tag array with dynamic error injection.
// The input is a 22b tag.
// The output is {5b_ecc, 1b_parity}.
--------------------------------------------*/
void l2warm_slam_tag_error()
for(l2warm_vars
.bank
= 0; l2warm_vars
.bank
< 4; l2warm_vars
.bank
++){
l2warm_vars
.l2_index
= l2warm_vars
.tag_pidx_now
[l2warm_vars
.bank
];
pos
= l2warm_vars
.tag_pos_now
[l2warm_vars
.bank
] - (l2warm_vars
.bank
* 71 + 4);
if(!(l2warm_vars
.tag_pend_now
& ( 1 << l2warm_vars
.bank
)) || pos
> 11 || pos
< 0){
io_printf("(%d):Info PLI Argment error(%d) bank(%d)\n", tf_gettime(), pos
, l2warm_vars
.bank
);
tf_nodeinfo(l2warm_vars
.tag_pos_now
[l2warm_vars
.bank
] , &l2warm_vars
.node_info
);
avalPtr
= l2warm_vars
.node_info
.node_value
.memoryval_p
+ l2warm_vars
.l2_index
* l2warm_vars
.tag_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.tag_num
;
for(groups
= l2warm_vars
.tag_num
- 1; groups
>= 0;groups
--){
tag_data
|= avalPtr
[groups
] & 0xff;
if(l2warm_check_parity_two(tag_data
, 28))continue;
err
= l2warm_error_enject_long(tag_data
);
io_printf("Info(%0d): L2_Tag error injection L2_bank(%d) way(%d) index(%d) original_tag(%x) after_tag(%x)\n",
tf_gettime(), l2warm_vars
.bank
, pos
, l2warm_vars
.l2_index
, tag_data
, err
);
for(groups
= 0; groups
< l2warm_vars
.tag_num
;groups
++){
avalPtr
[groups
] = err
& 0xff;
l2warm_vars
.tag_pend_now
= 0;
/*------------------------------------------
dynamicaly inject error int l2 tag or data.
4). data subbank0:wenable 2'b01:way0_decc, 2'b10:way1_decc
--------------------------------------------*/
void l2warm_l2_data_update(int wren
, int loc
)
if(l2warm_percent(&l2warm_vars
.taken_d
, &l2warm_vars
.not_taken_d
)){
pos
= l2warm_get_long(loc
+1);
for(idx
= 0; idx
< 6;idx
++){
l2warm_vars
.data_pend
|= (1 << l2warm_vars
.bank
);
l2warm_vars
.data_pidx
[l2warm_vars
.bank
] = pos
& 0x3ff;
l2warm_vars
.data_pos
[l2warm_vars
.bank
] = (idx
<< 1) + loc
+ 3;//
if(wren
& 2)l2warm_vars
.tag_pos
[l2warm_vars
.bank
]++;
if((l2warm_vars
.data_pend_now
& (1 << l2warm_vars
.bank
)) &&
(l2warm_vars
.data_pidx
[l2warm_vars
.bank
] == l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
])&&
(l2warm_vars
.data_pos
[l2warm_vars
.bank
] == l2warm_vars
.data_pos_now
[l2warm_vars
.bank
] ))l2warm_vars
.data_pend_now
^= (1 << l2warm_vars
.bank
);
/*--------------------------------------------
slam tag into tag array with dynamic error injection.
// The input is a 22b tag.
// The output is {5b_ecc, 1b_parity}.
{cache_data_out_c5[31:0], cache_ecc_out_c5[6:0]} = cache_decc_out_c5[38:0];
{cache_data_out_c5[63:32], cache_ecc_out_c5[13:7]} = cache_decc_out_c5[77:39];
{cache_data_out_c5[95:64], cache_ecc_out_c5[20:14]} = cache_decc_out_c5[116:78];
{cache_data_out_c5[127:96], cache_ecc_out_c5[27:21]} = cache_decc_out_c5[155:117];
groups0[4:0] {38, 37, 36, 35, 34, 33, 32}
groups1[9:5] {77, 76, 75, 74, 73, 72}
--------------------------------------------*/
void l2warm_slam_data_error()
for(l2warm_vars
.bank
= 0; l2warm_vars
.bank
< 4; l2warm_vars
.bank
++){
if(!(l2warm_vars
.data_pend_now
& ( 1 << l2warm_vars
.bank
)))continue;
tf_nodeinfo(l2warm_vars
.data_pos_now
[l2warm_vars
.bank
] , &l2warm_vars
.node_info
);
l2warm_vars
.l2_index
= l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
];
avalPtr
= l2warm_vars
.node_info
.node_value
.memoryval_p
+ l2warm_vars
.l2_index
* l2warm_vars
.data_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.data_num
;
for(groups
= l2warm_vars
.tag_num
- 1; groups
>= 0;groups
--)l2warm_vars
.slam_data
[groups
] = avalPtr
[groups
];
if(l2warm_check_parity())continue;
temp_val
= l2warm_vars
.slam_data
[4] & 0x7f;
for(idx
= 3; idx
>= 0;idx
--){
temp_val
|= l2warm_vars
.slam_data
[idx
] & 0xff;
if(!l2warm_check_parity_two(temp_val
, 39)){
io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
tf_gettime(), l2warm_vars
.bank
, l2warm_vars
.data_way_now
[l2warm_vars
.bank
], l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
]);
io_printf(" orginal_data(%016llx) ", temp_val
);
temp_val
= l2warm_error_enject_long(temp_val
);//error inject
io_printf(" after_data(%016llx)\n", temp_val
);
for(idx
= 0; idx
< 4;idx
++){
l2warm_vars
.slam_data
[idx
] = temp_val
& 0xff;
l2warm_vars
.slam_data
[4] &= 0x80;
l2warm_vars
.slam_data
[4] |= temp_val
& 0x7f;
temp_val
= l2warm_vars
.slam_data
[9] & 0x3f;
for(idx
= 8; idx
>= 5;idx
--){
temp_val
|= l2warm_vars
.slam_data
[idx
] & 0xff;
temp_val
|= l2warm_vars
.slam_data
[4] & 0x80 ? 1 : 0;
if(!l2warm_check_parity_two(temp_val
, 39)){
io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
tf_gettime(), l2warm_vars
.bank
, l2warm_vars
.data_way_now
[l2warm_vars
.bank
], l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
]);
io_printf(" orginal_data(%016llx) ", temp_val
);
temp_val
= l2warm_error_enject_long(temp_val
);//error inject
io_printf(" after_data(%016llx)\n", temp_val
);
l2warm_vars
.slam_data
[4] &= 0x7f;
l2warm_vars
.slam_data
[4] |= temp_val
& 1 ? 0x80 : 0;
for(idx
= 5; idx
< 10;idx
++){
l2warm_vars
.slam_data
[idx
] = temp_val
& 0xff;
l2warm_vars
.slam_data
[9] &= 0xc0;
l2warm_vars
.slam_data
[9] |= temp_val
& 0x3f;
temp_val
= l2warm_vars
.slam_data
[14] & 0x1f;
for(idx
= 13; idx
>= 10;idx
--){
temp_val
|= l2warm_vars
.slam_data
[idx
] & 0xff;
temp_val
|= (l2warm_vars
.slam_data
[9] >> 6) & 3;
if(!l2warm_check_parity_two(temp_val
, 39)){
io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
tf_gettime(), l2warm_vars
.bank
, l2warm_vars
.data_way_now
[l2warm_vars
.bank
], l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
]);
io_printf(" orginal_data(%016llx) ", temp_val
);
temp_val
= l2warm_error_enject_long(temp_val
);//error inject
io_printf(" after_data(%016llx)\n", temp_val
);
l2warm_vars
.slam_data
[9] &= 0x3f;
l2warm_vars
.slam_data
[9] |= ((temp_val
& 3) << 6);
for(idx
= 10; idx
< 14;idx
++){
l2warm_vars
.slam_data
[idx
] = temp_val
& 0xff;
l2warm_vars
.slam_data
[14] &= 0xe0;
l2warm_vars
.slam_data
[14] |= temp_val
& 0x1f;
temp_val
= l2warm_vars
.slam_data
[19] & 0xf;
for(idx
= 18; idx
>= 15;idx
--){
temp_val
|= l2warm_vars
.slam_data
[idx
] & 0xff;
temp_val
|= (l2warm_vars
.slam_data
[14] >> 5) & 7;
if(!l2warm_check_parity_two(temp_val
, 39)){
io_printf("Info(%0d): L2_Data error injection L2_l2warm_vars.bank(%d) way(%0x) index(%05d)",
tf_gettime(), l2warm_vars
.bank
, l2warm_vars
.data_way_now
[l2warm_vars
.bank
], l2warm_vars
.data_pidx_now
[l2warm_vars
.bank
]);
io_printf(" orginal_data(%016llx) ", temp_val
);
temp_val
= l2warm_error_enject_long(temp_val
);//error inject
io_printf(" after_data(%016llx)\n", temp_val
);
l2warm_vars
.slam_data
[14] &= 0x1f;
l2warm_vars
.slam_data
[14] |= ((temp_val
& 7) << 5);
for(idx
= 15; idx
< 19;idx
++){
l2warm_vars
.slam_data
[idx
] = temp_val
& 0xff;
l2warm_vars
.slam_data
[19] |= temp_val
& 0xf;
for(groups
= l2warm_vars
.tag_num
- 1; groups
>= 0;groups
--){
avalPtr
[groups
] = l2warm_vars
.slam_data
[groups
];
l2warm_vars
.data_pend_now
= 0;
/*------------------------------------------
--------------------------------------------*/
void l2warm_error_enject_void()
// save the previous write to avoid the confliction between
// the current and the previous update.
if(l2warm_vars
.tag_pend
){
l2warm_vars
.tag_pend_now
= l2warm_vars
.tag_pend
;
for(sub
= 0; sub
< 4; sub
++){
l2warm_vars
.tag_pidx_now
[sub
] = l2warm_vars
.tag_pidx
[sub
];
l2warm_vars
.tag_pos_now
[sub
] = l2warm_vars
.tag_pos
[sub
];
l2warm_vars
.tag_pend
= 0;
if(l2warm_vars
.data_pend
){
l2warm_vars
.data_pend_now
= l2warm_vars
.data_pend
;
for(sub
= 0; sub
< 4; sub
++){
l2warm_vars
.data_pidx_now
[sub
] = l2warm_vars
.data_pidx
[sub
];
l2warm_vars
.data_pos_now
[sub
] = l2warm_vars
.data_pos
[sub
];
l2warm_vars
.data_way_now
[sub
] = l2warm_vars
.data_way
[sub
];
l2warm_vars
.data_pend
= 0;
//Are there Tag or data updated?
for(l2warm_vars
.bank
= 0; l2warm_vars
.bank
< MAX_BANK
; l2warm_vars
.bank
++){
l2warm_vars
.wren
= tf_getp(loc
);//arg 1
l2warm_vars
.way
= tf_getp(loc
+2);//arg 3 way
if(l2warm_vars
.wren
&& l2warm_vars
.way
)l2warm_l2_tag_update(loc
);//arg 1
loc
+= 15;//move loc to data. arg 16
for(sub
= 0; sub
< 4; sub
++){//16
if(tf_getp(loc
))l2warm_l2_data_update(tf_getp(loc
), loc
);//pass 16
if(l2warm_vars
.tag_pend_now
)l2warm_slam_tag_error();
if(l2warm_vars
.data_pend_now
)l2warm_slam_data_error();
/*------------------------------------------
--------------------------------------------*/
void l2warm_clean_reg(int loc
)
tf_nodeinfo(loc
, &l2warm_vars
.node_info
);
for(groups
= 0; groups
< l2warm_vars
.node_info
.node_ngroups
; groups
++){
l2warm_vars
.node_info
.node_value
.vecval_p
[groups
].avalbits
= 0;
/*--------------------------------------------
// The input is a 22b tag.
// The output is {5b_ecc, 1b_parity}.
--------------------------------------------*/
int idx
= l2warm_vars
.bank
* TAG
+ l2warm_vars
.way
;
avalPtr
= l2warm_vars
.tag_avalPtr
[idx
] + l2warm_vars
.l2_index
* l2warm_vars
.tag_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.tag_num
;
l2warm_vars
.tag_data
= 0;
for(groups
= l2warm_vars
.tag_num
- 1; groups
>= 0;groups
--){
l2warm_vars
.tag_data
<<= 8;
l2warm_vars
.tag_data
|= avalPtr
[groups
] & 0xff;
l2warm_vars
.tag
>>= 6;//6bit ecc
l2warm_vars
.tag
&= 0x3ffff;//22 bit
/*--------------------------------------------
--------------------------------------------*/
void l2warm_pack_4bytes(int idx
, char* unpk
){
l2warm_vars
.staledata
[l2warm_vars
.stale_idx
] = 0;
l2warm_vars
.staledata
[l2warm_vars
.stale_idx
] <<= 1;
l2warm_vars
.staledata
[l2warm_vars
.stale_idx
] |= unpk
[idx
--];
/*--------------------------------------------
--------------------------------------------*/
void l2warm_pack_data(char* unpk
)
l2warm_pack_4bytes(155, unpk
);
l2warm_pack_4bytes(116, unpk
);
l2warm_pack_4bytes(77, unpk
);
l2warm_pack_4bytes(38, unpk
);
/*--------------------------------------------
--------------------------------------------*/
int l1bank
, j
, pkidx
, groups
;
char *avalPtr
, ch
, unpk
[156];
int idx
= l2warm_vars
.bank
* DDATA
;//place the pointer on the target bank.
l2warm_vars
.stale_idx
= 0;
for(l1bank
= 3; l1bank
>= 0;l1bank
--){//process data by l1 cache size
avalPtr
= l2warm_vars
.data_avalPtr
[idx
+ l1bank
* SUBBANK
+ l2warm_vars
.way
] + l2warm_vars
.l2_index
* l2warm_vars
.data_num
* 2;
for(groups
= 0; groups
< l2warm_vars
.data_num
;groups
++){
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
long long l2warm_get_long(int loc
){
low
= tf_getlongp(&high
, loc
);
/*------------------------------------------
--------------------------------------------*/
l2warm_vars
.mask_addr
= 0;
l2warm_vars
.mask_addr
|= l2warm_vars
.tag
<< 18;
l2warm_vars
.mask_addr
|= l2warm_vars
.l2_index
<< 8;
l2warm_vars
.mask_addr
|= l2warm_vars
.bank
<< 6;
/*------------------------------------------
--------------------------------------------*/
void l2warm_l2_invalidate(int bank_t
)
//generate the subsript for vuad access based on index.
int subarray
, vuadarray
, vuad
, idx
, groups
;
l2warm_vars
.bank
= bank_t
;
for(l2warm_vars
.l2_index
= 0; l2warm_vars
.l2_index
< INDEX
; l2warm_vars
.l2_index
++){
subarray
= (l2warm_vars
.l2_index
>> 7) & 0x7;
vuadarray
= (l2warm_vars
.l2_index
>> 2) & 0x1f;//32 array
vuad
= l2warm_vars
.l2_index
& 0x3;//4 words
idx
= l2warm_vars
.bank
* VUAD
+ subarray
;
//valid and dirty data field
avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
+8] + vuadarray
* l2warm_vars
.vuad_num
* 2;
bvalPtr
= avalPtr
+ l2warm_vars
.vuad_num
;
for(groups
= 0; groups
< l2warm_vars
.vuad_num
;groups
++)l2warm_vars
.slam_data
[groups
] = avalPtr
[groups
];
l2warm_unpack();//unpack hexa to binary
l2warm_extract_vuad(vuad
);
for(l2warm_vars
.way
= 0; l2warm_vars
.way
< L2WAY
; l2warm_vars
.way
++){
if((l2warm_vars
.up_vuad
& 1) && (l2warm_vars
.low_vuad
& 1)){
//write_dram_call(&mask_addr, staledata);
l2warm_vars
.up_vuad
>>= 1;
l2warm_vars
.low_vuad
>>= 1;
l2warm_l2_clear_vuad(l2warm_vars
.bank
);
/*------------------------------------------
enject error during run time.
--------------------------------------------*/
void l2warm_l1_invalidate(int ivld
, int dvld
, int cpu
)
l2warm_vars
.cpu_invalid
^= 1 << cpu
;
io_printf("%0d:Info Invalidated L1cache core(%0d)\n",tf_gettime(), cpu
);
/*------------------------------------------
When l2_bypass is deasserted, slam dram memory.
--------------------------------------------*/
void l2warm_stale_data(int loc
)
l2warm_vars
.bank
= tf_getp(loc
);
//addr_ptr = addr_list[bank].shift();
l2warm_vars
.mask_addr
= addr_ptr
->addr
;
for(i
= 0; i
< 64;i
++)l2warm_vars
.staledata
[i
] = random() & 0xff;
//write_dram_call(&mask_addr, staledata);
//addr_ptr = addr_list[bank].shift();
/*------------------------------------------
--------------------------------------------*/
int idx
, sub
, groups
, col
;
for(idx
= 0; idx
< 4;idx
++){
io_printf("Info:L2 Tag valid bits for bank(%d)\n", idx
);
for(sub
= 8; sub
< 16;sub
++){
io_printf("(%d) Sub array", sub
);
io_printf("(%d) Sub Array\n", sub
-8);
for(col
= 0; col
< 32;col
++){
avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
* VUAD
+ sub
] + col
* l2warm_vars
.vuad_num
* 2;
io_printf("index(%02d) -> valid/dirty bits(", col
);
io_printf("%01x",avalPtr
[l2warm_vars
.vuad_num
- 1] & 0xf);
for(groups
= l2warm_vars
.vuad_num
- 2;groups
>= 0; groups
--)io_printf("%02x", avalPtr
[groups
] & 0xff);
io_printf(" index(%02d) -> u/a bits(", col
);
avalPtr
= l2warm_vars
.vuad_avalPtr
[idx
* VUAD
+ sub
-8] + col
* l2warm_vars
.vuad_num
* 2;
io_printf("%01x",avalPtr
[l2warm_vars
.vuad_num
- 1] & 0xf);
for(groups
= l2warm_vars
.vuad_num
- 2;groups
>= 0; groups
--)io_printf("%02x",avalPtr
[groups
] & 0xff);
/*---------------------------------------
----------------------------------------*/
void l2warm_replace(char* str
)
for(i
= 0; i
< strlen(str
);i
++){
str
[i
] == ',')str
[i
] = ' ';
/*---------------------------------------
----------------------------------------*/
void l2warm_rmhexa(char* buf
){
for(i
= 0;i
< strlen(buf
);i
++)if(buf
[i
] == 'h' || buf
[i
] == 'x')break;
for(i
= i
+1;i
< strlen(buf
);i
++){