Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / pli / cache / c / src / iob_main.c
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: iob_main.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 <malloc.h>
39#include "global.h"
40
41#include "b_ary.h"
42#include "bw_lib.h"
43#include "list.h"
44#include "l2warm.h"
45#include "l1warm.h"
46#include "utility.h"
47
48typedef struct iop_main_struct{
49 b_tree_node_ptr sysMem;//b_try for memory
50 list_head_ptr l1_list;
51
52}*iop_main_structPtr;
53static struct iop_main_struct iop_TempVariable;
54//---------------------------------------------------------------
55//
56char* searchPattern(char *buf, char* pattern)
57{
58 return strpbrk(buf, pattern);
59}
60//---------------------------------------------------------------
61//
62void copyStr(char *nextPtr, char* tbuf, char* pattern)
63{
64
65 int size;
66 if(strlen(nextPtr) == 0){
67 tbuf[0] = '\0';
68 }
69 else{
70 size = strcspn(nextPtr, pattern);
71 memcpy(tbuf, nextPtr, size);
72 tbuf[size] = '\0';
73 }
74}
75//---------------------------------------------------------------
76//
77int extract_intValue(char *nextPtr, char* pattern)
78{
79 char tbuf[BUFFER];
80 copyStr(nextPtr, tbuf, pattern);
81 return atoi(tbuf);
82}
83//---------------------------------------------------------------
84//
85unsigned long long extract_longValue(char *nextPtr, char* pattern)
86{
87 char tbuf[BUFFER];
88 copyStr(nextPtr, tbuf, pattern);
89 return n2_ck_getEight(tbuf, 0);
90}
91/*-------------------------------------------------------------------------------
92 convert ascii to hex array.
93--------------------------------------------------------------------------------*/
94void packingData(char* buf, char* cbuf)
95{
96 char ch;
97 int idx, cidx;
98 idx = 0;
99 cidx= 0;
100 while(buf[idx] != '\0'){
101 ch = buf[idx] > '9' ? ((buf[idx] & 0xf) + 9) : buf[idx] & 0xf;
102 ch <<= 4;
103 idx++;
104 if(buf[idx] == '\0')break;
105 ch |= buf[idx] > '9' ? ((buf[idx] & 0xf) + 9) : buf[idx] & 0xf;
106 cbuf[cidx] = ch;
107 idx++;
108 cidx++;
109 }
110}
111
112/*------------------------------------------
113load and go
114
115-------------------------------------------*/
116void l2_warm_forloadAndgo_call()
117{
118
119 char *pargs;
120
121 io_printf("Info(PLI):loadandgo warm start....\n");
122 l2warm_set();
123 FILE *fp;
124 char buf [BUFFER];
125 char tbuf[BUFFER];
126 KeyType addr;
127
128 int subbank;
129 char *nextPtr;
130 char hexa[17] = "0123456789abcdef";
131 char space[3] = " \n";
132 char data[65]; //hold data
133 int expected;
134 int set, bank, way;
135
136 //get options will bes used in this file.
137 pargs = mc_scan_plusargs ("loadngo_log=");
138 if(pargs != (char *) 0)fp = fopen(pargs, "r");
139 else fp = fopen("loadngo_l2array_dumped.log", "r");
140
141 if(fp == null){
142 io_printf("Error: can not open file %s for reading\n", pargs != (char *) 0 ? pargs :
143 "loadngo_l2array_dumped.log");
144 tf_dofinish();
145 }
146 io_printf("Info: reading %s file \n", pargs != (char *) 0 ? pargs : "loadngo_l2array_dumped.log");
147 expected = 0;
148 while(fgets(buf, BUFFER, fp)){
149
150 if(expected){//slam here
151 nextPtr = searchPattern(buf, hexa);
152 if(nextPtr == null)continue;
153 copyStr(nextPtr, tbuf, space);
154 packingData(tbuf, data);
155
156 subbank = (int)((addr >> 4) & 0x3);
157 l2warm_get_Mode(&addr);
158 l2warm_vars.way = way;
159 l2warm_vars.bank = bank;
160 l2warm_vars.l2_index = set;
161
162 l2warm_slam_tag(); //process tag
163 l2warm_slam_vuad();//process vuad
164 // for(int idx = 0;idx<64;idx++)io_printf("%02x",data[idx] &0xff);io_printf("\n");
165 l2warm_slam_real_data(data, subbank);//process data
166 expected = 0;
167 continue;
168 }
169 if((nextPtr = strstr(buf, "Set")) == null)continue;
170 nextPtr = searchPattern(nextPtr+3, hexa);
171 set = extract_intValue(nextPtr, space);
172 if((nextPtr = strstr(buf, "Bank")) == null)continue;
173 nextPtr = searchPattern(nextPtr+4, hexa);
174 bank = extract_intValue(nextPtr, space);
175 if((nextPtr = strstr(buf, "Way")) == null)continue;
176 nextPtr = searchPattern(nextPtr+4, hexa);
177 way = extract_intValue(nextPtr, space);
178 if((nextPtr = strstr(buf, "Addr")) == null)continue;
179 nextPtr = searchPattern(nextPtr+4, hexa);
180 addr = extract_longValue(nextPtr, space);
181 expected = 1;
182 }
183 fclose(fp);
184}
185
186/*------------------------------------------
187do l2 warming here.
188-------------------------------------------*/
189void l2_warm_call()
190{
191 int idx ;
192 char *pargs, cbuf[17];
193 //b_tree_node_ptr sysMem;//b_try for memory
194 char zero_data[64];
195 int slam_flag;
196 b_tree_atom_ptr data;//b-tree node.
197 list_node_ptr addr_ptr;
198 list_head_ptr addr_list;
199 KeyType mask_addr, b_addr;
200 //get options will bes used in this file.
201 pargs = mc_scan_plusargs ("loandgo=");
202 if(pargs != (char *) 0)l2warm_vars.loadandgo = atoi(pargs);
203 if(l2warm_vars.loadandgo != 0){
204 l2_warm_forloadAndgo_call();
205 return;
206 }
207 l2warm_set();
208 //get options will bes used in this file.
209 l2warm_vars.l2_warm = 0;
210 pargs = mc_scan_plusargs ("l2warm=");
211 if(pargs != (char *) 0)l2warm_vars.l2_warm = atoi(pargs);
212 l2warm_vars.l1_warm = 0;
213 pargs = mc_scan_plusargs ("l1warm=");
214 if(pargs != (char *) 0)l2warm_vars.l1_warm = atoi(pargs);
215 if(l2warm_vars.l2_warm == 0)return;
216 addr_list = (list_head_ptr)malloc(sizeof(struct list_head_node));
217 addr_list->head_ptr = 0;
218 addr_list->tail_ptr = 0;
219 addr_list->num = 0;
220
221 //set argment
222 iop_TempVariable.sysMem = b_create();//create
223 n2_ck_read_mem("mem.image", &iop_TempVariable.sysMem, addr_list);//read memory
224
225 io_printf("Info:l2 warm start....\n");
226 l2warm_vars.check_range = 0;
227 pargs = mc_scan_plusargs ("l2range=");
228
229 if(pargs != (char *) 0){
230 l2warm_vars.check_range = 1;
231 idx = l2warm_copy(pargs, cbuf, 0);
232 l2warm_vars.up_bound = l2warm_getEight(cbuf);
233 l2warm_copy(pargs, cbuf, idx);
234 l2warm_vars.low_bound = l2warm_getEight(cbuf);
235 io_printf("Info:L2warm range %llx:%llx\n", l2warm_vars.up_bound, l2warm_vars.low_bound);
236 }
237 for(idx = 0; idx < MAX_BANK;idx++)l2warm_l2_clear_vuad(idx);
238 if(l2warm_vars.l1_warm ){
239 iop_TempVariable.l1_list = (list_head_ptr)malloc(sizeof(struct list_head_node));
240 iop_TempVariable.l1_list->head_ptr = 0;
241 iop_TempVariable.l1_list->tail_ptr = 0;
242 iop_TempVariable.l1_list->num = 0;
243 io_printf("Info:L1warm is on\n");
244 }
245 if(l2warm_vars.check_range){
246 for(b_addr = l2warm_vars.low_bound & 0xffffffffc0 ; b_addr < l2warm_vars.up_bound;b_addr += 64){
247 mask_addr = (b_addr >> 6) & 0x3ffffffff;
248 data = b_Find(&iop_TempVariable.sysMem, &mask_addr);
249 if(data == 0)for(idx = 0; idx < 64;idx++)zero_data[idx] = random() & 0xff;
250 slam_flag = data ? l2warm_slam(b_addr, data->data) : l2warm_slam(b_addr, zero_data);
251 if(l2warm_vars.l1_warm && (slam_flag & 1) ){//slam this address
252 addr_ptr = (list_node_ptr)malloc(sizeof(struct list_node));
253 addr_ptr->addr = b_addr;
254 addr_ptr->way = (slam_flag >> 1) & 0xf;
255 n2_ck_push(iop_TempVariable.l1_list, &addr_ptr);
256 }
257 }
258 }
259 else{
260 //warm start
261 while((addr_ptr = n2_ck_pop(addr_list)) != 0 ){//get address
262 mask_addr = (addr_ptr->addr >> 6) & 0x3ffffffff;
263 data = b_Find(&iop_TempVariable.sysMem, &mask_addr);//get data to be slammed.
264 slam_flag = data ? l2warm_slam(addr_ptr->addr, data->data) : l2warm_slam(addr_ptr->addr, zero_data);
265 if(l2warm_vars.l1_warm && (slam_flag & 1)){
266 addr_ptr->way = (slam_flag >> 1) & 0xf;
267 n2_ck_push(iop_TempVariable.l1_list, &addr_ptr);
268 }
269 else free(addr_ptr);
270 }
271 }
272 if(l2warm_vars.l1_warm == 0)b_destory(&iop_TempVariable.sysMem);
273}
274/*------------------------------------------
275do l1 warming here.
276-------------------------------------------*/
277void l1_warm_call()
278{
279 int dev;
280 char* pargs;
281 b_tree_atom_ptr data;//b-tree node.
282 list_node_ptr addr_ptr;
283 KeyType mask_addr;
284
285 //no l2slam, it means that we dont need l1slam.
286 //because l2 is an inclusive cache.
287 pargs = mc_scan_plusargs ("l2warm=");
288 if(pargs != (char *) 0)dev = atoi(pargs);
289 else return;
290 if(dev == 0)return;
291 pargs = mc_scan_plusargs ("l1warm=");
292 if(pargs != (char *) 0)dev = atoi(pargs);
293 else return;
294 if(dev == 0)return;
295
296 l1warm_set_cpu();//get the infomation how many core is on.
297
298 l1warm_set();
299 l1warm_clean_dir();
300 io_printf("Info:L1 warm start\n");
301 //warm start
302 while((addr_ptr = n2_ck_pop(iop_TempVariable.l1_list)) != 0){
303 //here we can slam l1 randomly.
304 mask_addr = (addr_ptr->addr >> 6) & 0x3ffffffff;
305 data = b_Find(&iop_TempVariable.sysMem, &mask_addr);
306 if(data)l1warm_slam(addr_ptr->addr, data->data, addr_ptr->way);
307 //io_printf("Info address %llx %x\n", addr_ptr->addr, addr_ptr->way);
308 free(addr_ptr);
309 }
310 l1warm_store_parityValidAddr();
311 b_destory(&iop_TempVariable.sysMem);
312}
313
314/*------------------------------------------
315get l2event.
316!$EV trig_pc_d(1, 64'h0000000001834140) -> l2warm()
317
318--------------------------------------------*/
319void l2warm_get_event(char *str)
320{
321 FILE *fp;//file pointer
322 char buf [BUFFER], cbuf[BUFFER];//temp variavle for intermiate data
323 int idx;
324 long long key;
325
326 l2warm_vars.avl_ptr = 0;
327 if((fp = fopen(str, "r")) == 0){
328 io_printf("Info(Warnning): can not open the event file %s for reading\n", str);
329 return;
330 }
331 while(fgets(buf, BUFFER, fp)){
332 idx = n2_ck_rmSpace(buf, 0, BUFFER);
333 l2warm_replace(buf);
334 if(strncmp(buf, "trig_pc_d ", 10))continue;
335 idx = n2_ck_rmSpace(buf, 10, BUFFER);
336 idx = l2warm_copy(buf, cbuf, idx);
337
338 idx = n2_ck_rmSpace(buf, idx, BUFFER);
339 idx = l2warm_copy(buf, cbuf, idx);//pc value
340
341 l2warm_rmhexa(cbuf);
342 key = l2warm_getEight(cbuf);
343 idx = n2_ck_rmSpace(buf, idx, BUFFER);
344 idx = l2warm_copy(buf, cbuf, idx);
345
346 if(strncmp(cbuf, "l2warm", 6))continue;//here only handle interrupt
347 l2warm_insert_avl_node(&l2warm_vars.avl_ptr, &key);
348
349 }
350 fclose(fp);
351}
352/*------------------------------------------
353do the pc event check here.
354-------------------------------------------*/
355void n2_check_event_call()
356{
357 int active, l2warm, loc, low, high, idx;
358 long long pc, tlow, thigh;
359 char *str;
360 if(tf_getp(1) == 2){
361 l2warm = tf_getp(3);
362 if(l2warm)return;//have event to be executed.
363 active = tf_getp(2);
364 loc = 4;
365 for(idx = 0;idx < (tf_nump() - 4);idx += 2){
366 if(tf_getp(loc)){
367 low = tf_getlongp(&high, loc+1);
368 tlow = low;
369 thigh = high;
370 thigh <<= 32;
371 thigh &= 0xffffffff00000000;
372 tlow &= 0x00000000ffffffff;
373 pc = thigh | tlow;
374 if(l2warm_vars.avl_ptr && l2warm_search_node(&l2warm_vars.avl_ptr, &pc)){
375 io_printf("Info(%d): l2warm event HIT pc = %llx\n", tf_gettime(), pc);
376 tf_putp(3, 1);
377 break;
378 }
379 }
380 loc += 2;
381 }
382 }
383 else if(tf_getp(1) == 1){
384 l2warm_vars.avl_ptr = 0;
385 str = tf_getcstringp(3); // a get file name
386 l2warm_get_event(str);
387 l2warm_setRdancy(tf_getp(4));
388 }
389}