Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / infineon / c / src / mem.c
CommitLineData
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
61static int slam_val;
62static int dimm_config;
63static avl_conf_ptr dram_tree;
64static unsigned int ck_mcu0;
65static unsigned int ck_mcu1;
66static unsigned int ck_mcu2;
67static unsigned int ck_mcu3;
68static int shift;
69
70//function prototypes
71avl_node_ptr search_node(avl_node_ptr *t_ptr, long long *addr);
72long long pm_address_shift(long long addr, int shift);
73long long fc_hash_pa(long long addr, int dimm_config);
74long long decode_cs(long long *addr, int dimm_config, int shift);
75long long address_decode(long long *addr, int dimm_config, int shift);
76int pm_bank_s(long long addr, int shift);
77int check_if_valid_PA(long long addr, int dimm_config, int shift);
78
79/*-------------------------------------------------------------------
80 create ecc data. {{{
81---------------------------------------------------------------------*/
82void 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----------------------------------------------------------------------*/
215void 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---------------------------------------------------------------------*/
279int 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---------------------------------------------------------------------*/
329avl_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---------------------------------------------------------------------*/
494long 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---------------------------------------------------------------------*/
536void 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---------------------------------------------------------------------*/
683void 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---------------------------------------------------------------------*/
834void 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
905void 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/*-------------------------------------------------------------------
1122Write 4 bytes to memory
1123---------------------------------------------------------------------*/
1124void write_dram_call() {
1125char buf[BUFFER];
1126int high, dlow;
1127long long addr = 0;
1128long long data, tempdata;
1129int index;
1130char d_buf[BUFFER], ecc[16];
1131int d_ind, num_bit, l_bit, b_ind;
1132unsigned int lowt;
1133int shift;
1134
1135
1136// for reads
1137int bank, i_bank, bank_s, t, ecc_index;//address
1138long long dway;
1139avl_node_ptr t_ptr;
1140long long cs;
1141unsigned 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---------------------------------------------------------------------*/
1235void 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---------------------------------------------------------------------*/
1271int 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--------------------------------------------------------------------*/
1283void 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----------------------------------------------------------------------*/
1314void 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
1693int mem_size() { return(32); }
1694#else
1695#endif