* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: mem.c
* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For the avoidance of doubt, and except that if any non-GPL license
* choice is available it will apply instead, Sun elects to use only
* the General Public License version 2 (GPLv2) at this time for any
* software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later version
* may be used, or where a choice of which version of the GPL is applied is
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* ========== Copyright Header End ============================================
#define DUAL_CHANNEL 0x100
#define SNG_CHANNEL 0x200
#define STACK_DIMM 0x1000
#define PARTIAL_BANK_2BK 0x20000
#define PARTIAL_BANK_4BK 0x40000
static avl_conf_ptr dram_tree
;
static unsigned int ck_mcu0
;
static unsigned int ck_mcu1
;
static unsigned int ck_mcu2
;
static unsigned int ck_mcu3
;
avl_node_ptr
search_node(avl_node_ptr
*t_ptr
, long long *addr
);
long long pm_address_shift(long long addr
, int shift
);
long long fc_hash_pa(long long addr
, int dimm_config
);
long long decode_cs(long long *addr
, int dimm_config
, int shift
);
long long address_decode(long long *addr
, int dimm_config
, int shift
);
int pm_bank_s(long long addr
, int shift
);
int check_if_valid_PA(long long addr
, int dimm_config
, int shift
);
/*-------------------------------------------------------------------
---------------------------------------------------------------------*/
int count
, multc
, tmpicount
, multresult
, mult_count
, tmpcount
,
divresult
, divc
, upper_test
, parity1
, parity2
, parity3
, parity4
;
primitive
= 0x13;//0b010011;
primitive = 0x11d;//0b0100011101;
for (count = 0; count < 16; count++) {
for (multc = 0; multc < 8; multc++) {
tmpicount = ((word[count] >> multc) & 1);
multresult = multresult ^ ((count + 1) << multc);
for (divc = 0; divc < 8; divc++) {
upper_test = divresult & 0xff00;//0b1111_1111_1111_0000_0000;
tmpicount = ((divresult >> (15 - divc)) & 1);
divresult = divresult ^ (primitive << (7 - divc));
parity0 = parity0 ^ divresult;
for (count = 0; count < 16; count++) {
parity1 = parity1 ^ (word[count] & 0xff);
ecc[1] = (parity0 >> 4 ) & 0xf;
ecc[0] = (parity0) & 0xf;
ecc[3] = (parity1 >> 4 ) & 0xf;
ecc[2] = (parity1) & 0xf;
for (count
= 0; count
< 16; count
++) {
hword
[31 - count
*2-1] = word
[count
] & 0xf;
hword
[31 - count
*2] = (word
[count
] >> 4) & 0xf;
for (count
= 0; count
!= 32; count
++) {
for (multc
= 0; multc
!= 4; multc
++) {
tmpicount
= ((hword
[count
] >> multc
) & 1);
multresult
= multresult
^ ((mult_count
+ 1) << multc
);
for (divc
= 0; divc
!= 4; divc
++) {
upper_test
= divresult
& 0xffff0; //0b1111_1111_1111_1111_0000;
tmpcount
= ((divresult
>> (7 - divc
)) & 1);
divresult
= divresult
^ (primitive
<< (3 - divc
));
parity1
= parity1
^ divresult
;
for (count
= 0; count
!= 15; count
++) {
parity2
= parity2
^ hword
[count
];
parity2
= parity2
^ hword
[30] ^ hword
[31];
for (count
= 15; count
!= 32; count
++) {
parity3
= parity3
^ hword
[count
];
for (count
= 0; count
!= 31; count
++) {
if (count
== 0 || count
== 15 || count
== 30 ) { mult_count
= 0; }
if (count
== 1 || count
== 16) { mult_count
= 8; }
if (count
== 2 || count
== 17) { mult_count
= 13; }
if (count
== 3 || count
== 18) { mult_count
= 12; }
if (count
== 4 || count
== 19) { mult_count
= 10; }
if (count
== 5 || count
== 20) { mult_count
= 6; }
if (count
== 6 || count
== 21) { mult_count
= 5; }
if (count
== 7 || count
== 22) { mult_count
= 14; }
if (count
== 8 || count
== 23) { mult_count
= 1; }
if (count
== 9 || count
== 24) { mult_count
= 11; }
if (count
== 10 || count
== 25) { mult_count
= 4; }
if (count
== 11 || count
== 26) { mult_count
= 9; }
if (count
== 12 || count
== 27) { mult_count
= 3; }
if (count
== 13 || count
== 28) { mult_count
= 2; }
if (count
== 14 || count
== 29) { mult_count
= 7; }
for (multc
= 0; multc
!= 4; multc
++) {
tmpicount
= ((hword
[count
] >> multc
) & 1);
multresult
= multresult
^ ((mult_count
+ 1) << multc
);
for (divc
= 0; divc
!= 4; divc
++) {
upper_test
= divresult
& 0xffff0; //0b11111111111111110000;
tmpcount
= ((divresult
>> (7 - divc
)) & 1);
divresult
= divresult
^ (primitive
<< (3 - divc
));
parity4
= parity4
^ divresult
;
ecc
[1] = (parity1
) & 0xf;
ecc
[0] = (parity2
) & 0xf;
ecc
[3] = (parity3
) & 0xf;
ecc
[2] = (parity4
) & 0xf;
/*-------------------------------------------------------------------
syndrome regenerated from hamming syndrome by XORing address parity. {{{
----------------------------------------------------------------------*/
void addr_parity(char* data
, long long addr
, char* ecc
, int start_bit
, int shift
)
long long local_addr
= 0;
char parity
, addr_parity
;
//Partial mode shifting - James
addr
= pm_address_shift(addr
, shift
);
addr
= fc_hash_pa(addr
, dimm_config
);
//io_printf((char *)"(PLI) pre_xor ecc = (%02x %02x %02x %02x)\n", data[0], data[1], data[2], data[3]);
//io_printf((char *)"(PLI)addr_parity: addr = %llx, start_bit = %d\n", addr, start_bit);
local_addr
= local_addr
| (addr
& 0xfffffffe00);
local_addr
= (local_addr
>> 9);
local_addr
= (local_addr
<< 1) | ((addr
& 0x40) >> 6);
//io_printf((char *)"(PLI)addr_parity: local_addr = %llx\n", local_addr);
addr_parity
= addr_parity
^ (local_addr
& 1);
if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
) {
local_addr
= local_addr
| (addr
& 0x7fffffff8);
local_addr
= (local_addr
>> 3);
local_addr
= local_addr
| (addr
& 0x7fffffffc);
local_addr
= (local_addr
>> 2);
//io_printf((char *)"(PLI)addr_parity: local_addr = %llx\n", local_addr);
addr_parity
= addr_parity
^ (local_addr
& 1);
parity
= parity
| addr_parity
;
//io_printf((char *)"(PLI)addr_parity: parity = %x, addr_parity = %x\n", parity, addr_parity);
ecc
[1] = (data
[1] ^ parity
) & 0xf;
ecc
[0] = (data
[0] ^ parity
) & 0xf;
ecc
[3] = (data
[3] ^ parity
) & 0xf;
ecc
[2] = (data
[2] ^ parity
) & 0xf;
//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);
/*-------------------------------------------------------------------
check the address symbol that is "@". {{{
if symbol there, return address.
---------------------------------------------------------------------*/
int check_at_symbol(char *buf
, long long *addr
){
for(i
= 0; buf
[i
] != '\0'; i
++)
for(i
= i
-1; i
>= 0;i
--)if(buf
[i
] >= '0' && buf
[i
] <= '9'){
for(i
= 0; buf
[i
] != '\0'; i
++){
*addr
= ato_long(buf
, &i
);
// /*-------------------------------------------------------------------
// configure memory(address(bits) x datawidth(bits)). {{{
// ---------------------------------------------------------------------*/
// void config_mem_call(){
// tf_error((char *)"$config_mem_call requires at least two arguments(address, data-width).");
// a_tree = (avl_conf_ptr)malloc(sizeof(struct avl_conf_node));
// a_tree->addr = tf_getp(1);// get address size
// a_tree->half_byte = a_tree->addr / 4;
// if((a_tree->addr % 4) != 0)a_tree->half_byte++;
// a_tree->size = tf_getp(2);//get data width
// a_tree->word = a_tree->size / 32;
// a_tree->dram = 0;//dram
// if((a_tree->size % 32) != 0)a_tree->word++;
// //pointer for avl tree set NULL
// tf_putp(0, (unsigned int)a_tree);//reurn handle
// io_printf((char *)"(PLI)Info -> Creating Memory(address width(%dbits) data width(%dbits)\n", a_tree->addr, a_tree->size);
/*-------------------------------------------------------------------
set to an unintialized memory with random value. {{{
---------------------------------------------------------------------*/
avl_node_ptr
store_op(long long addr
, int handle
)
int i
, bank
, start
, ind
, i_bank
, l
;
char d_buf
[16], buf
[16], ecc
[4], pre_xor_ecc
[4];
t_ptr
= search_node(&(dram_tree
)->data
, &addr
);
if(bank
== 4){//when ecc read.
//io_printf((char *)"(PLI)t_ptr returned in store_op, start = %d, bank = %d, handle = %d \n",start, bank, handle);
if(t_ptr
== 0 || ((t_ptr
->val
[0].bval
[start
] & 0xff) == 0xff)){
f_val
[0].aval
.cval
[l
] = 0xff;
// slam_val for MCU SAT. Don't return zeros on uninitialized
if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
) {
if (mc_scan_plusargs("RANK_LOW") !=(char *)NULL
)
ras_cas
= addr
& 0x7fff800;
ras_cas
= addr
& 0x7ffff80;
if (mc_scan_plusargs("RANK_LOW") !=(char *)NULL
)
ras_cas
= addr
& 0x3fffc00;
ras_cas
= addr
& 0x3ffffc0;
//io_printf((char *)"(PLI)store_op: ras_cas = %x, addr = %llx\n", ras_cas, addr);
for(i
= 0; i
< 16; i
++) {
d_buf
[i
] = ((ras_cas
& (0xff000000 >> j
)) >> (24 - j
)) & 0xff;
for(i
= 0; i
< 16; i
++) d_buf
[i
] = 0;
//d_buf[i] = slam_val ? random() & 0xff : 0;// get ram data
//io_printf((char *)"(PLI)from store_op routine slam_val = %d, d_buf[%d] = %s", slam_val,i, d_buf[i]);
for(i_bank
= 0; i_bank
< 8;i_bank
++){
buf
[ind
++] = (d_buf
[i_bank
] >> 4) & 0xf;
buf
[ind
++] = d_buf
[i_bank
] & 0xf;
for(i_bank
= 0; i_bank
< 16;i_bank
++){
(t_ptr
)->val
[0].aval
.cval
[start
+ i_bank
] = buf
[15-i_bank
];
(t_ptr
)->val
[0].bval
[start
+ i_bank
] = 0;
f_val
[0].aval
.cval
[start
+i_bank
] = buf
[15-i_bank
];
f_val
[0].bval
[start
+i_bank
] = 0;
for(i_bank
= 8; i_bank
< 16;i_bank
++){
buf
[ind
++] = (d_buf
[i_bank
] >> 4) & 0xf;
buf
[ind
++] = d_buf
[i_bank
] & 0xf;
for(i_bank
= 0; i_bank
< 16;i_bank
++){
(t_ptr
)->val
[0].aval
.cval
[start
+i_bank
] = buf
[15-i_bank
];
(t_ptr
)->val
[0].bval
[start
+i_bank
] = 0;
f_val
[0].aval
.cval
[start
+i_bank
] = buf
[15-i_bank
];
f_val
[0].bval
[start
+i_bank
] = 0;
hamming(d_buf
, pre_xor_ecc
);
//io_printf((char *)"(PLI) calling addr_parity in store_op foR ADDR = %llx \n", addr);
addr_parity(pre_xor_ecc
, addr
, ecc
, 6, 0);
(t_ptr
)->val
[0].aval
.cval
[start
+0] = ecc
[0];
(t_ptr
)->val
[0].bval
[start
+0] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+1] = ecc
[1];
(t_ptr
)->val
[0].bval
[start
+1] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+2] = 0; // data
(t_ptr
)->val
[0].bval
[start
+2] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+3] = 0; // data
(t_ptr
)->val
[0].bval
[start
+3] = 0;
(t_ptr
)->val
[0].aval
.cval
[tmp_adjust
+ 14] = ecc
[2]; // data
(t_ptr
)->val
[0].bval
[tmp_adjust
+ 14] = 0;
(t_ptr
)->val
[0].aval
.cval
[tmp_adjust
+ 15] = ecc
[3]; // data
(t_ptr
)->val
[0].bval
[tmp_adjust
+ 15] = 0;
if(dimm_config
& CHIPKILL
)
(t_ptr
)->val
[0].aval
.cval
[start
+0] = ecc
[1];
(t_ptr
)->val
[0].bval
[start
+0] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+1] = 0; // displaced data
(t_ptr
)->val
[0].bval
[start
+1] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+2] = 0; // data
(t_ptr
)->val
[0].bval
[start
+2] = 0;
(t_ptr
)->val
[0].aval
.cval
[start
+3] = 0; // data
(t_ptr
)->val
[0].bval
[start
+3] = 0;
(t_ptr
)->val
[0].aval
.cval
[tmp_adjust
+ 14] = ecc
[3]; // data
(t_ptr
)->val
[0].bval
[tmp_adjust
+ 14] = 0;
(t_ptr
)->val
[0].aval
.cval
[tmp_adjust
+ 15] = ecc
[0]; // data
(t_ptr
)->val
[0].bval
[tmp_adjust
+ 15] = 0;
f_val
[0].aval
.cval
[start
+0] = ecc
[0];
f_val
[0].bval
[start
+0] = 0;
f_val
[0].aval
.cval
[start
+1] = ecc
[1];
f_val
[0].bval
[start
+1] = 0;
f_val
[0].aval
.cval
[start
+2] = 0; // data
f_val
[0].bval
[start
+2] = 0;
f_val
[0].aval
.cval
[start
+3] = 0; // data
f_val
[0].bval
[start
+3] = 0;
f_val
[0].aval
.cval
[tmp_adjust
+ 14] = ecc
[2]; // data
f_val
[0].bval
[tmp_adjust
+ 14] = 0;
f_val
[0].aval
.cval
[tmp_adjust
+ 15] = ecc
[3]; // data
f_val
[0].bval
[tmp_adjust
+ 15] = 0;
if(dimm_config
& CHIPKILL
)
f_val
[0].aval
.cval
[start
+0] = ecc
[1];
f_val
[0].bval
[start
+0] = 0;
f_val
[0].aval
.cval
[start
+1] = 0; // displaced data
f_val
[0].bval
[start
+1] = 0;
f_val
[0].aval
.cval
[start
+2] = 0; // data
f_val
[0].bval
[start
+2] = 0;
f_val
[0].aval
.cval
[start
+3] = 0; // data
f_val
[0].bval
[start
+3] = 0;
f_val
[0].aval
.cval
[tmp_adjust
+ 14] = ecc
[3]; // data
f_val
[0].bval
[tmp_adjust
+ 14] = 0;
f_val
[0].aval
.cval
[tmp_adjust
+ 15] = ecc
[0]; // data
f_val
[0].bval
[tmp_adjust
+ 15] = 0;
io_printf((char *)"(PLI)(%0d)Alert: access an uninitialized address({dimm,ras,cas[10:3],bank,cas[2:0]}=%llx)\n", tf_gettime(), addr
);
if(t_ptr
== 0)insert_avl_node(&(dram_tree
)->data
, &addr
, f_val
);
/*-------------------------------------------------------------------
---------------------------------------------------------------------*/
long long x8_address_decode(long long addr
)
dway = RAS[14:0], CAS[10:2], BA[2:0], CAS[1:0]
[28:14] [13:5] [4:2] [1:0]
dway = RAS[14:0], CAS[10:3], BA[2:0], CAS[2:0]
[28:14] [13:6] [5:3] [2:0]
if (mc_scan_plusargs("DIMM_SIZE_1G") !=(char *)NULL
) {
addr
|= ((addr
& 0x10000000) >> 15);
else if (mc_scan_plusargs("DIMM_SIZE_512") !=(char *)NULL
) {
if (mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
) {
addr
|= ((addr
& 0x20) << 8);
addr
|= ((addr
& 0x10) << 9);
else if (mc_scan_plusargs("DIMM_SIZE_256") !=(char *)NULL
) {
addr
|= ((addr
& 0x8000000) >> 14);
addr
|= ((addr
& 0x10000000) >> 15);
/*-------------------------------------------------------------------
$mem_read call routine. {{{
input: handle, bank, way.
---------------------------------------------------------------------*/
handle
= tf_getp(1); // get this data base.
addr
= (long long)tf_getp(3);// get index.
//io_printf((char *)"(PLI)(%0d) read_mem_call with args(before) addr = %llx, handle = %d\n", tf_gettime(),addr, handle);
if (mc_scan_plusargs("X8") !=(char *)NULL
) { addr
= x8_address_decode(addr
); }
//io_printf((char *)"(PLI)(%0d) read_mem_call with args(after) addr = %llx, handle = %d\n", tf_gettime(),addr, handle);
if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
)&& (addr
& 0x1)) {
if(handle
< 288 && handle
>= 144){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
< 432 && handle
>= 288){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 432 && handle
< 576){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 576 && handle
< 720){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 720 && handle
< 864){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 864 && handle
< 1008){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1008 && handle
< 1152){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1152 && handle
< 1296){
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1296 && handle
< 1440){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1440 && handle
< 1584){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1584 && handle
< 1728){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1728 && handle
< 1872){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1872 && handle
< 2016){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 2016 && handle
< 2160){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 2160 && handle
< 2304){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
)&& (btemp
== 1)) {
if(tbank
== 4){//when ecc read.
//io_printf((char *)"(PLI)calling read_mem with args addr = %llx, handle = %d\n", addr, handle);
t_ptr
= store_op(addr
, handle
);
t_ptr
= search_node(&(dram_tree
)->data
, &addr
);
//io_printf((char *)"(PLI)read_mem: slam_mem: with args addr = %llx, handle = %d\n", addr, handle);
//for(l = 0;l < 144; l++){
// io_printf((char *)"(PLI)rval[%d] = %x, ",l, t_ptr->val[0].aval.cval[l]);
slam_memory((t_ptr
)->val
, dram_tree
->word
, 2, 1, handle
);
/*-------------------------------------------------------------------
$write_mem call routine. {{{
---------------------------------------------------------------------*/
addr
= (long long)tf_getp(3);
handle
= tf_getp(1); // get this data base.
//io_printf((char *)"(PLI)(%0d) write_mem_call with args(before) addr = %llx, handle = %d\n", tf_gettime(),addr, handle);
if (mc_scan_plusargs("X8") !=(char *)NULL
) { addr
= x8_address_decode(addr
); }
//io_printf((char *)"(PLI)(%0d) write_mem_call with args(after) addr = %llx, handle = %d\n", tf_gettime(),addr, handle);
if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
)&&(addr
& 0x1)) {
if(handle
< 288 && handle
>= 144){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)writing here, handle = %d, addr = %d\n",handle, addr);
else if(handle
< 432 && handle
>= 288){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)writing here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 432 && handle
< 576){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 576 && handle
< 720){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 720 && handle
< 864){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 864 && handle
< 1008){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1008 && handle
< 1152){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1152 && handle
< 1296){
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1296 && handle
< 1440){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1440 && handle
< 1584){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1584 && handle
< 1728){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1728 && handle
< 1872){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 1872 && handle
< 2016){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 2016 && handle
< 2160){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
else if(handle
>= 2160 && handle
< 2304){
addr
|= (dimm_addr
<< 29);
// io_printf((char *)"(PLI)here, handle = %d, addr = %d\n",handle, addr);
if ((mc_scan_plusargs("SNG_CHANNEL") !=(char *)NULL
)&& (btemp
== 1)) {
if(tbank
== 4){//when ecc read.
//io_printf((char *)"(PLI)calling write_mem with args addr = %llx, handle = %d\n", addr, handle);
t_ptr
= search_node(&(dram_tree
)->data
, &addr
);
nval
[0].aval
.cval
[l
] = 0xff;
dump_memory(nval
, dram_tree
->word
, 2, handle
);
t_ptr
->val
[0].aval
.cval
[handle
] = nval
[0].aval
.cval
[handle
];
t_ptr
->val
[0].bval
[handle
] = nval
[0].bval
[handle
];
else insert_avl_node(&(dram_tree
)->data
, &addr
, nval
);
/*-------------------------------------------------------------------
receive the phyical address from rtl. {{{
---------------------------------------------------------------------*/
int high
, bank
, i_bank
, bank_s
;//address
unsigned long long tempdata1
= 0;
lowt
= (unsigned int)tf_getlongp(&high
, 1);//get address
addr
= (unsigned long long) (high
& 0xffffffff);
//io_printf((char *)"(PLI)(%0d) read_dram_call with args(before X8) addr = %llx\n", tf_gettime(),addr);
if (mc_scan_plusargs("X8") !=(char *)NULL
) { addr
= x8_address_decode(addr
); }
//io_printf((char *)"(PLI)(%0d) read_dram_call with args(after X8) addr = %llx\n", tf_gettime(),addr);
addr
= pm_address_shift(addr
, shift
);
dway
= address_decode(&addr
, dimm_config
, 0);
cs
= decode_cs(&addr
, dimm_config
, 0);
//io_printf((char *)"(PLI)read_dram: addr = %llx, dway = %llx\n", addr, dway);
bank_s
= (addr
>> 7) & 0x3;
if((addr
& 0x8)== 0x8)bank
+= 16;
t_ptr
= (dram_tree
)->data
? search_node(&(dram_tree
)->data
, &dway
) : 0;
for (i_bank
= 13; i_bank
>= 0; i_bank
--){
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[bank
+i_bank
] & 0xf;
ecc_index
= 128 + bank_s
* 4;
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[ecc_index
+3] & 0xf;
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[ecc_index
+2] & 0xf;
} // else tempdata1 returned will be zero.
for (i_bank
= 15; i_bank
>= 0; i_bank
--){
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[bank
+i_bank
] & 0xf;
} // else tempdata1 returned will be zero.
// io_printf((char *)"(PLI)read_dram: tempdata1 = %llx\n", tempdata1);
tf_putp(3, (tempdata1
>> 32));
/*-------------------------------------------------------------------
extract memory content from string and store data into memory. {{{
---------------------------------------------------------------------*/
void store_into_rdram(char *buf
, long long *addr
, int index
,
char *d_buf
, int *d_ind
, int *num_bit
, int* l_bit
,
int *b_ind
, char* ecc
, int dimm_config
, int shift
){
int bank
, i_bank
, i
, j
, l
, bank_s
;
int start_index_avl
, chipkill_index
, datafill_index
;
//io_printf ("store_into_rdram with addr %llx, index %x\n", *addr, index);
while((index
= remove_leading_space(buf
, index
, BUFFER
)) >= 0){
convert_a2b(buf
, &index
, d_buf
, d_ind
, num_bit
);
dway
= address_decode(addr
, dimm_config
, shift
);
cs
= decode_cs(addr
, dimm_config
, shift
);
//io_printf((char *)"(PLI) after decode: addr=%llx, dimm_config=%d, dway=%llx, cs=%d\n",*addr, dimm_config, dway, cs);
//Partial mode shifting - James
bank_s
= pm_bank_s(*addr
, shift
);
// done with address decoding
if (((*b_ind
) & 0x1) == 1) bank
+= 16;
//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);
t_ptr
= dram_tree
->data
? search_node(&(dram_tree
)->data
, &dway
) : 0;
if(t_ptr
== 0){//new node
f_val
[0].aval
.cval
[l
] = 0xff;
//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);
for (i_bank
= 0; i_bank
< 16; i_bank
++){
//io_printf((char *)"(PLI)WHEN DO WE ENTER THIS BLOCK ?\n");
f_val
[0].aval
.cval
[bank
+i_bank
] = 0;
d_buf
[16+(*d_ind
)-1] = 0;
ck_tmp_buf
[t_index
-i_bank
-1] = 0;
// 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]);
f_val
[0].aval
.cval
[bank
+i_bank
] = d_buf
[(*d_ind
)-1] & 0xf;
tmp_buf
[15-i_bank
] = d_buf
[(*d_ind
)-1] & 0xf;
ck_tmp_buf
[t_index
-i_bank
-1] = d_buf
[(*d_ind
)-1] & 0xf;
//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);
f_val
[0].bval
[bank
+i_bank
] = 0;
insert_avl_node(&(dram_tree
)->data
, &dway
, f_val
);
else{//node already exist.
//io_printf((char *)"(PLI) overwriting node at : addr %llx, bank %d , dway = %llx, d_ind=%d\n", *addr, bank + i_bank, dway, *d_ind);
for (i_bank
= 0; i_bank
< 16; i_bank
++){
//io_printf((char *)"(PLI)2 WHEN DO WE ENTER THIS BLOCK ?\n");
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
] = 0;
d_buf
[16+(*d_ind
)-1] = 0;
ck_tmp_buf
[t_index
-i_bank
-1] = 0;
//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]);
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
] = d_buf
[(*d_ind
)-1] & 0xf;
tmp_buf
[15-i_bank
] = d_buf
[(*d_ind
)-1] & 0xf;
ck_tmp_buf
[t_index
-i_bank
-1] = d_buf
[(*d_ind
)-1] & 0xf;
//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);
t_ptr
->val
[0].bval
[bank
+i_bank
] = 0;
//for(j = 0; j < 32; j++)
//io_printf((char *)"(PLI) ck_tmp_buf[%d] = %x; ",j, ck_tmp_buf[j]);
i_bank
= ((*addr
>> 3) & 1) * 8;
for (i
= i_bank
; i
< i_bank
+ 8; i
++){
ecc
[i
] = d_buf
[j
*2 + 1] | (d_buf
[j
*2] << 4);
//io_printf((char *)"(PLI) ecc[%d] is %x\n", i, ecc[i]);
t_ptr
= search_node(&(dram_tree
)->data
, &dway
);
//io_printf((char *)"(PLI) calling hamming foR data = %16x\n", &ecc);
hamming(ecc
, pre_xor_ecc
);
//io_printf((char *)"(PLI) calling addr_parity foR ADDR = %llx, pre_xor_ecc =%4x\n", (*addr), &pre_xor_ecc);
addr_parity(pre_xor_ecc
, *addr
, d_buf
, 0, shift
);
if(dimm_config
& CHIPKILL
){
mcu
= ((*addr
) >> 7) & 0x3;
chipkill_index
= ck_mcu0
;
chipkill_index
= ck_mcu1
;
chipkill_index
= ck_mcu2
;
chipkill_index
= ck_mcu3
;
for(i_bank
= 0; i_bank
< 16; i_bank
++) {
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
] = ck_tmp_buf
[t_index
];
if(datafill_index
!= chipkill_index
)
ecc_index
= 128 + bank_s
* 4;
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 2] = ck_tmp_buf
[t_index
];
t_ptr
->val
[0].bval
[ecc_index
+ 2] = 0;
if(datafill_index
!= chipkill_index
)
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 3] = ck_tmp_buf
[t_index
] ;
t_ptr
->val
[0].bval
[ecc_index
+ 3] = 0;
if(datafill_index
!= chipkill_index
)
for(i_bank
= 0; i_bank
< 14; i_bank
++) {
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
] = ck_tmp_buf
[t_index
];
if(datafill_index
!= chipkill_index
)
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 1] = ck_tmp_buf
[t_index
] & 0xf;
t_ptr
->val
[0].bval
[ecc_index
+ 1] = 0;
t_ptr
->val
[0].aval
.cval
[ecc_index
] = d_buf
[1];
t_ptr
->val
[0].bval
[ecc_index
] = 0;
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
] = d_buf
[3];
t_ptr
->val
[0].aval
.cval
[bank
+i_bank
+1] = d_buf
[0];
//for(l = 0;l < 144; l++){
// io_printf((char *)"(PLI)cval[%d] = %x, ",l, t_ptr->val[0].aval.cval[l]);
for (i_bank
= 0; i_bank
< 14; i_bank
++){
t_ptr
->val
[0].aval
.cval
[start_index_avl
+i_bank
] = ck_tmp_buf
[13 - i_bank
] & 0xf;
// 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));
t_ptr
->val
[0].aval
.cval
[start_index_avl
+i_bank
] = d_buf
[2];
// io_printf ("rewriting node for avl tree at dway = %llx, cval[%d] = %x \n", dway, (start_index_avl + i_bank), d_buf[2] );
t_ptr
->val
[0].aval
.cval
[start_index_avl
+i_bank
+ 1] = d_buf
[3];
// io_printf ("rewriting node for avl tree at dway = %llx, cval[%d] = %x \n", dway, (start_index_avl + i_bank + 1), d_buf[3] );
ecc_index
= 128 + bank_s
* 4;
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 1] = d_buf
[1];
t_ptr
->val
[0].bval
[ecc_index
+ 1] = 0;
t_ptr
->val
[0].aval
.cval
[ecc_index
] = d_buf
[0];
t_ptr
->val
[0].bval
[ecc_index
] = 0;
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 2] = ck_tmp_buf
[i_bank
+ 1];
t_ptr
->val
[0].bval
[ecc_index
+ 2] = 0;
t_ptr
->val
[0].aval
.cval
[ecc_index
+ 3] = ck_tmp_buf
[i_bank
] ;
t_ptr
->val
[0].bval
[ecc_index
+ 3] = 0;
(*addr
) += 8;//data[0]-> size / ADDRESS;
/*-------------------------------------------------------------------
---------------------------------------------------------------------*/
long long data
, tempdata
;
char d_buf
[BUFFER
], ecc
[16];
int d_ind
, num_bit
, l_bit
, b_ind
;
int bank
, i_bank
, bank_s
, t
, ecc_index
;//address
unsigned long long tempdata1
;
lowt
= (unsigned int)tf_getlongp(&high
, 1);//get address
addr
= (unsigned long long) (high
& 0xffffffff);
//io_printf((char *)"(PLI)(%0d) write_dram_call with args(before X8) addr = %llx\n", tf_gettime(),addr);
if (mc_scan_plusargs("X8") !=(char *)NULL
) { addr
= x8_address_decode(addr
); }
//io_printf((char *)"(PLI)(%0d) write_dram_call with args(after X8) addr = %llx\n", tf_gettime(),addr);
addr
= pm_address_shift(addr
, shift
);
dlow
= tf_getlongp(&high
, 2);
data
= (unsigned long long) high
<< 32;
tempdata
= (unsigned) dlow
;
data
|= (unsigned long long) tempdata
;
//io_printf((char *)"(PLI)write_dram: addr = %llx, data = %llx \n",addr,data);
sprintf (buf
, "%016llx", data
);
// Do a read of 64 bits and then write those 64 bits
dway
= address_decode(&addr
, dimm_config
, 0);
cs
= decode_cs(&addr
, dimm_config
, 0);
bank_s
= (addr
>> 7) & 0x3;
if((addr
& 0x8)== 0x8)bank
+= 16;
t_ptr
= (dram_tree
)->data
? search_node(&(dram_tree
)->data
, &dway
) : 0;
for (i_bank
= 13; i_bank
>= 0; i_bank
--){
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[bank
+i_bank
] & 0xf;
ecc_index
= 128 + bank_s
* 4;
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[ecc_index
+3] & 0xf;
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[ecc_index
+2] & 0xf;
} // else tempdata1 returned will be zero.
sprintf(buf
, "%016llx %016llx", tempdata1
, data
);
d_ind
= 0;num_bit
= 0;l_bit
= 0;
//b_ind = low >> 3;//initial
sprintf(ecc
, "%d", index
);
dway
= address_decode(&addr
, dimm_config
, 0);
cs
= decode_cs(&addr
, dimm_config
, 0);
bank_s
= (addr
>> 7) & 0x3;
if((addr
& 0x8)== 0x8)bank
+= 16;
t_ptr
= (dram_tree
)->data
? search_node(&(dram_tree
)->data
, &dway
) : 0;
for (i_bank
= 15; i_bank
>= 0; i_bank
--){
tempdata1
|= (t_ptr
)->val
[0].aval
.cval
[bank
+i_bank
] & 0xf;
} // else tempdata1 returned will be zero.
sprintf(buf
, "%016llx %016llx", data
, tempdata1
);
sprintf(ecc
, "%d", index
);
d_ind
= 0;num_bit
= 0;l_bit
= 0;
b_ind
= addr
>> 3;//initial
store_into_rdram (buf
, &addr
, index
, d_buf
, &d_ind
, &num_bit
, &l_bit
, &b_ind
, ecc
, dimm_config
, 0);
/*-------------------------------------------------------------------
read mem.image and build memory. {{{
---------------------------------------------------------------------*/
void padding(char* buf
, int index
)
if((buf
[ind
] == '\n') || (buf
[ind
] == '\0')){
if(num
< 64){//do padding
if(buf
[ind
] != ' ')ind
++;
/*-------------------------------------------------------------------
check the address range based on dram config. {{{
---------------------------------------------------------------------*/
int check_address_range(long long addr
, int dimm_config
, int shift
)
if(check_if_valid_PA(addr
, dimm_config
, shift
) < 0)
/*------------------------------------------------------------------
read mem.image and build memory. {{{
--------------------------------------------------------------------*/
void build_rdram(FILE *fp
, int dimm_config
, int shift
){
long long addr
, tmp_addr
;
char buf
[BUFFER
], d_buf
[BUFFER
], ecc
[16];
int index
, d_ind
, num_bit
, l_bit
, b_ind
;
addr
= 0;d_ind
= 0;num_bit
= 0;l_bit
= 0;b_ind
= 0;//initial
while(fgets(buf
, BUFFER
, fp
)){
index
= remove_leading_space(buf
, 0, BUFFER
);
if(index
< 0 || strncmp (buf
, "//", 2) == 0)continue;//empty string
if(check_at_symbol(buf
, &addr
)){//get address
skip_data
= check_address_range(addr
, dimm_config
, shift
);
mask_value(dram_tree
->addr
, &addr
);
d_ind
= 0;num_bit
= 0;l_bit
= 0;
if(skip_data
== 1) continue;//skip data part for invalid PA
//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);
store_into_rdram(buf
, &addr
, index
, d_buf
, &d_ind
, &num_bit
, &l_bit
, &b_ind
, ecc
, dimm_config
, shift
);
/*--------------------------------------------------------------------
----------------------------------------------------------------------*/
dram_tree
= (avl_conf_ptr
)malloc(sizeof(struct avl_conf_node
));
io_printf((char *)"(PLI)ERROR : Unable to allocate memory in $init_dram\n");
if (mc_scan_plusargs("X8") !=(char *)NULL
) {
io_printf((char *)"(PLI)(%0d) X8 inside init_dram_call...\n",tf_gettime());
if ( (mc_scan_plusargs("DIMM_SIZE_2G") !=(char *)NULL
) ||
( (mc_scan_plusargs("DIMM_SIZE_1G") == (char *)NULL
) &&
(mc_scan_plusargs("DIMM_SIZE_512") == (char *)NULL
) &&
(mc_scan_plusargs("DIMM_SIZE_256") == (char *)NULL
) ) ) {
io_printf((char *)"(PLI)\n\n\n\t*** CANNOT run X8 mode with DIMM size of 2G!***\n\n\n");
io_printf((char *)"(PLI)(%0d) X4 inside init_dram_call...\n",tf_gettime());
dram_tree
->addr
= 40;//address size;
dram_tree
->size
= 4;//tf_getp(2);//get data width
dram_tree
->word
= dram_tree
->size
/ 32;
dram_tree
->dram
= 0;//dram
if((dram_tree
->size
% 32) != 0)dram_tree
->word
++;
//pointer for avl tree set NULL
str
= tf_getcstringp(1); // get a file name.
dimm_config
= tf_getp(2);//get dram config
//io_printf((char *)"(PLI)Info: reading %s in init_dram_call\n", str);
//io_printf((char *)"(PLI)Info: dimm_config = %d, str = %s, dram_tree->word = %d", dimm_config, str, dram_tree->word);
if((fp
= fopen(str
, "r")) == 0){
tf_error((char *)"Error: $init_dram can not open file %s for reading\n", str
);
build_rdram(fp
, dimm_config
, shift
);
//slam value if not specified, randomly initialize.
str
= mc_scan_plusargs ("slam_init_value");
if(str
!= (char *) 0)slam_val
= 1;
//io_printf((char *)"(PLI)Info: exiting init_dram_call\n");
// io_printf((char *)"(PLI)arg %d\n", tf_nump());
// tf_error((char *)"$in_order call requires at least two arguments(address, datawidth).");
// str = tf_getcstringp(2);
// if((fp = fopen(str, "w")) == 0){
// tf_error((char *)"Error: $in_order can not open file %s for writing\n", str);
// handle = (avl_conf_ptr) tf_getp(1);
// in_order(&(handle)->data, fp, &shft, &(handle)->size);
// /*-------------------------------------------------------------------
// dump verilog instance contents. {{{
// --------------------------------------------------------------------*/
// void v_set_delay_call(){
// double rise, fall, toz;
// acc_configure(accPathDelayCount, (char *)"3");
// hand = acc_handle_by_name(tf_getcstringp(1), 0);
// switch(acc_fetch_delay_mode(hand)){
// case accDelayModeNone : io_printf((char *)"(PLI)none\n");break;
// case accDelayModePath : io_printf((char *)"(PLI)path\n");
// acc_replace_delays(hand, rise, fall, toz);
// /*-------------------------------------------------------------------
// dump verilog instance contents. {{{
// ---------------------------------------------------------------------*/
// s_setval_value valStruct;
// s_setval_delay delStruct;
// hand = acc_handle_by_name(tf_getcstringp(1), 0);
// io_printf((char *)"(PLI)%0d : Info: Object not found %s\n", tf_gettime(), tf_getcstringp(1));
// valStruct.format = accBinStrVal;
// valStruct.value.str = (char*)malloc(acc_fetch_size(hand));
// strcpy(valStruct.value.str, tf_getcstringp(2));
// switch(acc_fetch_type(hand)){
// delStruct.model = accForceFlag;
// timStruct.type = accTime;
// delStruct.time = timStruct;
// delStruct.model = accInertialDelay;
// acc_set_value(hand, &valStruct, &delStruct);
// /*-------------------------------------------------------------------
// dump verilog instance contents. {{{
// ---------------------------------------------------------------------*/
// hand = acc_handle_by_name(tf_getcstringp(1), 0);
// io_printf((char *)"(PLI)%0d : Info: Object not found %s\n", tf_gettime(), tf_getcstringp(1));
// switch(acc_fetch_type(hand)){
// io_printf((char *)"(PLI)%0d : Info -> %s = 0x%s\n", tf_gettime(), tf_getcstringp(1),
// acc_fetch_value(hand, (char *)"%h", 0));
// io_printf((char *)"(PLI)%0d : Info -> %s = 0x%s\n", tf_gettime(), tf_getcstringp(1),
// acc_fetch_value(hand, (char *)"%h", 0));
// v_size = acc_fetch_size(hand);
// acc_fetch_range(hand, &msb, &lsb);
// io_printf((char *)"(PLI)SIZE %d %d %d\n", v_size, msb, lsb);
// /*-------------------------------------------------------------------
// initialize memory. {{{
// ---------------------------------------------------------------------*/
// void warm_specified(int val, int size, int arg_loc){
// char* avalPtr, *bvalPtr;
// int word, ind, groups;
// s_tfnodeinfo node_info;
// tf_nodeinfo(arg_loc, &node_info);
// switch(node_info.node_type){
// if(size > node_info.node_mem_size)return;
// word = node_info.node_ngroups * 2;
// avalPtr = node_info.node_value.memoryval_p + size * word;
// bvalPtr = avalPtr + node_info.node_ngroups;
// for(groups = node_info.node_ngroups - 1; groups >= 0;groups--){
// avalPtr[groups] = val & 0xff;
// for(groups = 0; groups < node_info.node_ngroups ; groups++){
// node_info.node_value.vecval_p[groups].avalbits = val & 0xff;
// node_info.node_value.vecval_p[groups].bvalbits = 0;
// tf_propagatep(arg_loc);
// case TF_NETVECTOR_NODE :
// for(groups = 0; groups < node_info.node_ngroups ; groups++){
// node_info.node_value.vecval_p[groups].avalbits = val & 0xff;
// node_info.node_value.vecval_p[groups].bvalbits = 0;
// tf_propagatep(arg_loc);
// /*-------------------------------------------------------------------
// dump verilog instance contents. {{{
// ---------------------------------------------------------------------*/
// str = tf_getcstringp(1); // a get file name.
// if((fp = fopen(str, "r")) == 0){
// io_printf((char *)"(PLI)Warning -> SPD not set(File not Found %s)\n", str);
// while(fscanf(fp, "%x %x", &addr, &val) != EOF)warm_specified(val & 0xff, addr & 0xff, 2);
// /*-------------------------------------------------------------------
// syndrome for irf and frf. {{{
// --------------------------------------------------------------------*/
// char syndrome(char* data, int fl)
// char bits [64], ch, byte[8];
// for(i = num - 1 ; i >= 0;i--){
// for(j = 0; j < 8;j++){
// byte[0] = bits[0] ^ bits[1] ^ bits[3] ^ bits[4] ^ bits[6] ^
// bits[8] ^ bits[10] ^ bits[11] ^ bits[13] ^ bits[15] ^
// bits[17] ^ bits[19] ^ bits[21] ^ bits[23] ^ bits[25] ^
// bits[26] ^ bits[28] ^ bits[30];
// byte[1] = bits[0] ^ bits[2] ^ bits[3] ^ bits[5] ^ bits[6] ^
// bits[9] ^ bits[10] ^ bits[12] ^ bits[13] ^ bits[16] ^
// bits[17] ^ bits[20] ^ bits[21] ^ bits[24] ^ bits[25] ^
// bits[27] ^ bits[28] ^ bits[31];
// byte[2] = bits[1] ^ bits[2] ^ bits[3] ^ bits[7] ^ bits[8] ^
// bits[9] ^ bits[10] ^ bits[14] ^ bits[15] ^ bits[16] ^
// bits[17] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25] ^
// bits[29] ^ bits[30] ^ bits[31];
// byte[3] = bits[4] ^ bits[5] ^ bits[6] ^ bits[7] ^ bits[8] ^
// bits[9] ^ bits[10] ^ bits[18] ^ bits[19] ^ bits[20] ^
// bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25];
// byte[4] = bits[11] ^ bits[12] ^ bits[13] ^ bits[14] ^ bits[15] ^
// bits[16] ^ bits[17] ^ bits[18] ^ bits[19] ^ bits[20] ^
// bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^ bits[25];
// byte[5] = bits[26] ^ bits[27] ^ bits[28] ^ bits[29] ^ bits[30] ^
// byte[6] = bits[0] ^ bits[1] ^ bits[2] ^ bits[4] ^ bits[5] ^
// bits[7] ^ bits[10] ^ bits[11] ^ bits[12] ^ bits[14] ^
// bits[17] ^ bits[18] ^ bits[21] ^ bits[23] ^ bits[24] ^
// bits[26] ^ bits[27] ^ bits[29];
// byte[1] <<= 1;byte[2] <<= 2;byte[3] <<= 3;
// byte[4] <<= 4;byte[5] <<= 5;byte[6] <<= 6;
// for(i = 0; i < 7; i++)ch |= byte[i];
// byte[0] = bits[0] ^ bits[1] ^ bits[3] ^ bits[4] ^ bits[6] ^ bits[8] ^ bits[10] ^
// bits[11] ^ bits[13] ^ bits[15] ^ bits[17] ^ bits[19] ^ bits[21] ^ bits[23] ^
// bits[25] ^ bits[26] ^ bits[28] ^ bits[30] ^ bits[32] ^ bits[34] ^ bits[36] ^
// bits[38] ^ bits[40] ^ bits[42] ^ bits[44] ^ bits[46] ^ bits[48] ^ bits[50] ^
// bits[52] ^ bits[54] ^ bits[56] ^ bits[57] ^ bits[59] ^ bits[61] ^ bits[63];
// byte[1] = bits[0] ^ bits[2] ^ bits[3] ^ bits[5] ^ bits[6] ^ bits[9] ^ bits[10] ^
// bits[12] ^ bits[13] ^ bits[16] ^ bits[17] ^ bits[20] ^ bits[21] ^ bits[24] ^
// bits[25] ^ bits[27] ^ bits[28] ^ bits[31] ^ bits[32] ^ bits[35] ^ bits[36] ^
// bits[39] ^ bits[40] ^ bits[43] ^ bits[44] ^ bits[47] ^ bits[48] ^ bits[51] ^
// bits[52] ^ bits[55] ^ bits[56] ^ bits[58] ^ bits[59] ^ bits[62] ^ bits[63];
// byte[2] = bits[1] ^ bits[2] ^ bits[3] ^ bits[7] ^ bits[8] ^ bits[9] ^ bits[10] ^
// bits[14] ^ bits[15] ^ bits[16] ^ bits[17] ^ bits[22] ^ bits[23] ^ bits[24] ^
// bits[25] ^ bits[29] ^ bits[30] ^ bits[31] ^ bits[32] ^ bits[37] ^ bits[38] ^
// bits[39] ^ bits[40] ^ bits[45] ^ bits[46] ^ bits[47] ^ bits[48] ^ bits[53] ^
// bits[54] ^ bits[55] ^ bits[56] ^ bits[60] ^ bits[61] ^ bits[62] ^ bits[63];
// byte[3] = bits[4] ^ bits[5] ^ bits[6] ^ bits[7] ^ bits[8] ^ bits[9] ^ bits[10] ^
// bits[18] ^ bits[19] ^ bits[20] ^ bits[21] ^ bits[22] ^ bits[23] ^ bits[24] ^
// bits[25] ^ bits[33] ^ bits[34] ^ bits[35] ^ bits[36] ^ bits[37] ^ bits[38] ^
// bits[39] ^ bits[40] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^ bits[53] ^
// bits[54] ^ bits[55] ^ bits[56];
// byte[4] = bits[11] ^ bits[12] ^ bits[13] ^ bits[14] ^ bits[15] ^ bits[16] ^
// bits[17] ^ bits[18] ^ bits[19] ^ bits[20] ^ bits[21] ^ bits[22] ^ bits[23] ^
// bits[24] ^ bits[25] ^ bits[41] ^ bits[42] ^ bits[43] ^ bits[44] ^ bits[45] ^
// bits[46] ^ bits[47] ^ bits[48] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^
// bits[53] ^ bits[54] ^ bits[55] ^ bits[56];
// byte[5] = bits[26] ^ bits[27] ^ bits[28] ^ bits[29] ^ bits[30] ^ bits[31] ^
// bits[32] ^ bits[33] ^ bits[34] ^ bits[35] ^ bits[36] ^ bits[37] ^ bits[38] ^
// bits[39] ^ bits[40] ^ bits[41] ^ bits[42] ^ bits[43] ^ bits[44] ^ bits[45] ^
// bits[46] ^ bits[47] ^ bits[48] ^ bits[49] ^ bits[50] ^ bits[51] ^ bits[52] ^
// bits[53] ^ bits[54] ^ bits[55] ^ bits[56];
// byte[6] = bits[57] ^ bits[58] ^ bits[59] ^ bits[60] ^ bits[61] ^ bits[62] ^ bits[63];
// byte[7] = bits[0] ^ bits[1] ^ bits[2] ^ bits[4] ^ bits[5] ^ bits[7] ^ bits[10] ^ bits[11] ^
// bits[12] ^ bits[14] ^ bits[17] ^ bits[18] ^ bits[21] ^ bits[23] ^ bits[24] ^ bits[26] ^
// bits[27] ^ bits[29] ^ bits[32] ^ bits[33] ^ bits[36] ^ bits[38] ^ bits[39] ^ bits[41] ^
// bits[44] ^ bits[46] ^ bits[47] ^ bits[50] ^ bits[51] ^ bits[53] ^ bits[56] ^ bits[57] ^
// bits[58] ^ bits[60] ^ bits[63];
// byte[1] <<= 1;byte[2] <<= 2;byte[3] <<= 3;
// byte[4] <<= 4;byte[5] <<= 5;byte[6] <<= 6;byte[7] <<= 7;
// for(i = 0; i < 8; i++)ch |= byte[i];
// void slam_random_call() {
// int size, num, word, groups, fl, ind, val, rnd;
// char* avalPtr, *bvalPtr, ch;
// s_tfnodeinfo node_info;
// tf_nodeinfo(1, &node_info);
// pargs = mc_scan_plusargs ("slam_value=");
// if(pargs != (char *) 0) {
// word = node_info.node_ngroups * 2;
// for(size = 0;size < num;size++){
// avalPtr = node_info.node_value.memoryval_p + size * word;
// bvalPtr = avalPtr + node_info.node_ngroups;
// for(groups = 0; groups < node_info.node_ngroups; groups++){
// ch = syndrome(data, fl);
// avalPtr[groups] = ch & 0xff;
// ch = rnd ? random() & 0xff : val;
int mem_size() { return(32); }