Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / pli / cache / c / src / l2warm.c
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: l2warm.c
5* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
6* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
7*
8* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9*
10* This program is free software; you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation; version 2 of the License.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License
20* along with this program; if not, write to the Free Software
21* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*
23* For the avoidance of doubt, and except that if any non-GPL license
24* choice is available it will apply instead, Sun elects to use only
25* the General Public License version 2 (GPLv2) at this time for any
26* software where a choice of GPL license versions is made
27* available with the language indicating that GPLv2 or any later version
28* may be used, or where a choice of which version of the GPL is applied is
29* otherwise unspecified.
30*
31* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
32* CA 95054 USA or visit www.sun.com if you need additional information or
33* have any questions.
34*
35*
36* ========== Copyright Header End ============================================
37*/
38#include "l2warm.h"
39/*--------------------------------------------
40initialize scoreboard to hold the info of
41slam, it will be used to select the slam line.
42--------------------------------------------*/
43void l2warm_set_init()
44{
45 int i,j,idx;
46 char* pargs, cbuf[17];
47
48 //mark blackboard.
49 for( i = 0; i < L2WAY; i++){
50 for( j = 0; j < 16; j++){
51 l2warm_vars.blackboard[0][i][j] = 0;
52 l2warm_vars.blackboard[1][i][j] = 0;
53 l2warm_vars.blackboard[2][i][j] = 0;
54 l2warm_vars.blackboard[3][i][j] = 0;
55 l2warm_vars.blackboard[4][i][j] = 0;
56 l2warm_vars.blackboard[5][i][j] = 0;
57 l2warm_vars.blackboard[6][i][j] = 0;
58 l2warm_vars.blackboard[7][i][j] = 0;
59 }
60 }
61 //n2 initialize
62 for(idx = 0;idx < MAX_BANK;idx++)l2warm_vars.round_robin[idx] = 0;
63 //get bank mode default 8 bank
64
65 l2warm_vars.l2mask = 0xf;
66 l2warm_vars.bank_type = 4;
67 pargs = mc_scan_plusargs ("bank_set_mask=");
68 if(pargs != (char *) 0){
69 l2warm_vars.l2mask = atoi(pargs);
70 if(*pargs == 'a')l2warm_vars.l2mask = 10;
71 else if(*pargs == 'b')l2warm_vars.l2mask = 11;
72 else if(*pargs == 'c')l2warm_vars.l2mask = 12;
73
74 l2warm_vars.bank_type = 0;
75 for(idx = 0; idx < 4;idx++){
76 if( l2warm_vars.l2mask & (1 << idx))l2warm_vars.bank_type++;
77 }
78 }
79 int t_mask = l2warm_vars.l2mask;
80 int type = 0;
81
82 for( i = 0; i < 4;i++){
83 if(t_mask & (1 << i))type += 2;
84 }
85
86 if(type == 0)type = 8;
87 io_printf("Info: L2 bank MASK(%x) %d bank mode selected\n", l2warm_vars.l2mask, type);
88
89 //default 8 bank
90 l2warm_vars.l1mask = 0xf;
91 l2warm_vars.core_type = 4;
92 pargs = mc_scan_plusargs ("core_set_mask=");
93
94 if(pargs != (char *) 0){
95 l2warm_vars.l1mask = atoi(pargs);
96 if(*pargs == 'a')l2warm_vars.l1mask = 10;
97 else if(*pargs == 'b')l2warm_vars.l1mask = 11;
98 else if(*pargs == 'c')l2warm_vars.l1mask = 12;
99 l2warm_vars.core_type = 0;
100 for(idx = 0; idx < 4;idx++){
101 if( l2warm_vars.l1mask & (1 << idx))l2warm_vars.core_type++;
102 }
103 }
104 t_mask = l2warm_vars.l1mask;
105 type = 0;
106 for( i = 0; i < 4;i++){
107 if(t_mask & (1 << i))type += 2;
108 }
109 if(type == 0)type = 8;
110 io_printf("Info: L1 bank MASK(%x) %d bank mode selected\n", l2warm_vars.l1mask, type);
111
112 //get options
113 pargs = mc_scan_plusargs ("l2valid=");
114 if(pargs != (char *) 0)l2warm_vars.turn_on_valid = 1;
115
116 pargs = mc_scan_plusargs ("l2dirty=");
117 if(pargs != (char *) 0)l2warm_vars.turn_on_dirty = 1;
118
119 pargs = mc_scan_plusargs ("l2dirty_off=");
120 if(pargs != (char *) 0)l2warm_vars.turn_off_dirty= 1;
121
122 pargs = mc_scan_plusargs ("err_enjection_on");
123 if(pargs != (char *) 0)l2warm_vars.err_enjection = 1;
124
125 //replace
126 pargs = mc_scan_plusargs ("l2warm_round_robin=");
127 if(pargs != (char *) 0)l2warm_vars.replace = 1;
128
129 //warm all the cache line.
130 pargs = mc_scan_plusargs ("warm_all=");
131 if(pargs != (char *) 0)l2warm_vars.warm_all = 1;
132
133 pargs = mc_scan_plusargs ("uncorrectable_err=");
134 if(pargs != (char *) 0)l2warm_vars.uncorrect_err = atoi(pargs);
135
136 if(l2warm_vars.uncorrect_err)l2warm_vars.err_enjection = 1;
137 pargs = mc_scan_plusargs ("l2range=");
138 l2warm_vars.check_range = 0;
139
140 if(pargs != (char *) 0){
141 l2warm_vars.check_range = 1;
142 idx = l2warm_copy(pargs, cbuf, 0);
143 l2warm_vars.up_bound = l2warm_getEight(cbuf);
144 l2warm_copy(pargs, cbuf, idx);
145 l2warm_vars.low_bound = l2warm_getEight(cbuf);
146 io_printf("Info:L2warm range %llx:%llx\n", l2warm_vars.up_bound, l2warm_vars.low_bound);
147 }
148 //run time error
149 pargs = mc_scan_plusargs ("l2run_error=");
150 if(pargs != (char *) 0)l2warm_vars.l2run_error = 1;
151 pargs = mc_scan_plusargs ("l2run_percent=");
152 if(pargs != (char *) 0){
153 l2warm_vars.l2run_percent = atoi(pargs);
154 io_printf("Info: L2 runtime percent %d\n", l2warm_vars.l2run_percent);
155 }
156 pargs = mc_scan_plusargs ("l2run_range=");
157
158 if(pargs != (char *) 0){
159 l2warm_vars.rcheck_range = 1;
160 idx = l2warm_copy(pargs, cbuf, 0);
161 l2warm_vars.rup_bound = l2warm_getEight(cbuf);
162 l2warm_copy(pargs, cbuf, idx);
163 l2warm_vars.rlow_bound = l2warm_getEight(cbuf);
164 io_printf("Info:L2run_error range %llx:%llx\n", l2warm_vars.rup_bound, l2warm_vars.rlow_bound);
165 }
166 //data way laoytout
167 l2warm_vars.wayLayout[0] = 0;
168 l2warm_vars.wayLayout[1] = 4;
169 l2warm_vars.wayLayout[2] = 1;
170 l2warm_vars.wayLayout[3] = 5;
171
172 l2warm_vars.wayLayout[4] = 8;
173 l2warm_vars.wayLayout[5] = 12;
174
175 l2warm_vars.wayLayout[6] = 9;
176 l2warm_vars.wayLayout[7] = 13;
177
178 l2warm_vars.wayLayout[8] = 2;
179 l2warm_vars.wayLayout[9] = 6;
180
181 l2warm_vars.wayLayout[10] = 3;
182 l2warm_vars.wayLayout[11] = 7;
183
184 l2warm_vars.wayLayout[12] = 10;
185 l2warm_vars.wayLayout[13] = 14;
186
187 l2warm_vars.wayLayout[14] = 11;
188 l2warm_vars.wayLayout[15] = 15;
189 //array
190 //ssign way3[3:0] = {wrway[15:14],wrway[11:10]};
191 //assign way2[3:0] = {wrway[7:6],wrway[3:2]};
192 //assign way1[3:0] = {wrway[13:12],wrway[9:8]};
193 //assign way0[3:0] = {wrway[5:4],wrway[1:0]};
194
195 //assign way_a0[1:0] = {way[2], way[0]};
196 //assign way_a1[1:0] = {way[3], way[1]};
197
198 l2warm_vars.tagWay[0] = 0;l2warm_vars.tagPos[0] = 0;
199 l2warm_vars.tagWay[4] = 0;l2warm_vars.tagPos[4] = 1;
200
201 l2warm_vars.tagWay[1] = 2;l2warm_vars.tagPos[1] = 0;
202 l2warm_vars.tagWay[5] = 2;l2warm_vars.tagPos[5] = 1;
203
204 l2warm_vars.tagWay[8] = 4;l2warm_vars.tagPos[8] = 0;
205 l2warm_vars.tagWay[12] = 4;l2warm_vars.tagPos[12]= 1;
206
207 l2warm_vars.tagWay[9] = 6;l2warm_vars.tagPos[9] = 0;
208 l2warm_vars.tagWay[13] = 6;l2warm_vars.tagPos[13] = 1;
209
210 l2warm_vars.tagWay[2] = 8;l2warm_vars.tagPos[2] = 0;
211 l2warm_vars.tagWay[6] = 8;l2warm_vars.tagPos[6] = 1;
212
213 l2warm_vars.tagWay[3] = 10;l2warm_vars.tagPos[3] = 0;
214 l2warm_vars.tagWay[7] = 10;l2warm_vars.tagPos[7] = 1;
215
216 l2warm_vars.tagWay[10] = 12;l2warm_vars.tagPos[10] = 0;
217 l2warm_vars.tagWay[14] = 12;l2warm_vars.tagPos[14] = 1;
218
219 l2warm_vars.tagWay[11] = 14;l2warm_vars.tagPos[11] = 0;
220 l2warm_vars.tagWay[15] = 14;l2warm_vars.tagPos[15] = 1;
221}
222/*--------------------------------------------
223constructor.
224bind caller's argments to pointer table.
225--------------------------------------------*/
226void l2warm_setRdancy(int value){
227 l2warm_vars.redundancy = value;
228 io_printf("Info: Which mod of Tag(%x)\n", value);
229}
230/*--------------------------------------------
231constructor.
232bind caller's argments to pointer table.
233--------------------------------------------*/
234void l2warm_set()
235{
236 s_tfnodeinfo node_info;
237 int idx, bank;
238 int loc = 1;//argment should be 1.
239 l2warm_vars.tag_num = 0;
240 l2warm_vars.vuad_num = 0;
241 l2warm_vars.data_num = 0;
242 l2warm_set_init();
243
244 for(bank = 0; bank < MAX_BANK; bank++){
245 for(idx = bank * TAG; idx < (bank + 1) * TAG; idx++){//get tag
246 tf_nodeinfo(loc, &node_info);
247 if(l2warm_vars.tag_num == 0)l2warm_vars.tag_num = node_info.node_ngroups;
248 l2warm_vars.tag_avalPtr[idx] = node_info.node_value.memoryval_p;
249 loc++;
250 }
251 for(idx = (bank * VUAD); idx < (bank + 1) * VUAD; idx++){//get vuad
252 tf_nodeinfo(loc, &node_info);
253 if(l2warm_vars.vuad_num == 0)l2warm_vars.vuad_num = node_info.node_ngroups;
254 l2warm_vars.vuad_avalPtr[idx] = node_info.node_value.memoryval_p;
255 loc++;
256 }
257
258 for(idx = (bank * DDATA); idx < (bank + 1) * DDATA; idx++){//get data
259 tf_nodeinfo(loc, &node_info);
260 if(l2warm_vars.data_num == 0)l2warm_vars.data_num = node_info.node_ngroups;
261 l2warm_vars.data_avalPtr[idx] = node_info.node_value.memoryval_p;
262 loc++;
263 }
264 }
265}
266
267/*-------------------------------------------------------------------------------
268 convert ascii to hex array.
269--------------------------------------------------------------------------------*/
270int l2warm_copy(char* buf, char* cbuf, int idx)
271{
272 int ind = 0;
273 while((buf[idx] != '\0') &&
274 (buf[idx] != ':') &&
275 (buf[idx] != ' '))cbuf[ind++] = buf[idx++];
276 cbuf[ind] = '\0';
277 return ++idx;
278}
279/*-------------------------------------------------------------------------------
280 check the address symbol that is "@".
281 if symbol there, return address.
282--------------------------------------------------------------------------------*/
283long long l2warm_getEight(char *buf)
284{
285 int i;
286 long long key = 0;
287
288 for(i = 0; buf[i] != '\0';i++){
289 key <<= 4;
290 key |= buf[i] > '9' ? ((buf[i] & 0xf) + 9) : buf[i] & 0xf;
291 }
292 return key;
293}
294/*--------------------------------------------
295clear vuad array.
296not valid, not dirty, not used and not alloc.
297--------------------------------------------*/
298void l2warm_l2_clear_vuad(int bank)
299{
300 char *avalPtr, *bvalPtr;
301 int vuad, size, idx, groups;
302 //for(int bank = 0; bank < BANK; bank++){
303 for(vuad = 0; vuad < VUAD;vuad++){
304 idx = bank * VUAD + vuad;
305 for(size = 0; size < 32;size++){
306 avalPtr = l2warm_vars.vuad_avalPtr[idx] + size * l2warm_vars.vuad_num * 2;
307 bvalPtr = avalPtr + l2warm_vars.vuad_num;
308 for(groups = 0; groups < l2warm_vars.vuad_num;groups++){
309 avalPtr[groups] = 0;
310 bvalPtr[groups] = 0;
311 }
312 }
313 }
314}
315/*--------------------------------------------
316compute even parity.
317--------------------------------------------*/
318int l2warm_even_parity(int data, int num)
319{
320 int i, parity;
321 parity= 0;
322 for(i = 0; i < num;i++){
323 parity ^= (data & 1);
324 data >>= 1;
325 }
326 return parity;
327}
328/*--------------------------------------------
329compute even parity.
330--------------------------------------------*/
331int l2warm_range(int max)
332{
333 int num = random() & 0xff;
334 return num % max;
335}
336/*--------------------------------------------
337enject error.
338--------------------------------------------*/
339void l2warm_error_enject_three(char* bits, int low, int high, int parity)
340{
341 int num;
342
343 if(l2warm_vars.err_enjection){
344 num = l2warm_range(high - low);
345 if(num == parity)num = 0;
346 bits[low+num] ^= 1;//flip bit
347 }
348}
349/*--------------------------------------------
350enject error.
351--------------------------------------------*/
352void l2warm_error_enject_two(int* bits, int low, int high)
353{
354 int num;
355
356 if(l2warm_vars.err_enjection){
357 num = l2warm_range(high - low);
358 *bits ^= (1 << num);//flip bit
359 }
360}
361/*--------------------------------------------
362enject error.
363--------------------------------------------*/
364int l2warm_error_enject_one(int bits)
365{
366 int num = l2warm_range(28);
367 bits ^= (1 << num);//flip bit
368 return bits;
369}
370/*--------------------------------------------
371enject error.
372--------------------------------------------*/
373long long l2warm_error_enject_long(long long bits)
374{
375 int num = l2warm_range(38);
376 bits ^= (1 << num);//flip bit
377 return bits;
378}
379/*--------------------------------------------
380check parity
381--------------------------------------------*/
382int l2warm_check_parity_two(long long bits, int num)
383{
384 int i, p;
385 p = 0;
386 for(i = 0; i < num; i++){
387 p ^= bits & 1;
388 bits >>= 1;
389 }
390 return p;
391}
392/*--------------------------------------------
393check parity
394--------------------------------------------*/
395int l2warm_check_parity()
396{
397 char ch;
398 int j, i;
399 int p = 0;
400 for(j = 0; j < 19;j++){
401 ch = l2warm_vars.slam_data[j];
402 for(i = 0; i < 8; i++){
403 p ^= ch & 1;
404 ch >>= 1;
405 }
406 }
407 ch = l2warm_vars.slam_data[19];
408 for(i = 0; i < 4; i++){
409 p ^= ch& 1;
410 ch >>= 1;
411 }
412 return p;
413}
414/*--------------------------------------------
415// This task generates the 7b ECC for a 32b data segment.
416// The input is a 32b data segment.
417// The output is {1b_parity, 6b_ecc}.
418--------------------------------------------*/
419int l2warm_decc(int data){
420 char d[32], dcc[7];
421 int i;
422 int ecc;
423 for(i = 0; i < 32;i++){//unpack
424 d[i] = data & 1;
425 data >>= 1;
426 }
427 // parity bit
428 dcc[6] = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[5] ^ d[7] ^ d[10] ^
429 d[11] ^ d[12] ^ d[14] ^ d[17] ^ d[18] ^ d[21] ^ d[23] ^
430 d[24] ^ d[26] ^ d[27] ^ d[29];
431 // ecc bits
432 dcc[5] = d[31] ^ d[30] ^ d[29] ^ d[28] ^ d[27] ^ d[26];
433 dcc[4] = d[25] ^ d[24] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^
434 d[19] ^ d[18] ^ d[17] ^ d[16] ^ d[15] ^ d[14] ^
435 d[13] ^ d[12] ^ d[11];
436
437 dcc[3] = d[25] ^ d[24] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^
438 d[19] ^ d[18] ^ d[10] ^ d[9] ^ d[8] ^ d[7] ^
439 d[6] ^ d[5] ^ d[4];
440
441 dcc[2] = d[31] ^ d[30] ^ d[29] ^ d[25] ^ d[24] ^ d[23] ^ d[22] ^
442 d[17] ^ d[16] ^ d[15] ^ d[14] ^ d[10] ^ d[9] ^ d[8] ^
443 d[7] ^ d[3] ^ d[2] ^ d[1];
444
445 dcc[1] = d[0] ^ d[2] ^ d[3] ^ d[5] ^ d[6] ^ d[9] ^ d[10] ^
446 d[12] ^ d[13] ^ d[16] ^ d[17] ^ d[20] ^ d[21] ^ d[24] ^
447 d[25] ^ d[27] ^ d[28] ^ d[31];
448
449 dcc[0] = d[0] ^ d[1] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[10] ^
450 d[11] ^ d[13] ^ d[15] ^ d[17] ^ d[19] ^ d[21] ^ d[23] ^
451 d[25] ^ d[26] ^ d[28] ^ d[30];
452
453 //pack binarty to hexa.
454 ecc = 0;
455 for(i = 6; i >= 0; i--){
456 ecc <<= 1;
457 ecc |= dcc[i];
458 }
459 return ecc;
460}
461
462/*--------------------------------------------
463// This function generates the 6b ECC for a 22b tag.
464
465// The input is a 22b tag.
466// The output is {5b_ecc, 1b_parity}.
467--------------------------------------------*/
468int l2warm_tecc(int tag){
469 char t[22], tcc[6];
470 int i;
471 int ecc;
472 //unpack
473 for(i = 0; i < 22;i++){
474 t[i] = tag & 1;
475 tag >>= 1;
476 }
477 // parity bit
478 tcc[0] = t[0] ^ t[1] ^ t[2] ^ t[4] ^ t[5] ^ t[7] ^ t[10] ^
479 t[11] ^ t[12] ^ t[14] ^ t[17] ^ t[18] ^ t[21];
480 // ecc bits
481 tcc[1] = t[0] ^ t[1] ^ t[3] ^ t[4] ^ t[6] ^ t[8] ^ t[10] ^
482 t[11] ^ t[13] ^ t[15] ^ t[17] ^ t[19] ^ t[21];
483
484 tcc[2] = t[0] ^ t[2] ^ t[3] ^ t[5] ^ t[6] ^ t[9] ^ t[10] ^
485 t[12] ^ t[13] ^ t[16] ^ t[17] ^ t[20] ^ t[21];
486
487 tcc[3] = t[17] ^ t[16] ^ t[15] ^ t[14] ^ t[10] ^ t[9] ^ t[8] ^
488 t[7] ^ t[3] ^ t[2] ^ t[1];
489
490 tcc[4] = t[21] ^ t[20] ^ t[19] ^ t[18] ^ t[10] ^ t[9] ^ t[8] ^
491 t[7] ^ t[6] ^ t[5] ^ t[4];
492
493 tcc[5] = t[21] ^ t[20] ^ t[19] ^ t[18] ^ t[17] ^ t[16] ^ t[15] ^
494 t[14] ^ t[13] ^ t[12] ^ t[11];
495
496 ecc = 0;
497 for(i = 5; i >= 0; i--){
498 ecc <<= 1;
499 ecc |= tcc[i];
500 }
501 return ecc;
502}
503
504/*--------------------------------------------
505initilally, used bit reseted.
506--------------------------------------------*/
507void l2warm_slam_value(int num)
508{
509 int groups;
510 for(groups = 0; groups < num;groups++){
511 l2warm_vars.avalPtr[groups] = l2warm_vars.slam_data[groups];
512 l2warm_vars.bvalPtr[groups] = 0;
513 }
514}
515/*--------------------------------------------
516initilally, used bit reseted.
517--------------------------------------------*/
518int l2warm_used(int vuad)
519{
520 vuad &= 0xfff;
521 //do here
522 vuad |= (l2warm_even_parity(vuad, 12) << 12);
523 return vuad;
524}
525/*--------------------------------------------
526initilally, alloc bit reseted.
527--------------------------------------------*/
528int l2warm_alloc(int vuad)
529{
530 vuad &= 0xfff;
531 //do here
532 vuad |= (l2warm_even_parity(vuad, 12) << 12);
533 return vuad;
534}
535/*--------------------------------------------
536turn on the valid bit used the way index.
537--------------------------------------------*/
538int l2warm_valid(int vuad)
539{
540 //set valid
541
542 vuad |= (l2warm_vars.valid_bit << l2warm_vars.way);
543 vuad &= 0xffff;
544 return vuad;
545}
546/*--------------------------------------------
547initilally, alloc bit reseted.
548--------------------------------------------*/
549int l2warm_dirty(int vuad)
550{
551
552 vuad |= (l2warm_vars.dirty_bit << l2warm_vars.way);
553 vuad &= 0xffff;
554 return vuad;
555}
556/*--------------------------------------------
557unpack char array into binary format.
558data layout:
559RTL:bit [107:0]
560C++:word[0].....word[13]
561--------------------------------------------*/
562void l2warm_unpack()
563{
564 char ch;
565 int i, j, idx;
566
567 idx = 0;
568 for(i = 0; i < l2warm_vars.vuad_num - 1;i++){
569 ch = l2warm_vars.slam_data[i];
570 for(j = 0; j < 8;j++){
571 l2warm_vars.vuad_unpk[idx++] = ch & 1;
572 ch >>= 1;
573 }
574 }
575 //process the last 4 bits.
576 ch = l2warm_vars.slam_data[i];
577 for(j = 0; j < 4;j++){
578 l2warm_vars.vuad_unpk[idx++] = ch & 1;
579 ch >>= 1;
580 }
581}
582/*--------------------------------------------
583pack binary format to char foramy.
584--------------------------------------------*/
585void l2warm_pack()
586{
587 char ch;
588 int i, j, idx;
589
590 idx = 0;
591 for(i = 0; i < l2warm_vars.vuad_num;i++){
592 ch = 0;
593 for(j = 0; j < 8;j++)ch |= (l2warm_vars.vuad_unpk[idx++] << j);
594 l2warm_vars.slam_data[i] = ch;
595 }
596}
597/*--------------------------------------------
598N1:{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
599{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
600N1:layout of vuad
601 .din0 ({vd_ecc_wr_data_c4[6:0], valid_c4[15:0], dirty_c4[15:0]}),
602
603--------------------------------------------*/
604void l2warm_extract_vuad(int vuad_idx)
605{
606 int i;
607
608 l2warm_vars.low_vuad = 0;
609 for(i = 60; i >= 0;i -= 4){//get alloc and dirty.
610 l2warm_vars.low_vuad <<= 1;
611 l2warm_vars.low_vuad |= l2warm_vars.vuad_unpk[i + vuad_idx];
612 }
613
614 l2warm_vars.up_vuad = 0;
615 for(i = 124; i >= 64;i -= 4){//get used and valid
616 l2warm_vars.up_vuad <<= 1;
617 l2warm_vars.up_vuad |= l2warm_vars.vuad_unpk[i + vuad_idx];
618 }
619}
620/*--------------------------------------------
621{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
622{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
623--------------------------------------------*/
624void l2warm_integrate_vuad(int vuad_idx, int ecc)
625{
626 int i;
627
628 for(i = 0; i < 64;i += 4){//get alloc and dirty.
629 l2warm_vars.vuad_unpk[i + vuad_idx] = l2warm_vars.low_vuad & 1;
630 l2warm_vars.low_vuad >>= 1;
631 }
632 for(i = 64; i < 128;i += 4){//get used and valid
633 l2warm_vars.vuad_unpk[i + vuad_idx] = l2warm_vars.up_vuad & 1;
634 l2warm_vars.up_vuad >>= 1;
635 }
636
637 for(i = 128; i < 156;i += 4){
638 l2warm_vars.vuad_unpk[i + vuad_idx] = ecc & 1;
639 ecc >>= 1;
640 }
641}
642/*--------------------------------------------
643initilally, used bit reseted.
644--------------------------------------------*/
645void l2warm_updated_ua(int idx, int vuadarray, int vuad)
646{
647 int groups, ecc;
648 //get the pointer of ua
649 l2warm_vars.avalPtr = l2warm_vars.vuad_avalPtr[idx] + vuadarray * l2warm_vars.vuad_num * 2;
650 l2warm_vars.bvalPtr = l2warm_vars.avalPtr + l2warm_vars.vuad_num;
651 //read vuad data.
652 //used and alloc data field
653
654 for(groups = 0; groups < l2warm_vars.vuad_num;groups++)l2warm_vars.slam_data[groups] = l2warm_vars.avalPtr[groups];
655 l2warm_unpack();
656 l2warm_extract_vuad(vuad);
657 //modify fields.
658 l2warm_vars.up_vuad = l2warm_used(l2warm_vars.up_vuad);
659 l2warm_vars.low_vuad = l2warm_alloc(l2warm_vars.low_vuad);
660 ecc = l2warm_decc((l2warm_vars.up_vuad << 16) | l2warm_vars.low_vuad);
661 l2warm_integrate_vuad(vuad, ecc);
662 l2warm_pack();
663 l2warm_slam_value(l2warm_vars.vuad_num);
664}
665/*--------------------------------------------
666set valid/dirty bit randomly.
667vuadarray is index of 32 array.
668vuad contain index of word.
669--------------------------------------------*/
670void l2warm_updated_vd(int idx, int vuadarray, int vuad)
671{
672 int groups, ecc;
673
674 //valid and dirty data field
675 l2warm_vars.avalPtr = l2warm_vars.vuad_avalPtr[idx+4] + vuadarray * l2warm_vars.vuad_num * 2;
676 l2warm_vars.bvalPtr = l2warm_vars.avalPtr + l2warm_vars.vuad_num;
677 //get 160 bits.
678 //ascending order.
679
680 for(groups = 0; groups < l2warm_vars.vuad_num;groups++)l2warm_vars.slam_data[groups] = l2warm_vars.avalPtr[groups];
681 l2warm_unpack();//unpack hexa to binary
682 l2warm_extract_vuad(vuad);
683
684 //modify fields.
685 l2warm_vars.up_vuad = l2warm_valid(l2warm_vars.up_vuad);
686 l2warm_vars.low_vuad = l2warm_dirty(l2warm_vars.low_vuad);
687
688 ecc = l2warm_decc((l2warm_vars.up_vuad << 16) | l2warm_vars.low_vuad);
689 l2warm_integrate_vuad(vuad, ecc);
690
691 l2warm_pack();
692 l2warm_slam_value(l2warm_vars.vuad_num);
693}
694/*--------------------------------------------
695layout:
696{cache_data_out_c5[31:0], cache_ecc_out_c5[6:0]} = cache_decc_out_c5[38:0];[38:7]
697{cache_data_out_c5[63:32], cache_ecc_out_c5[13:7]} = cache_decc_out_c5[77:39];[77:46]
698{cache_data_out_c5[95:64], cache_ecc_out_c5[20:14]} = cache_decc_out_c5[116:78];[116:85]
699{cache_data_out_c5[127:96], cache_ecc_out_c5[27:21]} = cache_decc_out_c5[155:117];[155:124]
700
701{cache_data_out_c5[159:128], cache_ecc_out_c5[34:28]} = cache_decc_out_c5[194:156];[194:163]
702{cache_data_out_c5[191:160], cache_ecc_out_c5[41:35]} = cache_decc_out_c5[233:195];[233:202]
703{cache_data_out_c5[223:192], cache_ecc_out_c5[48:42]} = cache_decc_out_c5[272:234];[272:241]
704{cache_data_out_c5[255:224], cache_ecc_out_c5[55:49]} = cache_decc_out_c5[311:273];[311:280]
705
706{cache_data_out_c5[287:256], cache_ecc_out_c5[62:56]} = cache_decc_out_c5[350:312];[350:329]
707{cache_data_out_c5[319:288], cache_ecc_out_c5[69:63]} = cache_decc_out_c5[389:351];[389:358]
708{cache_data_out_c5[351:320], cache_ecc_out_c5[76:70]} = cache_decc_out_c5[428:390];[428:397]
709{cache_data_out_c5[383:352], cache_ecc_out_c5[83:77]} = cache_decc_out_c5[467:429];[467:436]
710
711{cache_data_out_c5[415:384], cache_ecc_out_c5[90:84]} = cache_decc_out_c5[506:468];[506:475]
712{cache_data_out_c5[447:416], cache_ecc_out_c5[97:91]} = cache_decc_out_c5[545:507];[545:514]
713{cache_data_out_c5[479:448], cache_ecc_out_c5[104:98]} = cache_decc_out_c5[584:546];[584:553]
714{cache_data_out_c5[511:480], cache_ecc_out_c5[111:105]} = cache_decc_out_c5[623:585];[623:592]
715
716data:unpack ascending order.
717--------------------------------------------*/
718void l2warm_adjust_data(int which_shift)
719{
720 char ch, unpk[156], temp[128];
721 int i, j;
722
723 //unpack
724 int idx = 0;
725 for(i = 15; i >= 0; i--){
726 ch = l2warm_vars.l1line[i];
727 for(j = 0; j < 8;j++){
728 temp[idx++] = ch & 1;
729 ch >>= 1;
730 }
731 }
732 //insert ecc into data array.
733 ch = l2warm_vars.ecc[0];//first four bytes
734 idx = 124;
735 for(i = 96;i < 128;i++)unpk[idx++] = temp[i];
736 for(i = 117; i < 124;i++){
737 unpk[i] = ch & 1;
738 ch >>= 1;
739 }
740
741 //the second four bytes
742 ch = l2warm_vars.ecc[1];
743 idx = 85;
744 for(i = 64;i < 96;i++)unpk[idx++] = temp[i];
745 for(i = 78; i < 85;i++){
746 unpk[i] = ch & 1;
747 ch >>= 1;
748 }
749
750 //the third four bytes
751 ch = l2warm_vars.ecc[2];
752 idx = 46;
753 for(i = 32;i < 64;i++)unpk[idx++] = temp[i];
754 for(i = 39; i < 46;i++){
755 unpk[i] = ch & 1;
756 ch >>= 1;
757 }
758
759 //last 4 bytes
760 ch = l2warm_vars.ecc[3];
761 idx = 7;
762 for(i = 0;i < 32;i++)unpk[idx++] = temp[i];
763 for(i = 0;i < 7;i++){
764 unpk[i] = ch & 1;
765 ch >>= 1;
766 }
767
768 //pack binaray data to hexa
769 //we need to adjust this routine.
770 for(i = 0;i < 8;i++){
771 for(j = 0; j < 3;j++)l2warm_vars.parts[i][j] = 0;
772 }
773
774 idx = 0;
775 for(i = 0;i < 19;i++){
776 ch = 0;
777 for(j = 0;j < 8;j++)ch |= unpk[idx++] << j;
778 }
779 l2warm_vars.idx = 0;
780 if(which_shift > 1){
781 l2warm_parts(7, 4, unpk); //19
782 l2warm_parts(6, 3, unpk); //20
783 l2warm_parts(5, 4, unpk); //19
784 l2warm_parts(4, 3, unpk);//20
785
786 l2warm_parts(3, 4, unpk);
787 l2warm_parts(2, 3, unpk);
788 l2warm_parts(1, 4, unpk);
789 l2warm_parts(0, 3, unpk);
790 }
791 else{
792 l2warm_parts(7, 3, unpk); //20
793 l2warm_parts(6, 4, unpk); //19
794 l2warm_parts(5, 3, unpk); //20
795 l2warm_parts(4, 4, unpk);//19
796
797 l2warm_parts(3, 3, unpk);
798 l2warm_parts(2, 4, unpk);
799 l2warm_parts(1, 3, unpk);
800 l2warm_parts(0, 4, unpk);
801 }
802}
803/*--------------------------------------------
804slam data into data array.
805index :address[17:8]
806--------------------------------------------*/
807void l2warm_parts(int row, int etc, char* unpk)
808{
809 int i, j;
810 //parts[0]
811 for(i = 0; i < 2;i++){
812 for(j = 0; j < 8; j++){
813 l2warm_vars.parts[row][i] |= unpk[l2warm_vars.idx++] << j;
814 }
815 }
816
817 for(j = 0; j < etc; j++){
818 l2warm_vars.parts[row][i] |= unpk[l2warm_vars.idx++] << j;
819 }
820}
821
822/*--------------------------------------------
823slam data
824--------------------------------------------*/
825
826void l2warm_slam_data(int row)
827{
828 int groups;
829
830 l2warm_vars.bvalPtr = l2warm_vars.avalPtr + l2warm_vars.data_num;
831 for(groups = 0; groups < 3;groups++){
832 l2warm_vars.avalPtr[groups] = l2warm_vars.parts[row][groups];
833 l2warm_vars.bvalPtr[groups] = 0;
834
835 }
836}
837/*--------------------------------------------
838slam data into data array.
839index :address[17:8]
840sub bank select:address<5:4>->the same as l1 cache size
841way :12
842sub-bank includes:
843block_5 : way_sel[1:0]
844block_4 : way_sel[3:2]
845........
846block_4 : way_sel[11:10]
847l1line layout:
848
849[58:39] [19:0]
850[136:117] [97:78]
851[155:137] [116:98]
852[77:59] [38:20]
853-------------------------------------------*/
854void l2warm_slam_real_data(char* data, int subbank)
855{
856 int l1bank, fbyte[4], i, sub, l2index, l2high, ind, pointer;
857 int idx = l2warm_vars.bank * DDATA;//place the pointer on the target bank.
858 int didx = 0;//start from the first byte
859
860 l2index = l2warm_vars.l2_index & 0xff;
861 l2high = l2warm_vars.l2_index & 0x100 ? 0 : 4;
862
863 for(l1bank = 3; l1bank >= 0;l1bank--){//process data by l1 cache size
864 //get 16 bytes
865 for(i = 0;i < 16; i++){
866 l2warm_vars.l1line[i] = data[didx++];
867 fbyte[i / 4] <<= 8;
868 fbyte[i / 4] |= l2warm_vars.l1line[i] & 0xff;
869 }
870 for(i = 0; i < 4;i++)l2warm_vars.ecc[i] = l2warm_decc(fbyte[i]);
871 l2warm_adjust_data(subbank);
872 sub = subbank == 0 || subbank == 2 ? 0 : 1;//deceide top or bottom based on addr[5:4]
873
874 //parts[0]
875 ind = idx + sub * QUAD * 2 + l2warm_vars.way * 8 + l2high ;
876 pointer = l2index * l2warm_vars.data_num * 2;
877
878 if(subbank== 0 || subbank == 1){
879 //left
880 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 128+1] + pointer ;//0lo
881 l2warm_slam_data(0);
882 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 3] + pointer;//1hi
883 l2warm_slam_data(1);
884 //right
885 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 128 +1] + pointer;//0lo
886 l2warm_slam_data(2);
887 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 3] + pointer;//1hi
888 l2warm_slam_data(3);
889 //left
890 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 128] + pointer;//0hi
891 l2warm_slam_data(4);
892 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 2] + pointer;//1lo
893 l2warm_slam_data(5);
894 //right
895 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 128] + pointer;//0lo
896 l2warm_slam_data(6);
897 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 2]+ pointer;//1hi
898 l2warm_slam_data(7);
899 }
900 else if(subbank == 2 ||subbank == 3 ){
901 //left
902 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 128 + 3]+ pointer;//0lo
903 l2warm_slam_data(0);
904 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 1]+ pointer;//1hi
905 l2warm_slam_data(1);
906
907 //right numb= 3
908 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 128 + 3]+ pointer;//0lo
909 l2warm_slam_data(2);
910 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 1]+ pointer;//1hi
911 l2warm_slam_data(3);
912
913 //left num=2
914 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 128 + 2]+ pointer;//0hi
915 l2warm_slam_data(4);
916 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind]+ pointer;//1lo
917 l2warm_slam_data(5);
918
919 //right
920 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256 + 128+2]+ pointer;//0lo
921 l2warm_slam_data(6);
922 l2warm_vars.avalPtr = l2warm_vars.data_avalPtr[ind + 256]+ pointer;//1hi
923 l2warm_slam_data(7);
924 }
925 subbank++;
926 if(subbank == 4)subbank = 0;
927 }
928
929}
930/*--------------------------------------------
931slam vuad into vuad array.
932vuad memory:[107:0] vuad [31:0]
933
934ua->51:26 valid dirty
935 <51-39> <38-26> <25-13> <12-0>
936{parity, 11-0} {parity, 11-0} {parity, 11- 0} {parity, 11- 0}
937array0: array8:
938array1: array9:
939array2: array10:
940array3: array11:
941array4: array12:
942array5: array13:
943array6: array14:
944array7: array15:
945
946layout of vuad:
947index[9:8] ->be used as an index of vuad.
948index[14:10]->be used as an index of vuad array.
949index[17:15]->be used as an index of subarray.
950{parity, used} ->{51, 50:39} {parity, alloc}->{38, 37:26}
951{parity, valid}->{25, 24:13} {parity, dirty}->{12, 11:0}
952
953//N2
954array0: array8:
955array1: array9:
956array2: array10:
957array3: array11:
958reg [159:0] inq_ary [31:0];
959
960<135-119> <118-102> <101-85> <84-68> <67-51> <50-34> <33-17> <16-0>
961l6 index 9 bits
962inq_ary 8-7
963index 6-2
964vuad 1-0
96598 sub array
96610 word
967--------------------------------------------*/
968void l2warm_slam_vuad()
969{
970 //generate the subsript for vuad access based on index.
971 int subarray = (l2warm_vars.l2_index >> 7) & 0x3;//4 inq_arry
972 int vuadarray = (l2warm_vars.l2_index >> 2) & 0x1f;//32 array
973 int vuad = l2warm_vars.l2_index & 0x3;//4 words
974 int idx = l2warm_vars.bank * VUAD + subarray;
975 l2warm_vars.valid_bit = 1;
976 l2warm_vars.dirty_bit = 0;
977 l2warm_updated_vd(idx, vuadarray, vuad);
978}
979/*--------------------------------------------
980implemented:
981// 29 27 25 |23 21 19 17|15 13 11 9|7 5 3 1
982--------------------------------------------*/
983void l2warm_fillerOdd(char* aval, char*bval, int cval, int num)
984{
985 int i, j;
986 char val;
987 for(j = 0; j < 3;j++){
988 val = 0;
989 for(i = 0; i < 4;i++){
990 val |= ((cval & 1) << (2*i+ 1));
991 cval >>= 1;
992 }
993 aval[j] &= 0x55;//0101_0101
994 aval[j] |= val;
995 bval[j] &= 0x55;//0101_0101
996 }
997
998 val = 0;
999 for(i = 0; i < num;i++){
1000 val |= ((cval & 1) << (2*i+ 1));
1001 cval >>= 1;
1002 }
1003 aval[3] &= 0x55;//0101_0101
1004 aval[3] |= val;
1005 bval[3] &= 0x55;//0101_0101
1006}
1007/*--------------------------------------------
100830 28 26 24 |22 20 18 16 |14 12 10 8 |6 4 2
1009--------------------------------------------*/
1010void l2warm_fillerEven(char* aval, char*bval, int cval, int add)
1011{
1012 int i, j;
1013 char val;
1014
1015 val = 0;
1016 for(i = 0; i < 3;i++){
1017 val |= ((cval & 1) << (2*i+ 2 + add));
1018 cval >>= 1;
1019 }
1020 aval[0] &= 0xaa;//1010 1010
1021 aval[0] |= val;
1022 bval[0] &= 0xaa;//1010 1010
1023
1024 for(j = 1; j < 4;j++){
1025 val = 0;
1026 for(i = 0; i < 4;i++){
1027 val |= ((cval & 1) << (2*i));
1028 cval >>= 1;
1029 }
1030 aval[j] &= 0xaa;//0101_0101
1031 aval[j] |= val;
1032 bval[j] &= 0xaa;//0101_0101
1033 }
1034}
1035
1036/*--------------------------------------------
10372 | 4 6 8 10 | 12 14 16 18 | 20 22 24 26
1038--------------------------------------------*/
1039void l2warm_filler13(char* aval, char* bval, int cval, int num)
1040{
1041 int i, j, idx;
1042 char val;
1043 for(j = 0; j < 3;j++){
1044 val = 0;
1045 for(i = 0; i < 4;i++){
1046 idx = 2 * i;
1047 val |= (cval & 1) ? 1 << idx : 0 ;
1048 cval >>= 1;
1049 }
1050 aval[j] &= 0xaa;//0101_0101
1051 aval[j] |= val;
1052 bval[j] &= 0xaa;//0101_0101
1053 }
1054 val = 0;
1055 for(i = 0; i < num;i++){
1056 idx = 2 * i;
1057 val |= (cval & 1) ? 1 << idx : 0;
1058 cval >>= 1;
1059 }
1060 aval[3] &= 0xaa;//0101_0101
1061 aval[3] |= val;
1062 bval[3] &= 0xaa;//0101_0101
1063}
1064/*--------------------------------------------
10650 2 | 4 6 8 10 | 12 14 16 18 | 20 22 24
1066--------------------------------------------*/
1067void l2warm_filler13o(char* aval, char* bval, int cval)
1068{
1069 int i, j, idx;
1070 char val;
1071 val = 0;
1072 for(i = 0; i < 3;i++){
1073 val |= ((cval & 1) << (2*i+ 2));
1074 cval >>= 1;
1075 }
1076 aval[0] &= 0xaa;//0101 0101
1077 aval[0] |= val;
1078 bval[0] &= 0xaa;//0101 0101
1079 for(j = 1; j < 3;j++){
1080 val = 0;
1081 for(i = 0; i < 4;i++){
1082 idx = 2 * i;
1083 val |= (cval & 1) ? 1 << idx : 0 ;
1084 cval >>= 1;
1085 }
1086 aval[j] &= 0xaa;//0101_0101
1087 aval[j] |= val;
1088 bval[j] &= 0xaa;//0101_0101
1089 }
1090 val = 0;
1091 for(i = 0; i < 2;i++){
1092 idx = 2 * i;
1093 val |= (cval & 1) ? 1 << idx : 0;
1094 cval >>= 1;
1095 }
1096 aval[3] &= 0xaa;//0101_0101
1097 aval[3] |= val;
1098 bval[3] &= 0xaa;//0101_0101
1099}
1100/*--------------------------------------------
1101slam tag into tag array.
1102// The input is a 22b tag.
1103// The output is {5b_ecc, 1b_parity}.
1104--------------------------------------------*/
1105void l2warm_slam_tag()
1106{
1107
1108 char *avalPtr, *bvalPtr;
1109 char aval[4], bval[4];
1110 int way, up_half, low_half ;
1111 int groups, tag_data, idx, even;
1112
1113 //new layout of l2tag
1114 tag_data = l2warm_vars.tag << 6 | l2warm_tecc(l2warm_vars.tag);
1115 low_half = tag_data & 0x1fff;
1116 up_half = (tag_data >> 13) & 0x7fff;
1117
1118 // way = l2warm_varsl2warm_vars.way % 2 ? l2warm_vars.way - 1 : l2warm_vars.way;//need even number
1119 way = l2warm_vars.tagWay[l2warm_vars.way];
1120 even = l2warm_vars.tagPos[l2warm_vars.way];
1121 idx = l2warm_vars.bank * TAG + way;
1122 //io_printf("TAG = %x low = %x up = %x\n", tag_data, low_half, up_half);
1123 //upper 15 bits
1124 avalPtr = l2warm_vars.tag_avalPtr[idx] + l2warm_vars.l2_index * l2warm_vars.tag_num * 2;
1125 bvalPtr = avalPtr + l2warm_vars.tag_num;
1126 //read data
1127
1128 //io_printf("read up = ");
1129 for(groups = 0; groups < l2warm_vars.tag_num;groups++){
1130 aval[groups] = avalPtr[groups];
1131 bval[groups] = bvalPtr[groups];
1132 //io_printf("%02x",avalPtr[groups] & 0xff);
1133 }
1134
1135 if(l2warm_vars.redundancy)
1136 even ? l2warm_fillerEven(aval, bval, up_half, 0): l2warm_fillerOdd(aval, bval, up_half, 3);
1137 else
1138 //even ? l2warm_fillerOdd(aval, bval, up_half, 3) : l2warm_fillerEven(aval, bval, up_half, -2);
1139 even ? l2warm_fillerOdd(aval, bval, up_half, 3) :l2warm_filler13(aval, bval, up_half, 3);
1140
1141 //io_printf(" write up = ");
1142 //write data
1143 for(groups = 0; groups < l2warm_vars.tag_num;groups++){
1144 avalPtr[groups] = aval[groups];
1145 bvalPtr[groups] = bval[groups];
1146 //io_printf("%02x",avalPtr[groups] & 0xff);
1147 }
1148
1149 //13 bits
1150 avalPtr = l2warm_vars.tag_avalPtr[idx+1] + l2warm_vars.l2_index * l2warm_vars.tag_num * 2;
1151 bvalPtr = avalPtr + l2warm_vars.tag_num;
1152 //io_printf("read low = ");
1153
1154 for(groups = 0; groups < l2warm_vars.tag_num;groups++){
1155 aval[groups] = avalPtr[groups];
1156 bval[groups] = bvalPtr[groups];
1157 //io_printf("%02x",avalPtr[groups] & 0xff);
1158 }
1159
1160 if(l2warm_vars.redundancy)
1161 even ? l2warm_filler13(aval, bval, low_half,1) : l2warm_fillerOdd(aval, bval, low_half, 1);
1162 else //no redundancy
1163 even ? l2warm_fillerOdd(aval, bval, low_half, 1) : l2warm_filler13o(aval, bval, low_half);
1164
1165 //io_printf(" write low = ");
1166
1167 for(groups = 0; groups < l2warm_vars.tag_num;groups++){
1168 avalPtr[groups] = aval[groups];
1169 bvalPtr[groups] = bval[groups];
1170 //io_printf("%02x",avalPtr[groups] & 0xff);
1171 }
1172 //io_printf("\n");
1173}
1174/*------------------------------------------
1175mask out address and get index, tag and bank
1176based on the bank type.
1177--------------------------------------------*/
1178void l2warm_get_Mode(KeyType* addr)
1179{
1180 int idx, bank;
1181 bool found;
1182 //generate the variables, index, bank, tag of l2 cache.
1183 if(l2warm_vars.bank_type == 4){
1184 *addr &= 0xffffffffc0;
1185 l2warm_vars.bank = (int)((*addr >> 6) & 0x7);//l2bank
1186 l2warm_vars.l2_index = (int)((*addr >> 9) & 0x1ff);//9 bits 512
1187 l2warm_vars.tag = (int)((*addr >> 18) & 0x3fffff);//22 bit
1188 l2warm_vars.selected = (l2warm_vars.l2_index & 0x3) | (((l2warm_vars.l2_index >> 7) & 0x3) << 2);
1189 }
1190 else if(l2warm_vars.bank_type == 2){
1191 *addr &= 0x7fffffffc0;
1192 bank = (int)((*addr >> 6) & 0x3);//l2bank
1193 l2warm_vars.l2_index = (int)((*addr >> 8) & 0x1ff);//9 bits 512
1194 l2warm_vars.tag = (int)((*addr >> 17) & 0x3fffff);//22 bit
1195 l2warm_vars.selected = (l2warm_vars.l2_index & 0x3) | (((l2warm_vars.l2_index >> 7) & 0x3) << 2);
1196 // io_printf("Info:address(%llx) bank(%x) ", *addr, l2warm_vars.bank);
1197 if(bank >= 2){//looking for high bit
1198 found = 0;
1199 for(idx = 0;idx < 4;idx++){
1200 if(l2warm_vars.l2mask & (1 << idx)){
1201 if(!found)found = 1;
1202 else{
1203
1204 l2warm_vars.bank = idx * 2;
1205 l2warm_vars.bank += bank % 2;
1206 // io_printf("inside %d", idx);
1207 break;
1208 }
1209 }//if
1210 }//for
1211 }
1212 else{//looking for low bit
1213 for(idx = 0;idx < 4;idx++){
1214 if(l2warm_vars.l2mask & (1 << idx)){
1215 l2warm_vars.bank = idx * 2;
1216 l2warm_vars.bank += bank % 2;
1217 break;
1218 }
1219 }
1220 }
1221 // io_printf("after(%x)\n", l2warm_vars.bank);
1222 }
1223 else if(l2warm_vars.bank_type == 1){
1224 *addr &= 0x3fffffffc0;
1225 bank = (int)((*addr >> 6) & 0x1);//l2bank
1226 l2warm_vars.l2_index = (int)((*addr >> 7) & 0x1ff);//9 bits 512
1227 l2warm_vars.tag = (int)((*addr >> 16) & 0x3fffff);//22 bit
1228 l2warm_vars.selected = (l2warm_vars.l2_index & 0x3) | (((l2warm_vars.l2_index >> 7) & 0x3) << 2);
1229 for(idx = 0;idx < 4;idx++){
1230 if(l2warm_vars.l2mask & (1 << idx)){
1231 l2warm_vars.bank = idx * 2 + bank;
1232 break;
1233 }
1234 }
1235 }
1236}
1237/*------------------------------------------
1238main routine of l2 warm
1239slam tag, data, vuad into rtl.
1240l1bank[5:4]
1241l2bank[7:6]
1242index[17:8]
1243tag[39:18]
1244`define L2T_ARR_D_WIDTH 28
1245`define L2T_ARR_DEPTH 512
1246reg [`L2T_ARR_D_WIDTH + 1:0] way0[`L2T_ARR_DEPTH - 1 :0]; //one extra bit for redundancy
1247reg [`L2T_ARR_D_WIDTH - 1:0] way1[`L2T_ARR_DEPTH - 1:0];
1248
1249--------------------------------------------*/
1250bool l2warm_slam(KeyType addr, char* data)
1251{
1252 int subbank, finite;
1253 // if(addr < 0x100)return 0;// 0x40040)return;
1254 subbank = (int)((addr >> 4) & 0x3); //l1 bank common for every bank type.
1255 l2warm_get_Mode(&addr);//generate the variables, index, bank, tag of l2 cache.
1256
1257 if((l2warm_vars.check_range == 0) ||
1258 (l2warm_vars.check_range && (addr < l2warm_vars.up_bound) && (addr >= l2warm_vars.low_bound))){
1259 // subbank = (int)((addr >> 4) & 0x3); //l1 bank common for every bank type.
1260 if(l2warm_vars.replace || l2warm_vars.check_range){
1261 l2warm_vars.way =l2warm_vars.round_robin[l2warm_vars.bank];
1262 finite = 0;
1263 while(l2warm_vars.blackboard[l2warm_vars.bank][l2warm_vars.way][l2warm_vars.selected]){
1264 l2warm_vars.round_robin[l2warm_vars.bank]++;
1265 l2warm_vars.way = l2warm_vars.round_robin[l2warm_vars.bank];
1266 if(l2warm_vars.way > (L2WAY-1)){
1267 l2warm_vars.way = 0;
1268 l2warm_vars.round_robin[l2warm_vars.bank] = 0;
1269 }
1270 finite++;
1271 if(finite > (L2WAY - 1))return 0;//no available way for this address
1272 }
1273 }
1274 else {
1275 l2warm_vars.way = random() & 0xf;
1276 finite = 0;
1277 while(l2warm_vars.blackboard[l2warm_vars.bank][l2warm_vars.way][l2warm_vars.selected]){
1278 finite++;
1279 if(finite > 15)return 0;
1280 l2warm_vars.way = random() & 0xf;
1281 }
1282 // if(l2warm_vars.way >0 && l2warm_vars.way <4 || l2warm_vars.way >7 && l2warm_vars.way <12)return 0;
1283 }
1284 //slam start here
1285 // io_printf("ADDRESS %llx way = %x bank = %d index = %x\n", addr, l2warm_vars.way, l2warm_vars.bank, l2warm_vars.l2_index);
1286 l2warm_vars.blackboard[l2warm_vars.bank][l2warm_vars.way][l2warm_vars.selected] = 1;
1287 l2warm_slam_tag(); //process tag
1288 l2warm_slam_vuad();//process vuad
1289 l2warm_slam_real_data(data, subbank);//process data
1290 return (l2warm_vars.way << 1 | 1);
1291 }//if(l2
1292 return 0;
1293}
1294/*------------------------------------------
1295warm cache line which is not in mem.image
1296--------------------------------------------*/
1297void l2warm_warm_all_cache(b_tree_node_ptr* mem)
1298{
1299 int i, subbank;
1300 int warm_tag[4];
1301 b_tree_atom_ptr data;//b-tree node.
1302 KeyType mask_addr;
1303 char rdata[64];
1304 // variables for warm_all
1305 KeyType last_addr[4];
1306
1307 for(i= 0; i < 4;i++){
1308 while(1){
1309 last_addr[i] += (KeyType)1 << 18;
1310 mask_addr = (last_addr[i] >> 6) & 0x3ffffffff;
1311 data = b_Find(mem, &mask_addr);
1312 if(data == 0){
1313 warm_tag[i] = (int)((last_addr[i] >> 18) & 0x3fffff);
1314 break;
1315 }
1316 }
1317 }
1318
1319 l2warm_vars.turn_on_dirty = 1;//on dirty bit.
1320 for(l2warm_vars.bank = 0; l2warm_vars.bank < 4;l2warm_vars. bank++){
1321 l2warm_vars.tag = warm_tag[l2warm_vars.bank];
1322 for(l2warm_vars.way = 0; l2warm_vars.way < L2WAY;l2warm_vars.way++){
1323 for(l2warm_vars.l2_index = 0; l2warm_vars.l2_index < 1024; l2warm_vars.l2_index++){
1324 subbank = 0;
1325 if(l2warm_vars.blackboard[l2warm_vars.bank][l2warm_vars.way][l2warm_vars.l2_index])continue;
1326 for(i = 0; i < 64;i++)rdata[i] = random() & 0xff;
1327 l2warm_slam_tag(); //process tag
1328 l2warm_slam_vuad();//process vuad
1329 l2warm_slam_real_data(rdata, subbank);//process data
1330 }
1331 }
1332 }
1333}
1334
1335/*------------------------------------------
1336how percent.
1337 --------------------------------------------*/
1338int l2warm_percent(int* taken, int* not_taken)
1339{
1340 int num, ret;
1341 if(l2warm_vars.l2run_percent == 0)return 1;
1342 num = l2warm_range(100);
1343 ret = 1;
1344 if(num > l2warm_vars.l2run_percent){//not taken
1345 if(*not_taken == (100 - l2warm_vars.l2run_percent)){
1346 *taken++;
1347 }
1348 else{
1349 ret = 0;
1350 *not_taken++;
1351 }
1352 }
1353 else{
1354 if(*taken == l2warm_vars.l2run_percent){
1355 *not_taken++;
1356 ret = 0;
1357 }
1358 else{
1359 *taken++;
1360 }
1361 }
1362 if((*taken + *not_taken) == 100){
1363 *taken = 0;
1364 *not_taken = 0;
1365 }
1366 return ret;
1367}
1368/*------------------------------------------
1369dynamically inject error int l2 tag or data.
13701). tag wenable, 1 bit
13712). tag index 10 bits
13723). tag way ->2'b10:way0, 2'b10:way1 2bits
1373 --------------------------------------------*/
1374void l2warm_l2_tag_update( int loc)
1375{
1376 long long pos;
1377 int idx, tidx;
1378
1379 if(l2warm_percent(&l2warm_vars.taken_t, &l2warm_vars.not_taken_t)){
1380 for(idx = 0; idx < 6;idx++){
1381 if((l2warm_vars.wren & 1) && (l2warm_vars.way & 3))break;
1382 l2warm_vars.wren >>= 1;
1383 l2warm_vars.way >>= 2;
1384 }
1385 l2warm_vars.way &= 3;
1386 pos = l2warm_get_long(loc+1);//arg 2 index
1387 tidx = (pos >> (idx * 10)) & 0x3ff;//get memory index
1388 l2warm_vars.tag_pend |= (1 << l2warm_vars.bank);
1389 l2warm_vars.tag_pidx[l2warm_vars.bank] = tidx;
1390 l2warm_vars.tag_pos[l2warm_vars.bank] = (idx << 1) + loc + 3;//arg 4
1391 if(l2warm_vars.way & 2)l2warm_vars.tag_pos[l2warm_vars.bank]++;
1392
1393 if((l2warm_vars.tag_pend_now & (1 << l2warm_vars.bank)) &&
1394 (l2warm_vars.tag_pidx[l2warm_vars.bank] == l2warm_vars.tag_pidx_now[l2warm_vars.bank])&&
1395 (l2warm_vars.tag_pos[l2warm_vars.bank] == l2warm_vars.tag_pos_now[l2warm_vars.bank] ))l2warm_vars.tag_pend_now ^= (1 << l2warm_vars.bank);
1396 }
1397}
1398/*--------------------------------------------
1399slam tag into tag array with dynamic error injection.
1400// The input is a 22b tag.
1401// The output is {5b_ecc, 1b_parity}.
1402--------------------------------------------*/
1403void l2warm_slam_tag_error()
1404{
1405 int groups, err;
1406 int pos;
1407 int tag_data;
1408 char *avalPtr, *bvalPtr;
1409
1410 for(l2warm_vars.bank = 0; l2warm_vars.bank < 4; l2warm_vars.bank++){
1411 l2warm_vars.l2_index = l2warm_vars.tag_pidx_now[l2warm_vars.bank];
1412 pos = l2warm_vars.tag_pos_now[l2warm_vars.bank] - (l2warm_vars.bank * 71 + 4);
1413 if(!(l2warm_vars.tag_pend_now & ( 1 << l2warm_vars.bank)) || pos > 11 || pos < 0){
1414 if(pos > 11 || pos < 0){
1415 io_printf("(%d):Info PLI Argment error(%d) bank(%d)\n", tf_gettime(), pos, l2warm_vars.bank);
1416 }
1417 continue;
1418 }
1419 tf_nodeinfo(l2warm_vars.tag_pos_now[l2warm_vars.bank] , &l2warm_vars.node_info);
1420 avalPtr = l2warm_vars.node_info.node_value.memoryval_p + l2warm_vars.l2_index * l2warm_vars.tag_num * 2;
1421 bvalPtr = avalPtr + l2warm_vars.tag_num;
1422 tag_data = 0;
1423 for(groups = l2warm_vars.tag_num - 1; groups >= 0;groups--){
1424 tag_data <<= 8;
1425 tag_data |= avalPtr[groups] & 0xff;
1426 }
1427 tag_data &= 0xfffffff;
1428 if(l2warm_check_parity_two(tag_data, 28))continue;
1429 err = l2warm_error_enject_long(tag_data);
1430 io_printf("Info(%0d): L2_Tag error injection L2_bank(%d) way(%d) index(%d) original_tag(%x) after_tag(%x)\n",
1431 tf_gettime(), l2warm_vars.bank, pos, l2warm_vars.l2_index, tag_data, err);
1432
1433 for(groups = 0; groups < l2warm_vars.tag_num;groups++){
1434 avalPtr[groups] = err & 0xff;
1435 bvalPtr[groups] = 0;
1436 err >>= 8;
1437 }
1438 }
1439 l2warm_vars.tag_pend_now = 0;
1440}
1441/*------------------------------------------
1442dynamicaly inject error int l2 tag or data.
14434). data subbank0:wenable 2'b01:way0_decc, 2'b10:way1_decc
14445). data subbank0:index
1445 --------------------------------------------*/
1446void l2warm_l2_data_update(int wren, int loc)
1447{
1448 long long pos;
1449 int idx;
1450 if(l2warm_percent(&l2warm_vars.taken_d, &l2warm_vars.not_taken_d)){
1451 pos = l2warm_get_long(loc+1);
1452 for(idx = 0; idx < 6;idx++){
1453 if(wren & 3)break;
1454 wren >>= 2;
1455 pos >>= 10;
1456 }
1457 l2warm_vars.data_pend |= (1 << l2warm_vars.bank);
1458 l2warm_vars.data_pidx[l2warm_vars.bank] = pos & 0x3ff;
1459 l2warm_vars.data_pos[l2warm_vars.bank] = (idx << 1) + loc + 3;//
1460 if(wren & 2)l2warm_vars.tag_pos[l2warm_vars.bank]++;
1461 if((l2warm_vars.data_pend_now & (1 << l2warm_vars.bank)) &&
1462 (l2warm_vars.data_pidx[l2warm_vars.bank] == l2warm_vars.data_pidx_now[l2warm_vars.bank])&&
1463 (l2warm_vars.data_pos[l2warm_vars.bank] == l2warm_vars.data_pos_now[l2warm_vars.bank] ))l2warm_vars.data_pend_now ^= (1 << l2warm_vars.bank);
1464 }
1465}
1466/*--------------------------------------------
1467slam tag into tag array with dynamic error injection.
1468// The input is a 22b tag.
1469// The output is {5b_ecc, 1b_parity}.
1470
1471{cache_data_out_c5[31:0], cache_ecc_out_c5[6:0]} = cache_decc_out_c5[38:0];
1472{cache_data_out_c5[63:32], cache_ecc_out_c5[13:7]} = cache_decc_out_c5[77:39];
1473{cache_data_out_c5[95:64], cache_ecc_out_c5[20:14]} = cache_decc_out_c5[116:78];
1474{cache_data_out_c5[127:96], cache_ecc_out_c5[27:21]} = cache_decc_out_c5[155:117];
1475groups0[4:0] {38, 37, 36, 35, 34, 33, 32}
1476groups1[9:5] {77, 76, 75, 74, 73, 72}
1477groups2[15:10]
1478groups3[19:16]
1479--------------------------------------------*/
1480void l2warm_slam_data_error()
1481{
1482 int groups, idx;
1483 long long temp_val;
1484 char *avalPtr, *bvalPtr;
1485
1486 for(l2warm_vars.bank = 0; l2warm_vars.bank < 4; l2warm_vars.bank++){
1487 if(!(l2warm_vars.data_pend_now & ( 1 << l2warm_vars.bank)))continue;
1488 tf_nodeinfo(l2warm_vars.data_pos_now[l2warm_vars.bank] , &l2warm_vars.node_info);
1489 l2warm_vars.l2_index = l2warm_vars.data_pidx_now[l2warm_vars.bank];
1490 if(1){
1491 avalPtr = l2warm_vars.node_info.node_value.memoryval_p + l2warm_vars.l2_index * l2warm_vars.data_num * 2;
1492 bvalPtr = avalPtr + l2warm_vars.data_num;
1493 for(groups = l2warm_vars.tag_num - 1; groups >= 0;groups--)l2warm_vars.slam_data[groups] = avalPtr[groups];
1494 if(l2warm_check_parity())continue;
1495 switch(l2warm_range(4)){
1496 case 0 :
1497 temp_val = l2warm_vars.slam_data[4] & 0x7f;
1498 for(idx = 3; idx >= 0;idx--){
1499 temp_val <<= 8;
1500 temp_val |= l2warm_vars.slam_data[idx] & 0xff;
1501 }
1502 if(!l2warm_check_parity_two(temp_val, 39)){
1503 io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
1504 tf_gettime(), l2warm_vars.bank, l2warm_vars.data_way_now[l2warm_vars.bank], l2warm_vars.data_pidx_now[l2warm_vars.bank]);
1505 io_printf(" orginal_data(%016llx) ", temp_val);
1506 temp_val = l2warm_error_enject_long(temp_val);//error inject
1507 io_printf(" after_data(%016llx)\n", temp_val);
1508 for(idx = 0; idx < 4;idx++){
1509 l2warm_vars.slam_data[idx] = temp_val & 0xff;
1510 temp_val >>= 8;
1511 }
1512 l2warm_vars.slam_data[4] &= 0x80;
1513 l2warm_vars.slam_data[4] |= temp_val & 0x7f;
1514 }
1515 break;
1516 case 1 :
1517 temp_val = l2warm_vars.slam_data[9] & 0x3f;
1518 for(idx = 8; idx >= 5;idx--){
1519 temp_val <<= 8;
1520 temp_val |= l2warm_vars.slam_data[idx] & 0xff;
1521 }
1522 temp_val <<= 1;
1523 temp_val |= l2warm_vars.slam_data[4] & 0x80 ? 1 : 0;
1524 if(!l2warm_check_parity_two(temp_val, 39)){
1525 io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
1526 tf_gettime(), l2warm_vars.bank, l2warm_vars.data_way_now[l2warm_vars.bank], l2warm_vars.data_pidx_now[l2warm_vars.bank]);
1527 io_printf(" orginal_data(%016llx) ", temp_val);
1528 temp_val = l2warm_error_enject_long(temp_val);//error inject
1529 io_printf(" after_data(%016llx)\n", temp_val);
1530 l2warm_vars.slam_data[4] &= 0x7f;
1531 l2warm_vars.slam_data[4] |= temp_val & 1 ? 0x80 : 0;
1532 temp_val >>= 1;
1533 for(idx = 5; idx < 10;idx++){
1534 l2warm_vars.slam_data[idx] = temp_val & 0xff;
1535 temp_val >>= 8;
1536 }
1537 l2warm_vars.slam_data[9] &= 0xc0;
1538 l2warm_vars.slam_data[9] |= temp_val & 0x3f;
1539 }
1540 break;
1541 case 2:
1542 temp_val = l2warm_vars.slam_data[14] & 0x1f;
1543 for(idx = 13; idx >= 10;idx--){
1544 temp_val <<= 8;
1545 temp_val |= l2warm_vars.slam_data[idx] & 0xff;
1546 }
1547 temp_val <<= 2;
1548 temp_val |= (l2warm_vars.slam_data[9] >> 6) & 3;
1549 if(!l2warm_check_parity_two(temp_val, 39)){
1550 io_printf("Info(%0d): L2_Data error injection L2_bank(%d) way(%0x) index(%05d)",
1551 tf_gettime(), l2warm_vars.bank, l2warm_vars.data_way_now[l2warm_vars.bank], l2warm_vars.data_pidx_now[l2warm_vars.bank]);
1552 io_printf(" orginal_data(%016llx) ", temp_val);
1553 temp_val = l2warm_error_enject_long(temp_val);//error inject
1554 io_printf(" after_data(%016llx)\n", temp_val);
1555 l2warm_vars.slam_data[9] &= 0x3f;
1556 l2warm_vars.slam_data[9] |= ((temp_val & 3) << 6);
1557 temp_val >>= 2;
1558 for(idx = 10; idx < 14;idx++){
1559 l2warm_vars.slam_data[idx] = temp_val & 0xff;
1560 temp_val >>= 8;
1561 }
1562 l2warm_vars.slam_data[14] &= 0xe0;
1563 l2warm_vars.slam_data[14] |= temp_val & 0x1f;
1564 }
1565 break;
1566 case 3 :
1567 temp_val = l2warm_vars.slam_data[19] & 0xf;
1568 for(idx = 18; idx >= 15;idx--){
1569 temp_val <<= 8;
1570 temp_val |= l2warm_vars.slam_data[idx] & 0xff;
1571 }
1572 temp_val <<= 3;
1573 temp_val |= (l2warm_vars.slam_data[14] >> 5) & 7;
1574 if(!l2warm_check_parity_two(temp_val, 39)){
1575 io_printf("Info(%0d): L2_Data error injection L2_l2warm_vars.bank(%d) way(%0x) index(%05d)",
1576 tf_gettime(), l2warm_vars.bank, l2warm_vars.data_way_now[l2warm_vars.bank], l2warm_vars.data_pidx_now[l2warm_vars.bank]);
1577 io_printf(" orginal_data(%016llx) ", temp_val);
1578 temp_val = l2warm_error_enject_long(temp_val);//error inject
1579 io_printf(" after_data(%016llx)\n", temp_val);
1580 l2warm_vars.slam_data[14] &= 0x1f;
1581 l2warm_vars.slam_data[14] |= ((temp_val & 7) << 5);
1582 for(idx = 15; idx < 19;idx++){
1583 l2warm_vars.slam_data[idx] = temp_val & 0xff;
1584 temp_val >>= 8;
1585 }
1586 l2warm_vars.slam_data[19] |= temp_val & 0xf;
1587 }
1588 break;
1589 }
1590 //slam
1591 for(groups = l2warm_vars.tag_num - 1; groups >= 0;groups--){
1592 avalPtr[groups] = l2warm_vars.slam_data[groups];
1593 bvalPtr[groups] = 0;
1594 }
1595 }
1596 }
1597 l2warm_vars.data_pend_now = 0;
1598}
1599/*------------------------------------------
1600 inject error.
1601 --------------------------------------------*/
1602void l2warm_error_enject_void()
1603{
1604 int sub;
1605 int loc = 1;
1606 // save the previous write to avoid the confliction between
1607 // the current and the previous update.
1608
1609 if(l2warm_vars.tag_pend){
1610 l2warm_vars.tag_pend_now = l2warm_vars.tag_pend;
1611 for(sub = 0; sub < 4; sub++){
1612 l2warm_vars.tag_pidx_now[sub] = l2warm_vars.tag_pidx[sub];
1613 l2warm_vars.tag_pos_now[sub] = l2warm_vars.tag_pos[sub];
1614 }
1615 l2warm_vars.tag_pend = 0;
1616 }
1617 if(l2warm_vars.data_pend){
1618 l2warm_vars.data_pend_now = l2warm_vars.data_pend;
1619 for(sub = 0; sub < 4; sub++){
1620 l2warm_vars.data_pidx_now[sub] = l2warm_vars.data_pidx[sub];
1621 l2warm_vars.data_pos_now[sub] = l2warm_vars.data_pos[sub];
1622 l2warm_vars.data_way_now[sub] = l2warm_vars.data_way[sub];
1623 }
1624 l2warm_vars.data_pend = 0;
1625 }
1626
1627 //Are there Tag or data updated?
1628 for(l2warm_vars.bank = 0; l2warm_vars.bank < MAX_BANK; l2warm_vars.bank++){
1629 l2warm_vars.wren = tf_getp(loc);//arg 1
1630 l2warm_vars.way = tf_getp(loc+2);//arg 3 way
1631 if(l2warm_vars.wren && l2warm_vars.way)l2warm_l2_tag_update(loc);//arg 1
1632 loc += 15;//move loc to data. arg 16
1633 for(sub = 0; sub < 4; sub++){//16
1634 if(tf_getp(loc))l2warm_l2_data_update(tf_getp(loc), loc);//pass 16
1635 loc += 14;//30
1636 }
1637 }
1638 if(l2warm_vars.tag_pend_now)l2warm_slam_tag_error();
1639 if(l2warm_vars.data_pend_now)l2warm_slam_data_error();
1640}
1641/*------------------------------------------
1642invalidate icache
1643--------------------------------------------*/
1644void l2warm_clean_reg(int loc)
1645{
1646 int groups;
1647
1648 tf_nodeinfo(loc, &l2warm_vars.node_info);
1649 for(groups = 0; groups < l2warm_vars.node_info.node_ngroups ; groups++){
1650 l2warm_vars.node_info.node_value.vecval_p[groups].avalbits = 0;
1651 }
1652 tf_propagatep(loc);
1653}
1654/*--------------------------------------------
1655slam tag into tag array.
1656// The input is a 22b tag.
1657// The output is {5b_ecc, 1b_parity}.
1658--------------------------------------------*/
1659void l2warm_get_tag()
1660{
1661 int groups;
1662 char *avalPtr, *bvalPtr;
1663 int idx = l2warm_vars.bank * TAG + l2warm_vars.way;
1664 avalPtr = l2warm_vars.tag_avalPtr[idx] + l2warm_vars.l2_index * l2warm_vars.tag_num * 2;
1665 bvalPtr = avalPtr + l2warm_vars.tag_num;
1666 l2warm_vars.tag_data = 0;
1667 for(groups = l2warm_vars.tag_num - 1; groups >= 0;groups--){
1668 l2warm_vars.tag_data <<= 8;
1669 l2warm_vars.tag_data |= avalPtr[groups] & 0xff;
1670 }
1671 l2warm_vars.tag >>= 6;//6bit ecc
1672 l2warm_vars.tag &= 0x3ffff;//22 bit
1673}
1674
1675/*--------------------------------------------
1676pack 4 bytes.
1677--------------------------------------------*/
1678void l2warm_pack_4bytes(int idx, char* unpk){
1679
1680 int i, j;
1681
1682 for(i = 0; i < 4; i++){
1683 l2warm_vars.staledata[l2warm_vars.stale_idx] = 0;
1684 for(j = 0; j < 8; j++){
1685 l2warm_vars.staledata[l2warm_vars.stale_idx] <<= 1;
1686 l2warm_vars.staledata[l2warm_vars.stale_idx] |= unpk[idx--];
1687 }
1688 l2warm_vars.stale_idx++;
1689 }
1690}
1691/*--------------------------------------------
1692pack 16 bytes.
1693--------------------------------------------*/
1694void l2warm_pack_data(char* unpk)
1695{
1696 l2warm_pack_4bytes(155, unpk);
1697 l2warm_pack_4bytes(116, unpk);
1698 l2warm_pack_4bytes(77, unpk);
1699 l2warm_pack_4bytes(38, unpk);
1700}
1701/*--------------------------------------------
1702read data from scdat.
1703--------------------------------------------*/
1704void l2warm_get_data()
1705{
1706 int l1bank, j, pkidx, groups ;
1707 char *avalPtr, ch, unpk[156];
1708
1709 int idx = l2warm_vars.bank * DDATA;//place the pointer on the target bank.
1710
1711 l2warm_vars.stale_idx = 0;
1712 for(l1bank = 3; l1bank >= 0;l1bank--){//process data by l1 cache size
1713 avalPtr = l2warm_vars.data_avalPtr[idx + l1bank * SUBBANK + l2warm_vars.way] + l2warm_vars.l2_index * l2warm_vars.data_num * 2;
1714 pkidx = 0;
1715 for(groups = 0; groups < l2warm_vars.data_num;groups++){
1716 ch = avalPtr[groups];
1717 for(j = 0; j < 8;j++){
1718 unpk[pkidx++] = ch & 1;
1719 ch >>= 1;
1720 }
1721 }
1722 l2warm_pack_data(unpk);
1723 }
1724}
1725/*-------------------------------------------------------------------------------
1726 get 64 bits.
1727--------------------------------------------------------------------------------*/
1728long long l2warm_get_long(int loc){
1729 int low, high;
1730 long long val;
1731
1732 low = tf_getlongp(&high, loc);
1733 val = high;
1734 val <<= 32;
1735 val |= low;
1736 return val;
1737}
1738
1739/*------------------------------------------
1740l2bank[7:6]
1741index[17:8]
1742tag[39:18]
1743--------------------------------------------*/
1744void l2warm_gen_addr()
1745{
1746 l2warm_vars.mask_addr = 0;
1747 l2warm_vars.mask_addr |= l2warm_vars.tag << 18;
1748 l2warm_vars.mask_addr |= l2warm_vars.l2_index << 8;
1749 l2warm_vars.mask_addr |= l2warm_vars.bank << 6;
1750}
1751/*------------------------------------------
1752invalidate cache.
1753--------------------------------------------*/
1754void l2warm_l2_invalidate(int bank_t)
1755{
1756//generate the subsript for vuad access based on index.
1757 int subarray, vuadarray, vuad, idx, groups;
1758 char *avalPtr, *bvalPtr;
1759 l2warm_vars.bank = bank_t;
1760 for(l2warm_vars.l2_index = 0; l2warm_vars.l2_index < INDEX; l2warm_vars.l2_index++){
1761 subarray = (l2warm_vars.l2_index >> 7) & 0x7;
1762 vuadarray = (l2warm_vars.l2_index >> 2) & 0x1f;//32 array
1763 vuad = l2warm_vars.l2_index & 0x3;//4 words
1764 idx = l2warm_vars.bank * VUAD + subarray;
1765 //valid and dirty data field
1766 avalPtr = l2warm_vars.vuad_avalPtr[idx+8] + vuadarray * l2warm_vars.vuad_num * 2;
1767 bvalPtr = avalPtr + l2warm_vars.vuad_num;
1768 //get 108 bits.
1769 //ascending order.
1770 for(groups = 0; groups < l2warm_vars.vuad_num;groups++)l2warm_vars.slam_data[groups] = avalPtr[groups];
1771 l2warm_unpack();//unpack hexa to binary
1772 l2warm_extract_vuad(vuad);
1773 for(l2warm_vars.way = 0; l2warm_vars.way < L2WAY; l2warm_vars.way++){
1774 if((l2warm_vars.up_vuad & 1) && (l2warm_vars.low_vuad & 1)){
1775 l2warm_get_tag();
1776 l2warm_get_data();
1777 l2warm_gen_addr();
1778 //write_dram_call(&mask_addr, staledata);
1779 }
1780 l2warm_vars.up_vuad >>= 1;
1781 l2warm_vars.low_vuad >>= 1;
1782 }
1783 }
1784
1785 //after writeback
1786 l2warm_l2_clear_vuad(l2warm_vars.bank);
1787}
1788/*------------------------------------------
1789enject error during run time.
1790--------------------------------------------*/
1791void l2warm_l1_invalidate(int ivld, int dvld, int cpu)
1792{
1793 l2warm_clean_reg(dvld);
1794 l2warm_clean_reg(ivld);
1795 //mark uninvalid cpu.
1796 l2warm_vars.cpu_invalid ^= 1 << cpu;
1797 io_printf("%0d:Info Invalidated L1cache core(%0d)\n",tf_gettime(), cpu);
1798}
1799/*------------------------------------------
1800When l2_bypass is deasserted, slam dram memory.
1801--------------------------------------------*/
1802void l2warm_stale_data(int loc)
1803{
1804 int i;
1805 list_node_ptr addr_ptr;
1806
1807 l2warm_vars.bank = tf_getp(loc);
1808 //addr_ptr = addr_list[bank].shift();
1809
1810 while(addr_ptr){
1811 l2warm_vars.mask_addr = addr_ptr->addr;
1812 for(i = 0; i < 64;i++)l2warm_vars.staledata[i] = random() & 0xff;
1813 //write_dram_call(&mask_addr, staledata);
1814 //addr_ptr = addr_list[bank].shift();
1815 }
1816}
1817/*------------------------------------------
1818display l2 warm data.
1819--------------------------------------------*/
1820void l2warm_debug()
1821{
1822 int idx, sub, groups, col;
1823 char *avalPtr;
1824 for(idx = 0; idx < 4;idx++){
1825 io_printf("Info:L2 Tag valid bits for bank(%d)\n", idx);
1826 for(sub = 8; sub < 16;sub++){
1827 io_printf("(%d) Sub array", sub);
1828 io_printf(" ");
1829 io_printf("(%d) Sub Array\n", sub-8);
1830 for(col = 0; col < 32;col++){
1831 avalPtr = l2warm_vars.vuad_avalPtr[idx * VUAD + sub] + col * l2warm_vars.vuad_num * 2;
1832 io_printf("index(%02d) -> valid/dirty bits(", col);
1833 io_printf("%01x",avalPtr[l2warm_vars.vuad_num - 1] & 0xf);
1834 for(groups = l2warm_vars.vuad_num - 2;groups >= 0; groups--)io_printf("%02x", avalPtr[groups] & 0xff);
1835 io_printf(")");
1836 io_printf(" index(%02d) -> u/a bits(", col);
1837 avalPtr = l2warm_vars.vuad_avalPtr[idx * VUAD + sub-8] + col * l2warm_vars.vuad_num * 2;
1838 io_printf("%01x",avalPtr[l2warm_vars.vuad_num - 1] & 0xf);
1839 for(groups = l2warm_vars.vuad_num - 2;groups >= 0; groups--)io_printf("%02x",avalPtr[groups] & 0xff);
1840 io_printf(")\n");
1841 }
1842 }
1843 }
1844}
1845
1846/*---------------------------------------
1847 replace char with space.
1848 ----------------------------------------*/
1849void l2warm_replace(char* str)
1850{
1851 int i;
1852 for(i = 0; i < strlen(str);i++){
1853 if(
1854 str[i] == '(' ||
1855 str[i] == ')' ||
1856 str[i] == '-' ||
1857 str[i] == '>' ||
1858 str[i] == '"' ||
1859 str[i] == ',')str[i] = ' ';
1860 }
1861}
1862/*---------------------------------------
1863 replace char with space.
1864 ----------------------------------------*/
1865void l2warm_rmhexa(char* buf){
1866 int i, j;
1867
1868 for(i = 0;i < strlen(buf);i++)if(buf[i] == 'h' || buf[i] == 'x')break;
1869 j = 0;
1870 for(i = i+1;i < strlen(buf);i++){
1871 buf[j++] = buf[i];
1872 }
1873 buf[j] = '\0';
1874}