Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / pli / cache / c / src / l1warm.c
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: l1warm.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 "l1warm.h"
39/*--------------------------------------------
40constructor.
41bind caller's argments to pointer table.
42--------------------------------------------*/
43void l1warm_init()
44{
45 int i;
46 l1warm_vars.idir_num = 0;
47 l1warm_vars.ddir_num = 0;
48 //slam icache & dcache 50%, respectively.
49 l1warm_vars.icache = 50;
50 l1warm_vars.dcache = 50;
51 l1warm_vars.idone = 0;
52 l1warm_vars.ddone = 0;
53 l1warm_vars.dcache_num = 0;
54 l1warm_vars.icache_num = 0;
55 l1warm_vars.dtag_num = 0;
56 l1warm_vars.itag_num = 0;
57 l1warm_vars.ivalid_num = 0;
58 l1warm_vars.dvalid_num = 0;
59
60 for(i = 0; i < 8 * MAX_BANK; i++){
61 l1warm_vars.dir_ivalid[i] = 0;
62 l1warm_vars.dir_dvalid[i] = 0;
63 l1warm_vars.dir_iparity[i] = 0;
64 l1warm_vars.dir_dparity[i] = 0;
65 l1warm_vars.dir_iaddr4[i] = 0;
66 l1warm_vars.dir_daddr4[i] = 0;
67 }
68 l1warm_vars.iround = 0;
69 //debug
70 l1warm_vars.l1_debug = 0;
71 l1warm_vars.check_irange = 0;
72 l1warm_vars.check_drange = 0;
73}
74/*-------------------------------------------------------------------------------
75 convert ascii to hex array.
76--------------------------------------------------------------------------------*/
77void l1warm_clean_dir()
78{
79 int i;
80 for(i = 0; i < 8 * MAX_BANK; i++){
81 l1warm_vars.dir_ivalid[i] = 0;
82 l1warm_vars.dir_dvalid[i] = 0;
83 l1warm_vars.dir_iparity[i] = 0;
84 l1warm_vars.dir_dparity[i] = 0;
85 }
86}
87/*-------------------------------------------------------------------------------
88 convert ascii to hex array.
89--------------------------------------------------------------------------------*/
90int l1warm_copy(char* buf, char* cbuf, int idx)
91{
92 int ind = 0;
93 while((buf[idx] != '\0') &&
94 (buf[idx] != ':') &&
95 (buf[idx] != ' ') &&
96 (ind < 16))cbuf[ind++] = buf[idx++];
97 cbuf[ind] = '\0';
98 return ++idx;
99}
100/*-------------------------------------------------------------------------------
101 check the address symbol that is "@".
102 if symbol there, return address.
103--------------------------------------------------------------------------------*/
104long long l1warm_getEight(char *buf)
105{
106 int i;
107 long long key = 0;
108
109 for(i = 0; buf[i] != '\0';i++){
110 key <<= 4;
111 key |= buf[i] > '9' ? ((buf[i] & 0xf) + 9) : buf[i] & 0xf;
112 }
113 return key;
114}
115/*-------------------------------------------
116check whether it is invalidate_all.
117---------------------------------------------*/
118long long l1warm_get_long(int loc){
119 int low, high;
120 long long sixty;
121
122 low = tf_getlongp(&high, loc);
123 sixty = high;
124 sixty <<= 32;
125 sixty |= low;
126 return sixty;
127}
128/*--------------------------------------------
129constructor.
130bind caller's argments to pointer table.
131--------------------------------------------*/
132void l1warm_set()
133{
134 int arg, idx, bank, row, panel;
135 //set options.
136 char* pargs, cbuf[16];
137 s_tfnodeinfo node_info;
138 l1warm_init();
139
140 //get dcache directory pointer
141 //l1 dcache
142 idx = 0;arg = 2;
143 for(bank = 0; bank < MAX_BANK;bank++){
144 idx = bank * 8;
145 for(row = 0; row < 2;row++){
146 for(panel = 0; panel < 4; panel++){
147 tf_nodeinfo(arg, &node_info);
148 if(l1warm_vars.ddir_num == 0)l1warm_vars.ddir_num = node_info.node_ngroups;
149 l1warm_vars.dir_darray[idx] = node_info.node_value.memoryval_p;
150 arg += 4;
151 idx++;
152 }
153 }
154
155 //l2 icache directory
156 //64 for each memory
157 idx = bank * 8;
158 for(row = 0; row < 2;row++){
159 for(panel = 0; panel < 4; panel++){
160 tf_nodeinfo(arg, &node_info);
161 if(l1warm_vars.idir_num == 0)l1warm_vars.idir_num = node_info.node_ngroups;
162 l1warm_vars.dir_iarray[idx] = node_info.node_value.memoryval_p;
163 arg += 4;
164 idx++;
165 }
166 }
167 }//for(bank = 0; bank < MAX_BANK;bank++){
168
169 /*
170 //i$ & D$ of l1
171 for(idx = 0;idx < MAX_CORE;idx++){
172 if(l1warm_vars.cpu_status & (1 << idx)){//if instantiate, do it.
173 //get the dcache pointer.
174 for(i = 0; i < 4;i++){
175 tf_nodeinfo(arg++, &node_info);
176 l1warm_vars.dcache_w[idx][i] = node_info.node_value.memoryval_p;//way and core
177 if(l1warm_vars.dcache_num == 0)l1warm_vars.dcache_num = node_info.node_ngroups;
178 }
179 //tag
180 for(i = 0; i < 4;i++){
181 tf_nodeinfo(arg++, &node_info);
182 l1warm_vars.dcache_tag[idx][i] = node_info.node_value.memoryval_p;//way and core
183 if(l1warm_vars.dtag_num == 0)l1warm_vars.dtag_num = node_info.node_ngroups;
184 }
185 //valid
186 //slam valid to zero.
187 l1warm_vars.dcache_vld[idx] = arg;
188 tf_nodeinfo(arg++, &node_info);
189 for(i = 0; i < node_info.node_ngroups;i++){
190 node_info.node_value.vecval_p[i].avalbits = 0;
191 node_info.node_value.vecval_p[i].bvalbits = 0;
192 }
193 tf_propagatep(l1warm_vars.dcache_vld[idx]);
194
195 //get icache pointer
196 //icache data
197
198 for(i = 0; i < 16;i++){
199 tf_nodeinfo(arg++, &node_info);
200 l1warm_vars.icache_data[idx][i] = node_info.node_value.memoryval_p;//way and core
201 if(l1warm_vars.dtag_num == 0)l1warm_vars.icache_num = node_info.node_ngroups;
202 }
203 for(i = 0; i < 8;i++){
204 tf_nodeinfo(arg++, &node_info);
205 l1warm_vars.icache_tag[idx][i] = node_info.node_value.memoryval_p;//way and core
206 if(l1warm_vars.itag_num == 0)l1warm_vars.itag_num = node_info.node_ngroups;
207 }
208 //slam valid to zero.
209 l1warm_vars.icache_vld[idx] = arg;
210 tf_nodeinfo(arg++, &node_info);
211 for(i = 0; i < node_info.node_ngroups;i++){
212 node_info.node_value.vecval_p[i].avalbits = 0;
213 node_info.node_value.vecval_p[i].bvalbits = 0;
214 }
215 tf_propagatep(l1warm_vars.icache_vld[idx]);
216 }
217 }
218 //get option for l1 warm
219 */
220 pargs = mc_scan_plusargs ("l1_debug=");
221 if(pargs != (char *) 0)l1warm_vars.l1_debug = 1;
222
223 pargs = mc_scan_plusargs ("l1_irange=");
224 if(pargs != (char *) 0){
225 l1warm_vars.check_irange = 1;
226 idx = l1warm_copy(pargs, cbuf, 0);
227 l1warm_vars.up_ibound = l1warm_getEight(cbuf);
228 l1warm_copy(pargs, cbuf, idx);
229 l1warm_vars.low_ibound = l1warm_getEight(cbuf);
230 io_printf("Info:L1_islam range %llx:%llx\n", l1warm_vars.up_ibound, l1warm_vars.low_ibound);
231 }
232
233 pargs = mc_scan_plusargs ("l1_drange=");
234 if(pargs != (char *) 0){
235 l1warm_vars.check_drange = 1;
236 idx = l1warm_copy(pargs, cbuf, 0);
237 l1warm_vars.up_dbound = l1warm_getEight(cbuf);
238 l1warm_copy(pargs, cbuf, idx);
239 l1warm_vars.low_dbound = l1warm_getEight(cbuf);
240 io_printf("Info:L1_dslam range %llx:%llx\n", l1warm_vars.up_dbound, l1warm_vars.low_dbound);
241 }
242
243 //check bank mode.
244 l1warm_vars.l2mask = 0xf;
245 l1warm_vars.l2bank_type = 4;
246 pargs = mc_scan_plusargs ("bank_set+mask=");
247 if(pargs != (char *) 0){
248 l1warm_vars.l2mask = atoi(pargs);
249 l1warm_vars.l2bank_type = 0;
250 for(idx = 0; idx < 4;idx++){
251 if(l1warm_vars.l2mask & (1 << idx))l1warm_vars.l2bank_type++;
252 }
253 }
254}
255
256/*--------------------------------------------
257after slam tag, save valid & parity into memory.
258--------------------------------------------*/
259void l1warm_store_parityValidAddr()
260{
261 int bank, row, pair, arg, idx;
262 //ddirectory
263 for(bank = 0; bank < 8;bank++){
264 for(row = 0; row < 2;row++){
265 for(pair = 0; pair < 4; pair++){
266 idx = bank * BANK_NUM + row * ROW_NUM + pair;
267 arg = 3 + bank * BANK_NUM + row * ROW_NUM + pair;
268 tf_putlongp(arg++, l1warm_vars.dir_dvalid[idx], l1warm_vars.dir_dvalid[idx] >> 32);
269 tf_putlongp(arg++, l1warm_vars.dir_dparity[idx], l1warm_vars.dir_dparity[idx] >> 32);
270 tf_putlongp(arg, l1warm_vars.dir_daddr4[idx], l1warm_vars.dir_daddr4[idx] >> 32);
271 }
272 }
273 }
274 //idirectory
275 for(bank = 0; bank < 8;bank++){
276 for(row = 0; row < 2;row++){
277 for(pair = 0; pair < 4; pair++){
278 idx = bank * BANK_NUM + row * ROW_NUM + pair;
279 arg = 35+ bank * BANK_NUM + row * ROW_NUM + pair;
280 tf_putlongp(arg++, l1warm_vars.dir_ivalid[idx], l1warm_vars.dir_ivalid[idx] >> 32);
281 tf_putlongp(arg++, l1warm_vars.dir_iparity[idx], l1warm_vars. dir_iparity[idx] >> 32);
282 tf_putlongp(arg, l1warm_vars.dir_daddr4[idx], l1warm_vars.dir_iaddr4[idx] >> 32);
283 }
284 }
285 }
286}
287
288/*--------------------------------------------
289clean valid bits when l2_warm is called beacuse
290ni is inclusive cache.
291--------------------------------------------*/
292void l1warm_clean_valid()
293{
294
295 int idx, byte;
296 s_tfnodeinfo node_info;
297
298 for(idx = 2; idx < tf_nump();idx++){
299 //slam valid to zero.
300 tf_nodeinfo(idx, &node_info);
301 for(byte = 0; byte < node_info.node_ngroups;byte++){
302 node_info.node_value.vecval_p[byte].avalbits = 0;
303 node_info.node_value.vecval_p[byte].bvalbits = 0;
304 }
305 tf_propagatep(idx);
306 }
307}
308/*--------------------------------------------
309clean valid bits when l2_warm is called beacuse
310ni is inclusive cache.
311--------------------------------------------*/
312void l1warm_clean_dirvld()
313{
314int idx;
315 for(idx = 2; idx < tf_nump();idx++)tf_putlongp(idx, 0, 0);
316
317}
318/*--------------------------------------------
319got the predecode information.
320--------------------------------------------*/
321int l1warm_predecoder(int inst)
322{
323 int out, op, op1, op2, op3;
324 op = (inst >> 30 ) & 0x3;
325 out = 0;
326 if(op == 1)out = 1;//call
327 else if(op == 0){//branch, sethi, nop
328 op1 = (inst >> 22) & 0x7;
329 if(op1 == 0x4)out = 0; // nop/sethi
330 else out = 1;// branch
331 }
332 else if(op == 2){// arith, shift, mem#, mov
333 op1 = (inst >> 23) & 0x3;
334 if(op1 == 3)out = 1;// wrpr, vis, save, jmpl
335 else if((op1 & 2) == 0){// arith
336 op2 = (inst >> 22) & 0x3;
337 op3 = (inst >> 19) & 0x3;
338 if((op2 & 1) == 0)out = 0;// alu op
339 else if((op2 & 1) && (op3 == 0))out = 0;// subc or addc
340 else out = 1;// mul, div
341 }
342 else{// if (in[24:23] == 2'b10) shft, mov, rdpr, tag
343 op2 = (inst >> 19) & 0xf;
344 if(op2 == 4)out = 1; // mulscc
345 else if((op2 & 0x8) == 0)out = 0;
346 else if((op2 == 0xc) ||(op2 == 0xf)) out = 0;// mov
347 else out = 1;// rdsr, mem#, popc, flushw, rdpr
348 }
349 }
350 else{// ld st
351 op1 = (inst >> 19) & 0x3f;
352 op2 = (inst >> 21) & 0x3;
353 if(op1 & 0x20 || op1 & 0x10 || (op1 & 0x4) == 0)out = 1; // fp, alt space or ld
354 else if (((op1 & 0x10) == 0) &&((op1& 0xf) == 0xe)) out = 0; // stx
355 else if (op2 == 1)out = 0; // other st
356 else out = 1;
357 }
358 return out;
359}
360/*--------------------------------------------
361deceide which cache is slammed at this time.
362--------------------------------------------*/
363int l1warm_which_cache()
364{
365 int which = (random() & 1) + 1;
366 if(which == 1){//dcache
367 if(l1warm_vars.ddone == l1warm_vars.dcache){
368 l1warm_vars.idone++;
369 which = 2;
370 }
371 else l1warm_vars.ddone++;
372 }
373 else {//icache
374 if(l1warm_vars.idone == l1warm_vars.icache){
375 l1warm_vars.ddone++;
376 which = 1;
377 }
378 else l1warm_vars.idone++;
379 }
380 if((l1warm_vars.icache == l1warm_vars.idone) && (l1warm_vars.dcache == l1warm_vars.ddone)){
381 l1warm_vars.idone = 0;
382 l1warm_vars.ddone = 0;
383 }
384 return which;
385}
386/*--------------------------------------------
387choose the way to be slammed.
388--------------------------------------------*/
389int l1warm_which_way(KeyType addr)
390{
391 long long lword;
392 int gidx, sidx, idx;
393 int addr_idx, i, j, avld;
394 int etag;
395 s_tfnodeinfo node_info;
396 char *avalPtr;
397
398 l1warm_vars.itag = (addr >> 12) & 0xfffffff;//28 bits addr[39:12]
399 addr_idx = (addr >> 5) & 0x7f;
400 addr_idx <<= 2;
401 tf_nodeinfo(l1warm_vars.icache_vld[l1warm_vars.cpu], &node_info);
402 for(i = 0; i < 4;i++){
403 idx = addr_idx + i;
404 gidx = idx / 32;
405 sidx = idx % 32;
406 avld = node_info.node_value.vecval_p[gidx].avalbits;
407 if((avld & ( 1 << sidx)) == 0)continue;
408 //avalPtr = l1warm_vars.icache_tag[l1warm_vars.cpu] + idx * l1warm_vars.itag_num * 2;
409 for(j = l1warm_vars.itag_num - 1; j >= 0;j--){
410 lword <<= 8;
411 lword |= avalPtr[j] & 0xff;
412 }
413 etag = (lword >> 1) & 0xfffffff;
414 if(l1warm_vars.itag == etag){
415 l1warm_vars.way = i;
416 return 1;
417 }
418 }
419 if(i == 4)l1warm_vars.way = random() & 0x3;
420 return 0;
421}
422/*--------------------------------------------
423count how many cores are turned on.
424--------------------------------------------*/
425void l1warm_set_cpu()
426{
427 int idx, stat;
428 l1warm_vars.cpu_status = tf_getp(1);
429 l1warm_vars.cpu_num = 0;
430
431 for(idx = 0; idx < MAX_CORE;idx++){
432 if(stat & (1 << idx))l1warm_vars.cpu_ptr[l1warm_vars.cpu_num++] = idx;
433 }
434 io_printf("Info Core_status(%x) number(%d)\n", l1warm_vars.cpu_status, l1warm_vars.cpu_num);
435}
436/*--------------------------------------------
437choose the core to be slammed.
438--------------------------------------------*/
439void l1warm_core(int num)
440{
441 l1warm_vars.cpu = l1warm_vars.cpu_chose[num];
442}
443/*--------------------------------------------
444choose the followings to be slammed:
4451. how many core.
4462. which core.
447--------------------------------------------*/
448int l1warm_howmany_cpu()
449{
450 int i,chose, status = 0;
451 int num = random() % l1warm_vars.cpu_num + 1;
452
453 for(i = 0; i < num;i++){
454 while(1){
455 chose = random() % l1warm_vars.cpu_num;
456 if((status & ( 1 << chose)) == 0){
457 status |= (1 << chose);
458 l1warm_vars.cpu_chose[i] = l1warm_vars.cpu_ptr[chose];
459 break;
460 }
461 }
462 }
463 return num;
464}
465/*--------------------------------------------
466compute even parity.
467--------------------------------------------*/
468int l1warm_even_parity(int data, int num)
469{
470 int i,parity = 0;
471 for(i = 0; i < num;i++){
472 parity ^= (data & 1);
473 data >>= 1;
474 }
475 return parity;
476}
477/*--------------------------------------------
478compute even parity.
479--------------------------------------------*/
480int l1warm_even_parityLong(long long data, int num)
481{
482
483 int i,parity = 0;
484 for(i = 0; i < num;i++){
485 parity ^= (data & 1);
486 data >>= 1;
487 }
488 return parity;
489}
490/*--------------------------------------------
491get options from command line.
492--------------------------------------------*/
493void l1warm_option()
494{
495 char* pargs;
496
497 pargs = mc_scan_plusargs ("icache=");
498 if(pargs != (char *) 0)l1warm_vars.icache = atoi(pargs);
499 pargs = mc_scan_plusargs ("dcache=");
500 if(pargs != (char *) 0)l1warm_vars.dcache = atoi(pargs);
501}
502/*--------------------------------------------
503slam data into dir. cache.
504
505--------------------------------------------*/
506void l1warm_slam_tag(int word, int size)
507{
508int groups;
509 for(groups = 0; groups < size;groups++){
510 l1warm_vars.avalPtr[groups] = word & 0xff;
511 l1warm_vars.bvalPtr[groups] = 0;
512 word >>= 8;
513 }
514}
515/*--------------------------------------------
516slam data into cache.
517--------------------------------------------*/
518void l1warm_slam_dataLong(long long word, int size)
519{
520 int groups;
521 for(groups = 0; groups < size;groups++){
522 l1warm_vars.avalPtr[groups] = word & 0xff;
523 l1warm_vars.bvalPtr[groups] = 0;
524 word >>= 8;
525 }
526}
527/*--------------------------------------------
528slam data into cache.
529--------------------------------------------*/
530void l1warm_slam_data(char* word, int size)
531{
532 int groups;
533 for(groups = 0; groups < size;groups++){
534 l1warm_vars.avalPtr[groups] = word[groups] & 0xff;
535 l1warm_vars.bvalPtr[groups] = 0;
536 }
537}
538/*--------------------------------------------
539set valid bit.
540--------------------------------------------*/
541void l1warm_find_location(int idx,int *vld )
542{
543 s_tfnodeinfo node_info;
544 tf_nodeinfo(vld[l1warm_vars.cpu], &node_info);
545
546 int gidx = idx / 32;
547 int sidx = idx % 32;
548 int word = node_info.node_value.vecval_p[gidx].avalbits;
549 word |= (1 << sidx);
550 node_info.node_value.vecval_p[gidx].avalbits = word;
551 tf_propagatep(vld[l1warm_vars.cpu]);
552}
553/*--------------------------------------------
554extract 4 bytes from memory buffer.
555--------------------------------------------*/
556int l1warm_get_word(char*data, int num)
557{
558 int i,word = 0;
559 for(i = num; i < (num+4);i++){
560 word <<= 8;
561 word |= data[i] & 0xff;
562 }
563 return word;
564}
565/*--------------------------------------------
566create icache data to be slammed into icd.
5671). generate predecoder bit.
5682). parity bit.
569--------------------------------------------*/
570long long l1warm_make_icache_data(int word)
571{
572 long long lparity, lword = word & 0xffffffff;
573 lword <<= 1;
574 if(l1warm_predecoder(word))lword |= 1;
575 if(l1warm_even_parityLong(lword, 33)){
576 lparity = 1;
577 lparity <<= 33;
578 lword |= lparity;
579 }
580 return lword;
581}
582/*--------------------------------------------
583slam data inti icd.
584--------------------------------------------*/
585void l1warm_slam_l1idata(KeyType addr, char* data, int num)
586{
587 int word;
588 int addr_idx = addr & 0xff0;
589 addr_idx |= l1warm_vars.way;
590 //word 0;
591 //l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + addr_idx * l1warm_vars.icache_num * 2;
592 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.icache_num;
593 word = l1warm_get_word(data, num);
594 l1warm_slam_dataLong(l1warm_make_icache_data(word), l1warm_vars.icache_num);
595 //word 1;
596 //l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 4) * l1warm_vars.icache_num * 2;
597 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.icache_num;
598 word = l1warm_get_word(data, 4+num);
599 l1warm_slam_dataLong(l1warm_make_icache_data(word), l1warm_vars.icache_num);
600 //word 0;
601 //l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 8) * l1warm_vars.icache_num * 2;
602 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.icache_num;
603 word = l1warm_get_word(data, 8+num);
604 l1warm_slam_dataLong(l1warm_make_icache_data(word), l1warm_vars.icache_num);
605 //word 1;
606 //l1warm_vars.avalPtr = l1warm_vars.icache_data[l1warm_vars.cpu] + (addr_idx + 12) * l1warm_vars.icache_num * 2;
607 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.icache_num;
608 word = l1warm_get_word(data, 12+num);
609 l1warm_slam_dataLong(l1warm_make_icache_data(word), l1warm_vars.icache_num);
610}
611/*--------------------------------------------
612 assign wr_index0 = {index_f[11:4], 2'b00, wrway_f};
613 assign wr_index1 = {index_f[11:4], 2'b01, wrway_f};
614 assign wr_index2 = {index_f[11:4], 2'b10, wrway_f};
615 assign wr_index3 = {index_f[11:4], 2'b11, wrway_f};
616//tag
617{4'b0, ifq_ict_wrtag_f[`IC_TAG_SZ:0]}
618--------------------------------------------*/
619void l1warm_slam_icache(KeyType addr, char* data, int num)
620{
621 int addr_idx;
622 long long lword;
623 //slam data
624 l1warm_slam_l1idata(addr, data, num);
625 l1warm_slam_l1idata(addr+16, data, num+16);
626
627 //slam tag
628 l1warm_vars.itag = (addr >> 12) & 0xfffffff;//28 bits addr[39:12]
629 addr_idx = (addr >> 5) & 0x7f;
630 addr_idx <<= 2;
631 addr_idx |= l1warm_vars.way;
632
633 //l1warm_vars.avalPtr = l1warm_vars.icache_tag[l1warm_vars.cpu] + addr_idx * l1warm_vars.itag_num * 2;
634 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.itag_num;
635 l1warm_vars.itag |= (l1warm_even_parity(l1warm_vars.itag, 28) << 28);
636 lword = l1warm_vars.itag;
637 //io_printf("addr %llx TAG tag = %x addr_idx %x way=%d \n", addr, itag, addr_idx, way);
638 l1warm_slam_dataLong(lword, l1warm_vars.itag_num);
639 //valid bit
640 l1warm_find_location(addr_idx, l1warm_vars.icache_vld);
641}
642
643/*--------------------------------------------
644slam data inti icm.
645index for dcm_array:dcache_rwaddr_e[10:4]
64616 byte128 bits
647
648// way0 and way1 are interleaved physically across 2 subbanks
649// [288,277,..................,145,144] -- xdec -- [143,142,.............,1,0]
650// H L H L H L H L -- xdec -- L H L H L H L H
651// way1 = [288,287,284,283,...,151,150,147,146 -- xdec -- 141,140,137,136,...,5,4,1,0
652// way0 = [286,285,282,281,...,149,148,145,144 -- xdec -- 143,142,139,138,...,7,6,3,2
653--------------------------------------------*/
654void l1warm_slam_l1ddata(KeyType addr, char* data, int num)
655{
656 char l1size[18];
657 int i, parity, idx, word;
658 int addr_idx = ((addr >> 4) & 0x7f);
659 // l1warm_vars.way =
660 l1warm_vars.avalPtr = l1warm_vars.dcache_w[l1warm_vars.cpu][l1warm_vars.way] + addr_idx * l1warm_vars.dcache_num * 2;
661 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.dcache_num;
662 parity = 0;
663 idx = 17;
664 //create parity bits
665 for(i = 0 ; i < 16;i++){
666 word = data[num+i];
667 l1size[idx] = data[num+i];
668 parity |= (l1warm_even_parity(word, 8) << (15-i));
669 idx--;
670 }
671 l1size[1] = (parity >> 8) & 0xff;
672 l1size[0] = parity & 0xff;
673 l1warm_slam_data(l1size, l1warm_vars.dcache_num);
674}
675/*--------------------------------------------
676tag: lmq_ld_addr[39:11];
67776 75 74 73 72 71 70 69 68 67 66 65 64
67812 11 10 9 8 7 6 5 4 3 2 1 0
679--------------------------------------------*/
680void l1warm_slam_dcache(KeyType addr, char* data, int num)
681{
682 int addr_idx;
683 long long lword;
684
685 //slam l1 dcache
686 l1warm_slam_l1ddata(addr, data, num);
687 //tag
688 l1warm_vars.dtag = (addr >> 11) & 0x1fffffff;
689 addr_idx = ((addr >> 4) & 0x7f);
690 addr_idx <<= 2;
691 addr_idx |= l1warm_vars.way;
692
693 // l1warm_vars.avalPtr = l1warm_vars.dcache_tag[l1warm_vars.cpu] + addr_idx * l1warm_vars.dtag_num * 2;
694 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.dtag_num;
695 l1warm_vars.dtag |= (l1warm_even_parity(l1warm_vars.dtag, 29) << 29);
696 lword = l1warm_vars.dtag;
697 l1warm_slam_dataLong(lword, l1warm_vars.dtag_num);
698 //valid
699 l1warm_find_location(addr_idx, l1warm_vars.dcache_vld);
700 //io_printf(" addr %llx DTAG tag = %x addr_idx %x way=%d\n", addr, dtag, addr_idx, way);
701}
702/*------------------------------------------
703mask out address and get index, tag and bank
704based on the bank type.
705--------------------------------------------*/
706void l1warm_get_Mode(KeyType* addr)
707{
708 int idx;
709 bool found;
710 //generate the variables, index, bank, tag of l2 cache.
711 if(l1warm_vars.l2bank_type == 4){
712 l1warm_vars.bank = (int)((*addr >> 6) & 0x7);//l2bank
713 l1warm_vars.tag = (int)((*addr >> 9) & 0x1ff);
714 }
715 else if(l1warm_vars.l2bank_type == 2){
716 l1warm_vars.bank = (int)((*addr >> 6) & 0x3);//l2bank
717 l1warm_vars.tag = (int)((*addr >> 8) & 0x1ff);
718
719 if(l1warm_vars.bank >= 2){//looking for high bit
720 found = 0;
721 for(idx = 0;idx < 4;idx++){
722 if(l1warm_vars.l2mask & (1 << idx)){
723 if(!found){
724 found = 1;
725 continue;
726 }
727 l1warm_vars.bank = idx * 2 + l1warm_vars.bank % 2 ? 1 : 0;
728 break;
729 }
730 }
731 }
732 else{//looking for low bit
733 for(idx = 0;idx < 4;idx++){
734 if(l1warm_vars.l2mask & (1 << idx)){
735 l1warm_vars.bank = idx * 2 + l1warm_vars.bank % 2 ? 1 : 0;
736 break;
737 }
738 }
739 }
740 }
741 else if(l1warm_vars.l2bank_type == 1){
742 l1warm_vars.bank = (int)((*addr >> 6) & 0x1);//l2bank
743 l1warm_vars.tag = (int)((*addr >> 7) & 0x1ff);
744
745 for(idx = 0;idx < 4;idx++){
746 if(l1warm_vars.l2mask & (1 << idx)){
747 l1warm_vars.bank = idx * 2 + l1warm_vars.bank;
748 break;
749 }
750 }
751 }
752 l1warm_vars.tag = (l1warm_vars.tag << 4 ) | l1warm_vars.l2way;//9 bits 512
753}
754/*--------------------------------------------
755slam tag into d$ directory.
756 .din0(lkup_addr_c3[17:9]), // original idx , all banks enabled
757 .din1(lkup_addr_c3[16:8]), // 1 bit shifted idx in case of 4 banks enabled
758 .din2(lkup_addr_c3[15:7]), // 2 bit shifted idx in case of 2 banks enabled
759
760addr_array[rw_addr] <= wr_data[12:0] ; // BS and SR 11/18/03 Reverse Directory change
761addr_bit4[rw_addr] <= wr_data[13] ; // BS and SR 11/18/03 Reverse Directory change
762parity[rw_addr] <= wr_data[14] ; // BS and SR 11/18/03 Reverse Directory change
763valid[rw_addr] <= wr_data[15] ; // BS and SR 11/18/03 Reverse Directory change
764The Four panels correspond to addr<10:9> decoded.
765input [15:0] wr_data; // { parity, valid, addr<4>,addr<17:9>, L2 way[3:0]}
766assign dir_wr_par_c4 = ^(lkup_wr_data_c4[13:0]) ^ address_bit4;
767
768row:[5:4]
769col[10:9]
770index{cpu[2:0]. way[1:0]}
771index addr[4], cpu_id, way[1:0]
772
773assign dirrep_dc_lkup_panel_dec_c4[0] = ( lkup_row_addr_dcd_c4[1:0] == 2'd0 );
774assign dirrep_dc_lkup_panel_dec_c4[1] = ( lkup_row_addr_dcd_c4[1:0] == 2'd1 );
775assign dirrep_dc_lkup_panel_dec_c4[2] = ( lkup_row_addr_dcd_c4[1:0] == 2'd2 );
776assign dirrep_dc_lkup_panel_dec_c4[3] = ( lkup_row_addr_dcd_c4[1:0] == 2'd3 );
777
778assign dir_wr_par_c4 = ^(lkup_wr_data_c4[13:0]) ^ address_bit4;
779
780--------------------------------------------*/
781void l1warm_slam_ddirectory(KeyType addr_tmp){
782 int index, addr4, addr5, entry;
783 long long temp_val;
784
785 l1warm_get_Mode(&addr_tmp);
786 addr4 = addr_tmp & 0x10 ? 1 : 0;
787 addr5 = addr_tmp & 0x20 ? 1 : 0;
788 //create parity bit based on index and way.
789 int parity = l1warm_even_parity(l1warm_vars.tag, 13) ^ addr4;
790
791 //make entry index. which 63-0 5bits
792 entry = addr4 << 5;
793 entry = l1warm_vars.way;
794 entry |= (l1warm_vars.cpu << 3);
795
796 //column
797 l1warm_vars.col = (addr_tmp >> 9) & 0x3;//deceide 4 panel
798 index = l1warm_vars.bank * BANK_NUM + addr5 * ROW_NUM + l1warm_vars.col;
799
800 l1warm_vars.avalPtr = l1warm_vars.dir_darray[index] + entry * l1warm_vars.ddir_num * 2;
801 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.ddir_num;
802
803 l1warm_slam_tag(l1warm_vars.tag, l1warm_vars.ddir_num);
804
805 temp_val = parity ? ( 1 << entry) : 0;
806 l1warm_vars.dir_dparity[index] |= temp_val;
807 temp_val = (1 << entry);
808 l1warm_vars.dir_dvalid[index] |= temp_val;
809
810 temp_val = (addr4 << entry);
811 l1warm_vars.dir_daddr4[index] |= temp_val;
812 // io_printf("DIER addr=%llx entry = %d row = %d col = %d bank = %d index = %d %llx %llx tag %x\n",
813 // addr_tmp, entry, row, col, bank, index, dir_dparity[index], dir_dvalid[index], dtag);
814}
815/*--------------------------------------------
816slam l2 directory of l1 icache.
817l2 bank 7:6
818entry<cpu_id[2:0],way[1:0], addr[8]>
819row<addr[5], addr[11]>
820--------------------------------------------*/
821void l1warm_slam_idirectory(KeyType addr_tmp)
822{
823 int index, entry, addr4, addr5;
824 long long temp_val;
825
826 l1warm_get_Mode(&addr_tmp);
827 l1warm_vars.iround ^= 1;
828 addr4 = l1warm_vars.iround;
829 addr5 = addr_tmp & 0x20 ? 1 : 0;
830 //make entry index.
831 int parity = l1warm_even_parity(l1warm_vars.tag, 13) ^ addr4;
832
833 //make entry index.
834 entry = addr4 << 5;
835 entry |= l1warm_vars.way;
836 entry |= (l1warm_vars.cpu << 3);
837 l1warm_vars.col = (addr_tmp >> 9) & 0x3;//deceide 4 panel
838 //get the pointer of valid and parity.
839 index = l1warm_vars.bank * MAX_BANK + addr5 * ROW_NUM + l1warm_vars.col;
840 l1warm_vars.avalPtr = l1warm_vars.dir_iarray[index] + l1warm_vars.entry * l1warm_vars.idir_num * 2;
841 l1warm_vars.bvalPtr = l1warm_vars.avalPtr + l1warm_vars.idir_num;
842 l1warm_slam_tag(l1warm_vars.tag, l1warm_vars.idir_num);
843
844 temp_val = (parity << entry);
845 l1warm_vars.dir_iparity[index] |= temp_val;
846 temp_val = (1 << entry);
847 l1warm_vars.dir_ivalid[index] |= temp_val;
848
849 temp_val = (addr4 << entry);
850 l1warm_vars.dir_iaddr4[index] |= temp_val;
851}
852/*--------------------------------------------
853slam icache and dcache
854data format to dcm:
855[32:0] { addr<39:10>, addr<8>, parity, valid}
856reg [29:0] addr_array[63:0]
857dcache:
858l1dcache: 16 bytes.
859
860<10 9 8 7 6 5 4>
861 ^ ^ ^
862 | | |
863 col bank row
864
865index <cpu_id, way, 8> -> 64 entries
866icache:
867l1icache: 32 bytes
868--------------------------------------------*/
869void l1warm_slam_ionly(KeyType addr, char* data)
870{
871 int num, i, j;
872 KeyType addr_tmp;
873 num = l1warm_howmany_cpu();
874
875 for(j = 0; j < num;j++){
876 l1warm_core(j);//which core
877 l1warm_which_way(addr);//which way
878 addr_tmp = addr;
879 if(l1warm_vars.l1_debug){
880 io_printf("Info: l1icache slam address %llx\n", addr);
881 io_printf("data-->");
882 for(i = 0; i < 64; i++)io_printf("%02x", data[i] &0xff);
883 io_printf("\n");
884 }
885 for(i = 0; i < 2; i++){
886 l1warm_slam_icache(addr_tmp, data, i * 32);
887 l1warm_slam_idirectory(addr_tmp);
888 addr_tmp += 32;
889 }
890 }
891}
892/*--------------------------------------------
893check range.
894--------------------------------------------*/
895int l1warm_islam(KeyType addr, char* data)
896{
897 if(addr >= l1warm_vars.low_ibound &&
898 addr < l1warm_vars.up_ibound){
899 l1warm_slam_ionly(addr, data);
900 return 1;
901 }
902 return 0;
903}
904/*--------------------------------------------
905slam dcahe.
906--------------------------------------------*/
907void l1warm_slam_donly(KeyType addr, char* data)
908{
909 int num, i, j;
910 KeyType addr_tmp;
911 num = l1warm_howmany_cpu();
912 for(j = 0; j < num;j++){
913 l1warm_core(j);//which core
914 l1warm_which_way(addr);//which way
915 addr_tmp = addr;
916 if(l1warm_vars.l1_debug){
917 io_printf("Info: l1dcache slam address %llx\n", addr);
918 io_printf("data-->");
919 for(i = 0; i < 64; i++)io_printf("%02x", data[i] &0xff);
920 io_printf("\n");
921 }
922 for(i = 0; i < 4;i++){
923 l1warm_slam_dcache(addr_tmp, data, i * 16);
924 l1warm_slam_ddirectory(addr_tmp);
925 addr_tmp += 16;
926 }
927 }
928}
929/*--------------------------------------------
930check range.
931--------------------------------------------*/
932int l1warm_dslam(KeyType addr, char* data)
933{
934
935 if(addr >= l1warm_vars.low_dbound &&
936 addr < l1warm_vars.up_dbound){
937 l1warm_slam_donly(addr, data);
938 return 1;
939 }
940 return 0;
941}
942/*--------------------------------------------
943slam l1 caches
944--------------------------------------------*/
945int l1warm_slam(KeyType addr, char* data, int l2way)
946{
947 int i,j, num;
948 KeyType addr_tmp;
949 //common thing
950 addr &= 0xffffffffc0;//always 64 bytes aligment.
951 l1warm_vars.tag = (addr >> 10) & 0x3fffffff;//30 bits
952
953 // if(l1warm_vars.check_irange && l1warm_islam(addr, data))return 1;
954 //if(l1warm_vars.check_drange && l1warm_dslam(addr, data))return 1;
955 l1warm_vars.l2way = l2way;
956
957 //if(l1warm_vars.check_irange == 0 && l1warm_vars.check_drange == 0){
958 num = l1warm_howmany_cpu();
959 for(j = 0; j < num;j++){
960 l1warm_core(j);//which core
961 // l1warm_which_way(addr);//which way
962 addr_tmp = addr;
963 switch(l1warm_which_cache()){//which cache
964 case 1 ://dcache
965 //first 16 bytes
966 if(l1warm_vars.l1_debug){
967 io_printf("Info: l1dcache slam address %llx\n", addr);
968 io_printf("data-->");
969 for(i = 0; i < 64; i++)io_printf("%02x", data[i] &0xff);
970 io_printf("\n");
971 }
972 for(i = 0; i < 4;i++){
973 // l1warm_slam_dcache(addr_tmp, data, i * 16);
974 l1warm_slam_ddirectory(addr_tmp);
975 addr_tmp += 16;
976 }
977 break;
978 case 2 ://do icache operation.
979 //first 16 bytes
980 if(l1warm_vars.l1_debug){
981 io_printf("Info: l1icache slam address %llx\n", addr);
982 io_printf("data-->");
983 for(i = 0; i < 64; i++)io_printf("%02x", data[i] &0xff);
984 io_printf("\n");
985 }
986 for(i = 0; i < 2; i++){
987 //l1warm_slam_icache(addr_tmp, data, i * 32);
988 l1warm_slam_idirectory(addr_tmp);
989 addr_tmp += 32;
990 }
991 break;
992 }
993 }
994 //}
995 return 0;
996}