* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: l1warm.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 ============================================
/*--------------------------------------------
bind caller's argments to pointer table.
--------------------------------------------*/
l1warm_vars
.idir_num
= 0;
l1warm_vars
.ddir_num
= 0;
//slam icache & dcache 50%, respectively.
l1warm_vars
.dcache_num
= 0;
l1warm_vars
.icache_num
= 0;
l1warm_vars
.dtag_num
= 0;
l1warm_vars
.itag_num
= 0;
l1warm_vars
.ivalid_num
= 0;
l1warm_vars
.dvalid_num
= 0;
for(i
= 0; i
< 8 * MAX_BANK
; i
++){
l1warm_vars
.dir_ivalid
[i
] = 0;
l1warm_vars
.dir_dvalid
[i
] = 0;
l1warm_vars
.dir_iparity
[i
] = 0;
l1warm_vars
.dir_dparity
[i
] = 0;
l1warm_vars
.dir_iaddr4
[i
] = 0;
l1warm_vars
.dir_daddr4
[i
] = 0;
l1warm_vars
.l1_debug
= 0;
l1warm_vars
.check_irange
= 0;
l1warm_vars
.check_drange
= 0;
/*-------------------------------------------------------------------------------
convert ascii to hex array.
--------------------------------------------------------------------------------*/
for(i
= 0; i
< 8 * MAX_BANK
; i
++){
l1warm_vars
.dir_ivalid
[i
] = 0;
l1warm_vars
.dir_dvalid
[i
] = 0;
l1warm_vars
.dir_iparity
[i
] = 0;
l1warm_vars
.dir_dparity
[i
] = 0;
/*-------------------------------------------------------------------------------
convert ascii to hex array.
--------------------------------------------------------------------------------*/
int l1warm_copy(char* buf
, char* cbuf
, int idx
)
while((buf
[idx
] != '\0') &&
(ind
< 16))cbuf
[ind
++] = buf
[idx
++];
/*-------------------------------------------------------------------------------
check the address symbol that is "@".
if symbol there, return address.
--------------------------------------------------------------------------------*/
long long l1warm_getEight(char *buf
)
for(i
= 0; buf
[i
] != '\0';i
++){
key
|= buf
[i
] > '9' ? ((buf
[i
] & 0xf) + 9) : buf
[i
] & 0xf;
/*-------------------------------------------
check whether it is invalidate_all.
---------------------------------------------*/
long long l1warm_get_long(int loc
){
low
= tf_getlongp(&high
, loc
);
/*--------------------------------------------
bind caller's argments to pointer table.
--------------------------------------------*/
int arg
, idx
, bank
, row
, panel
;
//get dcache directory pointer
for(bank
= 0; bank
< MAX_BANK
;bank
++){
for(row
= 0; row
< 2;row
++){
for(panel
= 0; panel
< 4; panel
++){
tf_nodeinfo(arg
, &node_info
);
if(l1warm_vars
.ddir_num
== 0)l1warm_vars
.ddir_num
= node_info
.node_ngroups
;
l1warm_vars
.dir_darray
[idx
] = node_info
.node_value
.memoryval_p
;
for(row
= 0; row
< 2;row
++){
for(panel
= 0; panel
< 4; panel
++){
tf_nodeinfo(arg
, &node_info
);
if(l1warm_vars
.idir_num
== 0)l1warm_vars
.idir_num
= node_info
.node_ngroups
;
l1warm_vars
.dir_iarray
[idx
] = node_info
.node_value
.memoryval_p
;
}//for(bank = 0; bank < MAX_BANK;bank++){
for(idx = 0;idx < MAX_CORE;idx++){
if(l1warm_vars.cpu_status & (1 << idx)){//if instantiate, do it.
//get the dcache pointer.
tf_nodeinfo(arg++, &node_info);
l1warm_vars.dcache_w[idx][i] = node_info.node_value.memoryval_p;//way and core
if(l1warm_vars.dcache_num == 0)l1warm_vars.dcache_num = node_info.node_ngroups;
tf_nodeinfo(arg++, &node_info);
l1warm_vars.dcache_tag[idx][i] = node_info.node_value.memoryval_p;//way and core
if(l1warm_vars.dtag_num == 0)l1warm_vars.dtag_num = node_info.node_ngroups;
l1warm_vars.dcache_vld[idx] = arg;
tf_nodeinfo(arg++, &node_info);
for(i = 0; i < node_info.node_ngroups;i++){
node_info.node_value.vecval_p[i].avalbits = 0;
node_info.node_value.vecval_p[i].bvalbits = 0;
tf_propagatep(l1warm_vars.dcache_vld[idx]);
tf_nodeinfo(arg++, &node_info);
l1warm_vars.icache_data[idx][i] = node_info.node_value.memoryval_p;//way and core
if(l1warm_vars.dtag_num == 0)l1warm_vars.icache_num = node_info.node_ngroups;
tf_nodeinfo(arg++, &node_info);
l1warm_vars.icache_tag[idx][i] = node_info.node_value.memoryval_p;//way and core
if(l1warm_vars.itag_num == 0)l1warm_vars.itag_num = node_info.node_ngroups;
l1warm_vars.icache_vld[idx] = arg;
tf_nodeinfo(arg++, &node_info);
for(i = 0; i < node_info.node_ngroups;i++){
node_info.node_value.vecval_p[i].avalbits = 0;
node_info.node_value.vecval_p[i].bvalbits = 0;
tf_propagatep(l1warm_vars.icache_vld[idx]);
pargs
= mc_scan_plusargs ("l1_debug=");
if(pargs
!= (char *) 0)l1warm_vars
.l1_debug
= 1;
pargs
= mc_scan_plusargs ("l1_irange=");
l1warm_vars
.check_irange
= 1;
idx
= l1warm_copy(pargs
, cbuf
, 0);
l1warm_vars
.up_ibound
= l1warm_getEight(cbuf
);
l1warm_copy(pargs
, cbuf
, idx
);
l1warm_vars
.low_ibound
= l1warm_getEight(cbuf
);
io_printf("Info:L1_islam range %llx:%llx\n", l1warm_vars
.up_ibound
, l1warm_vars
.low_ibound
);
pargs
= mc_scan_plusargs ("l1_drange=");
l1warm_vars
.check_drange
= 1;
idx
= l1warm_copy(pargs
, cbuf
, 0);
l1warm_vars
.up_dbound
= l1warm_getEight(cbuf
);
l1warm_copy(pargs
, cbuf
, idx
);
l1warm_vars
.low_dbound
= l1warm_getEight(cbuf
);
io_printf("Info:L1_dslam range %llx:%llx\n", l1warm_vars
.up_dbound
, l1warm_vars
.low_dbound
);
l1warm_vars
.l2mask
= 0xf;
l1warm_vars
.l2bank_type
= 4;
pargs
= mc_scan_plusargs ("bank_set+mask=");
l1warm_vars
.l2mask
= atoi(pargs
);
l1warm_vars
.l2bank_type
= 0;
for(idx
= 0; idx
< 4;idx
++){
if(l1warm_vars
.l2mask
& (1 << idx
))l1warm_vars
.l2bank_type
++;
/*--------------------------------------------
after slam tag, save valid & parity into memory.
--------------------------------------------*/
void l1warm_store_parityValidAddr()
int bank
, row
, pair
, arg
, idx
;
for(bank
= 0; bank
< 8;bank
++){
for(row
= 0; row
< 2;row
++){
for(pair
= 0; pair
< 4; pair
++){
idx
= bank
* BANK_NUM
+ row
* ROW_NUM
+ pair
;
arg
= 3 + bank
* BANK_NUM
+ row
* ROW_NUM
+ pair
;
tf_putlongp(arg
++, l1warm_vars
.dir_dvalid
[idx
], l1warm_vars
.dir_dvalid
[idx
] >> 32);
tf_putlongp(arg
++, l1warm_vars
.dir_dparity
[idx
], l1warm_vars
.dir_dparity
[idx
] >> 32);
tf_putlongp(arg
, l1warm_vars
.dir_daddr4
[idx
], l1warm_vars
.dir_daddr4
[idx
] >> 32);
for(bank
= 0; bank
< 8;bank
++){
for(row
= 0; row
< 2;row
++){
for(pair
= 0; pair
< 4; pair
++){
idx
= bank
* BANK_NUM
+ row
* ROW_NUM
+ pair
;
arg
= 35+ bank
* BANK_NUM
+ row
* ROW_NUM
+ pair
;
tf_putlongp(arg
++, l1warm_vars
.dir_ivalid
[idx
], l1warm_vars
.dir_ivalid
[idx
] >> 32);
tf_putlongp(arg
++, l1warm_vars
.dir_iparity
[idx
], l1warm_vars
. dir_iparity
[idx
] >> 32);
tf_putlongp(arg
, l1warm_vars
.dir_daddr4
[idx
], l1warm_vars
.dir_iaddr4
[idx
] >> 32);
/*--------------------------------------------
clean valid bits when l2_warm is called beacuse
--------------------------------------------*/
void l1warm_clean_valid()
for(idx
= 2; idx
< tf_nump();idx
++){
tf_nodeinfo(idx
, &node_info
);
for(byte
= 0; byte
< node_info
.node_ngroups
;byte
++){
node_info
.node_value
.vecval_p
[byte
].avalbits
= 0;
node_info
.node_value
.vecval_p
[byte
].bvalbits
= 0;
/*--------------------------------------------
clean valid bits when l2_warm is called beacuse
--------------------------------------------*/
void l1warm_clean_dirvld()
for(idx
= 2; idx
< tf_nump();idx
++)tf_putlongp(idx
, 0, 0);
/*--------------------------------------------
got the predecode information.
--------------------------------------------*/
int l1warm_predecoder(int inst
)
int out
, op
, op1
, op2
, op3
;
op
= (inst
>> 30 ) & 0x3;
if(op
== 1)out
= 1;//call
else if(op
== 0){//branch, sethi, nop
op1
= (inst
>> 22) & 0x7;
if(op1
== 0x4)out
= 0; // nop/sethi
else if(op
== 2){// arith, shift, mem#, mov
op1
= (inst
>> 23) & 0x3;
if(op1
== 3)out
= 1;// wrpr, vis, save, jmpl
else if((op1
& 2) == 0){// arith
op2
= (inst
>> 22) & 0x3;
op3
= (inst
>> 19) & 0x3;
if((op2
& 1) == 0)out
= 0;// alu op
else if((op2
& 1) && (op3
== 0))out
= 0;// subc or addc
else{// if (in[24:23] == 2'b10) shft, mov, rdpr, tag
op2
= (inst
>> 19) & 0xf;
if(op2
== 4)out
= 1; // mulscc
else if((op2
& 0x8) == 0)out
= 0;
else if((op2
== 0xc) ||(op2
== 0xf)) out
= 0;// mov
else out
= 1;// rdsr, mem#, popc, flushw, rdpr
op1
= (inst
>> 19) & 0x3f;
op2
= (inst
>> 21) & 0x3;
if(op1
& 0x20 || op1
& 0x10 || (op1
& 0x4) == 0)out
= 1; // fp, alt space or ld
else if (((op1
& 0x10) == 0) &&((op1
& 0xf) == 0xe)) out
= 0; // stx
else if (op2
== 1)out
= 0; // other st
/*--------------------------------------------
deceide which cache is slammed at this time.
--------------------------------------------*/
int which
= (random() & 1) + 1;
if(l1warm_vars
.ddone
== l1warm_vars
.dcache
){
else l1warm_vars
.ddone
++;
if(l1warm_vars
.idone
== l1warm_vars
.icache
){
else l1warm_vars
.idone
++;
if((l1warm_vars
.icache
== l1warm_vars
.idone
) && (l1warm_vars
.dcache
== l1warm_vars
.ddone
)){
/*--------------------------------------------
choose the way to be slammed.
--------------------------------------------*/
int l1warm_which_way(KeyType addr
)
int addr_idx
, i
, j
, avld
;
l1warm_vars
.itag
= (addr
>> 12) & 0xfffffff;//28 bits addr[39:12]
addr_idx
= (addr
>> 5) & 0x7f;
tf_nodeinfo(l1warm_vars
.icache_vld
[l1warm_vars
.cpu
], &node_info
);
avld
= node_info
.node_value
.vecval_p
[gidx
].avalbits
;
if((avld
& ( 1 << sidx
)) == 0)continue;
//avalPtr = l1warm_vars.icache_tag[l1warm_vars.cpu] + idx * l1warm_vars.itag_num * 2;
for(j
= l1warm_vars
.itag_num
- 1; j
>= 0;j
--){
lword
|= avalPtr
[j
] & 0xff;
etag
= (lword
>> 1) & 0xfffffff;
if(l1warm_vars
.itag
== etag
){
if(i
== 4)l1warm_vars
.way
= random() & 0x3;
/*--------------------------------------------
count how many cores are turned on.
--------------------------------------------*/
l1warm_vars
.cpu_status
= tf_getp(1);
for(idx
= 0; idx
< MAX_CORE
;idx
++){
if(stat
& (1 << idx
))l1warm_vars
.cpu_ptr
[l1warm_vars
.cpu_num
++] = idx
;
io_printf("Info Core_status(%x) number(%d)\n", l1warm_vars
.cpu_status
, l1warm_vars
.cpu_num
);
/*--------------------------------------------
choose the core to be slammed.
--------------------------------------------*/
void l1warm_core(int num
)
l1warm_vars
.cpu
= l1warm_vars
.cpu_chose
[num
];
/*--------------------------------------------
choose the followings to be slammed:
--------------------------------------------*/
int num
= random() % l1warm_vars
.cpu_num
+ 1;
chose
= random() % l1warm_vars
.cpu_num
;
if((status
& ( 1 << chose
)) == 0){
l1warm_vars
.cpu_chose
[i
] = l1warm_vars
.cpu_ptr
[chose
];
/*--------------------------------------------
--------------------------------------------*/
int l1warm_even_parity(int data
, int num
)
/*--------------------------------------------
--------------------------------------------*/
int l1warm_even_parityLong(long long data
, int num
)
/*--------------------------------------------
get options from command line.
--------------------------------------------*/
pargs
= mc_scan_plusargs ("icache=");
if(pargs
!= (char *) 0)l1warm_vars
.icache
= atoi(pargs
);
pargs
= mc_scan_plusargs ("dcache=");
if(pargs
!= (char *) 0)l1warm_vars
.dcache
= atoi(pargs
);
/*--------------------------------------------
slam data into dir. cache.
--------------------------------------------*/
void l1warm_slam_tag(int word
, int size
)
for(groups
= 0; groups
< size
;groups
++){
l1warm_vars
.avalPtr
[groups
] = word
& 0xff;
l1warm_vars
.bvalPtr
[groups
] = 0;
/*--------------------------------------------
--------------------------------------------*/
void l1warm_slam_dataLong(long long word
, int size
)
for(groups
= 0; groups
< size
;groups
++){
l1warm_vars
.avalPtr
[groups
] = word
& 0xff;
l1warm_vars
.bvalPtr
[groups
] = 0;
/*--------------------------------------------
--------------------------------------------*/
void l1warm_slam_data(char* word
, int size
)
for(groups
= 0; groups
< size
;groups
++){
l1warm_vars
.avalPtr
[groups
] = word
[groups
] & 0xff;
l1warm_vars
.bvalPtr
[groups
] = 0;
/*--------------------------------------------
--------------------------------------------*/
void l1warm_find_location(int idx
,int *vld
)
tf_nodeinfo(vld
[l1warm_vars
.cpu
], &node_info
);
int word
= node_info
.node_value
.vecval_p
[gidx
].avalbits
;
node_info
.node_value
.vecval_p
[gidx
].avalbits
= word
;
tf_propagatep(vld
[l1warm_vars
.cpu
]);
/*--------------------------------------------
extract 4 bytes from memory buffer.
--------------------------------------------*/
int l1warm_get_word(char*data
, int num
)
for(i
= num
; i
< (num
+4);i
++){
/*--------------------------------------------
create icache data to be slammed into icd.
1). generate predecoder bit.
--------------------------------------------*/
long long l1warm_make_icache_data(int word
)
long long lparity
, lword
= word
& 0xffffffff;
if(l1warm_predecoder(word
))lword
|= 1;
if(l1warm_even_parityLong(lword
, 33)){
/*--------------------------------------------
--------------------------------------------*/
void l1warm_slam_l1idata(KeyType addr
, char* data
, int num
)
int addr_idx
= addr
& 0xff0;
addr_idx
|= l1warm_vars
.way
;
//l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + addr_idx * l1warm_vars.icache_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.icache_num
;
word
= l1warm_get_word(data
, num
);
l1warm_slam_dataLong(l1warm_make_icache_data(word
), l1warm_vars
.icache_num
);
//l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 4) * l1warm_vars.icache_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.icache_num
;
word
= l1warm_get_word(data
, 4+num
);
l1warm_slam_dataLong(l1warm_make_icache_data(word
), l1warm_vars
.icache_num
);
//l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 8) * l1warm_vars.icache_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.icache_num
;
word
= l1warm_get_word(data
, 8+num
);
l1warm_slam_dataLong(l1warm_make_icache_data(word
), l1warm_vars
.icache_num
);
//l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 12) * l1warm_vars.icache_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.icache_num
;
word
= l1warm_get_word(data
, 12+num
);
l1warm_slam_dataLong(l1warm_make_icache_data(word
), l1warm_vars
.icache_num
);
/*--------------------------------------------
assign wr_index0 = {index_f[11:4], 2'b00, wrway_f};
assign wr_index1 = {index_f[11:4], 2'b01, wrway_f};
assign wr_index2 = {index_f[11:4], 2'b10, wrway_f};
assign wr_index3 = {index_f[11:4], 2'b11, wrway_f};
{4'b0, ifq_ict_wrtag_f[`IC_TAG_SZ:0]}
--------------------------------------------*/
void l1warm_slam_icache(KeyType addr
, char* data
, int num
)
l1warm_slam_l1idata(addr
, data
, num
);
l1warm_slam_l1idata(addr
+16, data
, num
+16);
l1warm_vars
.itag
= (addr
>> 12) & 0xfffffff;//28 bits addr[39:12]
addr_idx
= (addr
>> 5) & 0x7f;
addr_idx
|= l1warm_vars
.way
;
//l1warm_vars.avalPtr = l1warm_vars.icache_tag[l1warm_vars.cpu] + addr_idx * l1warm_vars.itag_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.itag_num
;
l1warm_vars
.itag
|= (l1warm_even_parity(l1warm_vars
.itag
, 28) << 28);
lword
= l1warm_vars
.itag
;
//io_printf("addr %llx TAG tag = %x addr_idx %x way=%d \n", addr, itag, addr_idx, way);
l1warm_slam_dataLong(lword
, l1warm_vars
.itag_num
);
l1warm_find_location(addr_idx
, l1warm_vars
.icache_vld
);
/*--------------------------------------------
index for dcm_array:dcache_rwaddr_e[10:4]
// way0 and way1 are interleaved physically across 2 subbanks
// [288,277,..................,145,144] -- xdec -- [143,142,.............,1,0]
// H L H L H L H L -- xdec -- L H L H L H L H
// way1 = [288,287,284,283,...,151,150,147,146 -- xdec -- 141,140,137,136,...,5,4,1,0
// way0 = [286,285,282,281,...,149,148,145,144 -- xdec -- 143,142,139,138,...,7,6,3,2
--------------------------------------------*/
void l1warm_slam_l1ddata(KeyType addr
, char* data
, int num
)
int i
, parity
, idx
, word
;
int addr_idx
= ((addr
>> 4) & 0x7f);
l1warm_vars
.avalPtr
= l1warm_vars
.dcache_w
[l1warm_vars
.cpu
][l1warm_vars
.way
] + addr_idx
* l1warm_vars
.dcache_num
* 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.dcache_num
;
l1size
[idx
] = data
[num
+i
];
parity
|= (l1warm_even_parity(word
, 8) << (15-i
));
l1size
[1] = (parity
>> 8) & 0xff;
l1size
[0] = parity
& 0xff;
l1warm_slam_data(l1size
, l1warm_vars
.dcache_num
);
/*--------------------------------------------
76 75 74 73 72 71 70 69 68 67 66 65 64
12 11 10 9 8 7 6 5 4 3 2 1 0
--------------------------------------------*/
void l1warm_slam_dcache(KeyType addr
, char* data
, int num
)
l1warm_slam_l1ddata(addr
, data
, num
);
l1warm_vars
.dtag
= (addr
>> 11) & 0x1fffffff;
addr_idx
= ((addr
>> 4) & 0x7f);
addr_idx
|= l1warm_vars
.way
;
// l1warm_vars.avalPtr = l1warm_vars.dcache_tag[l1warm_vars.cpu] + addr_idx * l1warm_vars.dtag_num * 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.dtag_num
;
l1warm_vars
.dtag
|= (l1warm_even_parity(l1warm_vars
.dtag
, 29) << 29);
lword
= l1warm_vars
.dtag
;
l1warm_slam_dataLong(lword
, l1warm_vars
.dtag_num
);
l1warm_find_location(addr_idx
, l1warm_vars
.dcache_vld
);
//io_printf(" addr %llx DTAG tag = %x addr_idx %x way=%d\n", addr, dtag, addr_idx, way);
/*------------------------------------------
mask out address and get index, tag and bank
--------------------------------------------*/
void l1warm_get_Mode(KeyType
* addr
)
//generate the variables, index, bank, tag of l2 cache.
if(l1warm_vars
.l2bank_type
== 4){
l1warm_vars
.bank
= (int)((*addr
>> 6) & 0x7);//l2bank
l1warm_vars
.tag
= (int)((*addr
>> 9) & 0x1ff);
else if(l1warm_vars
.l2bank_type
== 2){
l1warm_vars
.bank
= (int)((*addr
>> 6) & 0x3);//l2bank
l1warm_vars
.tag
= (int)((*addr
>> 8) & 0x1ff);
if(l1warm_vars
.bank
>= 2){//looking for high bit
for(idx
= 0;idx
< 4;idx
++){
if(l1warm_vars
.l2mask
& (1 << idx
)){
l1warm_vars
.bank
= idx
* 2 + l1warm_vars
.bank
% 2 ? 1 : 0;
else{//looking for low bit
for(idx
= 0;idx
< 4;idx
++){
if(l1warm_vars
.l2mask
& (1 << idx
)){
l1warm_vars
.bank
= idx
* 2 + l1warm_vars
.bank
% 2 ? 1 : 0;
else if(l1warm_vars
.l2bank_type
== 1){
l1warm_vars
.bank
= (int)((*addr
>> 6) & 0x1);//l2bank
l1warm_vars
.tag
= (int)((*addr
>> 7) & 0x1ff);
for(idx
= 0;idx
< 4;idx
++){
if(l1warm_vars
.l2mask
& (1 << idx
)){
l1warm_vars
.bank
= idx
* 2 + l1warm_vars
.bank
;
l1warm_vars
.tag
= (l1warm_vars
.tag
<< 4 ) | l1warm_vars
.l2way
;//9 bits 512
/*--------------------------------------------
slam tag into d$ directory.
.din0(lkup_addr_c3[17:9]), // original idx , all banks enabled
.din1(lkup_addr_c3[16:8]), // 1 bit shifted idx in case of 4 banks enabled
.din2(lkup_addr_c3[15:7]), // 2 bit shifted idx in case of 2 banks enabled
addr_array[rw_addr] <= wr_data[12:0] ; // BS and SR 11/18/03 Reverse Directory change
addr_bit4[rw_addr] <= wr_data[13] ; // BS and SR 11/18/03 Reverse Directory change
parity[rw_addr] <= wr_data[14] ; // BS and SR 11/18/03 Reverse Directory change
valid[rw_addr] <= wr_data[15] ; // BS and SR 11/18/03 Reverse Directory change
The Four panels correspond to addr<10:9> decoded.
input [15:0] wr_data; // { parity, valid, addr<4>,addr<17:9>, L2 way[3:0]}
assign dir_wr_par_c4 = ^(lkup_wr_data_c4[13:0]) ^ address_bit4;
index{cpu[2:0]. way[1:0]}
index addr[4], cpu_id, way[1:0]
assign dirrep_dc_lkup_panel_dec_c4[0] = ( lkup_row_addr_dcd_c4[1:0] == 2'd0 );
assign dirrep_dc_lkup_panel_dec_c4[1] = ( lkup_row_addr_dcd_c4[1:0] == 2'd1 );
assign dirrep_dc_lkup_panel_dec_c4[2] = ( lkup_row_addr_dcd_c4[1:0] == 2'd2 );
assign dirrep_dc_lkup_panel_dec_c4[3] = ( lkup_row_addr_dcd_c4[1:0] == 2'd3 );
assign dir_wr_par_c4 = ^(lkup_wr_data_c4[13:0]) ^ address_bit4;
--------------------------------------------*/
void l1warm_slam_ddirectory(KeyType addr_tmp
){
int index
, addr4
, addr5
, entry
;
l1warm_get_Mode(&addr_tmp
);
addr4
= addr_tmp
& 0x10 ? 1 : 0;
addr5
= addr_tmp
& 0x20 ? 1 : 0;
//create parity bit based on index and way.
int parity
= l1warm_even_parity(l1warm_vars
.tag
, 13) ^ addr4
;
//make entry index. which 63-0 5bits
entry
|= (l1warm_vars
.cpu
<< 3);
l1warm_vars
.col
= (addr_tmp
>> 9) & 0x3;//deceide 4 panel
index
= l1warm_vars
.bank
* BANK_NUM
+ addr5
* ROW_NUM
+ l1warm_vars
.col
;
l1warm_vars
.avalPtr
= l1warm_vars
.dir_darray
[index
] + entry
* l1warm_vars
.ddir_num
* 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.ddir_num
;
l1warm_slam_tag(l1warm_vars
.tag
, l1warm_vars
.ddir_num
);
temp_val
= parity
? ( 1 << entry
) : 0;
l1warm_vars
.dir_dparity
[index
] |= temp_val
;
l1warm_vars
.dir_dvalid
[index
] |= temp_val
;
temp_val
= (addr4
<< entry
);
l1warm_vars
.dir_daddr4
[index
] |= temp_val
;
// io_printf("DIER addr=%llx entry = %d row = %d col = %d bank = %d index = %d %llx %llx tag %x\n",
// addr_tmp, entry, row, col, bank, index, dir_dparity[index], dir_dvalid[index], dtag);
/*--------------------------------------------
slam l2 directory of l1 icache.
entry<cpu_id[2:0],way[1:0], addr[8]>
--------------------------------------------*/
void l1warm_slam_idirectory(KeyType addr_tmp
)
int index
, entry
, addr4
, addr5
;
l1warm_get_Mode(&addr_tmp
);
addr4
= l1warm_vars
.iround
;
addr5
= addr_tmp
& 0x20 ? 1 : 0;
int parity
= l1warm_even_parity(l1warm_vars
.tag
, 13) ^ addr4
;
entry
|= l1warm_vars
.way
;
entry
|= (l1warm_vars
.cpu
<< 3);
l1warm_vars
.col
= (addr_tmp
>> 9) & 0x3;//deceide 4 panel
//get the pointer of valid and parity.
index
= l1warm_vars
.bank
* MAX_BANK
+ addr5
* ROW_NUM
+ l1warm_vars
.col
;
l1warm_vars
.avalPtr
= l1warm_vars
.dir_iarray
[index
] + l1warm_vars
.entry
* l1warm_vars
.idir_num
* 2;
l1warm_vars
.bvalPtr
= l1warm_vars
.avalPtr
+ l1warm_vars
.idir_num
;
l1warm_slam_tag(l1warm_vars
.tag
, l1warm_vars
.idir_num
);
temp_val
= (parity
<< entry
);
l1warm_vars
.dir_iparity
[index
] |= temp_val
;
l1warm_vars
.dir_ivalid
[index
] |= temp_val
;
temp_val
= (addr4
<< entry
);
l1warm_vars
.dir_iaddr4
[index
] |= temp_val
;
/*--------------------------------------------
[32:0] { addr<39:10>, addr<8>, parity, valid}
reg [29:0] addr_array[63:0]
index <cpu_id, way, 8> -> 64 entries
--------------------------------------------*/
void l1warm_slam_ionly(KeyType addr
, char* data
)
num
= l1warm_howmany_cpu();
l1warm_core(j
);//which core
l1warm_which_way(addr
);//which way
if(l1warm_vars
.l1_debug
){
io_printf("Info: l1icache slam address %llx\n", addr
);
for(i
= 0; i
< 64; i
++)io_printf("%02x", data
[i
] &0xff);
l1warm_slam_icache(addr_tmp
, data
, i
* 32);
l1warm_slam_idirectory(addr_tmp
);
/*--------------------------------------------
--------------------------------------------*/
int l1warm_islam(KeyType addr
, char* data
)
if(addr
>= l1warm_vars
.low_ibound
&&
addr
< l1warm_vars
.up_ibound
){
l1warm_slam_ionly(addr
, data
);
/*--------------------------------------------
--------------------------------------------*/
void l1warm_slam_donly(KeyType addr
, char* data
)
num
= l1warm_howmany_cpu();
l1warm_core(j
);//which core
l1warm_which_way(addr
);//which way
if(l1warm_vars
.l1_debug
){
io_printf("Info: l1dcache slam address %llx\n", addr
);
for(i
= 0; i
< 64; i
++)io_printf("%02x", data
[i
] &0xff);
l1warm_slam_dcache(addr_tmp
, data
, i
* 16);
l1warm_slam_ddirectory(addr_tmp
);
/*--------------------------------------------
--------------------------------------------*/
int l1warm_dslam(KeyType addr
, char* data
)
if(addr
>= l1warm_vars
.low_dbound
&&
addr
< l1warm_vars
.up_dbound
){
l1warm_slam_donly(addr
, data
);
/*--------------------------------------------
--------------------------------------------*/
int l1warm_slam(KeyType addr
, char* data
, int l2way
)
addr
&= 0xffffffffc0;//always 64 bytes aligment.
l1warm_vars
.tag
= (addr
>> 10) & 0x3fffffff;//30 bits
// if(l1warm_vars.check_irange && l1warm_islam(addr, data))return 1;
//if(l1warm_vars.check_drange && l1warm_dslam(addr, data))return 1;
l1warm_vars
.l2way
= l2way
;
//if(l1warm_vars.check_irange == 0 && l1warm_vars.check_drange == 0){
num
= l1warm_howmany_cpu();
l1warm_core(j
);//which core
// l1warm_which_way(addr);//which way
switch(l1warm_which_cache()){//which cache
if(l1warm_vars
.l1_debug
){
io_printf("Info: l1dcache slam address %llx\n", addr
);
for(i
= 0; i
< 64; i
++)io_printf("%02x", data
[i
] &0xff);
// l1warm_slam_dcache(addr_tmp, data, i * 16);
l1warm_slam_ddirectory(addr_tmp
);
case 2 ://do icache operation.
if(l1warm_vars
.l1_debug
){
io_printf("Info: l1icache slam address %llx\n", addr
);
for(i
= 0; i
< 64; i
++)io_printf("%02x", data
[i
] &0xff);
//l1warm_slam_icache(addr_tmp, data, i * 32);
l1warm_slam_idirectory(addr_tmp
);