* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: utility.h
* 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 ============================================
typedef struct f_state_node
{
char cval
[144];//total number of dimms
}state_node
, *f_state_ptr
;
// define avl tree data structure for memory model
struct avl_node
*leftPtr
;
struct avl_node
*rightPtr
;
// define avl data structure.
typedef struct avl_conf_node
{
int addr
; //how many bits
int half_byte
;//how many half_byte;
avl_node_ptr
search_node(avl_node_ptr
* t_ptr
, long long* addr
);
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
avl_node_ptr
create_avl_node(long long addr
, f_state_ptr val
){
n_ptr
= (avl_node_ptr
)malloc(sizeof(struct avl_node
));
t_tmp
= (f_state_ptr
)malloc(sizeof(struct f_state_node
));
io_printf((char *)"Error : Out of memory\n");
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
int difference(avl_node_ptr t_ptr
){
if(t_ptr
->leftPtr
!= 0)left
= t_ptr
->leftPtr
->balance
;
if(t_ptr
->rightPtr
!= 0)right
= t_ptr
->rightPtr
->balance
;
/*-------------------------------------------------------------------------------
rotate nodes pointed to by pivotptr.
--------------------------------------------------------------------------------*/
void rotate_right(avl_node_ptr
* pivot_ptr
){
if((*pivot_ptr
)->leftPtr
!= 0){
t_ptr
= (*pivot_ptr
)->leftPtr
;
(*pivot_ptr
)->leftPtr
= t_ptr
->rightPtr
;
t_ptr
->rightPtr
= *pivot_ptr
;
*pivot_ptr
= t_ptr
; // t_ptr becomes new root of this whole subtree.
/*-------------------------------------------------------------------------------
rotate nodes pointed to by pivotptr.
--------------------------------------------------------------------------------*/
void rotate_left(avl_node_ptr
* pivot_ptr
){
if((*pivot_ptr
)->rightPtr
!= 0){
t_ptr
= (*pivot_ptr
)->rightPtr
;
(*pivot_ptr
)->rightPtr
= t_ptr
->leftPtr
;
t_ptr
->leftPtr
= *pivot_ptr
;
*pivot_ptr
= t_ptr
; // t_ptr becomes new root of this whole subtree.
/*-------------------------------------------------------------------------------
rotate nodes pointed to by pivotptr.
--------------------------------------------------------------------------------*/
void balance_right(avl_node_ptr
* t_ptr
){
if(difference((*t_ptr
)->rightPtr
) == 0){
(*t_ptr
)->leftPtr
->balance
++;
else if(difference((*t_ptr
)->rightPtr
) < 0){
(*t_ptr
)->leftPtr
->balance
-= 2;
rotate_right(&(*t_ptr
)->rightPtr
);
(*t_ptr
)->leftPtr
->balance
-= 2;
(*t_ptr
)->rightPtr
->balance
--;
/*-------------------------------------------------------------------------------
rotate nodes pointed to by pivotptr.
--------------------------------------------------------------------------------*/
void balance_left(avl_node_ptr
* t_ptr
){
if(difference((*t_ptr
)->leftPtr
) == 0){
(*t_ptr
)->rightPtr
->balance
++;
else if(difference((*t_ptr
)->leftPtr
) < 0){
(*t_ptr
)->rightPtr
->balance
-= 2;
rotate_left(&(*t_ptr
)->leftPtr
);
(*t_ptr
)->rightPtr
->balance
-= 2;
(*t_ptr
)->leftPtr
->balance
--;
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
void fixFB(avl_node_ptr t_ptr
){
if(t_ptr
->leftPtr
!= 0)left
= t_ptr
->leftPtr
->balance
;
if(t_ptr
->rightPtr
!= 0)right
= t_ptr
->rightPtr
->balance
;
if(left
> right
)t_ptr
->balance
= left
+ 1;
else t_ptr
->balance
= right
+ 1;
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
int insert_avl_node(avl_node_ptr
*t_ptr
, long long* addr
, f_state_ptr val
){
(*t_ptr
) = create_avl_node(*addr
, val
); // add new node to tree.
io_printf((char *)"Error : Out of Memory\n");
else if(*addr
== (*t_ptr
)->addr
)return 1;
if(*addr
< (*t_ptr
)->addr
)insert_avl_node(&(*t_ptr
)->leftPtr
, addr
, val
);
else insert_avl_node(&(*t_ptr
)->rightPtr
, addr
, val
);
if(difference(*t_ptr
) > 1) balance_left (&(*t_ptr
));
else if(difference(*t_ptr
) < -1) balance_right(&(*t_ptr
));
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
avl_node_ptr
search_node(avl_node_ptr
* t_ptr
, long long* addr
){
if((*t_ptr
)->addr
== *addr
){
if((*t_ptr
)->addr
> *addr
){
if((*t_ptr
)->leftPtr
== 0){
return search_node(&(*t_ptr
)->leftPtr
, addr
);
if((*t_ptr
)->rightPtr
== 0){
return search_node(&(*t_ptr
)->rightPtr
, addr
);
/*-------------------------------------------------------------------------------
convert unsigned int to char array
--------------------------------------------------------------------------------*/
long long mask_upbit(int width
, long long val
){
/*-------------------------------------------------------------------------------
traverse an avl-tree by visitint a left subtree.
--------------------------------------------------------------------------------*/
void in_order(avl_node_ptr
* t_ptr
, FILE* fp
, int* shft
, int* size
){
in_order(&(*t_ptr
)->leftPtr
, fp
, shft
, size
);
fprintf(fp
, "way -> %x ", mask_upbit(64 - (*shft
), (*t_ptr
)->addr
>> (*shft
)));
fprintf(fp
, "index -> %02x data -> ", mask_upbit(*shft
, (*t_ptr
)->addr
));
num
= (*size
) / 32;if(((*size
) % 32) != 0)num
++;
for(i
= num
- 1;i
>= 0;i
--)fprintf(fp
, "%x", (*t_ptr
)->val
[i
].aval
);
fprintf(fp
, "address -> %016llx data -> ", (*t_ptr
)->addr
);
num
= (*size
) / 32;if(((*size
) % 32) != 0)num
++;
for(i
= num
- 1;i
>= 0;i
--)fprintf(fp
, "%x", (*t_ptr
)->val
[i
].aval
);
in_order(&(*t_ptr
)->rightPtr
, fp
, shft
, size
);
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------
remove leading space or tab.
if found carriage return, return -1 to indicate anenpty string.
--------------------------------------------------------------------------------*/
int remove_leading_space(char* buf
, int index
, int max
){
while((index
< max
) && (buf
[index
] == ' ' || buf
[index
] == '\t'))index
++;
return buf
[index
] == '\n' || buf
[index
] == '\0' ? -1 : index
;
/*-------------------------------------------------------------------------------
make address from alpha string.
--------------------------------------------------------------------------------*/
long long ato_long(char* buf
, int* index
){
while((buf
[*index
] != ' ') && (buf
[*index
] != '\0') && (buf
[*index
] != '\n')){
val
|= buf
[*index
] > '9' ? ((buf
[*index
] & 0xf) + 9) : buf
[*index
] & 0xf;
/*-------------------------------------------------------------------------------
convert ascii to hex array.
--------------------------------------------------------------------------------*/
void convert_a2b(char* buf
, int* index
, char* d_buf
, int* d_ind
, int* num_bit
){
while((buf
[*index
] != ' ') && (buf
[*index
] != '\0') && (buf
[*index
] != '\n')){
d_buf
[*d_ind
] = buf
[*index
] > '9' ? ((buf
[*index
] & 0xf) + 9) : buf
[*index
] & 0xf;
/*-------------------------------------------------------------------------------
convert unsigned int to char array
--------------------------------------------------------------------------------*/
unsigned int mask_low_bits(int mask_num
, int num
, unsigned int val
){
val
>>= (num
- mask_num
);// shift and drop bits.
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
void shift_left(unsigned int o_data
, char* val
, int num
){
*val
= (o_data
<< num
) | *val
;
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
void tag_address(long long addr
, long long * way
, unsigned int* tag_data
){
*tag_data
= (addr
>> 16) & 0xffffff; //[39:16]
/*-------------------------------------------------------------------------------
slam_memory(data pointer, size, argument location, valid);
--------------------------------------------------------------------------------*/
void slam_memory(f_state_ptr val
, int size
, int arg_loc
, int valid
, int loc
){
tf_nodeinfo(arg_loc
, &node_info
);
switch(node_info
.node_type
){
tf_nodeinfo(arg_loc
, &node_info
);
word
= node_info
.node_ngroups
* 2;
for(size
= 0;size
< node_info
.node_mem_size
;size
++){
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
] = valid
? val
[ind
].aval
.cval
[loc
] : 0 ; //0xff;
bvalPtr
[groups
] = valid
? val
[ind
].bval
[loc
] : 0; //0xff;
tf_exprinfo(arg_loc
, &expr_info
);
for(groups
= 0; groups
< expr_info
.expr_ngroups
; groups
++){
expr_info
.expr_value_p
[groups
].avalbits
= valid
? val
[groups
].aval
.cval
[loc
] : 0xffffffff;
expr_info
.expr_value_p
[groups
].bvalbits
= valid
? val
[groups
].bval
[loc
] : 0xffffffff;
tf_exprinfo(arg_loc
, &expr_info
);
for(groups
= 0; groups
< expr_info
.expr_ngroups
; groups
++){
expr_info
.expr_value_p
[groups
].avalbits
= valid
? val
[groups
].aval
.cval
[loc
] : 0xffffffff;
expr_info
.expr_value_p
[groups
].bvalbits
= valid
? val
[groups
].bval
[loc
] : 0xffffffff;
/*-------------------------------------------------------------------------------
slam_memory(data pointer, size, argument location, valid);
--------------------------------------------------------------------------------*/
void dump_memory(f_state_ptr val
, int size
, int arg_loc
, int loc
){
tf_nodeinfo(arg_loc
, &node_info
);
switch(node_info
.node_type
){
word
= node_info
.node_ngroups
* 2;
for(size
= 0;size
< node_info
.node_mem_size
;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
++){
val
[groups
].aval
.cval
[loc
] = node_info
.node_value
.vecval_p
[groups
].avalbits
;
val
[groups
].bval
[loc
] = node_info
.node_value
.vecval_p
[groups
].bvalbits
;
for(groups
= 0; groups
< node_info
.node_ngroups
; groups
++){
val
[groups
].aval
.cval
[loc
] = node_info
.node_value
.vecval_p
[groups
].avalbits
;
val
[groups
].bval
[loc
] = node_info
.node_value
.vecval_p
[groups
].bvalbits
;
/*-------------------------------------------------------------------------------
convert unsigned int to char array
--------------------------------------------------------------------------------*/
void mask_value(int width
, long long* val
){
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
avl_node_ptr
create_event_node(long long addr
, f_state_ptr val
, char* buf
, int size
){
n_ptr
= (avl_node_ptr
)malloc(sizeof(struct avl_node
));
t_tmp
= (f_state_ptr
)malloc(sizeof(struct f_state_node
) * 1);
cmt
= (char*)malloc(strlen(buf
));
for(i
= 0; i
< size
;i
++)t_tmp
[i
] = val
[i
];
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
int insert_event_node(avl_node_ptr
*t_ptr
, long long* addr
,
f_state_ptr val
, char* buf
, int* size
){
(*t_ptr
) = create_event_node(*addr
, val
, buf
, *size
); // add new node to tree.
io_printf((char *)"Error : Out of memory\n");
else if(*addr
== (*t_ptr
)->addr
){
for(i
= 0; i
< *size
;i
++)(*t_ptr
)->val
[i
] = val
[i
];
if(*addr
< (*t_ptr
)->addr
)insert_event_node(&(*t_ptr
)->leftPtr
, addr
, val
, buf
, size
);
else insert_event_node(&(*t_ptr
)->rightPtr
, addr
, val
, buf
, size
);
if(difference(*t_ptr
) > 1) balance_left (&(*t_ptr
));
else if(difference(*t_ptr
) < -1) balance_right(&(*t_ptr
));
/*-------------------------------------------------------------------------------
--------------------------------------------------------------------------------*/
void get_event(avl_conf_ptr a_tree
, FILE *fp
){
char buf
[BUFFER
], d_buf
[BUFFER
];
int ind
, d_ind
, num_bit
, type
, reg
, size
;
while(fgets(buf
, BUFFER
, fp
)){
ind
= remove_leading_space(buf
, 0, BUFFER
);
if(ind
< 0)continue;//empty string
if(strncmp(buf
,"trig_pc_d", 9) == 0){
for(ind
= 0; ind
< strlen(buf
); ind
++)
buf
[ind
] == '(')buf
[ind
] = ' ';
ind
= remove_leading_space(buf
, 0, BUFFER
);
convert_a2b(buf
, &ind
, d_buf
, &d_ind
, &num_bit
);
strcpy(buf
, buf
+ ind
);//remove dummy argument
ind
= remove_leading_space(buf
, 0, BUFFER
);
strcpy(buf
, buf
+ ind
);//remove hexa indicator
for(ind
= 0; ind
< strlen(buf
); ind
++)
if(((buf
[ind
] == '\'') && (buf
[ind
+1] == 'h')) ||
((buf
[ind
] == '0') && (buf
[ind
+1] == 'x'))) {
addr
= ato_long(buf
, &ind
);
ind
= remove_leading_space(buf
, 0, BUFFER
);
if(strncmp(buf
,"printhex", 8) == 0)type
= 1;
if(strncmp(buf
,"printdec", 8) == 0)type
= 2;
if(type
== 0)continue;//find verilog event only
ind
= remove_leading_space(buf
, 0, BUFFER
);
strcpy(buf
, buf
+ 1);//remove the leading "
for(ind
= 0; ind
< strlen(buf
);ind
++)
(buf
[ind
] != '\n'))d_buf
[ind
] = buf
[ind
];
buf
[ind
] == '\n' )continue;
strcpy(buf
, buf
+ ind
+ 1);//remove the tailing "
ind
= remove_leading_space(buf
, 0, BUFFER
);
reg
= 8 + (buf
[2] & 0x0f);
reg
= 16 + (buf
[2] & 0x0f);
reg
= 24 + (buf
[2] & 0x0f);
else continue;//no register
f_val
[0].aval
.ival
[0] = reg
;
insert_event_node(&(a_tree
)->data
, &addr
, f_val
, d_buf
, &size
);
// /*-------------------------------------------------------------------------------
// create an instance for any needs.
// --------------------------------------------------------------------------------*/
// void create_event_handle_call()
// a_tree = (avl_conf_ptr)malloc(sizeof(struct avl_conf_node));
// str = tf_getcstringp(1); // get a file name.
// if((fp = fopen(str, "r")) == NULL){
// tf_error((char *)"Error: cannot open the file %s for reading\n", str);
// a_tree->dram = 0;//dram
// get_event(a_tree, fp);
// tf_putp(0, (unsigned int)a_tree);//reurn handle
// /*-------------------------------------------------------------------------------
// monitor verilog even and do the proper action when it hits.
// --------------------------------------------------------------------------------*/
// int thread, word, size, groups, low, high;
// s_tfnodeinfo node_info;
// handle = (avl_conf_ptr) tf_getp(1);
// // addr = (unsigned long long)tf_getp(3);
// low = tf_getlongp(&high, 3);
// t_ptr = search_node(&(handle)->data, &addr);
// if(t_ptr->val[0].aval.ival[0] < 8)str = 'g';
// else if(t_ptr->val[0].aval.ival[0] < 16)str = 'o';
// else if(t_ptr->val[0].aval.ival[0] < 24)str = 'l';
// thread = tf_getp(2);//get thread
// size = (thread << 5) | (t_ptr->val[0].aval.ival[0] & 0x1f);
// tf_nodeinfo(4, &node_info);
// word = node_info.node_ngroups * 2;
// avalPtr = node_info.node_value.memoryval_p + size * word;
// for(groups = node_info.node_ngroups - 2; groups >= 0;groups--){
// val |= (avalPtr[groups] & 0xff);
// switch(t_ptr->val[0].bval[0]){//type
// if(t_ptr->comment)io_printf((char *)"%0dInfo:%s reg(%c%d)->val(0x%llx)\n", tf_gettime(), t_ptr->comment, str,
// (t_ptr->val[0].aval.ival[0] & 7), val);
// else io_printf((char *)"%0dInfo: reg(%c%d)->val(0x%llx)\n", tf_gettime(), str,
// (t_ptr->val[0].aval.ival[0] & 7), val);
// if(t_ptr->comment)io_printf((char *)"%0dInfo:%s reg(%c%d)->val(%lld)\n", tf_gettime(), t_ptr->comment, str,
// (t_ptr->val[0].aval.ival[0] & 7), val);
// else io_printf((char *)"%0dInfo: reg(%c%d)->val(%lld)\n", tf_gettime(), str,
// (t_ptr->val[0].aval.ival[0] & 7), val);