Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: mem.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 "vcsuser.h" | |
39 | #include "acc_user.h" | |
40 | #include <malloc.h> | |
41 | #include <stdio.h> | |
42 | #include <stdlib.h> | |
43 | #include "utility.h" | |
44 | #include "print_dimm.h" | |
45 | ||
46 | #define BUFFER 1024 | |
47 | #define CHIPKILL 0x10000 | |
48 | ||
49 | #define DUAL_CHANNEL 0x100 | |
50 | #define SNG_CHANNEL 0x200 | |
51 | #define RANK_HIGH 0x400 | |
52 | #define RANK_LOW 0x800 | |
53 | #define STACK_DIMM 0x1000 | |
54 | #define PARTIAL_BANK_2BK 0x20000 | |
55 | #define PARTIAL_BANK_4BK 0x40000 | |
56 | ||
57 | #define HASH_PA 0x100000 | |
58 | ||
59 | ||
60 | //define global variable | |
61 | static int slam_val; | |
62 | static int dimm_config; | |
63 | static avl_conf_ptr dram_tree; | |
64 | static unsigned int ck_mcu0; | |
65 | static unsigned int ck_mcu1; | |
66 | static unsigned int ck_mcu2; | |
67 | static unsigned int ck_mcu3; | |
68 | static int shift; | |
69 | ||
70 | //function prototypes | |
71 | avl_node_ptr search_node(avl_node_ptr *t_ptr, long long *addr); | |
72 | long long pm_address_shift(long long addr, int shift); | |
73 | long long fc_hash_pa(long long addr, int dimm_config); | |
74 | long long decode_cs(long long *addr, int dimm_config, int shift); | |
75 | long long address_decode(long long *addr, int dimm_config, int shift); | |
76 | int pm_bank_s(long long addr, int shift); | |
77 | int check_if_valid_PA(long long addr, int dimm_config, int shift); | |
78 | ||
79 | /*------------------------------------------------------------------- | |
80 | create ecc data. {{{ | |
81 | ---------------------------------------------------------------------*/ | |
82 | void hamming(char *word, | |
83 | char *ecc){ | |
84 | ||
85 | int count, multc, tmpicount, multresult, mult_count, tmpcount, | |
86 | divresult, divc, upper_test, parity1, parity2, parity3, parity4; | |
87 | int primitive; | |
88 | char hword[32]; | |
89 | primitive = 0x13;//0b010011; | |
90 | parity1 = 0; | |
91 | parity2 = 0; | |
92 | parity3 = 0; | |
93 | parity4 = 0; | |
94 | ||
95 | /* | |
96 | primitive = 0x11d;//0b0100011101; | |
97 | for (count = 0; count < 16; count++) { | |
98 | multresult = 0; | |
99 | for (multc = 0; multc < 8; multc++) { | |
100 | tmpicount = ((word[count] >> multc) & 1); | |
101 | if (tmpicount == 1) { | |
102 | multresult = multresult ^ ((count + 1) << multc); | |
103 | } | |
104 | } | |
105 | divresult = multresult; | |
106 | for (divc = 0; divc < 8; divc++) { | |
107 | upper_test = divresult & 0xff00;//0b1111_1111_1111_0000_0000; | |
108 | if (upper_test != 0) { | |
109 | tmpicount = ((divresult >> (15 - divc)) & 1); | |
110 | if (tmpicount == 1) { | |
111 | divresult = divresult ^ (primitive << (7 - divc)); | |
112 | } | |
113 | } | |
114 | } | |
115 | parity0 = parity0 ^ divresult; | |
116 | } | |
117 | for (count = 0; count < 16; count++) { | |
118 | parity1 = parity1 ^ (word[count] & 0xff); | |
119 | } | |
120 | ecc[1] = (parity0 >> 4 ) & 0xf; | |
121 | ecc[0] = (parity0) & 0xf; | |
122 | ecc[3] = (parity1 >> 4 ) & 0xf; | |
123 | ecc[2] = (parity1) & 0xf; | |
124 | */ | |
125 | ||
126 | ||
127 | for (count = 0; count < 16; count++) { | |
128 | hword[31 - count*2-1] = word[count] & 0xf; | |
129 | hword[31 - count*2] = (word[count] >> 4) & 0xf; | |
130 | } | |
131 | for (count = 0; count != 32; count++) { | |
132 | if (count != 30) { | |
133 | multresult = 0; | |
134 | if (count > 14) { | |
135 | if (count == 31) { | |
136 | mult_count = 0; | |
137 | } else { | |
138 | mult_count = count - 15; | |
139 | } | |
140 | } else { | |
141 | mult_count = count; | |
142 | } | |
143 | for (multc = 0; multc != 4; multc++) { | |
144 | tmpicount = ((hword[count] >> multc) & 1); | |
145 | if (tmpicount == 1) { | |
146 | multresult = multresult ^ ((mult_count + 1) << multc); | |
147 | } | |
148 | } | |
149 | divresult = multresult; | |
150 | for (divc = 0; divc != 4; divc++) { | |
151 | upper_test = divresult & 0xffff0; //0b1111_1111_1111_1111_0000; | |
152 | if (upper_test != 0) { | |
153 | tmpcount = ((divresult >> (7 - divc)) & 1); | |
154 | if (tmpcount == 1) { | |
155 | divresult = divresult ^ (primitive << (3 - divc)); | |
156 | } | |
157 | } | |
158 | } | |
159 | parity1 = parity1 ^ divresult; | |
160 | } // if | |
161 | } | |
162 | for (count = 0; count != 15; count++) { | |
163 | parity2 = parity2 ^ hword[count]; | |
164 | } | |
165 | parity2 = parity2 ^ hword[30] ^ hword[31]; | |
166 | for (count = 15; count != 32; count++) { | |
167 | parity3 = parity3 ^ hword[count]; | |
168 | } | |
169 | for (count = 0; count != 31; count++) { | |
170 | multresult = 0; | |
171 | if (count == 0 || count == 15 || count == 30 ) { mult_count = 0; } | |
172 | if (count == 1 || count == 16) { mult_count = 8; } | |
173 | if (count == 2 || count == 17) { mult_count = 13; } | |
174 | if (count == 3 || count == 18) { mult_count = 12; } | |
175 | if (count == 4 || count == 19) { mult_count = 10; } | |
176 | if (count == 5 || count == 20) { mult_count = 6; } | |
177 | if (count == 6 || count == 21) { mult_count = 5; } | |
178 | if (count == 7 || count == 22) { mult_count = 14; } | |
179 | if (count == 8 || count == 23) { mult_count = 1; } | |
180 | if (count == 9 || count == 24) { mult_count = 11; } | |
181 | if (count == 10 || count == 25) { mult_count = 4; } | |
182 | if (count == 11 || count == 26) { mult_count = 9; } | |
183 | if (count == 12 || count == 27) { mult_count = 3; } | |
184 | if (count == 13 || count == 28) { mult_count = 2; } | |
185 | if (count == 14 || count == 29) { mult_count = 7; } | |
186 | ||
187 | for (multc = 0; multc != 4; multc++) { | |
188 | tmpicount = ((hword[count] >> multc) & 1); | |
189 | if (tmpicount == 1) { | |
190 | multresult = multresult ^ ((mult_count + 1) << multc); | |
191 | } | |
192 | } | |
193 | divresult = multresult; | |
194 | for (divc = 0; divc != 4; divc++) { | |
195 | upper_test = divresult & 0xffff0; //0b11111111111111110000; | |
196 | if (upper_test != 0) { | |
197 | tmpcount = ((divresult >> (7 - divc)) & 1); | |
198 | if (tmpcount == 1) { | |
199 | divresult = divresult ^ (primitive << (3 - divc)); | |
200 | } | |
201 | } | |
202 | } | |
203 | parity4 = parity4 ^ divresult; | |
204 | } | |
205 | ecc[1] = (parity1) & 0xf; | |
206 | ecc[0] = (parity2) & 0xf; | |
207 | ecc[3] = (parity3) & 0xf; | |
208 | ecc[2] = (parity4) & 0xf; | |
209 | } | |
210 | // }}} | |
211 | ||
212 | /*------------------------------------------------------------------- | |
213 | syndrome regenerated from hamming syndrome by XORing address parity. {{{ | |
214 | ----------------------------------------------------------------------*/ | |
215 | void addr_parity(char* data, long long addr, char* ecc, int start_bit, int shift) | |
216 | { | |
217 | int i; | |
218 | long long local_addr = 0; | |
219 | char parity, addr_parity; | |
220 | addr_parity = 0; | |
221 | ||
222 | //Partial mode shifting - James | |
223 | addr = pm_address_shift(addr, shift); | |
224 | ||
225 | if(start_bit == 0) | |
226 | addr = fc_hash_pa(addr, dimm_config); | |
227 | ||
228 | //io_printf((char *)"(PLI) pre_xor ecc = (%02x %02x %02x %02x)\n", data[0], data[1], data[2], data[3]); | |
229 | //io_printf((char *)"(PLI)addr_parity: addr = %llx, start_bit = %d\n", addr, start_bit); | |
230 | if (start_bit == 0) | |
231 | { | |
232 | local_addr = local_addr | (addr & 0xfffffffe00); | |
233 | local_addr = (local_addr >> 9); | |
234 | // restore bit 6 | |
235 | local_addr = (local_addr << 1) | ((addr & 0x40) >> 6); | |
236 | //io_printf((char *)"(PLI)addr_parity: local_addr = %llx\n", local_addr); | |
237 | for(i = 0; i < 32; i++){ | |
238 | addr_parity = addr_parity ^ (local_addr & 1); | |
239 | local_addr >>= 1; | |
240 | } | |
241 | } | |
242 | else | |
243 | { | |
244 | if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL) { | |
245 | local_addr = local_addr | (addr & 0x7fffffff8); | |
246 | local_addr = (local_addr >> 3); | |
247 | } | |
248 | else { | |
249 | local_addr = local_addr | (addr & 0x7fffffffc); | |
250 | local_addr = (local_addr >> 2); | |
251 | } | |
252 | //io_printf((char *)"(PLI)addr_parity: local_addr = %llx\n", local_addr); | |
253 | for(i = 0; i < 32; i++){ | |
254 | addr_parity = addr_parity ^ (local_addr & 1); | |
255 | local_addr >>= 1; | |
256 | } | |
257 | } | |
258 | ||
259 | ||
260 | parity = addr_parity; | |
261 | for(i = 1; i < 8;i++){ | |
262 | parity <<=1; | |
263 | parity = parity | addr_parity; | |
264 | } | |
265 | ||
266 | //io_printf((char *)"(PLI)addr_parity: parity = %x, addr_parity = %x\n", parity, addr_parity); | |
267 | ecc[1] = (data[1] ^ parity) & 0xf; | |
268 | ecc[0] = (data[0] ^ parity) & 0xf; | |
269 | ecc[3] = (data[3] ^ parity) & 0xf; | |
270 | ecc[2] = (data[2] ^ parity) & 0xf; | |
271 | //io_printf((char *)"(PLI) ecc calculated after addr_parity is ecc(%02x %02x %02x %02x)\n", ecc[0] & 0xff, ecc[1] & 0xff, ecc[2] & 0xff, ecc[3] & 0xff); | |
272 | } | |
273 | // }}} | |
274 | ||
275 | /*------------------------------------------------------------------- | |
276 | check the address symbol that is "@". {{{ | |
277 | if symbol there, return address. | |
278 | ---------------------------------------------------------------------*/ | |
279 | int check_at_symbol(char *buf, long long *addr){ | |
280 | int i; | |
281 | ||
282 | for(i = 0; buf[i] != '\0'; i++) | |
283 | if(buf[i] == '/'){ | |
284 | for(i = i-1; i >= 0;i--)if(buf[i] >= '0' && buf[i] <= '9'){ | |
285 | buf[i+1] = '\0'; | |
286 | break; | |
287 | } | |
288 | break; | |
289 | } | |
290 | for(i = 0; buf[i] != '\0'; i++){ | |
291 | if(buf[i] == '@'){ | |
292 | i++; | |
293 | *addr = ato_long(buf, &i); | |
294 | return 1; | |
295 | } | |
296 | } | |
297 | return 0; | |
298 | } | |
299 | // }}} | |
300 | ||
301 | // /*------------------------------------------------------------------- | |
302 | // configure memory(address(bits) x datawidth(bits)). {{{ | |
303 | // ---------------------------------------------------------------------*/ | |
304 | // void config_mem_call(){ | |
305 | // avl_conf_ptr a_tree; | |
306 | // | |
307 | // if(tf_nump() < 2){ | |
308 | // tf_error((char *)"$config_mem_call requires at least two arguments(address, data-width)."); | |
309 | // tf_dofinish(); | |
310 | // } | |
311 | // a_tree = (avl_conf_ptr)malloc(sizeof(struct avl_conf_node)); | |
312 | // a_tree->addr = tf_getp(1);// get address size | |
313 | // a_tree->half_byte = a_tree->addr / 4; | |
314 | // if((a_tree->addr % 4) != 0)a_tree->half_byte++; | |
315 | // a_tree->size = tf_getp(2);//get data width | |
316 | // a_tree->word = a_tree->size / 32; | |
317 | // a_tree->dram = 0;//dram | |
318 | // if((a_tree->size % 32) != 0)a_tree->word++; | |
319 | // //pointer for avl tree set NULL | |
320 | // a_tree->data = 0; | |
321 | // tf_putp(0, (unsigned int)a_tree);//reurn handle | |
322 | // io_printf((char *)"(PLI)Info -> Creating Memory(address width(%dbits) data width(%dbits)\n", a_tree->addr, a_tree->size); | |
323 | // } | |
324 | // }}} | |
325 | ||
326 | /*------------------------------------------------------------------- | |
327 | set to an unintialized memory with random value. {{{ | |
328 | ---------------------------------------------------------------------*/ | |
329 | avl_node_ptr store_op(long long addr, int handle) | |
330 | { | |
331 | int i, bank, start, ind, i_bank, l; | |
332 | char d_buf[16], buf[16], ecc[4], pre_xor_ecc[4]; | |
333 | state_node f_val[1]; | |
334 | avl_node_ptr t_ptr; | |
335 | int tmp_adjust = 0; | |
336 | int ras_cas = 0; | |
337 | int j = 0; | |
338 | ||
339 | t_ptr = search_node(&(dram_tree)->data, &addr); | |
340 | bank = handle / 32; | |
341 | if(bank == 4){//when ecc read. | |
342 | handle -= 128; | |
343 | bank = handle / 4; | |
344 | } | |
345 | start = bank * 32; | |
346 | //io_printf((char *)"(PLI)t_ptr returned in store_op, start = %d, bank = %d, handle = %d \n",start, bank, handle); | |
347 | if(t_ptr == 0 || ((t_ptr->val[0].bval[start] & 0xff) == 0xff)){ | |
348 | if(t_ptr == 0){ | |
349 | for(l = 0;l < 144; l++){ | |
350 | f_val[0].aval.cval[l] = 0xff; | |
351 | f_val[0].bval[l] = 0xff; | |
352 | } | |
353 | } | |
354 | ||
355 | // slam_val for MCU SAT. Don't return zeros on uninitialized | |
356 | if (slam_val) { | |
357 | if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL) { | |
358 | if (mc_scan_plusargs("RANK_LOW") !=(char *)NULL) | |
359 | ras_cas = addr & 0x7fff800; | |
360 | else | |
361 | ras_cas = addr & 0x7ffff80; | |
362 | ras_cas = ras_cas >> 1; | |
363 | } else { | |
364 | if (mc_scan_plusargs("RANK_LOW") !=(char *)NULL) | |
365 | ras_cas = addr & 0x3fffc00; | |
366 | else | |
367 | ras_cas = addr & 0x3ffffc0; | |
368 | } | |
369 | ||
370 | //io_printf((char *)"(PLI)store_op: ras_cas = %x, addr = %llx\n", ras_cas, addr); | |
371 | for(i = 0; i < 16; i++) { | |
372 | if(i > 11) { | |
373 | j = (i % 4) * 8; | |
374 | d_buf[i] = ((ras_cas & (0xff000000 >> j)) >> (24 - j)) & 0xff; | |
375 | } else d_buf[i] = 0; | |
376 | } | |
377 | } else { | |
378 | for(i = 0; i < 16; i++) d_buf[i] = 0; | |
379 | } | |
380 | ||
381 | //d_buf[i] = slam_val ? random() & 0xff : 0;// get ram data | |
382 | //io_printf((char *)"(PLI)from store_op routine slam_val = %d, d_buf[%d] = %s", slam_val,i, d_buf[i]); | |
383 | ||
384 | ind = 0; | |
385 | for(i_bank = 0; i_bank < 8;i_bank++){ | |
386 | buf[ind++] = (d_buf[i_bank] >> 4) & 0xf; | |
387 | buf[ind++] = d_buf[i_bank] & 0xf; | |
388 | } | |
389 | for(i_bank = 0; i_bank < 16;i_bank++){ | |
390 | if(t_ptr){ | |
391 | (t_ptr)->val[0].aval.cval[start + i_bank] = buf[15-i_bank]; | |
392 | (t_ptr)->val[0].bval[start + i_bank] = 0; | |
393 | } | |
394 | else{ | |
395 | f_val[0].aval.cval[start+i_bank] = buf[15-i_bank]; | |
396 | f_val[0].bval[start+i_bank] = 0; | |
397 | } | |
398 | } | |
399 | start += 16; | |
400 | ind = 0; | |
401 | for(i_bank = 8; i_bank < 16;i_bank++){ | |
402 | buf[ind++] = (d_buf[i_bank] >> 4) & 0xf; | |
403 | buf[ind++] = d_buf[i_bank] & 0xf; | |
404 | } | |
405 | for(i_bank = 0; i_bank < 16;i_bank++){ | |
406 | if(t_ptr){ | |
407 | (t_ptr)->val[0].aval.cval[start+i_bank] = buf[15-i_bank]; | |
408 | (t_ptr)->val[0].bval[start+i_bank] = 0; | |
409 | } | |
410 | else { | |
411 | f_val[0].aval.cval[start+i_bank] = buf[15-i_bank]; | |
412 | f_val[0].bval[start+i_bank] = 0; | |
413 | } | |
414 | } | |
415 | tmp_adjust = start - 16; | |
416 | hamming(d_buf, pre_xor_ecc); | |
417 | //io_printf((char *)"(PLI) calling addr_parity in store_op foR ADDR = %llx \n", addr); | |
418 | addr_parity(pre_xor_ecc, addr, ecc, 6, 0); | |
419 | ||
420 | start = 128 + bank * 4; | |
421 | ||
422 | if(t_ptr){ | |
423 | (t_ptr)->val[0].aval.cval[start+0] = ecc[0]; | |
424 | (t_ptr)->val[0].bval[start+0] = 0; | |
425 | (t_ptr)->val[0].aval.cval[start+1] = ecc[1]; | |
426 | (t_ptr)->val[0].bval[start+1] = 0; | |
427 | (t_ptr)->val[0].aval.cval[start+2] = 0; // data | |
428 | (t_ptr)->val[0].bval[start+2] = 0; | |
429 | (t_ptr)->val[0].aval.cval[start+3] = 0; // data | |
430 | (t_ptr)->val[0].bval[start+3] = 0; | |
431 | (t_ptr)->val[0].aval.cval[tmp_adjust + 14] = ecc[2]; // data | |
432 | (t_ptr)->val[0].bval[tmp_adjust + 14] = 0; | |
433 | (t_ptr)->val[0].aval.cval[tmp_adjust + 15] = ecc[3]; // data | |
434 | (t_ptr)->val[0].bval[tmp_adjust + 15] = 0; | |
435 | ||
436 | if(dimm_config & CHIPKILL) | |
437 | { | |
438 | (t_ptr)->val[0].aval.cval[start+0] = ecc[1]; | |
439 | (t_ptr)->val[0].bval[start+0] = 0; | |
440 | (t_ptr)->val[0].aval.cval[start+1] = 0; // displaced data | |
441 | (t_ptr)->val[0].bval[start+1] = 0; | |
442 | (t_ptr)->val[0].aval.cval[start+2] = 0; // data | |
443 | (t_ptr)->val[0].bval[start+2] = 0; | |
444 | (t_ptr)->val[0].aval.cval[start+3] = 0; // data | |
445 | (t_ptr)->val[0].bval[start+3] = 0; | |
446 | (t_ptr)->val[0].aval.cval[tmp_adjust + 14] = ecc[3]; // data | |
447 | (t_ptr)->val[0].bval[tmp_adjust + 14] = 0; | |
448 | (t_ptr)->val[0].aval.cval[tmp_adjust + 15] = ecc[0]; // data | |
449 | (t_ptr)->val[0].bval[tmp_adjust + 15] = 0; | |
450 | } | |
451 | } | |
452 | else { | |
453 | f_val[0].aval.cval[start+0] = ecc[0]; | |
454 | f_val[0].bval[start+0] = 0; | |
455 | f_val[0].aval.cval[start+1] = ecc[1]; | |
456 | f_val[0].bval[start+1] = 0; | |
457 | f_val[0].aval.cval[start+2] = 0; // data | |
458 | f_val[0].bval[start+2] = 0; | |
459 | f_val[0].aval.cval[start+3] = 0; // data | |
460 | f_val[0].bval[start+3] = 0; | |
461 | f_val[0].aval.cval[tmp_adjust + 14] = ecc[2]; // data | |
462 | f_val[0].bval[tmp_adjust + 14] = 0; | |
463 | f_val[0].aval.cval[tmp_adjust + 15] = ecc[3]; // data | |
464 | f_val[0].bval[tmp_adjust + 15] = 0; | |
465 | ||
466 | if(dimm_config & CHIPKILL) | |
467 | { | |
468 | f_val[0].aval.cval[start+0] = ecc[1]; | |
469 | f_val[0].bval[start+0] = 0; | |
470 | f_val[0].aval.cval[start+1] = 0; // displaced data | |
471 | f_val[0].bval[start+1] = 0; | |
472 | f_val[0].aval.cval[start+2] = 0; // data | |
473 | f_val[0].bval[start+2] = 0; | |
474 | f_val[0].aval.cval[start+3] = 0; // data | |
475 | f_val[0].bval[start+3] = 0; | |
476 | f_val[0].aval.cval[tmp_adjust + 14] = ecc[3]; // data | |
477 | f_val[0].bval[tmp_adjust + 14] = 0; | |
478 | f_val[0].aval.cval[tmp_adjust + 15] = ecc[0]; // data | |
479 | f_val[0].bval[tmp_adjust + 15] = 0; | |
480 | } | |
481 | } | |
482 | ||
483 | io_printf((char *)"(PLI)(%0d)Alert: access an uninitialized address({dimm,ras,cas[10:3],bank,cas[2:0]}=%llx)\n", tf_gettime(), addr); | |
484 | if(t_ptr == 0)insert_avl_node(&(dram_tree)->data, &addr, f_val); | |
485 | } | |
486 | return t_ptr; | |
487 | } | |
488 | // }}} | |
489 | ||
490 | /*------------------------------------------------------------------- | |
491 | x8_address_decode {{{ | |
492 | long long addr | |
493 | ---------------------------------------------------------------------*/ | |
494 | long long x8_address_decode(long long addr) | |
495 | { | |
496 | /* | |
497 | DUAL CHANNEL: | |
498 | dway = RAS[14:0], CAS[10:2], BA[2:0], CAS[1:0] | |
499 | [28:14] [13:5] [4:2] [1:0] | |
500 | SINGLE CHANNEL: | |
501 | dway = RAS[14:0], CAS[10:3], BA[2:0], CAS[2:0] | |
502 | [28:14] [13:6] [5:3] [2:0] | |
503 | */ | |
504 | if (mc_scan_plusargs("DIMM_SIZE_1G") !=(char *)NULL) { | |
505 | addr |= ((addr & 0x10000000) >> 15); | |
506 | addr &= 0xfffffff; | |
507 | } | |
508 | else if (mc_scan_plusargs("DIMM_SIZE_512") !=(char *)NULL) { | |
509 | if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL) { | |
510 | addr |= ((addr & 0x20) << 8); | |
511 | addr &= 0x1fffffdf; | |
512 | } | |
513 | else { | |
514 | addr |= ((addr & 0x10) << 9); | |
515 | addr &= 0x1fffffef; | |
516 | } | |
517 | } | |
518 | else if (mc_scan_plusargs("DIMM_SIZE_256") !=(char *)NULL) { | |
519 | addr |= ((addr & 0x8000000) >> 14); | |
520 | addr &= 0x7ffffff; | |
521 | } | |
522 | else { // Default 1Gb | |
523 | addr |= ((addr & 0x10000000) >> 15); | |
524 | addr &= 0xfffffff; | |
525 | } | |
526 | return addr; | |
527 | } | |
528 | //}}} | |
529 | ||
530 | ||
531 | /*------------------------------------------------------------------- | |
532 | $mem_read call routine. {{{ | |
533 | input: handle, bank, way. | |
534 | output: read_data. | |
535 | ---------------------------------------------------------------------*/ | |
536 | void read_mem_call(){ | |
537 | long long addr; | |
538 | int handle; | |
539 | avl_node_ptr t_ptr; | |
540 | long long cs = 1; | |
541 | long long dimm_addr = 0; | |
542 | int btemp = 0; | |
543 | int tbank = 0; | |
544 | ||
545 | handle = tf_getp(1); // get this data base. | |
546 | addr = (long long)tf_getp(3);// get index. | |
547 | //io_printf((char *)"(PLI)(%0d) read_mem_call with args(before) addr = %llx, handle = %d\n", tf_gettime(),addr, handle); | |
548 | ||
549 | if (mc_scan_plusargs("X8") !=(char *)NULL) { addr = x8_address_decode(addr); } | |
550 | //io_printf((char *)"(PLI)(%0d) read_mem_call with args(after) addr = %llx, handle = %d\n", tf_gettime(),addr, handle); | |
551 | ||
552 | ||
553 | if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL)&& (addr & 0x1)) { | |
554 | addr = addr >> 1; | |
555 | addr = addr << 1; | |
556 | btemp = 1; | |
557 | } | |
558 | ||
559 | if(handle < 288 && handle >= 144){ | |
560 | handle -= 144; | |
561 | dimm_addr = 1; | |
562 | addr |= (dimm_addr << 29); | |
563 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
564 | } | |
565 | else if(handle < 432 && handle >= 288){ | |
566 | handle -= 288; | |
567 | dimm_addr = 2; | |
568 | addr |= (dimm_addr << 29); | |
569 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
570 | } | |
571 | else if(handle >= 432 && handle < 576){ | |
572 | handle -= 432; | |
573 | dimm_addr = 3; | |
574 | addr |= (dimm_addr << 29); | |
575 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
576 | } | |
577 | else if(handle >= 576 && handle < 720){ | |
578 | handle -= 576; | |
579 | dimm_addr = 4; | |
580 | addr |= (dimm_addr << 29); | |
581 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
582 | } | |
583 | else if(handle >= 720 && handle < 864){ | |
584 | handle -= 720; | |
585 | dimm_addr = 5; | |
586 | addr |= (dimm_addr << 29); | |
587 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
588 | } | |
589 | else if(handle >= 864 && handle < 1008){ | |
590 | handle -= 864; | |
591 | dimm_addr = 6; | |
592 | addr |= (dimm_addr << 29); | |
593 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
594 | } | |
595 | else if(handle >= 1008 && handle < 1152){ | |
596 | handle -= 1008; | |
597 | dimm_addr = 7; | |
598 | addr |= (dimm_addr << 29); | |
599 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
600 | } | |
601 | else if(handle >= 1152 && handle < 1296){ | |
602 | handle -= 1152; | |
603 | dimm_addr = 0; | |
604 | addr |= (cs << 32); | |
605 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
606 | } | |
607 | else if(handle >= 1296 && handle < 1440){ | |
608 | handle -= 1296; | |
609 | dimm_addr = 1; | |
610 | addr |= (cs << 32); | |
611 | addr |= (dimm_addr << 29); | |
612 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
613 | } | |
614 | else if(handle >= 1440 && handle < 1584){ | |
615 | handle -= 1440; | |
616 | dimm_addr = 2; | |
617 | addr |= (cs << 32); | |
618 | addr |= (dimm_addr << 29); | |
619 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
620 | } | |
621 | else if(handle >= 1584 && handle < 1728){ | |
622 | handle -= 1584; | |
623 | dimm_addr = 3; | |
624 | addr |= (cs << 32); | |
625 | addr |= (dimm_addr << 29); | |
626 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
627 | } | |
628 | else if(handle >= 1728 && handle < 1872){ | |
629 | handle -= 1728; | |
630 | dimm_addr = 4; | |
631 | addr |= (cs << 32); | |
632 | addr |= (dimm_addr << 29); | |
633 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
634 | } | |
635 | else if(handle >= 1872 && handle < 2016){ | |
636 | handle -= 1872; | |
637 | dimm_addr = 5; | |
638 | addr |= (cs << 32); | |
639 | addr |= (dimm_addr << 29); | |
640 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
641 | } | |
642 | else if(handle >= 2016 && handle < 2160){ | |
643 | handle -= 2016; | |
644 | dimm_addr = 6; | |
645 | addr |= (cs << 32); | |
646 | addr |= (dimm_addr << 29); | |
647 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
648 | } | |
649 | else if(handle >= 2160 && handle < 2304){ | |
650 | handle -= 2160; | |
651 | dimm_addr = 7; | |
652 | addr |= (cs << 32); | |
653 | addr |= (dimm_addr << 29); | |
654 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
655 | } | |
656 | ||
657 | if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL)&& (btemp == 1)) { | |
658 | tbank = handle / 32; | |
659 | if(tbank == 4){//when ecc read. | |
660 | handle += 2; | |
661 | } | |
662 | else | |
663 | handle += 16; | |
664 | } | |
665 | //io_printf((char *)"(PLI)calling read_mem with args addr = %llx, handle = %d\n", addr, handle); | |
666 | t_ptr = store_op(addr, handle); | |
667 | ||
668 | if(t_ptr == 0) | |
669 | t_ptr = search_node(&(dram_tree)->data, &addr); | |
670 | ||
671 | //io_printf((char *)"(PLI)read_mem: slam_mem: with args addr = %llx, handle = %d\n", addr, handle); | |
672 | //for(l = 0;l < 144; l++){ | |
673 | // io_printf((char *)"(PLI)rval[%d] = %x, ",l, t_ptr->val[0].aval.cval[l]); | |
674 | //} | |
675 | ||
676 | slam_memory((t_ptr)->val, dram_tree->word, 2, 1, handle); | |
677 | } | |
678 | // }}} | |
679 | ||
680 | /*------------------------------------------------------------------- | |
681 | $write_mem call routine. {{{ | |
682 | ---------------------------------------------------------------------*/ | |
683 | void write_mem_call(){ | |
684 | long long addr; | |
685 | state_node nval[1]; | |
686 | int handle, l; | |
687 | avl_node_ptr t_ptr; | |
688 | long long cs = 1; | |
689 | long long dimm_addr = 0; | |
690 | int btemp = 0; | |
691 | int tbank = 0; | |
692 | ||
693 | addr = (long long)tf_getp(3); | |
694 | handle = tf_getp(1); // get this data base. | |
695 | //io_printf((char *)"(PLI)(%0d) write_mem_call with args(before) addr = %llx, handle = %d\n", tf_gettime(),addr, handle); | |
696 | ||
697 | if (mc_scan_plusargs("X8") !=(char *)NULL) { addr = x8_address_decode(addr); } | |
698 | //io_printf((char *)"(PLI)(%0d) write_mem_call with args(after) addr = %llx, handle = %d\n", tf_gettime(),addr, handle); | |
699 | ||
700 | if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL)&&(addr & 0x1)) { | |
701 | addr = addr >> 1; | |
702 | addr = addr << 1; | |
703 | btemp = 1; | |
704 | } | |
705 | ||
706 | if(handle < 288 && handle >= 144){ | |
707 | handle -= 144; | |
708 | dimm_addr = 1; | |
709 | addr |= (dimm_addr << 29); | |
710 | // io_printf((char *)"(PLI)writing here, handle = %d, addr = %d\n",handle, addr); | |
711 | } | |
712 | else if(handle < 432 && handle >= 288){ | |
713 | handle -= 288; | |
714 | dimm_addr = 2; | |
715 | addr |= (dimm_addr << 29); | |
716 | // io_printf((char *)"(PLI)writing here, handle = %d, addr = %d\n",handle, addr); | |
717 | } | |
718 | else if(handle >= 432 && handle < 576){ | |
719 | handle -= 432; | |
720 | dimm_addr = 3; | |
721 | addr |= (dimm_addr << 29); | |
722 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
723 | } | |
724 | else if(handle >= 576 && handle < 720){ | |
725 | handle -= 576; | |
726 | dimm_addr = 4; | |
727 | addr |= (dimm_addr << 29); | |
728 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
729 | } | |
730 | else if(handle >= 720 && handle < 864){ | |
731 | handle -= 720; | |
732 | dimm_addr = 5; | |
733 | addr |= (dimm_addr << 29); | |
734 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
735 | } | |
736 | else if(handle >= 864 && handle < 1008){ | |
737 | handle -= 864; | |
738 | dimm_addr = 6; | |
739 | addr |= (dimm_addr << 29); | |
740 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
741 | } | |
742 | else if(handle >= 1008 && handle < 1152){ | |
743 | handle -= 1008; | |
744 | dimm_addr = 7; | |
745 | addr |= (dimm_addr << 29); | |
746 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
747 | } | |
748 | else if(handle >= 1152 && handle < 1296){ | |
749 | handle -= 1152; | |
750 | dimm_addr = 0; | |
751 | addr |= (cs << 32); | |
752 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
753 | } | |
754 | else if(handle >= 1296 && handle < 1440){ | |
755 | handle -= 1296; | |
756 | dimm_addr = 1; | |
757 | addr |= (cs << 32); | |
758 | addr |= (dimm_addr << 29); | |
759 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
760 | } | |
761 | else if(handle >= 1440 && handle < 1584){ | |
762 | handle -= 1440; | |
763 | dimm_addr = 2; | |
764 | addr |= (cs << 32); | |
765 | addr |= (dimm_addr << 29); | |
766 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
767 | } | |
768 | else if(handle >= 1584 && handle < 1728){ | |
769 | handle -= 1584; | |
770 | dimm_addr = 3; | |
771 | addr |= (cs << 32); | |
772 | addr |= (dimm_addr << 29); | |
773 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
774 | } | |
775 | else if(handle >= 1728 && handle < 1872){ | |
776 | handle -= 1728; | |
777 | dimm_addr = 4; | |
778 | addr |= (cs << 32); | |
779 | addr |= (dimm_addr << 29); | |
780 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
781 | } | |
782 | else if(handle >= 1872 && handle < 2016){ | |
783 | handle -= 1872; | |
784 | dimm_addr = 5; | |
785 | addr |= (cs << 32); | |
786 | addr |= (dimm_addr << 29); | |
787 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
788 | } | |
789 | else if(handle >= 2016 && handle < 2160){ | |
790 | handle -= 2016; | |
791 | dimm_addr = 6; | |
792 | addr |= (cs << 32); | |
793 | addr |= (dimm_addr << 29); | |
794 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
795 | } | |
796 | else if(handle >= 2160 && handle < 2304){ | |
797 | handle -= 2160; | |
798 | dimm_addr = 7; | |
799 | addr |= (cs << 32); | |
800 | addr |= (dimm_addr << 29); | |
801 | // io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr); | |
802 | } | |
803 | ||
804 | if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL)&& (btemp == 1)) { | |
805 | tbank = handle / 32; | |
806 | if(tbank == 4){//when ecc read. | |
807 | handle += 2; | |
808 | } | |
809 | else | |
810 | handle += 16; | |
811 | } | |
812 | //io_printf((char *)"(PLI)calling write_mem with args addr = %llx, handle = %d\n", addr, handle); | |
813 | t_ptr = search_node(&(dram_tree)->data, &addr); | |
814 | ||
815 | if(t_ptr == 0){ | |
816 | for(l = 0;l < 144; l++){ | |
817 | nval[0].aval.cval[l] = 0xff; | |
818 | nval[0].bval[l] = 0xff; | |
819 | } | |
820 | } | |
821 | dump_memory(nval, dram_tree->word, 2, handle); | |
822 | if(t_ptr){ | |
823 | t_ptr->val[0].aval.cval[handle] = nval[0].aval.cval[handle]; | |
824 | t_ptr->val[0].bval[handle] = nval[0].bval[handle]; | |
825 | } | |
826 | else insert_avl_node(&(dram_tree)->data, &addr, nval); | |
827 | } | |
828 | // }}} | |
829 | ||
830 | /*------------------------------------------------------------------- | |
831 | receive the phyical address from rtl. {{{ | |
832 | return 4 bytes to rtl. | |
833 | ---------------------------------------------------------------------*/ | |
834 | void read_dram_call(){ | |
835 | int high, bank, i_bank, bank_s;//address | |
836 | long long addr, dway; | |
837 | avl_node_ptr t_ptr; | |
838 | long long cs; | |
839 | unsigned int lowt; | |
840 | unsigned long long tempdata1 = 0; | |
841 | int ecc_index = 0; | |
842 | int t = 0; | |
843 | int shift; | |
844 | ||
845 | shift = tf_getp(4); | |
846 | lowt = (unsigned int)tf_getlongp(&high, 1);//get address | |
847 | addr = high; | |
848 | addr = (unsigned long long) (high & 0xffffffff); | |
849 | addr = addr << 32; | |
850 | addr |= lowt; | |
851 | ||
852 | //io_printf((char *)"(PLI)(%0d) read_dram_call with args(before X8) addr = %llx\n", tf_gettime(),addr); | |
853 | if (mc_scan_plusargs("X8") !=(char *)NULL) { addr = x8_address_decode(addr); } | |
854 | //io_printf((char *)"(PLI)(%0d) read_dram_call with args(after X8) addr = %llx\n", tf_gettime(),addr); | |
855 | addr = pm_address_shift(addr, shift); | |
856 | ||
857 | dway = address_decode(&addr, dimm_config, 0); | |
858 | cs = decode_cs(&addr, dimm_config, 0); | |
859 | ||
860 | dway |= (cs << 32); | |
861 | //io_printf((char *)"(PLI)read_dram: addr = %llx, dway = %llx\n", addr, dway); | |
862 | bank_s = (addr >> 7) & 0x3; | |
863 | bank = bank_s * 32; | |
864 | if((addr & 0x8)== 0x8)bank += 16; | |
865 | t_ptr = (dram_tree)->data ? search_node(&(dram_tree)->data, &dway) : 0; | |
866 | ||
867 | ||
868 | t = (addr >> 3) & 1; | |
869 | if(!t) | |
870 | { | |
871 | tempdata1 = 0; | |
872 | if(t_ptr){ | |
873 | for (i_bank = 13; i_bank >= 0; i_bank--){ | |
874 | tempdata1 <<= 4; | |
875 | tempdata1 |= (t_ptr)->val[0].aval.cval[bank+i_bank] & 0xf; | |
876 | } | |
877 | ecc_index = 128 + bank_s * 4; | |
878 | tempdata1 <<=4; | |
879 | tempdata1 |= (t_ptr)->val[0].aval.cval[ecc_index+3] & 0xf; | |
880 | tempdata1 <<=4; | |
881 | tempdata1 |= (t_ptr)->val[0].aval.cval[ecc_index+2] & 0xf; | |
882 | } // else tempdata1 returned will be zero. | |
883 | } | |
884 | else { | |
885 | tempdata1 = 0; | |
886 | if(t_ptr){ | |
887 | for (i_bank = 15; i_bank >= 0; i_bank--){ | |
888 | tempdata1 <<= 4; | |
889 | tempdata1 |= (t_ptr)->val[0].aval.cval[bank+i_bank] & 0xf; | |
890 | } | |
891 | } // else tempdata1 returned will be zero. | |
892 | } | |
893 | ||
894 | // io_printf((char *)"(PLI)read_dram: tempdata1 = %llx\n", tempdata1); | |
895 | ||
896 | tf_putp(2, tempdata1); | |
897 | tf_putp(3, (tempdata1 >> 32)); | |
898 | } | |
899 | // }}} | |
900 | ||
901 | /*------------------------------------------------------------------- | |
902 | extract memory content from string and store data into memory. {{{ | |
903 | ---------------------------------------------------------------------*/ | |
904 | ||
905 | void store_into_rdram(char *buf, long long *addr, int index, | |
906 | char *d_buf, int *d_ind, int *num_bit, int* l_bit, | |
907 | int *b_ind, char* ecc, int dimm_config, int shift){ | |
908 | long long dway; | |
909 | int bank, i_bank, i, j, l, bank_s; | |
910 | state_node f_val[1]; | |
911 | char pre_xor_ecc[4]; | |
912 | avl_node_ptr t_ptr; | |
913 | char tmp_buf[BUFFER]; | |
914 | long long cs; | |
915 | ||
916 | char ck_tmp_buf[BUFFER]; | |
917 | int start_index_avl, chipkill_index, datafill_index; | |
918 | int t_index = 0; | |
919 | int mcu, ecc_index ; | |
920 | ||
921 | //io_printf ("store_into_rdram with addr %llx, index %x\n", *addr, index); | |
922 | for(j = 0; j < 32; j++) | |
923 | ck_tmp_buf[j] = 0; | |
924 | ||
925 | while((index = remove_leading_space(buf, index, BUFFER)) >= 0){ | |
926 | convert_a2b(buf, &index, d_buf, d_ind, num_bit); | |
927 | ||
928 | dway = address_decode(addr, dimm_config, shift); | |
929 | cs = decode_cs(addr, dimm_config, shift); | |
930 | //io_printf((char *)"(PLI) after decode: addr=%llx, dimm_config=%d, dway=%llx, cs=%d\n",*addr, dimm_config, dway, cs); | |
931 | ||
932 | dway |= (cs << 32); | |
933 | ||
934 | //Partial mode shifting - James | |
935 | bank_s = pm_bank_s(*addr, shift); | |
936 | ||
937 | bank = bank_s * 32; | |
938 | // done with address decoding | |
939 | if (((*b_ind) & 0x1) == 1) bank += 16; | |
940 | (*b_ind)++; | |
941 | (*b_ind) &= 0xf; | |
942 | //get node if exist | |
943 | //io_printf((char *)"(PLI)from init mem: cs is %llx, dway is %llx, bank_s %d, bank %d addr %llx\n", cs, dway, bank_s, bank, *addr); | |
944 | ||
945 | ||
946 | t_ptr = dram_tree->data ? search_node(&(dram_tree)->data, &dway) : 0; | |
947 | if(t_ptr == 0){//new node | |
948 | for(l = 0;l < 144; l++){ | |
949 | f_val[0].aval.cval[l] = 0xff; | |
950 | f_val[0].bval[l] = 0xff; | |
951 | } | |
952 | i_bank = 0; | |
953 | //io_printf((char *)"(PLI) inserting new node at : addr %llx, bank = %d, dway = %llx, d_ind=%d \n", *addr, bank + i_bank, dway, *d_ind); | |
954 | t_index += 16; | |
955 | for (i_bank = 0; i_bank < 16; i_bank++){ | |
956 | if ((*d_ind) <= 0) { | |
957 | //io_printf((char *)"(PLI)WHEN DO WE ENTER THIS BLOCK ?\n"); | |
958 | f_val[0].aval.cval[bank+i_bank] = 0; | |
959 | d_buf[16+(*d_ind)-1] = 0; | |
960 | tmp_buf[15-i_bank] = 0; | |
961 | ck_tmp_buf[t_index-i_bank-1] = 0; | |
962 | // io_printf (" storing node for avl tree at dway = %llx, d_ind=%d, data=%x\n", dway, (*d_ind), d_buf[16+(*d_ind)-1]); | |
963 | } | |
964 | else { | |
965 | f_val[0].aval.cval[bank+i_bank] = d_buf[(*d_ind)-1] & 0xf; | |
966 | tmp_buf[15-i_bank] = d_buf[(*d_ind)-1] & 0xf; | |
967 | ck_tmp_buf[t_index-i_bank-1] = d_buf[(*d_ind)-1] & 0xf; | |
968 | //io_printf (" f_val.cval[%d] = %x = ck_tmp_buf[%d]; bank=%d, i_bank=%d, d_ind=%d, t_index=%d\n",(bank+i_bank), d_buf[(*d_ind)-1], (t_index-i_bank-1), bank, i_bank, *d_ind, t_index); | |
969 | } | |
970 | f_val[0].bval[bank+i_bank] = 0; | |
971 | (*d_ind)--; | |
972 | } | |
973 | d_buf = tmp_buf; | |
974 | insert_avl_node(&(dram_tree)->data, &dway, f_val); | |
975 | } // if t_ptr == 0 | |
976 | else{//node already exist. | |
977 | i_bank = 0; | |
978 | //io_printf((char *)"(PLI) overwriting node at : addr %llx, bank %d , dway = %llx, d_ind=%d\n", *addr, bank + i_bank, dway, *d_ind); | |
979 | t_index += 16; | |
980 | for (i_bank = 0; i_bank < 16; i_bank++){ | |
981 | if ((*d_ind) <= 0) { | |
982 | //io_printf((char *)"(PLI)2 WHEN DO WE ENTER THIS BLOCK ?\n"); | |
983 | t_ptr->val[0].aval.cval[bank+i_bank] = 0; | |
984 | d_buf[16+(*d_ind)-1] = 0; | |
985 | tmp_buf[15-i_bank] = 0; | |
986 | ck_tmp_buf[t_index-i_bank-1] = 0; | |
987 | //io_printf (" overwriting node for avl tree at dway = %llx, d_ind=%d, data=%x\n", dway, (*d_ind), d_buf[16+(*d_ind)-1]); | |
988 | } | |
989 | else { | |
990 | t_ptr->val[0].aval.cval[bank+i_bank] = d_buf[(*d_ind)-1] & 0xf; | |
991 | tmp_buf[15-i_bank] = d_buf[(*d_ind)-1] & 0xf; | |
992 | ck_tmp_buf[t_index-i_bank-1] = d_buf[(*d_ind)-1] & 0xf; | |
993 | //io_printf (" Overwriting t_ptr.cval[%d] = %x = ck_tmp_buf[%d]; bank=%d, i_bank=%d, d_ind=%d, t_index=%d\n",(bank+i_bank), d_buf[(*d_ind)-1], (t_index-i_bank-1), bank, i_bank, *d_ind, t_index); | |
994 | } | |
995 | t_ptr->val[0].bval[bank+i_bank] = 0; | |
996 | (*d_ind)--; | |
997 | } | |
998 | d_buf = tmp_buf; | |
999 | ||
1000 | // printf("\n"); | |
1001 | } | |
1002 | ck_tmp_buf[32] = '\0'; | |
1003 | //for(j = 0; j < 32; j++) | |
1004 | //io_printf((char *)"(PLI) ck_tmp_buf[%d] = %x; ",j, ck_tmp_buf[j]); | |
1005 | ||
1006 | i_bank = ((*addr >> 3) & 1) * 8; | |
1007 | j = 0; | |
1008 | for (i = i_bank; i < i_bank + 8; i++){ | |
1009 | ecc[i] = d_buf[j*2 + 1] | (d_buf[j*2] << 4); | |
1010 | //io_printf((char *)"(PLI) ecc[%d] is %x\n", i, ecc[i]); | |
1011 | j++; | |
1012 | } | |
1013 | //save data here. | |
1014 | if(i == 16) { | |
1015 | t_ptr = search_node(&(dram_tree)->data, &dway); | |
1016 | //io_printf((char *)"(PLI) calling hamming foR data = %16x\n", &ecc); | |
1017 | hamming(ecc, pre_xor_ecc); | |
1018 | //io_printf((char *)"(PLI) calling addr_parity foR ADDR = %llx, pre_xor_ecc =%4x\n", (*addr), &pre_xor_ecc); | |
1019 | addr_parity(pre_xor_ecc, *addr, d_buf, 0, shift); | |
1020 | ||
1021 | if(dimm_config & CHIPKILL){ | |
1022 | ||
1023 | mcu = ((*addr) >> 7) & 0x3; | |
1024 | if(mcu == 0) | |
1025 | chipkill_index = ck_mcu0; | |
1026 | else if(mcu == 1) | |
1027 | chipkill_index = ck_mcu1; | |
1028 | else if(mcu == 2) | |
1029 | chipkill_index = ck_mcu2; | |
1030 | else if(mcu == 3) | |
1031 | chipkill_index = ck_mcu3; | |
1032 | ||
1033 | ||
1034 | t_index = 31; | |
1035 | datafill_index = 0; | |
1036 | for(i_bank = 0; i_bank < 16; i_bank++) { | |
1037 | t_ptr->val[0].aval.cval[bank+i_bank] = ck_tmp_buf[t_index]; | |
1038 | if(datafill_index != chipkill_index) | |
1039 | { | |
1040 | t_index--; | |
1041 | } | |
1042 | datafill_index++; | |
1043 | } | |
1044 | ecc_index = 128 + bank_s * 4; | |
1045 | t_ptr->val[0].aval.cval[ecc_index + 2] = ck_tmp_buf[t_index]; | |
1046 | t_ptr->val[0].bval[ecc_index + 2] = 0; | |
1047 | if(datafill_index != chipkill_index) | |
1048 | { | |
1049 | t_index--; | |
1050 | } | |
1051 | datafill_index++; | |
1052 | t_ptr->val[0].aval.cval[ecc_index + 3] = ck_tmp_buf[t_index] ; | |
1053 | t_ptr->val[0].bval[ecc_index + 3] = 0; | |
1054 | if(datafill_index != chipkill_index) | |
1055 | { | |
1056 | t_index--; | |
1057 | } | |
1058 | datafill_index++; | |
1059 | ||
1060 | bank -= 16; | |
1061 | for(i_bank = 0; i_bank < 14; i_bank++) { | |
1062 | t_ptr->val[0].aval.cval[bank+i_bank] = ck_tmp_buf[t_index]; | |
1063 | if(datafill_index != chipkill_index) | |
1064 | { | |
1065 | t_index--; | |
1066 | } | |
1067 | datafill_index++; | |
1068 | } | |
1069 | t_ptr->val[0].aval.cval[ecc_index + 1] = ck_tmp_buf[t_index] & 0xf; | |
1070 | t_ptr->val[0].bval[ecc_index + 1] = 0; | |
1071 | t_ptr->val[0].aval.cval[ecc_index] = d_buf[1]; | |
1072 | t_ptr->val[0].bval[ecc_index] = 0; | |
1073 | t_ptr->val[0].aval.cval[bank+i_bank] = d_buf[3]; | |
1074 | t_ptr->val[0].aval.cval[bank+i_bank+1] = d_buf[0]; | |
1075 | ||
1076 | t_index = 0; | |
1077 | for(j = 0; j < 32; j++) | |
1078 | ck_tmp_buf[j] = 0; | |
1079 | ||
1080 | //for(l = 0;l < 144; l++){ | |
1081 | // io_printf((char *)"(PLI)cval[%d] = %x, ",l, t_ptr->val[0].aval.cval[l]); | |
1082 | //} | |
1083 | } | |
1084 | else | |
1085 | { | |
1086 | bank -= 16; | |
1087 | start_index_avl = bank; | |
1088 | for (i_bank = 0; i_bank < 14; i_bank++){ | |
1089 | t_ptr->val[0].aval.cval[start_index_avl+i_bank] = ck_tmp_buf[13 - i_bank] & 0xf; | |
1090 | // io_printf (" rewriting node for avl tree at dway = %llx, cval[%d] = %x, ck_tmp_buf[%d]\n", dway, (start_index_avl + i_bank), ck_tmp_buf[13 - i_bank], (13 - i_bank)); | |
1091 | } | |
1092 | t_ptr->val[0].aval.cval[start_index_avl+i_bank] = d_buf[2]; | |
1093 | // io_printf ("rewriting node for avl tree at dway = %llx, cval[%d] = %x \n", dway, (start_index_avl + i_bank), d_buf[2] ); | |
1094 | t_ptr->val[0].aval.cval[start_index_avl+i_bank + 1] = d_buf[3]; | |
1095 | // io_printf ("rewriting node for avl tree at dway = %llx, cval[%d] = %x \n", dway, (start_index_avl + i_bank + 1), d_buf[3] ); | |
1096 | ||
1097 | ecc_index = 128 + bank_s * 4; | |
1098 | t_ptr->val[0].aval.cval[ecc_index + 1] = d_buf[1]; | |
1099 | t_ptr->val[0].bval[ecc_index + 1] = 0; | |
1100 | t_ptr->val[0].aval.cval[ecc_index] = d_buf[0]; | |
1101 | t_ptr->val[0].bval[ecc_index] = 0; | |
1102 | t_ptr->val[0].aval.cval[ecc_index + 2] = ck_tmp_buf[i_bank + 1]; | |
1103 | t_ptr->val[0].bval[ecc_index + 2] = 0; | |
1104 | t_ptr->val[0].aval.cval[ecc_index + 3] = ck_tmp_buf[i_bank] ; | |
1105 | t_ptr->val[0].bval[ecc_index + 3] = 0; | |
1106 | t_index = 0; | |
1107 | for(j = 0; j < 32; j++) | |
1108 | ck_tmp_buf[j] = 0; | |
1109 | ||
1110 | ||
1111 | ||
1112 | } | |
1113 | } | |
1114 | (*addr) += 8;//data[0]-> size / ADDRESS; | |
1115 | *num_bit -= 64; | |
1116 | } | |
1117 | //tf_dofinish(); | |
1118 | } | |
1119 | // }}} | |
1120 | ||
1121 | /*------------------------------------------------------------------- | |
1122 | Write 4 bytes to memory | |
1123 | ---------------------------------------------------------------------*/ | |
1124 | void write_dram_call() { | |
1125 | char buf[BUFFER]; | |
1126 | int high, dlow; | |
1127 | long long addr = 0; | |
1128 | long long data, tempdata; | |
1129 | int index; | |
1130 | char d_buf[BUFFER], ecc[16]; | |
1131 | int d_ind, num_bit, l_bit, b_ind; | |
1132 | unsigned int lowt; | |
1133 | int shift; | |
1134 | ||
1135 | ||
1136 | // for reads | |
1137 | int bank, i_bank, bank_s, t, ecc_index;//address | |
1138 | long long dway; | |
1139 | avl_node_ptr t_ptr; | |
1140 | long long cs; | |
1141 | unsigned long long tempdata1; | |
1142 | ||
1143 | shift = tf_getp(3); | |
1144 | ||
1145 | lowt = (unsigned int)tf_getlongp(&high, 1);//get address | |
1146 | addr = high; | |
1147 | addr = (unsigned long long) (high & 0xffffffff); | |
1148 | addr = addr << 32; | |
1149 | addr |= lowt; | |
1150 | ||
1151 | //io_printf((char *)"(PLI)(%0d) write_dram_call with args(before X8) addr = %llx\n", tf_gettime(),addr); | |
1152 | if (mc_scan_plusargs("X8") !=(char *)NULL) { addr = x8_address_decode(addr); } | |
1153 | //io_printf((char *)"(PLI)(%0d) write_dram_call with args(after X8) addr = %llx\n", tf_gettime(),addr); | |
1154 | addr = pm_address_shift(addr, shift); | |
1155 | ||
1156 | dlow = tf_getlongp(&high, 2); | |
1157 | data = high; | |
1158 | data = (unsigned long long) high << 32; | |
1159 | tempdata = (unsigned) dlow; | |
1160 | data |= (unsigned long long) tempdata; | |
1161 | //io_printf((char *)"(PLI)write_dram: addr = %llx, data = %llx \n",addr,data); | |
1162 | sprintf (buf, "%016llx", data); | |
1163 | ||
1164 | t = (addr >> 3) & 1; | |
1165 | if(t) | |
1166 | { | |
1167 | addr -= 8; | |
1168 | ||
1169 | // Do a read of 64 bits and then write those 64 bits | |
1170 | dway = address_decode(&addr, dimm_config, 0); | |
1171 | cs = decode_cs(&addr, dimm_config, 0); | |
1172 | ||
1173 | dway |= (cs << 32); | |
1174 | bank_s = (addr >> 7) & 0x3; | |
1175 | bank = bank_s * 32; | |
1176 | if((addr & 0x8)== 0x8)bank += 16; | |
1177 | t_ptr = (dram_tree)->data ? search_node(&(dram_tree)->data, &dway) : 0; | |
1178 | tempdata1 = 0; | |
1179 | if(t_ptr){ | |
1180 | for (i_bank = 13; i_bank >= 0; i_bank--){ | |
1181 | tempdata1 <<= 4; | |
1182 | tempdata1 |= (t_ptr)->val[0].aval.cval[bank+i_bank] & 0xf; | |
1183 | } | |
1184 | ecc_index = 128 + bank_s * 4; | |
1185 | tempdata1 <<=4; | |
1186 | tempdata1 |= (t_ptr)->val[0].aval.cval[ecc_index+3] & 0xf; | |
1187 | tempdata1 <<=4; | |
1188 | tempdata1 |= (t_ptr)->val[0].aval.cval[ecc_index+2] & 0xf; | |
1189 | } // else tempdata1 returned will be zero. | |
1190 | ||
1191 | sprintf(buf, "%016llx %016llx", tempdata1, data); | |
1192 | d_ind = 0;num_bit = 0;l_bit = 0; | |
1193 | //b_ind = low >> 3;//initial | |
1194 | index = 0; | |
1195 | sprintf(ecc, "%d", index); | |
1196 | ||
1197 | ||
1198 | } | |
1199 | ||
1200 | if(!t) | |
1201 | { | |
1202 | addr += 8; | |
1203 | // Do a read of 64 bits | |
1204 | dway = address_decode(&addr, dimm_config, 0); | |
1205 | cs = decode_cs(&addr, dimm_config, 0); | |
1206 | ||
1207 | dway |= (cs << 32); | |
1208 | bank_s = (addr >> 7) & 0x3; | |
1209 | bank = bank_s * 32; | |
1210 | if((addr & 0x8)== 0x8)bank += 16; | |
1211 | t_ptr = (dram_tree)->data ? search_node(&(dram_tree)->data, &dway) : 0; | |
1212 | tempdata1 = 0; | |
1213 | if(t_ptr){ | |
1214 | for (i_bank = 15; i_bank >= 0; i_bank--){ | |
1215 | tempdata1 <<= 4; | |
1216 | tempdata1 |= (t_ptr)->val[0].aval.cval[bank+i_bank] & 0xf; | |
1217 | } | |
1218 | } // else tempdata1 returned will be zero. | |
1219 | ||
1220 | sprintf(buf, "%016llx %016llx", data, tempdata1); | |
1221 | sprintf(ecc, "%d", index); | |
1222 | addr -= 8; | |
1223 | } | |
1224 | d_ind = 0;num_bit = 0;l_bit = 0; | |
1225 | b_ind = addr >> 3;//initial | |
1226 | index = 0; | |
1227 | store_into_rdram (buf, &addr, index, d_buf, &d_ind, &num_bit, &l_bit, &b_ind, ecc, dimm_config, 0); | |
1228 | ||
1229 | } | |
1230 | // }}} | |
1231 | ||
1232 | /*------------------------------------------------------------------- | |
1233 | read mem.image and build memory. {{{ | |
1234 | ---------------------------------------------------------------------*/ | |
1235 | void padding(char* buf, int index) | |
1236 | { | |
1237 | int num, ind; | |
1238 | ind = index; | |
1239 | num = 0; | |
1240 | while(num < 64){ | |
1241 | if(buf[ind] == ' '){ | |
1242 | ind++; | |
1243 | continue; | |
1244 | } | |
1245 | if((buf[ind] == '\n') || (buf[ind] == '\0')){ | |
1246 | break; | |
1247 | } | |
1248 | ind++; | |
1249 | num++; | |
1250 | } | |
1251 | if(num < 64){//do padding | |
1252 | ind--; | |
1253 | if(buf[ind] != ' ')ind++; | |
1254 | while(num < 64){ | |
1255 | if((num % 16) == 0){ | |
1256 | buf[ind] = ' '; | |
1257 | ind++; | |
1258 | } | |
1259 | buf[ind] = '0'; | |
1260 | ind++; | |
1261 | num++; | |
1262 | } | |
1263 | buf[ind] = '\n'; | |
1264 | } | |
1265 | } | |
1266 | // }}} | |
1267 | ||
1268 | /*------------------------------------------------------------------- | |
1269 | check the address range based on dram config. {{{ | |
1270 | ---------------------------------------------------------------------*/ | |
1271 | int check_address_range(long long addr, int dimm_config, int shift) | |
1272 | { | |
1273 | if(check_if_valid_PA(addr, dimm_config, shift) < 0) | |
1274 | return 1; | |
1275 | ||
1276 | return 0; | |
1277 | } | |
1278 | // }}} | |
1279 | ||
1280 | /*------------------------------------------------------------------ | |
1281 | read mem.image and build memory. {{{ | |
1282 | --------------------------------------------------------------------*/ | |
1283 | void build_rdram(FILE *fp, int dimm_config, int shift){ | |
1284 | long long addr, tmp_addr; | |
1285 | char buf[BUFFER], d_buf[BUFFER], ecc[16]; | |
1286 | int index, d_ind, num_bit, l_bit, b_ind; | |
1287 | int skip_data = 0; | |
1288 | ||
1289 | addr = 0;d_ind = 0;num_bit = 0;l_bit = 0;b_ind = 0;//initial | |
1290 | ||
1291 | while(fgets(buf, BUFFER, fp)){ | |
1292 | index = remove_leading_space(buf, 0, BUFFER); | |
1293 | if(index < 0 || strncmp (buf, "//", 2) == 0)continue;//empty string | |
1294 | if(check_at_symbol(buf, &addr)){//get address | |
1295 | tmp_addr = addr; | |
1296 | skip_data = check_address_range(addr, dimm_config, shift); | |
1297 | mask_value(dram_tree->addr, &addr); | |
1298 | d_ind = 0;num_bit = 0;l_bit = 0; | |
1299 | b_ind = 0; | |
1300 | continue; | |
1301 | } | |
1302 | if(skip_data == 1) continue;//skip data part for invalid PA | |
1303 | padding(buf, index); | |
1304 | //io_printf((char *)"(PLI) check_at_symbol:store_into_rdram. buf=%s, tmp_addr=%llx, addr=%llx, index=%d, d_buf=%s, ecc=%s, dimm_config=%d",buf, tmp_addr, addr, index, d_buf, ecc, dimm_config); | |
1305 | store_into_rdram(buf, &addr, index, d_buf, &d_ind, &num_bit, &l_bit, &b_ind, ecc, dimm_config, shift); | |
1306 | } | |
1307 | } | |
1308 | //}}} | |
1309 | ||
1310 | ||
1311 | /*-------------------------------------------------------------------- | |
1312 | initialize dram. {{{ | |
1313 | ----------------------------------------------------------------------*/ | |
1314 | void init_dram_call(){ | |
1315 | char *str; | |
1316 | FILE *fp; | |
1317 | //allocate top tree. | |
1318 | dram_tree = (avl_conf_ptr)malloc(sizeof(struct avl_conf_node)); | |
1319 | if(dram_tree == null) | |
1320 | { | |
1321 | io_printf((char *)"(PLI)ERROR : Unable to allocate memory in $init_dram\n"); | |
1322 | tf_dofinish(); | |
1323 | } | |
1324 | print_dimm(); | |
1325 | if (mc_scan_plusargs("X8") !=(char *)NULL) { | |
1326 | io_printf((char *)"(PLI)(%0d) X8 inside init_dram_call...\n",tf_gettime()); | |
1327 | if ( (mc_scan_plusargs("DIMM_SIZE_2G") !=(char *)NULL) || | |
1328 | ( (mc_scan_plusargs("DIMM_SIZE_1G") == (char *)NULL) && | |
1329 | (mc_scan_plusargs("DIMM_SIZE_512") == (char *)NULL) && | |
1330 | (mc_scan_plusargs("DIMM_SIZE_256") == (char *)NULL) ) ) { | |
1331 | io_printf((char *)"(PLI)\n\n\n\t*** CANNOT run X8 mode with DIMM size of 2G!***\n\n\n"); | |
1332 | tf_dofinish(); | |
1333 | } | |
1334 | } | |
1335 | else { | |
1336 | io_printf((char *)"(PLI)(%0d) X4 inside init_dram_call...\n",tf_gettime()); | |
1337 | } | |
1338 | ||
1339 | dram_tree->addr = 40;//address size; | |
1340 | dram_tree->size = 4;//tf_getp(2);//get data width | |
1341 | dram_tree->word = dram_tree->size / 32; | |
1342 | dram_tree->dram = 0;//dram | |
1343 | if((dram_tree->size % 32) != 0)dram_tree->word++; | |
1344 | //pointer for avl tree set NULL | |
1345 | dram_tree->data = 0; | |
1346 | str = tf_getcstringp(1); // get a file name. | |
1347 | dimm_config = tf_getp(2);//get dram config | |
1348 | ck_mcu0 = tf_getp(3); | |
1349 | ck_mcu1 = tf_getp(4); | |
1350 | ck_mcu2 = tf_getp(5); | |
1351 | ck_mcu3 = tf_getp(6); | |
1352 | shift = tf_getp(7); | |
1353 | ||
1354 | //io_printf((char *)"(PLI)Info: reading %s in init_dram_call\n", str); | |
1355 | //io_printf((char *)"(PLI)Info: dimm_config = %d, str = %s, dram_tree->word = %d", dimm_config, str, dram_tree->word); | |
1356 | ||
1357 | if((fp = fopen(str, "r")) == 0){ | |
1358 | tf_error((char *)"Error: $init_dram can not open file %s for reading\n", str); | |
1359 | tf_dofinish(); | |
1360 | } | |
1361 | build_rdram(fp, dimm_config, shift); | |
1362 | fclose(fp); | |
1363 | //slam value if not specified, randomly initialize. | |
1364 | str = mc_scan_plusargs ("slam_init_value"); | |
1365 | slam_val = 0; | |
1366 | if(str != (char *) 0)slam_val = 1; | |
1367 | //io_printf((char *)"(PLI)Info: exiting init_dram_call\n"); | |
1368 | //tf_dofinish(); | |
1369 | } | |
1370 | //}}} | |
1371 | ||
1372 | ||
1373 | // void in_order_call(){ | |
1374 | // FILE* fp; | |
1375 | // avl_conf_ptr handle; | |
1376 | // int shft; | |
1377 | // char *str; | |
1378 | // | |
1379 | // if(tf_nump() < 2){ | |
1380 | // io_printf((char *)"(PLI)arg %d\n", tf_nump()); | |
1381 | // tf_error((char *)"$in_order call requires at least two arguments(address, datawidth)."); | |
1382 | // tf_dofinish(); | |
1383 | // } | |
1384 | // shft = -1; | |
1385 | // if(tf_nump() > 2){ | |
1386 | // shft = tf_getp(3); | |
1387 | // } | |
1388 | // str = tf_getcstringp(2); | |
1389 | // if((fp = fopen(str, "w")) == 0){ | |
1390 | // tf_error((char *)"Error: $in_order can not open file %s for writing\n", str); | |
1391 | // tf_dofinish(); | |
1392 | // } | |
1393 | // else{ | |
1394 | // handle = (avl_conf_ptr) tf_getp(1); | |
1395 | // in_order(&(handle)->data, fp, &shft, &(handle)->size); | |
1396 | // fclose(fp); | |
1397 | // } | |
1398 | // } | |
1399 | // // }}} | |
1400 | // | |
1401 | // /*------------------------------------------------------------------- | |
1402 | // dump verilog instance contents. {{{ | |
1403 | // --------------------------------------------------------------------*/ | |
1404 | // void v_set_delay_call(){ | |
1405 | // handle hand; | |
1406 | // double rise, fall, toz; | |
1407 | // acc_initialize(); | |
1408 | // acc_configure(accPathDelayCount, (char *)"3"); | |
1409 | // | |
1410 | // hand = acc_handle_by_name(tf_getcstringp(1), 0); | |
1411 | // switch(acc_fetch_delay_mode(hand)){ | |
1412 | // case accDelayModeNone : io_printf((char *)"(PLI)none\n");break; | |
1413 | // case accDelayModePath : io_printf((char *)"(PLI)path\n"); | |
1414 | // } | |
1415 | // acc_replace_delays(hand, rise, fall, toz); | |
1416 | // acc_close(); | |
1417 | // } | |
1418 | // // }}} | |
1419 | // | |
1420 | // /*------------------------------------------------------------------- | |
1421 | // dump verilog instance contents. {{{ | |
1422 | // ---------------------------------------------------------------------*/ | |
1423 | // void v_force_call(){ | |
1424 | // | |
1425 | // handle hand; | |
1426 | // s_setval_value valStruct; | |
1427 | // s_setval_delay delStruct; | |
1428 | // s_acc_time timStruct; | |
1429 | // | |
1430 | // acc_initialize(); | |
1431 | // hand = acc_handle_by_name(tf_getcstringp(1), 0); | |
1432 | // if(!hand){ | |
1433 | // io_printf((char *)"(PLI)%0d : Info: Object not found %s\n", tf_gettime(), tf_getcstringp(1)); | |
1434 | // acc_close(); | |
1435 | // return; | |
1436 | // } | |
1437 | // valStruct.format = accBinStrVal; | |
1438 | // valStruct.value.str = (char*)malloc(acc_fetch_size(hand)); | |
1439 | // strcpy(valStruct.value.str, tf_getcstringp(2)); | |
1440 | // | |
1441 | // switch(acc_fetch_type(hand)){ | |
1442 | // case accNet : | |
1443 | // delStruct.model = accForceFlag; | |
1444 | // break; | |
1445 | // case accRegister : | |
1446 | // timStruct.type = accTime; | |
1447 | // timStruct.low = 5; | |
1448 | // timStruct.high = 0; | |
1449 | // delStruct.time = timStruct; | |
1450 | // delStruct.model = accInertialDelay; | |
1451 | // } | |
1452 | // acc_set_value(hand, &valStruct, &delStruct); | |
1453 | // acc_close(); | |
1454 | // } | |
1455 | // // }}} | |
1456 | // | |
1457 | // /*------------------------------------------------------------------- | |
1458 | // dump verilog instance contents. {{{ | |
1459 | // ---------------------------------------------------------------------*/ | |
1460 | // void v_dump_call(){ | |
1461 | // handle hand; | |
1462 | // int v_size, msb, lsb; | |
1463 | // acc_initialize(); | |
1464 | // hand = acc_handle_by_name(tf_getcstringp(1), 0); | |
1465 | // if(!hand){ | |
1466 | // io_printf((char *)"(PLI)%0d : Info: Object not found %s\n", tf_gettime(), tf_getcstringp(1)); | |
1467 | // acc_close(); | |
1468 | // return; | |
1469 | // } | |
1470 | // switch(acc_fetch_type(hand)){ | |
1471 | // case accRegister: | |
1472 | // io_printf((char *)"(PLI)%0d : Info -> %s = 0x%s\n", tf_gettime(), tf_getcstringp(1), | |
1473 | // acc_fetch_value(hand, (char *)"%h", 0)); | |
1474 | // break; | |
1475 | // case accNet : | |
1476 | // io_printf((char *)"(PLI)%0d : Info -> %s = 0x%s\n", tf_gettime(), tf_getcstringp(1), | |
1477 | // acc_fetch_value(hand, (char *)"%h", 0)); | |
1478 | // break; | |
1479 | // default : | |
1480 | // v_size = acc_fetch_size(hand); | |
1481 | // acc_fetch_range(hand, &msb, &lsb); | |
1482 | // io_printf((char *)"(PLI)SIZE %d %d %d\n", v_size, msb, lsb); | |
1483 | // } | |
1484 | // acc_close(); | |
1485 | // } | |
1486 | // // }}} | |
1487 | // | |
1488 | // /*------------------------------------------------------------------- | |
1489 | // initialize memory. {{{ | |
1490 | // ---------------------------------------------------------------------*/ | |
1491 | // void warm_specified(int val, int size, int arg_loc){ | |
1492 | // char* avalPtr, *bvalPtr; | |
1493 | // int word, ind, groups; | |
1494 | // s_tfnodeinfo node_info; | |
1495 | // | |
1496 | // ind = 0; | |
1497 | // tf_nodeinfo(arg_loc, &node_info); | |
1498 | // switch(node_info.node_type){ | |
1499 | // case TF_MEMORY_NODE : | |
1500 | // if(size > node_info.node_mem_size)return; | |
1501 | // word = node_info.node_ngroups * 2; | |
1502 | // avalPtr = node_info.node_value.memoryval_p + size * word; | |
1503 | // bvalPtr = avalPtr + node_info.node_ngroups; | |
1504 | // for(groups = node_info.node_ngroups - 1; groups >= 0;groups--){ | |
1505 | // avalPtr[groups] = val & 0xff; | |
1506 | // bvalPtr[groups] = 0; | |
1507 | // ind++; | |
1508 | // } | |
1509 | // break; | |
1510 | // case TF_REG_NODE : | |
1511 | // for(groups = 0; groups < node_info.node_ngroups ; groups++){ | |
1512 | // node_info.node_value.vecval_p[groups].avalbits = val & 0xff; | |
1513 | // node_info.node_value.vecval_p[groups].bvalbits = 0; | |
1514 | // } | |
1515 | // tf_propagatep(arg_loc); | |
1516 | // break; | |
1517 | // case TF_NETVECTOR_NODE : | |
1518 | // for(groups = 0; groups < node_info.node_ngroups ; groups++){ | |
1519 | // node_info.node_value.vecval_p[groups].avalbits = val & 0xff; | |
1520 | // node_info.node_value.vecval_p[groups].bvalbits = 0; | |
1521 | // } | |
1522 | // tf_propagatep(arg_loc); | |
1523 | // break; | |
1524 | // } | |
1525 | // } | |
1526 | // // }}} | |
1527 | // | |
1528 | // /*------------------------------------------------------------------- | |
1529 | // dump verilog instance contents. {{{ | |
1530 | // ---------------------------------------------------------------------*/ | |
1531 | // void slam_mem_call(){ | |
1532 | // FILE *fp; | |
1533 | // char *str; | |
1534 | // int val, addr; | |
1535 | // | |
1536 | // str = tf_getcstringp(1); // a get file name. | |
1537 | // if((fp = fopen(str, "r")) == 0){ | |
1538 | // io_printf((char *)"(PLI)Warning -> SPD not set(File not Found %s)\n", str); | |
1539 | // return; | |
1540 | // } | |
1541 | // while(fscanf(fp, "%x %x", &addr, &val) != EOF)warm_specified(val & 0xff, addr & 0xff, 2); | |
1542 | // fclose(fp); | |
1543 | // } | |
1544 | // // }}} | |
1545 | // | |
1546 | // /*------------------------------------------------------------------- | |
1547 | // syndrome for irf and frf. {{{ | |
1548 | // --------------------------------------------------------------------*/ | |
1549 | // char syndrome(char* data, int fl) | |
1550 | // { | |
1551 | // int i, j, ind; | |
1552 | // char bits [64], ch, byte[8]; | |
1553 | // int num = fl ? 4 : 8; | |
1554 | // ind = 0; | |
1555 | // | |
1556 | // for(i = num - 1 ; i >= 0;i--){ | |
1557 | // ch = data[i]; | |
1558 | // for(j = 0; j < 8;j++){ | |
1559 | // bits[ind] = ch & 1; | |
1560 | // ind++; | |
1561 | // ch >>= 1; | |
1562 | // } | |
1563 | // } | |
1564 | // | |
1565 | // if(fl){ | |
1566 | // byte[0] = bits[0] ^ bits[1] ^ bits[3] ^ bits[4] ^ bits[6] ^ | |
1567 | // bits[8] ^ bits[10] ^ bits[11] ^ bits[13] ^ bits[15] ^ | |
1568 | // bits[17] ^ bits[19] ^ bits[21] ^ bits[23] ^ bits[25] ^ | |
1569 | // bits[26] ^ bits[28] ^ bits[30]; | |
1570 | // | |
1571 | // byte[1] = bits[0] ^ bits[2] ^ bits[3] ^ bits[5] ^ bits[6] ^ | |
1572 | // bits[9] ^ bits[10] ^ bits[12] ^ bits[13] ^ bits[16] ^ | |
1573 | // bits[17] ^ bits[20] ^ bits[21] ^ bits[24] ^ bits[25] ^ | |
1574 | // bits[27] ^ bits[28] ^ bits[31]; | |
1575 | // | |
1576 | // byte[2] = bits[1] ^ bits[2] ^ bits[3] ^ bits[7] ^ bits[8] ^ | |
1577 | // bits[9] ^ bits[10] ^ bits[14] ^ bits[15] ^ bits[16] ^ | |
1578 | // bits[17] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25] ^ | |
1579 | // bits[29] ^ bits[30] ^ bits[31]; | |
1580 | // | |
1581 | // byte[3] = bits[4] ^ bits[5] ^ bits[6] ^ bits[7] ^ bits[8] ^ | |
1582 | // bits[9] ^ bits[10] ^ bits[18] ^ bits[19] ^ bits[20] ^ | |
1583 | // bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25]; | |
1584 | // | |
1585 | // byte[4] = bits[11] ^ bits[12] ^ bits[13] ^ bits[14] ^ bits[15] ^ | |
1586 | // bits[16] ^ bits[17] ^ bits[18] ^ bits[19] ^ bits[20] ^ | |
1587 | // bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25]; | |
1588 | // | |
1589 | // byte[5] = bits[26] ^ bits[27] ^ bits[28] ^ bits[29] ^ bits[30] ^ | |
1590 | // bits[31]; | |
1591 | // | |
1592 | // byte[6] = bits[0] ^ bits[1] ^ bits[2] ^ bits[4] ^ bits[5] ^ | |
1593 | // bits[7] ^ bits[10] ^ bits[11] ^ bits[12] ^ bits[14] ^ | |
1594 | // bits[17] ^ bits[18] ^ bits[21] ^ bits[23] ^ bits[24] ^ | |
1595 | // bits[26] ^ bits[27] ^ bits[29]; | |
1596 | // ch = 0; | |
1597 | // byte[1] <<= 1;byte[2] <<= 2;byte[3] <<= 3; | |
1598 | // byte[4] <<= 4;byte[5] <<= 5;byte[6] <<= 6; | |
1599 | // for(i = 0; i < 7; i++)ch |= byte[i]; | |
1600 | // } | |
1601 | // else { | |
1602 | // byte[0] = bits[0] ^ bits[1] ^ bits[3] ^ bits[4] ^ bits[6] ^ bits[8] ^ bits[10] ^ | |
1603 | // bits[11] ^ bits[13] ^ bits[15] ^ bits[17] ^ bits[19] ^ bits[21] ^ bits[23] ^ | |
1604 | // bits[25] ^ bits[26] ^ bits[28] ^ bits[30] ^ bits[32] ^ bits[34] ^ bits[36] ^ | |
1605 | // bits[38] ^ bits[40] ^ bits[42] ^ bits[44] ^ bits[46] ^ bits[48] ^ bits[50] ^ | |
1606 | // bits[52] ^ bits[54] ^ bits[56] ^ bits[57] ^ bits[59] ^ bits[61] ^ bits[63]; | |
1607 | // | |
1608 | // byte[1] = bits[0] ^ bits[2] ^ bits[3] ^ bits[5] ^ bits[6] ^ bits[9] ^ bits[10] ^ | |
1609 | // bits[12] ^ bits[13] ^ bits[16] ^ bits[17] ^ bits[20] ^ bits[21] ^ bits[24] ^ | |
1610 | // bits[25] ^ bits[27] ^ bits[28] ^ bits[31] ^ bits[32] ^ bits[35] ^ bits[36] ^ | |
1611 | // bits[39] ^ bits[40] ^ bits[43] ^ bits[44] ^ bits[47] ^ bits[48] ^ bits[51] ^ | |
1612 | // bits[52] ^ bits[55] ^ bits[56] ^ bits[58] ^ bits[59] ^ bits[62] ^ bits[63]; | |
1613 | // | |
1614 | // byte[2] = bits[1] ^ bits[2] ^ bits[3] ^ bits[7] ^ bits[8] ^ bits[9] ^ bits[10] ^ | |
1615 | // bits[14] ^ bits[15] ^ bits[16] ^ bits[17] ^ bits[22] ^ bits[23] ^ bits[24] ^ | |
1616 | // bits[25] ^ bits[29] ^ bits[30] ^ bits[31] ^ bits[32] ^ bits[37] ^ bits[38] ^ | |
1617 | // bits[39] ^ bits[40] ^ bits[45] ^ bits[46] ^ bits[47] ^ bits[48] ^ bits[53] ^ | |
1618 | // bits[54] ^ bits[55] ^ bits[56] ^ bits[60] ^ bits[61] ^ bits[62] ^ bits[63]; | |
1619 | // | |
1620 | // byte[3] = bits[4] ^ bits[5] ^ bits[6] ^ bits[7] ^ bits[8] ^ bits[9] ^ bits[10] ^ | |
1621 | // bits[18] ^ bits[19] ^ bits[20] ^ bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^ | |
1622 | // bits[25] ^ bits[33] ^ bits[34] ^ bits[35] ^ bits[36] ^ bits[37] ^ bits[38] ^ | |
1623 | // bits[39] ^ bits[40] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^ bits[53] ^ | |
1624 | // bits[54] ^ bits[55] ^ bits[56]; | |
1625 | // | |
1626 | // byte[4] = bits[11] ^ bits[12] ^ bits[13] ^ bits[14] ^ bits[15] ^ bits[16] ^ | |
1627 | // bits[17] ^ bits[18] ^ bits[19] ^ bits[20] ^ bits[21] ^ bits[22] ^ bits[23] ^ | |
1628 | // bits[24] ^ bits[25] ^ bits[41] ^ bits[42] ^ bits[43] ^ bits[44] ^ bits[45] ^ | |
1629 | // bits[46] ^ bits[47] ^ bits[48] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^ | |
1630 | // bits[53] ^ bits[54] ^ bits[55] ^ bits[56]; | |
1631 | // | |
1632 | // byte[5] = bits[26] ^ bits[27] ^ bits[28] ^ bits[29] ^ bits[30] ^ bits[31] ^ | |
1633 | // bits[32] ^ bits[33] ^ bits[34] ^ bits[35] ^ bits[36] ^ bits[37] ^ bits[38] ^ | |
1634 | // bits[39] ^ bits[40] ^ bits[41] ^ bits[42] ^ bits[43] ^ bits[44] ^ bits[45] ^ | |
1635 | // bits[46] ^ bits[47] ^ bits[48] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^ | |
1636 | // bits[53] ^ bits[54] ^ bits[55] ^ bits[56]; | |
1637 | // | |
1638 | // byte[6] = bits[57] ^ bits[58] ^ bits[59] ^ bits[60] ^ bits[61] ^ bits[62] ^ bits[63]; | |
1639 | // | |
1640 | // byte[7] = bits[0] ^ bits[1] ^ bits[2] ^ bits[4] ^ bits[5] ^ bits[7] ^ bits[10] ^ bits[11] ^ | |
1641 | // bits[12] ^ bits[14] ^ bits[17] ^ bits[18] ^ bits[21] ^ bits[23] ^ bits[24] ^ bits[26] ^ | |
1642 | // bits[27] ^ bits[29] ^ bits[32] ^ bits[33] ^ bits[36] ^ bits[38] ^ bits[39] ^ bits[41] ^ | |
1643 | // bits[44] ^ bits[46] ^ bits[47] ^ bits[50] ^ bits[51] ^ bits[53] ^ bits[56] ^ bits[57] ^ | |
1644 | // bits[58] ^ bits[60] ^ bits[63]; | |
1645 | // ch = 0; | |
1646 | // byte[1] <<= 1;byte[2] <<= 2;byte[3] <<= 3; | |
1647 | // byte[4] <<= 4;byte[5] <<= 5;byte[6] <<= 6;byte[7] <<= 7; | |
1648 | // for(i = 0; i < 8; i++)ch |= byte[i]; | |
1649 | // } | |
1650 | // return ch; | |
1651 | // } | |
1652 | // // }}} | |
1653 | // | |
1654 | // void slam_random_call() { | |
1655 | // int size, num, word, groups, fl, ind, val, rnd; | |
1656 | // char* avalPtr, *bvalPtr, ch; | |
1657 | // char data[8]; | |
1658 | // char *pargs; | |
1659 | // s_tfnodeinfo node_info; | |
1660 | // tf_nodeinfo(1, &node_info); | |
1661 | // | |
1662 | // pargs = mc_scan_plusargs ("slam_value="); | |
1663 | // rnd = 1; | |
1664 | // if(pargs != (char *) 0) { | |
1665 | // val = atoi (pargs); | |
1666 | // rnd = 0; | |
1667 | // } | |
1668 | // | |
1669 | // num = tf_getp(2); | |
1670 | // fl = tf_getp(3); | |
1671 | // word = node_info.node_ngroups * 2; | |
1672 | // for(size = 0;size < num;size++){ | |
1673 | // avalPtr = node_info.node_value.memoryval_p + size * word; | |
1674 | // bvalPtr = avalPtr + node_info.node_ngroups; | |
1675 | // ind = fl ? 3 : 7; | |
1676 | // for(groups = 0; groups < node_info.node_ngroups; groups++){ | |
1677 | // if(ind < 0){ | |
1678 | // ch = syndrome(data, fl); | |
1679 | // avalPtr[groups] = ch & 0xff; | |
1680 | // bvalPtr[groups] = 0; | |
1681 | // continue; | |
1682 | // } | |
1683 | // ch = rnd ? random() & 0xff : val; | |
1684 | // avalPtr[groups] = ch; | |
1685 | // bvalPtr[groups] = 0; | |
1686 | // data[ind] = ch; | |
1687 | // ind--; | |
1688 | // } | |
1689 | // } | |
1690 | // } | |
1691 | ||
1692 | #ifdef NCV | |
1693 | int mem_size() { return(32); } | |
1694 | #else | |
1695 | #endif |