* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: socket.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 CMD_BUFSIZE 10240
#define RCV_BUFSIZE 102400
#define PLI_QUIT 0x01 /* None */
#define PLI_SSTEP 0x02 /* %1 th id */
#define PLI_READ_TH_REG 0x03 /* %1 th id, %2 win num, %3 reg num */
#define PLI_READ_TH_CTL_REG 0x04 /* %1 th id, %2 reg num */
#define PLI_READ_TH_FP_REG_I 0x05 /* %1 th id, %2 reg num */
#define PLI_READ_TH_FP_REG_X 0x06 /* %1 th id, %2 reg num */
#define PLI_RTL_DATA 0x07 /* 436 bytes rtl data */
#define PLI_RTL_CYCLE 0x08
#define PLI_WRITE_TH_XCC_REG 0x09
#define PLI_WRITE_TH_REG_HI 10
#define PLI_IHWTW 0x11 /* %1=tid %2=itlb-write-time
#define PLI_DHWTW 0x12 /* %1=tid %2=dtlb-write-time
%3=VA %4=ASI# %5=entry# */
#define PLI_ITLBREAD 0x13 /* %1=tid %2=itlb-read-time */
#define PLI_DTLBREAD 0x14 /* %1=tid %2=dtlb-read-time */
#define PLI_ITLBWRITE 0x15 /* %1=tid %2=itlb-write-time
#define PLI_DTLBWRITE 0x16 /* %1=tid %2=dtlb-write-time
#define PLI_ITLBPROBE 0x17 /* %1=tid %2=itlbprobe-time */
/* %0=cmd(1) for every command. (N) - N bytes */
/* %1=tid(1),%2=pa(5),%3=data(8),%4=size_vec(1),%5=itype(1),%6=time(4) */
#define PLI_MEM_ST_ISSUE 0x20
/* %1=tid(1),%2=pa(5),%3=size_vec(1),%4=inv_vec(2),%5=time(4) */
#define PLI_MEM_ST_L2_COMMIT 0x21
/* %1=cid(1),%2=src_tid(1),%3=pa(5),%4=time(4) */
#define PLI_MEM_ST_INV 0x22
/* %1=cid(1),%2=pa(5),%3=time(4) */
#define PLI_MEM_ST_UPDATE 0x23
/* %1=cid(1),%2=rmo(1),%3=time(4) */
#define PLI_MEM_ST_ACK 0x24
/* %1=tid(1),%2=ld_id(4),%3=pa(5),%4=size(1),%5=itype(1),%6=cache(1),%7=time(4)
#define PLI_MEM_LD_ISSUE 0x25
/* %1=tid(1),%2=ld_id(4),%3=pa(5),%4=size(1),%5=data_src(1),%6=cache(1),%7=time(4)
#define PLI_MEM_LD_DATA 0x26
/* %1=cid(1),%2=ld_id(4),%3=pa(5),%4=time(4) */
#define PLI_MEM_LD_FILL 0x27
/* %1=pa(5),%2=set(4),%3=way(1),%4=inv_vec(4),%5=time(4) */
#define PLI_MEM_EVICT 0x28
/* %1=cid(1),%2=src_bankid(1),%3=set(4),%4=way(1),%5=time(4) */
#define PLI_MEM_EVICT_INV 0x29
#define PLI_INT_INTP 0x40
/* %1=tid(1),%2=asr(1),%3=value(8) */
#define PLI_ASR_WRITE 0x41
/* %1=tid(1),%2=asi(1),%3=va(8),%4=value(8) */
#define PLI_ASI_WRITE 0x42
/* %1=tid(1) %2=asi(1) %3=va(1) %4=value(8) */
#define PLI_ASI_READ 0x43
/* %1=va(1) %2=value(8) */
#define PLI_CMP_WRITE 0x44
/* %1=tid(1),%2=asr(1),%3=value(8) */
#define PLI_ASR_READ 0x45
//list node for socket buffer
typedef struct buf_head_node
{
buf_node_ptr head_ptr
, tail_ptr
;
typedef struct sock_handle
{
char data
[RCV_BUFSIZE
+1];
buf_head_ptr active
, heap
;
int debug_socket
, use_flush
, send_count
;
// Execution string REGEX
static char *sim_instr_ere
= "([0-9]+):.+swvp([0-9]+).th([0-9]+).+<v:([0-9A-fa-f]+)>.+<p:([0-9A-Fa-f]+)>(.*)\n";
static char* symbolic [] = {
"TSTATE6","", "", "", "",
"ASYNCHRONOUS_FAULT_STATUS",
"ASYNCHRONOUS_FAULT_ADDRESS",
int send_socket_nfd(char* send_buf
, int len
);
/*----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
int csocket
, sockfd
, status
;
sock
= (sockPtr
)malloc(sizeof(struct sock_handle
));
pargs
= mc_scan_plusargs ("csocket=");
cDispmon("socket", MON_ERR
, "Socket Not Found");
if((sockfd
= socket (AF_INET
, SOCK_STREAM
, 0)) < 0){
cDispmon("socket", MON_ERR
, "Can't open stream socket");
bzero ((char *) &sin
, sizeof (sin
));
sin
.sin_family
= AF_INET
;
sin
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
sin
.sin_port
= htons (csocket
);
if(connect (sockfd
, (struct sockaddr
*) &sin
, sizeof (sin
)) < 0){
cDispmon("socket", MON_ERR
, "Can't connect to in server");
status
= fcntl(sockfd
, F_GETFL
, 0);
fcntl(sockfd
, F_SETFL
, status
);
sockbufsize
= RCV_BUFSIZE
;
err
= setsockopt(sockfd
, SOL_SOCKET
, SO_SNDBUF
, (char *)&sockbufsize
,
(int)sizeof(sockbufsize
));
err
= getsockopt(sockfd
, SOL_SOCKET
, SO_RCVBUF
, (char *)&sockbufsize
,&size
);
cDispmon("socket", MON_INFO
, "Socket Rcv Buffer size is %d bytes", sockbufsize
);
err
= getsockopt(sockfd
, SOL_SOCKET
, SO_SNDBUF
, (char *)&sockbufsize
,&size
);
cDispmon("socket", MON_INFO
, "Socket Snd Buffer size is %d bytes", sockbufsize
);
pargs
= mc_scan_plusargs ("max_count=");
if(pargs
!= (char *) 0) {
sock
->max
= atoi (pargs
);
sock
->active
= (buf_head_ptr
)malloc(sizeof(struct buf_head_node
));
sock
->heap
= (buf_head_ptr
)malloc(sizeof(struct buf_head_node
));
sock
->active
->head_ptr
= 0;
sock
->active
->tail_ptr
= 0;
sock
->heap
->head_ptr
= 0;
sock
->heap
->tail_ptr
= 0;
cDispmon ("socket", MON_NORMAL
, "Initialized socket %d.", csocket
);
// Initialize the Pattern matching strings
if (regcomp(®ex
, sim_instr_ere
, REG_EXTENDED
) != 0) {
cDispmon ("socket", MON_ERR
, "Regex compilation problem in Regcomp()");
// Initialize the Instruction sequence Queue
q_instr
= init_q(q_instr
);
cDispmon ("socket", MON_NORMAL
, "Initialized Sequence Queue\n");
if(mc_scan_plusargs ("debug_socket") ) {
if(mc_scan_plusargs ("socket_use_flush") ) {
cDispmon ("socket", MON_NORMAL
, "Socket in flush mode\n");
if(mc_scan_plusargs ("debug_queue") ) {
if(mc_scan_plusargs ("quiet") ) {
if(mc_scan_plusargs ("nas_trace") ) {
if((nas_fd
= open("nas.trace", O_CREAT
|O_WRONLY
|O_TRUNC
, S_IRUSR
|S_IWUSR
|S_IRGRP
))==-1) {
nas_fd
= fopen("nas.trace", "w");
cDispmon ("socket", MON_ERR
, "Could not open \"nas.trace\" for writing!");
cDispmon ("socket", MON_NORMAL
, "Nas trace dump enabled\n");
if(!(mc_scan_plusargs ("show_pa") == NULL
)) {
cDispmon ("socket", MON_NORMAL
, "Enabled PA display\n");
/*----------------------------------------------------------------------------
do the fron operation on the buffer list.
-----------------------------------------------------------------------------*/
buf_node_ptr
buf_pop(buf_head_ptr handle
)
tmp_ptr
= handle
->head_ptr
;
handle
->head_ptr
= tmp_ptr
->next
;
/*----------------------------------------------------------------------------
push a node on the buffer list.
-----------------------------------------------------------------------------*/
void buf_push(buf_head_ptr handle
, buf_node_ptr
* item
)
(*item
)->next
= 0;//indicates the last record.
if(handle
->head_ptr
== 0)
handle
->head_ptr
= *item
;
handle
->tail_ptr
->next
= *item
;
handle
->tail_ptr
= *item
;
/*----------------------------------------------------------------------------
remove leading space or tab.
if found carriage return, return -1 to indicate anenpty string.
-----------------------------------------------------------------------------*/
int rm_leading_space(char* buf
, int index
, int max
){
while((index
< max
) && (buf
[index
] == ' ' ||
buf
[index
] == ',' ))index
++;
return buf
[index
] == '\n' || buf
[index
] == '\0' ? -1 : index
;
/*----------------------------------------------------------------------------
Convert hex string to 64 bit value
-----------------------------------------------------------------------------*/
unsigned long long str2hex64(char* buf
) {
unsigned long long val
= 0;
for (i
= 0; i
<strlen (buf
); i
++) {
val
|= buf
[i
] > '9' ? ((buf
[i
] & 0xf) + 9) : buf
[i
] & 0xf;
/*----------------------------------------------------------------------------
Extract the instruction strings and insert into instr queue
Return 0 if valid match found, non-zero otherwise ..
216: [swvp0.th00] <v:fffffffff0080350> <p:000000fff0080350> nop
\d+: [swvp\d.th\d+] <v:val64> <p:val64> INSTRUCTION STRING
-----------------------------------------------------------------------------*/
int extract_instr_info(char *buf
) {
// Allocate submatch arrays
submatch
= (regmatch_t
*)malloc(sizeof(regmatch_t
)*(regex
.re_nsub
+1));
cDispmon ("socket", MON_ERR
, "Error in Allocating for Subexpressions");
if ((ret
= regexec (®ex
, buf
, regex
.re_nsub
+1, submatch
, 0)) ==0) {
// Populate the submatch variables ..
for (i
= 1; i
<=regex
.re_nsub
; i
++) {
if (submatch
[i
].rm_so
!= -1) {
len
= submatch
[i
].rm_eo
-submatch
[i
].rm_so
;
substrings
[i
] = (char *)malloc(sizeof(char)*(len
+1));
strncpy(substrings
[i
], buf
+submatch
[i
].rm_so
, len
);
substrings
[i
][len
] = NULL
;
// Now assign the values and push into Queue
item
= (t_instr_item_ptr
)malloc(sizeof(struct t_instr_item
));
cDispmon ("socket", MON_ERR
, "Malloc Error Instr queue (%d)");
item
->num
= atoi(substrings
[1]);
coreid
= atoi(substrings
[2]);
tid
= atoi(substrings
[3]);
item
->va
= str2hex64(substrings
[4]) & 0xffffffffffffULL
; // Only 48 bits
item
->pa
= str2hex64(substrings
[5]) & 0xffffffffffffULL
;
item
->instruction
= (char*)malloc(sizeof(char)*strlen(substrings
[6])+1);
strcpy (item
->instruction
, substrings
[6]);
if (! push_q (q_instr
, coreid
*NUMCORE
+tid
, item
)) {
cDispmon ("socket", MON_ERR
, "Error pushing values to queue (%d)",
for (i
= 1; i
<=regex
.re_nsub
; i
++) {
if (ret
!= REG_NOMATCH
) {
cDispmon ("socket", MON_ERR
, "Error in Regexec()\n");
/*----------------------------------------------------------------------------
Extract the updated data from simics and put into Expected queue ..
STEP: <tid> G <gl> <num> <val64>
STEP: <tid> W <win> <num> <val64>
STEP: <tid> F <num> <val32>
STEP: <tid> C <num> <val64>
Assumption - A carriage return will delimit instruction boundary
-----------------------------------------------------------------------------*/
void extract_step_info(mt_list_ptr queue
, char *buf
)
char buf1
[RCV_BUFSIZE
], buf2
[256], type
;
unsigned long long value
;
int tid
, regnum
, win
=0, level
=0;
t_check_item_ptr item
; // Individual record items
// io_printf("socket > InFo:(%d), %s\n", time, buf);
// Break String into 'STEP: ..' Sequences
strseq
= strtok(buf1
, "STEP:");
currlen
= currlen
+strlen(strseq
)+5;
//printf ("Found string %s (%d)\n", strseq, currlen); fflush (NULL);
tid
= atoi (strtok(buf2
, " "));
// printf("\tTID = %d\n", tid);
type
= (strtok(NULL
, " "))[0];
// printf("\tTYPE = %c\n", type);
case 'G' : // Global Register
level
= atoi(strtok(NULL
, " "));
// printf("\tLevel = %d\n", level);
case 'W' : // Window Register
win
= atoi(strtok(NULL
, " "));
// printf("\tWin = %d\n", win);
// Next is register number
regnum
= atoi(strtok(NULL
, " "));
// printf("\tNum = %d\n", regnum);
// Last is value - 64 bits
value
= str2hex64(strtok(NULL
, " "));
// printf("\tval = %llx\n", value);
// OK Lets save this in queue # tid ..
item
= (t_check_item_ptr
)malloc(sizeof(struct t_check_item
));
cDispmon ("socket", MON_ERR
, "Malloc Error pushing values to queue (%d)",
if (! push_q (queue
, tid
, item
)) {
cDispmon ("socket", MON_ERR
, "Error pushing values to queue (%d)",
// Get next STEP: entry ..
strcpy(buf1
, buf
+currlen
);
strseq
= strtok(buf1
, "STEP:");
// Push a END_INSTR into the queue for instruction delimitation .
item
= (t_check_item_ptr
)malloc(sizeof(struct t_check_item
));
cDispmon ("socket", MON_ERR
, "Malloc Error pushing values to queue (%d)",
item
->reg_num
= END_INSTR
;
if (! push_q (queue
, tid
, item
)) {
cDispmon ("socket", MON_ERR
, "Error pushing values to queue (%d)",
/*-----------------------------------------------------------------------------
Process the receiving data from simics.
-----------------------------------------------------------------------------*/
int parse_data(mt_list_ptr queue
)
cDispmon ("socket", MON_DEBUG
, "parse_data(%d) [%s]\n", sock
->len
, sock
->data
);
tmp_buf
[num
] = sock
->data
[num
];
if(tmp_buf
[num
] == '\n'){
if(strncmp (tmp_buf
, "ERROR:", 6) == 0){
cDispmon ("socket", MON_WARN
, " %s ", tmp_buf
);
strcpy(sock
->data
, sock
->data
+ num
);
if(strncmp (tmp_buf
, "STEP: ", 6) == 0){
strcpy(sock
->data
, sock
->data
+ num
);
extract_step_info(queue
, tmp_buf
);
// Check for Instruction string
if (extract_instr_info(tmp_buf
) != 0) {
if(strncmp (tmp_buf
, "regval", 6) != 0){
cDispmon ("socket", MON_NORMAL
, "%s", tmp_buf
);
strcpy(sock
->data
, sock
->data
+ num
);
strcpy(sock
->data
, sock
->data
+ num
);
/*----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
char read_buf
[RCV_BUFSIZE
+1];
// io_printf("socket > Starting to read socket ..\n");
len
= RCV_BUFSIZE
- sock
->len
;
if (debug_socket
) cWritemon ("socket", MON_INFO
, "Starting read of (%d) bytes [%d]", len
, sock
->len
);
len
= read(sock
->sockfd
, read_buf
, len
);
if (debug_socket
) cDispmon ("socket", MON_INFO
, ".. read (%d) bytes", len
);
if (errno
!= EAGAIN
&& errno
!= EINTR
) {
cDispmon ("socket", MON_ERR
, "Socket read error");
send_socket_nfd(read_buf
, 1);
if (len
== (RCV_BUFSIZE
- sock
->len
)) {
strcat(sock
->data
, read_buf
);
read_buf
[len
- 1] != '\n' ? cDispmon ("socket", MON_DEBUG
, "[%s:]", read_buf
) :
cWritemon ("socket", MON_DEBUG
, "[%s]", read_buf
);
// io_printf("socket > Just read %d from socket (Q=%d)\n", len,sock->len);
/*----------------------------------------------------------------------------
Receiving data from server.
Return back an information on which threads are in Recd queue
Arguments : 1. 'Expected' Queue handle
2. Conditional 2nd Queue hanlde for oldest tid
3. Conditional Sent back oldest tid info for 1nd queue
Returned : 64 bit queue status array
Conditional oldest (integer)
-----------------------------------------------------------------------------*/
unsigned long long sim_recv_call()
mt_list_ptr exp_queue
, act_queue
;
unsigned long long status
;
// Get handle for Expected queue
exp_queue
= (mt_list_ptr
) tf_getp (1);
act_queue
= (mt_list_ptr
) tf_getp (2);
// Read Socket and parse if data available ..
cDispmon ("socket", MON_DEBUG
, "Checking socket for incoming ..");
while(read_socket_nfd() && sock
->len
) {
temp
= parse_data(exp_queue
);
if (!sock
->max_recv
) break;
// Get Expected queue status - 64 bits
status
= status_q(exp_queue
);
tf_putp(3, oldest_t(act_queue
));
cDispmon ("socket", MON_DEBUG
, "Recd & parsed data with status = %llx", status
);
tf_putlongp(0, status
, status
>> 32);
for (i
= NUMCORE
*NUMTHREAD
-1; i
>= 0; i
--) {
j
= j
+size_q (exp_queue
, i
);
k
= k
+size_q (act_queue
, i
);
l
= l
+size_q (q_instr
, i
);
cDispmon ("queue", MON_INFO
, "[sim_recv_call] Exp Q = %d Act Q = %d Inst Q = %d ", j
, k
, l
);
/*----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
int send_socket_nfd(char* send_buf
, int len
)
slen
= send(sock
->sockfd
, send_buf
, len
, 0);
tot_slen
= tot_slen
+ slen
;
cDispmon("socket", MON_INFO
, ".. Sent %d of %d bytes (%d total)", slen
, len
, tot_slen
);
case (EINTR
): cDispmon ("socket", MON_DEBUG
, "Err=EINTR"); break;
case (EMSGSIZE
): cDispmon ("socket", MON_DEBUG
, "Err=EMSGSIZE"); break;
case (ENOMEM
): cDispmon ("socket", MON_DEBUG
, "Err=ENOMEM"); break;
case (ENOSR
): cDispmon ("socket", MON_DEBUG
, "Err=ENOSR"); break;
case (EWOULDBLOCK
): cDispmon ("socket", MON_DEBUG
, "Err=EWOULDBLOCK");
case (EINVAL
): cDispmon ("socket", MON_DEBUG
, "Err=EINVAL"); break;
case (EPIPE
): cDispmon ("socket", MON_DEBUG
, "Err=EPIPE"); break;
default : cDispmon ("socket", MON_DEBUG
, "Err=%d", errno
);
cDispmon ("socket", MON_NORMAL
, "Trying, but can't send data. Length(%d)", len
);
for(i
= slen
; i
< len
;i
++)send_buf
[counter
++] = send_buf
[i
];
/*----------------------------------------------------------------------------
Copy data to socket send buffer.
-----------------------------------------------------------------------------*/
void copyPacket(char* buf
, int num
)
for(idx
= 0; idx
< num
; idx
++)sock
->rerv
[sock
->num
++] = buf
[idx
];
/*----------------------------------------------------------------------------
shift data in list to reserved buffer of send.
-----------------------------------------------------------------------------*/
available
= CMD_BUFSIZE
- sock
->num
;
while(sock
->active
->head_ptr
&& available
){
node
= sock
->active
->head_ptr
;
if(num
<= available
){//move whole junk.
node
= (buf_node_ptr
) buf_pop(sock
->active
);
copyPacket(node
->data
+node
->start
, num
);
buf_push(sock
->heap
, &node
);
copyPacket(node
->data
+node
->start
, num
);
/*----------------------------------------------------------------------------
add the new data to the end of send list.
-----------------------------------------------------------------------------*/
void add_node(char* buf
, int index
, int num
)
int idx
, nidx
, available
;
if(sock
->active
->head_ptr
){//fill the last node if space is available.
node
= sock
->active
->tail_ptr
;
nidx
= node
->start
+ node
->count
;
available
= NODE_SIZE
- nidx
;
available
= available
> num
? num
: available
;
node
->count
+= available
;
for(idx
= nidx
; idx
< (nidx
+ available
);idx
++)node
->data
[idx
] = buf
[index
++];
if(sock
->heap
->head_ptr
)node
= buf_pop(sock
->heap
);
else node
= (buf_node_ptr
)malloc(sizeof(struct buf_node
));
available
= NODE_SIZE
> num
? num
: NODE_SIZE
;
for(idx
= 0; idx
< available
; idx
++)node
->data
[idx
] = buf
[index
++];
buf_push(sock
->active
, &node
);
/*----------------------------------------------------------------------------
Make the reusable buffer for socket send.
-----------------------------------------------------------------------------*/
void handle_buf(char *cmd_buf
, int num
)
int available
, idx
, send_max
;
available
= sock
->num
+ num
;
if((cmd_buf
[0] != PLI_RETRY
) &&
(cmd_buf
[0] != PLI_QUIT
) &&
(available
< send_max
)){//not reach the minimum number to be sent.
copyPacket(cmd_buf
, num
);
if(debug_socket
&& cmd_buf
[0] == PLI_QUIT
) {
cDispmon("socket", MON_ALWAYS
, "Socket Send Count Was %d", send_count
);
available
= CMD_BUFSIZE
- sock
->num
;
available
= available
> num
? num
: available
;
copyPacket(cmd_buf
, available
);
send_socket_nfd(sock
->rerv
, sock
->num
);
if(sock
->active
->head_ptr
)packed();
available
= CMD_BUFSIZE
- sock
->num
;
if(available
&& num
&& (sock
->active
->head_ptr
== 0)){
//move data on the send buffer if avaiable.
available
= available
> num
? num
: available
;
copyPacket(cmd_buf
+idx
, available
);
if(num
)add_node(cmd_buf
, idx
, num
);
/*----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
cDispmon ("socket", MON_INFO
, "Flush Send Buffer (%d)\n", sock
->num
);
if (use_flush
&& ( sock
->num
>0))
send_socket_nfd(sock
->rerv
, sock
->num
);
/*----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
unsigned long long sim_send_call()
unsigned long long longword
;
int groups
, ind
, num
, size
, hword
, i
;
// Need to format params in a byte stream ..
// 1st two are <command> <tid>, which will fit in bytes.
// Others need to be formatted into bytes ..
ind
= 0; // ind tracks bytes in message
// num tracks current parameter ..
cmd_buf
[ind
] = tf_getp(1);
if (nas_trace
) write(nas_fd
, &cmd_buf
[0], 1);
if (nas_trace
) fprintf(nas_fd
, "%02x", cmd_buf
[0]);
switch(cmd_buf
[0]){ // {{{ Debug Dispmons ..
cWritemon ("socket", MON_INFO
, "Sending quit\n");
cWritemon ("socket", MON_INFO
, "Sending step(%d) ", sock
->step
);
cWritemon ("socket", MON_INFO
, "Sending read ");
case(PLI_READ_TH_CTL_REG
) :
cWritemon ("socket", MON_INFO
, "Sending read-special ");
case(PLI_READ_TH_FP_REG_I
) :
cWritemon ("socket", MON_INFO
, "Sending float-32 ");
case(PLI_READ_TH_FP_REG_X
) :
cWritemon ("socket", MON_INFO
, "Sending float-64 ");
case(PLI_RTL_DATA
) : cWritemon ("socket", MON_INFO
, "Sending rtl-data") ;
case(PLI_WRITE_TH_XCC_REG
) :
cWritemon ("socket", MON_INFO
, "Sending PLI_WRITE_TH_XCC_REG ");
case(PLI_WRITE_TH_REG_HI
) :
cWritemon ("socket", MON_INFO
, "Sending PLI_WRITE_TH_REG ");
cWritemon ("socket", MON_INFO
, "Sending ReTry remained-data(%0d)\n", sock
->num
);
case(PLI_IHWTW
) : cWritemon ("socket", MON_INFO
, "Sending IHWTW ");
case(PLI_DHWTW
) : cWritemon ("socket", MON_INFO
, "Sending DHWTW ");
case(PLI_ITLBREAD
) : cWritemon ("socket", MON_INFO
, "Sending ITLBREAD ");
case(PLI_DTLBREAD
) : cWritemon ("socket", MON_INFO
, "Sending DTLBREAD ");
case(PLI_ITLBWRITE
) : cWritemon ("socket", MON_INFO
, "Sending ITLBWRITE ");
case(PLI_DTLBWRITE
) : cWritemon ("socket", MON_INFO
, "Sending DTLBWRITE ");
case(PLI_ITLBPROBE
) : cWritemon ("socket", MON_INFO
, "Sending ITLBPROBE ");
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_ST_ISSUE "); break;
case(PLI_MEM_ST_L2_COMMIT
):
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_ST_L2_COMMIT "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_ST_INV "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_ST_UPDATE "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_ST_ACK "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_LD_ISSUE "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_LD_DATA "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_LD_FILL "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_EVICT "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_MEM_EVICT_INV "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_INT_INTP "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_ASR_WRITE "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_ASI_WRITE "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_ASI_READ "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_CMP_WRITE "); break;
cWritemon ("socket", MON_INFO
, "Sending PLI_ASR_READ "); break;
default: cDispmon ("socket", MON_INFO
, "Unknown message %x\n", cmd_buf
[0]);
for(num
= 1; num
< tf_nump(); num
++) {
cWritemon ("socket", MON_DEBUG
, " Parm(%d)[%db=%dB] = ",
word
= tf_getlongp(&hword
, num
+1);
longword
= hword
; longword
<<= 32; longword
|= word
;
for (i
=groups
; i
>0;i
--) {
cmd_buf
[ind
] = (longword
>> ((i
-1)*8)) & 0xff;
cWritemon ("socket", MON_DEBUG
, "%02x", (unsigned char)cmd_buf
[ind
]);
if (nas_trace
) write(nas_fd
, &cmd_buf
[ind
], 1);
if (nas_trace
) fprintf(nas_fd
, "%02x", (unsigned char) cmd_buf
[ind
]);
for (i
=groups
; i
>0;i
--) {
cmd_buf
[ind
] = (word
>> ((i
-1)*8)) & 0xff;
cWritemon ("socket", MON_DEBUG
, "%02x", (unsigned char)cmd_buf
[ind
]);
if (nas_trace
) write(nas_fd
, &cmd_buf
[ind
], 1);
if (nas_trace
) fprintf(nas_fd
, "%02x", (unsigned char) cmd_buf
[ind
]);
if (debug_socket
) cWritemon ("socket", MON_DEBUG
, "\n");
if(cmd_buf
[0] == PLI_RTL_CYCLE
){//send rtl cycle
for(ind
= 0; ind
< num
;ind
++)cmd_buf
[ind
] = PLI_RTL_CYCLE
;
if(cmd_buf
[0] == PLI_RTL_DATA
){
tf_nodeinfo(2, &node_info
);
for(groups
= (node_info
.node_ngroups
- 1); groups
>= 0; groups
--){
word
= node_info
.node_value
.vecval_p
[groups
].avalbits
;
cmd_buf
[ind
] = (word
>> 24) & 0xff;
cmd_buf
[ind
+1] = (word
>> 16) & 0xff;
cmd_buf
[ind
+2] = (word
>> 8) & 0xff;
cmd_buf
[ind
+3] = word
& 0xff;
if(cmd_buf
[0] == PLI_RETRY
)ind
= 0;
if(cmd_buf
[0] == PLI_QUIT
){
if(sock
->active
->head_ptr
)sock
->active
->head_ptr
= 0;
if (nas_trace
) close(nas_fd
);
if (nas_trace
) fclose(nas_fd
);
handle_buf(cmd_buf
, ind
);