Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / pli / cache / c / src / bw_lib.c
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: bw_lib.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 <stdio.h>
40#include <string.h>
41#include "bw_lib.h"
42/*-------------------------------------------------------------------------------
43 remove leading space or tab.
44 if found carriage return, return -1 to indicate anenpty string.
45--------------------------------------------------------------------------------*/
46int n2_ck_rmSpace(char* buf, int index, int max){
47 while((index < max) && (buf[index] == ' ' || buf[index] == '\t'))index++;
48 return buf[index] == '\n' || buf[index] == '\0' ? -1 : index;
49}
50/*-------------------------------------------------------------------------------
51 check the address symbol that is "@".
52 if symbol there, return address.
53--------------------------------------------------------------------------------*/
54unsigned long long n2_ck_getEight(char *buf, int idx)
55{
56 int i;
57 unsigned long long addr = 0;
58
59 //for(i = idx; buf[i] != '\0';i++){
60 for(i = idx; ( ( (buf[i] >= '0') && (buf[i] <= '9') ) ||
61 ( (buf[i] >= 'a') && (buf[i] <= 'f') ) ) ;i++){
62 addr <<= 4;
63 addr |= buf[i] > '9' ? ((buf[i] & 0xf) + 9) : buf[i] & 0xf;
64 }
65 return addr;
66}
67/*-------------------------------------------------------------------------------
68 check the address symbol that is "@".
69 if symbol there, return address.
70--------------------------------------------------------------------------------*/
71int n2_ck_getAddr(char *buf, unsigned long long *addr, int idx){
72 int i;
73
74 for(i = idx; buf[i] != '\0'; i++)
75 if(buf[i] == '/'){
76 for(i = i-1; i >= 0;i--)
77 if(buf[i] >= '0' && buf[i] <= '9'){
78 buf[i+1] = '\0';
79 break;
80 }
81 break;
82 }
83 for(i = idx; buf[i] != '\0'; i++){
84 if(buf[i] == '@'){
85 i++;
86 // io_printf("BUFFER %s\n", buf);
87 *addr = n2_ck_getEight(buf, i);//ato_long(buf, &i);
88 return 1;
89 }
90 }
91 return 0;
92}
93/*-------------------------------------------------------------------------------
94 convert ascii to hex array.
95--------------------------------------------------------------------------------*/
96void n2_ck_a2h(char* buf,int idx, char* cbuf, int* cidx){
97
98 char ch;
99
100 while((buf[idx] != '\0') && (buf[idx] != '\n')){
101 if(buf[idx] == ' '){
102 idx++;
103 continue;
104 }
105 ch = buf[idx] > '9' ? ((buf[idx] & 0xf) + 9) : buf[idx] & 0xf;
106 ch <<= 4;
107 idx++;
108 if(buf[idx] == '\0' || buf[idx] == '\n'){
109 cbuf[*cidx] = ch;
110 (*cidx)++;
111 break;
112 }
113 ch |= buf[idx] > '9' ? ((buf[idx] & 0xf) + 9) : buf[idx] & 0xf;
114 cbuf[*cidx] = ch;
115 idx++;
116 (*cidx)++;
117 }
118}
119/*-------------------------------------------------------------------------------
120 convert ascii to hex array.
121--------------------------------------------------------------------------------*/
122int n2_ck_align_buf(char* cbuf, int cidx){
123 int i;
124
125 if(cidx < 64)return cidx;
126 for(i = 64; i < cidx;i++)cbuf[i-64] = cbuf[i];
127 return 64;
128}
129/*-------------------------------------------------------------------------------
130 1). only use 40 bits
131 2). line size 64 bytes.
132--------------------------------------------------------------------------------*/
133KeyType n2_ck_mask_addr (KeyType addr){
134
135 addr >>= 6;
136 addr &= 0x3ffffffff;
137 return addr;
138}
139/*-------------------------------------------------------------------------------
140 read mem.image and build memory.
141--------------------------------------------------------------------------------*/
142void n2_ck_padding(char* buf, int index)
143{
144 int num, ind;
145 ind = index;
146 num = 0;
147 // io_printf("PADDING %s\n", buf);
148 //counter how many character in buff.
149 while(num < 64){
150 if(buf[ind] == ' '){
151 ind++;
152 continue;
153 }
154 if((buf[ind] == '\n') || (buf[ind] == '\0')){
155 break;
156 }
157 ind++;
158 num++;
159 }
160
161 if(num < 64){//do padding
162 ind--;
163 if(buf[ind] != ' ')ind++;
164 while(num < 64){
165 if((num % 16) == 0){
166 buf[ind] = ' ';
167 ind++;
168 }
169 buf[ind] = '0';
170 ind++;
171 num++;
172 }
173 buf[ind] = '\n';
174 }// io_printf("after PADDING %s", buf);
175}
176/*------------------------------------------
177 initiliaze jbus handle.
178-------------------------------------------*/
179void n2_ck_read_mem(char* str,
180 b_tree_node_ptr* root,
181 list_head_ptr addr_list)
182{
183 FILE *fp;
184 char buf [BUFFER];
185 char cbuf[BUFFER];
186 int idx, cidx;
187 KeyType addr, t_addr;
188 b_tree_atom_ptr atom;//node for b-tree.
189 list_node_ptr addr_ptr;
190 int dev, zero;
191
192 if((fp = fopen(str, "r")) == 0){
193 io_printf("Error: can not open file %s for reading\n", str);
194 tf_dofinish();
195 }
196 cidx = 0;
197 addr = 0;
198 zero = 0;
199
200 while(fgets(buf, BUFFER, fp)){
201 idx = n2_ck_rmSpace(buf, 0, BUFFER);
202 if(idx < 0 || strncmp (buf, "//", 2) == 0){
203 idx = n2_ck_rmSpace(buf, idx+2, BUFFER);
204 if(strncmp(buf+idx, "zero_bytes", 10) == 0)zero = 1;
205 continue;//empty string
206 }
207 t_addr = addr;
208 if(n2_ck_getAddr(buf, &addr, idx)){//get address
209 //io_printf("IO ADDRESS %s %llx\n", buf, addr);
210 if(cidx){
211 atom = (b_tree_atom_ptr)malloc(sizeof(struct b_tree_atom));
212 for(idx = 0;idx < cidx;idx++)atom->data[idx] = cbuf[idx];
213 atom->data[cidx] = '\0';
214 atom->key = n2_ck_mask_addr(t_addr);
215 atom->size = cidx;
216 b_insert(root, &atom);
217 dev = (int)(t_addr >> 28);
218 dev &= 0xfff;
219 //if next data is zero byte, don't store address into list.
220 if(dev < 0x200){
221 //save address for l2warm
222 if(zero == 0){
223 addr_ptr = (list_node_ptr)malloc(sizeof(struct list_node));
224 addr_ptr->addr = t_addr;
225 n2_ck_push(addr_list, &addr_ptr);
226 }
227 }
228 zero = 0;
229 }
230 cidx = addr & 0x3f;
231 continue;
232 }//if(getAddr
233 n2_ck_padding(buf, idx);
234 n2_ck_a2h(buf, idx, cbuf, &cidx);
235 while(cidx >= 64){
236 atom = (b_tree_atom_ptr)malloc(sizeof(struct b_tree_atom));
237 for(idx = 0;idx < 64;idx++)atom->data[idx] = cbuf[idx];
238 atom->data[64] = '\0';
239 atom->key = n2_ck_mask_addr(addr);
240 atom->size = 64;
241 b_insert(root, &atom);
242 dev = (int)(addr >> 28);
243 dev &= 0xfff;
244 if(dev < 0x200){
245 if(zero == 0){
246 //save address
247 addr_ptr = (list_node_ptr)malloc(sizeof(struct list_node));
248 addr_ptr->addr = addr;
249 n2_ck_push(addr_list, &addr_ptr);
250 }
251 }
252 //generate the next address
253 cidx -= n2_ck_align_buf(cbuf, cidx);
254 addr += 64;
255 }
256 }//while(fgets(buf, BUFFER, fp)){
257 fclose(fp);
258
259 //process the last input
260 if(cidx){
261 atom = (b_tree_atom_ptr)malloc(sizeof(struct b_tree_atom));
262 for(idx = 0;idx < cidx;idx++)atom->data[idx] = cbuf[idx];
263 atom->data[cidx] = '\0';
264 atom->key = n2_ck_mask_addr(addr);
265 atom->size = cidx;
266 b_insert(root, &atom);
267 dev = (int)(addr >> 28);
268 dev &= 0xfff;
269 if(dev < 0x200){
270 if(zero == 0){
271 //save address
272 addr_ptr = (list_node_ptr)malloc(sizeof(struct list_node));
273 addr_ptr->addr = addr;
274 n2_ck_push(addr_list, &addr_ptr);
275 }
276 }
277 }
278}
279
280/*------------------------------------------
281set random seed
282-------------------------------------------*/
283void n2_ck_set_random()
284{
285 char *pargs;
286 unsigned int seed;
287 pargs = mc_scan_plusargs ("tg_seed=");
288 if(pargs != (char *) 0) {
289 seed = atoi(pargs);
290 srand(seed);
291 srandom(seed);
292 }
293}