URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2
- from Rev 45 to Rev 46
- ↔ Reverse comparison
Rev 45 → Rev 46
/bench/verilog/vpi/c/rsp-rtl_sim.h
60,12 → 60,16
|
#define DBG_ON 0 |
|
#define DBG_JP_VPI 0 |
|
#define DBG_VPI 0 |
|
extern int vpi_to_rsp_pipe[2]; // [0] - read, [1] - write |
extern int rsp_to_vpi_pipe[2]; // [0] - read, [1] - write |
extern int command_pipe[2]; // RSP end writes, VPI end reads ONLY |
#define DBG_CALLS 0 |
|
extern uint32_t vpi_to_rsp_pipe[2]; // [0] - read, [1] - write |
extern uint32_t rsp_to_vpi_pipe[2]; // [0] - read, [1] - write |
extern uint32_t command_pipe[2]; // RSP end writes, VPI end reads ONLY |
|
#if (DEBUG) || (DEBUG2) |
#define flush_debug() fflush(stdout) |
#else |
89,6 → 93,8
|
/* write a word to wishbone */ |
int dbg_wb_write32(uint32_t adr, uint32_t data); |
int dbg_wb_write16(uint32_t adr, uint16_t data); |
int dbg_wb_write8(uint32_t adr, uint8_t data); |
|
/* read a block from wishbone */ |
int dbg_wb_read_block32(uint32_t adr, uint32_t *data, int len); |
/bench/verilog/vpi/c/rsp-vpi.h
48,7 → 48,7
// 4'h4 cpu_ctrl_rd (output: ctrl value (2bits)) |
// 4'h5 cpu wr reg (inputs: address, data) |
// 4'h6 cpu rd reg (input: address; output: data) |
// 4'h7 wb wr 32 (inputs: address, data) |
// 4'h7 wb wr (inputs: address, data, size) |
// 4'h8 wb rd 32 (input: address; output: data) |
// 4'h9 wb wr block 32 (inputs: address, length, data) |
// 4'ha wb rd block 32 (inputs: address, length; output: data) |
65,7 → 65,7
#define CMD_CPU_CTRL_RD 0x4 |
#define CMD_CPU_WR_REG 0x5 |
#define CMD_CPU_RD_REG 0x6 |
#define CMD_WB_WR32 0x7 |
#define CMD_WB_WR 0x7 |
#define CMD_WB_RD32 0x8 |
#define CMD_WB_BLOCK_WR32 0x9 |
#define CMD_WB_BLOCK_RD32 0xa |
/bench/verilog/vpi/c/jp_vpi.c
217,9 → 217,9
|
#include <time.h> |
|
int vpi_to_rsp_pipe[2]; // [0] - read, [1] - write |
int rsp_to_vpi_pipe[2]; // [0] - read, [1] - write |
int command_pipe[2]; // RSP end writes, VPI end reads ONLY |
uint32_t vpi_to_rsp_pipe[2]; // [0] - read, [1] - write |
uint32_t rsp_to_vpi_pipe[2]; // [0] - read, [1] - write |
uint32_t command_pipe[2]; // RSP end writes, VPI end reads ONLY |
|
/* Global static to store the child rsp server PID if we want to kill it */ |
static pid_t rsp_server_child_pid = (pid_t) 0; // pid_t is just a signed int |
282,7 → 282,7
pid_t pid; |
int rv; |
|
if(DBG_ON) printf("jp_vpi: init_rsp_server\n"); |
if(DBG_JP_VPI) printf("jp_vpi: init_rsp_server\n"); |
|
// Setup pipes |
if(pipe(vpi_to_rsp_pipe) == -1) |
380,7 → 380,7
printf(" CPU reg read\n"); |
break; |
case 0x7 : |
printf(" WB write 32\n"); |
printf(" WB write\n"); |
break; |
case 0x8 : |
printf(" WB read 32\n"); |
414,7 → 414,7
|
unsigned char data; |
|
//if(DBG_ON) printf("check_for_command\n"); |
//if(DBG_JP_VPI) printf("check_for_command\n"); |
|
//n = read(rsp_to_vpi_pipe[0], &data, 1); |
|
433,7 → 433,7
exit(1); |
} |
|
if (DBG_ON) |
if (DBG_JP_VPI) |
{ |
printf("jp_vpi: c = %x:",data); |
print_command_string(data); |
457,7 → 457,7
// Now set the command value |
vpi_get_value(argh, &argval); |
|
argval.value.integer = (unsigned int) data; |
argval.value.integer = (uint32_t) data; |
|
// And vpi_put_value() it back into the sim |
vpi_put_value(argh, &argval, NULL, vpiNoDelay); |
466,9 → 466,9
vpi_free_object(args_iter); |
|
n = write(vpi_to_rsp_pipe[1],&data,1); |
if (DBG_ON) printf("jp_vpi: r"); |
if (DBG_JP_VPI) printf("jp_vpi: r"); |
|
if (DBG_ON) printf("\n"); |
if (DBG_JP_VPI) printf("\n"); |
|
return; |
} |
483,7 → 483,7
|
int n; |
|
unsigned int data; |
uint32_t data; |
|
char* recv_buf; |
|
497,7 → 497,7
return; |
} |
|
if (DBG_ON) printf("jp_vpi: get_command_address adr=0x%.8x\n",data); |
if (DBG_JP_VPI) printf("jp_vpi: get_command_address adr=0x%.8x\n",data); |
|
// now put the address into the argument passed to the task |
|
515,7 → 515,7
|
// Now set the address value |
vpi_get_value(argh, &argval); |
argval.value.integer = (unsigned int) data; |
argval.value.integer = (uint32_t) data; |
|
// And vpi_put_value() it back into the sim |
vpi_put_value(argh, &argval, NULL, vpiNoDelay); |
537,7 → 537,7
|
int n = 0; |
|
unsigned int data; |
uint32_t data; |
|
char* recv_buf; |
|
553,7 → 553,7
printf("jp_vpi: get_command_data errno: %d\n",errno); |
perror("jp_vpi: get_command_data read failed"); |
} |
if (DBG_ON) printf("jp_vpi: get_command_data = 0x%.8x\n",data); |
if (DBG_JP_VPI) printf("jp_vpi: get_command_data = 0x%.8x\n",data); |
|
// Obtain a handle to the argument list |
systfref = vpi_handle(vpiSysTfCall, NULL); |
569,7 → 569,7
|
// Now set the data value |
vpi_get_value(argh, &argval); |
argval.value.integer = (unsigned int) data; |
argval.value.integer = (uint32_t) data; |
|
// And vpi_put_value() it back into the sim |
vpi_put_value(argh, &argval, NULL, vpiNoDelay); |
592,8 → 592,8
|
int n; |
|
unsigned int data; |
unsigned int length; |
uint32_t data; |
uint32_t length; |
|
char* recv_buf; |
|
616,14 → 616,14
length = argval.value.integer; |
|
int num_words = length/4; |
|
if((length % 4) != 0) vpi_printf("length of %d bytes is not exactly word-aligned\n",length); |
|
//if((length % 4) != 0) vpi_printf("length of %d bytes is not exactly word-aligned\n",length); |
// If non-word aligned we throw away remainder |
int throw_away_bytes = length %4; |
|
int loaded_words = 0; |
|
if(DBG_ON)printf("jp_vpi: get_command_block_data: length=%d, num_words=%d\n",length,num_words); |
if(DBG_JP_VPI)printf("jp_vpi: get_command_block_data: length=%d, num_words=%d\n",length,num_words); |
|
// now get a handle on the next object (memory array) |
argh = vpi_scan(args_iter); |
658,7 → 658,7
|
if (array_word != NULL) |
{ |
argval.value.integer = (unsigned int) data; |
argval.value.integer = (uint32_t) data; |
|
// And vpi_put_value() it back into the sim |
vpi_put_value(array_word, &argval, NULL, vpiNoDelay); |
712,12 → 712,12
// Now set the data value |
vpi_get_value(argh, &argval); |
|
data = (unsigned int) argval.value.integer; |
data = (uint32_t) argval.value.integer; |
|
// Cleanup and return |
vpi_free_object(args_iter); |
|
if (DBG_ON) printf("jp_vpi: return_command_data 0x%.8x\n",data); |
if (DBG_JP_VPI) printf("jp_vpi: return_command_data 0x%.8x\n",data); |
|
send_buf = (char *) &data; //cast our long as a char buf |
|
738,11 → 738,17
|
int n; |
|
unsigned int data; |
unsigned int length; |
uint32_t data; |
uint32_t length; |
|
char* recv_buf; |
char *block_data_buf; |
uint32_t *block_word_data_buf_ptr; |
|
int num_words; |
int sent_words = 0; |
|
vpiHandle array_word; |
|
// Now setup the handles to verilog objects and check things |
// Obtain a handle to the argument list |
systfref = vpi_handle(vpiSysTfCall, NULL); |
771,16 → 777,31
return; |
} |
|
vpiHandle array_word; |
// We have to alloc memory here for lengths > 4 |
if (length > 4); |
{ |
block_data_buf = (char*) malloc(length * sizeof(char)); |
if (block_data_buf == NULL) |
{ |
vpi_printf("jp_vpi: return_command_block_data: Error. Could not allocate memory\n"); |
// Cleanup and return |
vpi_free_object(args_iter); |
return; |
} |
|
// Now cast it as a uint32_t array |
block_word_data_buf_ptr = (uint32_t *) block_data_buf; |
} |
|
num_words = length / 4; // We're always going to be dealing with whole words here |
|
int num_words = length/4; |
|
int sent_words = 0; |
|
// Loop to load the words |
if (DBG_JP_VPI) printf("jp_vpi: return_command_block_data: num_words %d\n", |
num_words); |
|
// Loop to load the words |
while (sent_words < num_words) { |
|
// now get a handle on the current word we want in the array that was passed to us |
// Get a handle on the current word we want in the array that was passed to us |
array_word = vpi_handle_by_index(argh, sent_words); |
|
if (array_word != NULL) |
787,22 → 808,36
{ |
vpi_get_value(array_word, &argval); |
|
data = (unsigned int) argval.value.integer; |
data = (uint32_t) argval.value.integer; |
|
block_word_data_buf_ptr[sent_words] = data; |
} |
else |
return; |
|
recv_buf = (char *) &data; |
|
n = write(vpi_to_rsp_pipe[1],recv_buf,4); |
|
if (DBG_JP_VPI) printf ( "jp_vpi: return_command_block_data: word %d 0x%.8x\n", |
sent_words, data); |
sent_words++; |
|
} |
|
if (!(length > 4)) |
{ |
block_data_buf = (char *) &data; |
} |
|
n = write(vpi_to_rsp_pipe[1],block_data_buf,length); |
|
|
if (length > 4) |
{ |
// Free the array |
free(block_data_buf); |
} |
|
|
// Cleanup and return |
vpi_free_object(args_iter); |
|
|
return; |
|
} |
818,7 → 853,7
// send a response byte |
n = write(vpi_to_rsp_pipe[1],&resp,1); |
|
if (DBG_ON) printf("jp_vpi: ret\n\n"); |
if (DBG_JP_VPI) printf("jp_vpi: ret\n\n"); |
|
return; |
|
/bench/verilog/vpi/c/rsp-rtl_sim.c
92,6 → 92,7
int n; |
char cmd_resp; |
|
if (DBG_CALLS)printf("send_command_to_vpi: cmd 0x%x \n", CMD); |
|
//n = write(rsp_to_vpi_pipe[1],&CMD, 1); // send the command to the sim |
n = write(command_pipe[1],&CMD, 1); // send the command to the sim |
112,6 → 113,8
|
char* send_buf; |
|
if (DBG_CALLS)printf("send_address_to_vpi: address 0x%.8x\n",address); |
|
send_buf = (char *) &address; |
|
n = write(rsp_to_vpi_pipe[1],send_buf, 4); // send the address to the sim |
128,6 → 131,8
|
char* send_buf; |
|
if (DBG_CALLS)printf("send_data_to_vpi: data 0x%.8x\n",data); |
|
send_buf = (char *) &data; |
|
n = write(rsp_to_vpi_pipe[1],send_buf, 4); // Write the data to the socket |
144,6 → 149,8
int n, i; |
|
char* send_buf; |
|
if (DBG_CALLS)printf("send_block_data_to_vpi: len %d\n",len); |
|
send_buf = (char *) data; |
|
190,6 → 197,8
|
n=0; |
|
if (DBG_CALLS)printf("rsp_rtl_sim: get_block_data_from_vpi len %d\n",len); |
|
while (n < len) |
{ |
|
198,13 → 207,16
if (status > 0) n += status; // we read "status" number of bytes |
|
} |
|
|
|
|
if (DBG_VPI){ |
printf("rsp-rtl_sim: get_block_data_from_vpi: %d bytes",len); |
for (i = 0;i < (len/4); i++) |
printf("rsp-rtl_sim: get_block_data_from_vpi: %d bytes: ",len); |
for (i = 0;i < (len); i++) |
{ |
printf("0x%.8x ",data[i]); |
if ((i%12) == 0) printf("\n\t"); |
printf("%.2x",recv_buf[i]); |
if ((i%3) == 0) printf(" "); |
|
} |
printf("\n"); |
} |
221,14 → 233,13
int n = 0; |
char tmp; |
|
if (DBG_CALLS)printf("get_response_from_vpi\n"); |
|
n = read(vpi_to_rsp_pipe[0],&tmp,1); // block and wait |
|
return; |
} |
|
/* Resets JTAG |
Writes TRST=0 |
and TRST=1 */ |
static void jp2_reset_JTAG() { |
int i; |
|
309,6 → 320,8
|
if (current_chain == chain) |
return DBG_ERR_OK; |
|
if (DBG_CALLS)printf("dbg_set_chain chain %d \n", chain); |
|
dbg_chain = chain; |
|
329,6 → 342,8
|
debug("\n"); |
debug2("ctrl\n"); |
|
if (DBG_CALLS)printf("dbg_ctrl: reset %d stall %d \n", reset, stall); |
|
dbg_set_chain(dbg_chain); |
|
352,6 → 367,8
|
debug("\n"); |
debug2("ctrl\n"); |
|
if (DBG_CALLS)printf("dbg_ctrl_read\n"); |
|
dbg_set_chain(dbg_chain); |
|
373,7 → 390,7
/* read a word from wishbone */ |
int dbg_wb_read32(uint32_t adr, uint32_t *data) |
{ |
//uint32_t resp; |
if (DBG_CALLS)printf("dbg_wb_read32: adr 0x%.8x \n",adr); |
|
dbg_set_chain(DC_WISHBONE); |
|
391,13 → 408,38
/* write a word to wishbone */ |
int dbg_wb_write32(uint32_t adr, uint32_t data) |
{ |
|
if (DBG_CALLS)printf("dbg_wb_write32: adr 0x%.8x data 0x%.8x\n",adr, data); |
|
dbg_set_chain(DC_WISHBONE); |
|
send_command_to_vpi(CMD_WB_WR); |
|
send_address_to_vpi(adr); |
|
send_data_to_vpi(sizeof(data)); |
|
send_data_to_vpi(data); |
|
get_response_from_vpi(); |
|
return 0; |
} |
|
/* write a hword to wishbone */ |
int dbg_wb_write16(uint32_t adr, uint16_t data) |
{ |
|
if (DBG_CALLS)printf("dbg_wb_write16: adr 0x%.8x data 0x%.4x\n",adr, data); |
|
dbg_set_chain(DC_WISHBONE); |
|
send_command_to_vpi(CMD_WB_WR32); |
send_command_to_vpi(CMD_WB_WR); |
|
send_address_to_vpi(adr); |
|
send_data_to_vpi(sizeof(data)); |
|
send_data_to_vpi(data); |
|
get_response_from_vpi(); |
405,6 → 447,28
return 0; |
} |
|
/* write a word to wishbone */ |
int dbg_wb_write8(uint32_t adr, uint8_t data) |
{ |
|
if (DBG_CALLS)printf("dbg_wb_write8: adr 0x%.8x data 0x%.2x\n",adr, data); |
|
dbg_set_chain(DC_WISHBONE); |
|
send_command_to_vpi(CMD_WB_WR); |
|
send_address_to_vpi(adr); |
|
send_data_to_vpi(sizeof(data)); |
|
send_data_to_vpi(data); |
|
get_response_from_vpi(); |
|
return 0; |
} |
|
|
/* read a block from wishbone */ |
int dbg_wb_read_block32(uint32_t adr, uint32_t *data, int len) |
{ |
411,7 → 475,7
|
// len is in B Y T E S ! ! |
|
if (DBG_VPI) printf("rsp-rtl_sim: block read len: %d from addr: 0x%.8x\n",len, adr); |
if (DBG_VPI) printf("xbrsp-rtl_sim: block read len: %d from addr: 0x%.8x\n",len, adr); |
|
dbg_set_chain(DC_WISHBONE); |
|
431,6 → 495,8
/* write a block to wishbone */ |
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, int len) |
{ |
|
if (DBG_CALLS)printf("dbg_wb_block32: adr 0x%.8x len %d bytes\n",adr, len); |
|
dbg_set_chain(DC_WISHBONE); |
|
450,6 → 516,8
/* read a register from cpu */ |
int dbg_cpu0_read(uint32_t adr, uint32_t *data) |
{ |
|
if (DBG_CALLS)printf("dbg_cpu0_read: adr 0x%.8x\n",adr); |
|
dbg_set_chain(DC_CPU0); |
|
469,7 → 537,7
int dbg_cpu0_write(uint32_t adr, uint32_t data) |
{ |
|
uint32_t resp; |
if (DBG_CALLS)printf("dbg_cpu0_write: adr 0x%.8x\n",adr); |
|
dbg_set_chain(DC_CPU0); |
|
/bench/verilog/vpi/c/gdb.c
60,6 → 60,7
// functions, adding stability when debugging on |
// a remote target. jb |
// 090608 A few hacks for VPI compatibilty added jb |
// 090827 Fixed endianness, block accesses, byte writes. jb |
|
#ifdef CYGWIN_COMPILE |
|
344,6 → 345,8
static void reset_or1k (void); |
static void gdb_ensure_or1k_stalled(); |
static int gdb_set_chain(int chain); |
static int gdb_write_byte(uint32_t adr, uint8_t data); |
static int gdb_write_short(uint32_t adr, uint16_t data); |
static int gdb_write_reg(uint32_t adr, uint32_t data); |
static int gdb_read_reg(uint32_t adr, uint32_t *data); |
static int gdb_write_block(uint32_t adr, uint32_t *data, int len); |
2171,8 → 2174,15
unsigned int addr; /* Where to read the memory */ |
int len; /* Number of bytes to read */ |
int off; /* Offset into the memory */ |
uint32_t temp_uint32 = 0; |
char *rec_buf; |
uint32_t temp_uint32 = 0; |
char *rec_buf, *rec_buf_ptr; |
int bytes_per_word = 4; /* Current OR implementation is 4-byte words */ |
int i; |
int len_cpy; |
/* Couple of temps we might need when doing aligning/leftover accesses */ |
uint32_t tmp_word; |
char *tmp_word_ptr = (char*) &tmp_word; |
|
|
|
if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len)) |
2193,7 → 2203,6
|
if(!(rec_buf = (char*)malloc(len))) { |
put_str_packet ("E01"); |
ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY); |
return; |
} |
|
2203,51 → 2212,132
// Set chain 5 --> Wishbone Memory chain |
err = gdb_set_chain(SC_WISHBONE); |
if(err){ |
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); |
put_str_packet ("E01"); |
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); |
put_str_packet ("E01"); |
return; |
} |
|
len_cpy = len; |
rec_buf_ptr = rec_buf; // Need to save a copy of pointer |
|
if (addr & 0x3) // address not aligned at the start |
{ |
// Have to read from the word-aligned address first and fetch the bytes |
// we need. |
if (DEBUG_GDB) |
printf("rsp_read_mem: unaligned address read - reading before bytes\n", |
err); |
int num_bytes_to_align = bytes_per_word - (addr & 0x3); |
uint32_t aligned_addr = addr & ~0x3; |
|
if (DEBUG_GDB) |
printf("rsp_read_mem: reading first %d of %d overall, from 0x%.8x\n", |
num_bytes_to_align, len_cpy, aligned_addr); |
|
err = gdb_read_reg(aligned_addr, &tmp_word); |
|
if (DEBUG_GDB) printf("rsp_read_mem: first word 0x%.8x\n", tmp_word); |
|
if(err){ |
put_str_packet ("E01"); |
return; |
} |
|
// Pack these bytes in first |
if (num_bytes_to_align > len_cpy) num_bytes_to_align = len_cpy; |
|
// A little strange - the OR is big endian, but they wind up |
// in this array in little endian format, so read them out |
// and pack the response array big endian (or, whatever the lowest |
// memory address first is... depends how you print it out I guess.) |
if (DEBUG_GDB_BLOCK_DATA)printf("rsp_read_mem: packing first bytes "); |
i=addr&0x3; int buf_ctr = 0; |
while (buf_ctr < num_bytes_to_align) |
{ |
rec_buf_ptr[buf_ctr] = tmp_word_ptr[bytes_per_word-1-i]; |
if (DEBUG_GDB_BLOCK_DATA)printf("i=%d=0x%x, ", i, |
tmp_word_ptr[bytes_per_word-1-i]); |
i++; |
buf_ctr++; |
} |
|
if (DEBUG_GDB_BLOCK_DATA)printf("\n"); |
|
// Adjust our status |
len_cpy -= num_bytes_to_align; addr += num_bytes_to_align; |
rec_buf_ptr += num_bytes_to_align; |
} |
if (len_cpy/bytes_per_word) // Now perform all full word accesses |
{ |
int words_to_read = len_cpy/bytes_per_word; // Full words to read |
if (DEBUG_GDB) printf("rsp_read_mem: reading %d words from 0x%.8x\n", |
words_to_read, addr); |
// Read full data words from Wishbone Memory chain |
err = gdb_read_block(addr, (uint32_t*)rec_buf_ptr, |
words_to_read*bytes_per_word); |
|
if(err){ |
put_str_packet ("E01"); |
return; |
} |
// A little strange, but these words will actually be little endian |
// in the buffer. So swap them around. |
uint32_t* rec_buf_u32_ptr = (uint32_t*)rec_buf_ptr; |
for(i=0;i<words_to_read;i++) |
{ |
// htonl() will work.(network byte order is big endian) |
// Note this is a hack, not actually about to send this |
// out onto the network. |
rec_buf_u32_ptr[i] = htonl(rec_buf_u32_ptr[i]); |
} |
|
|
// Read the data from Wishbone Memory chain |
err = gdb_read_block(addr, (uint32_t*)rec_buf, len); |
// Adjust our status |
len_cpy -= (words_to_read*bytes_per_word); |
addr += (words_to_read*bytes_per_word); |
rec_buf_ptr += (words_to_read*bytes_per_word); |
} |
if (len_cpy) // Leftover bytes |
{ |
if (DEBUG_GDB) |
printf("rsp_read_mem: reading %d left-over bytes from 0x%.8x\n", |
len_cpy, addr); |
|
err = gdb_read_reg(addr, &tmp_word); |
|
// Big endian - top byte first! |
for(i=0;i<len_cpy;i++) |
rec_buf_ptr[i] = tmp_word_ptr[bytes_per_word - 1 - i]; |
|
} |
|
if (DEBUG_GDB) |
printf("rsp_read_mem: err: %d\n",err); |
|
|
if(err){ |
put_str_packet ("E01"); |
return; |
} |
put_str_packet ("E01"); |
return; |
} |
|
/* Refill the buffer with the reply */ |
for( off = 0 ; off < len ; off ++ ) { |
; |
temp_uint32 = (temp_uint32 << 8) | (0x000000ff & *(rec_buf + off)); |
|
if((off %4 ) == 3){ |
temp_uint32 = htonl(temp_uint32); |
reg2hex (temp_uint32, &(p_buf->data[off * 2 - 6])); |
} |
if (DEBUG_GDB_BLOCK_DATA){ |
switch(off % 16) |
{ |
case 3: |
printf("Add 0x%08x Data 0x%08x ", addr + off - 3, temp_uint32); |
break; |
case 7: |
case 11: |
printf("0x%08x ", temp_uint32); |
break; |
case 15: |
printf("0x%08x\n", temp_uint32); |
break; |
default: |
break; |
} |
if ((len - off == 1) && (off % 16) < 15) printf("\n"); |
} |
; |
p_buf->data[(2*off)] = hexchars[((rec_buf[off]&0xf0)>>4)]; |
p_buf->data[(2*off)+1] = hexchars[(rec_buf[off]&0x0f)]; |
} |
|
|
if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout); |
free(rec_buf); |
p_buf->data[off * 2] = 0; /* End of string */ |
p_buf->len = strlen (p_buf->data); |
if (DEBUG_GDB_BLOCK_DATA){ |
printf("rsp_read_mem: adr 0x%.8x data: ", addr); |
for(i=0;i<len*2;i++) |
printf("%c",p_buf->data[i]); |
printf("\n"); |
} |
|
put_packet (p_buf); |
} /* rsp_read_mem () */ |
|
3050,9 → 3140,11
{ |
unsigned int addr; /* Where to write the memory */ |
int len; /* Number of bytes to write */ |
char *bindat; /* Pointer to the binary data */ |
char *bindat, *bindat_ptr; /* Pointer to the binary data */ |
int off = 0; /* Offset to start of binary data */ |
int newlen; /* Number of bytes in bin data */ |
int i; |
int bytes_per_word = 4; /* Current OR implementation is 4-byte words */ |
|
if (2 != sscanf (p_buf->data, "X%x,%x:", &addr, &len)) |
{ |
3129,8 → 3221,39
if ((len - off == 1) && (off % 16) < 15) printf("\n"); |
} |
} |
|
err = gdb_write_block(addr, (uint32_t*)bindat, len); |
|
bindat_ptr = bindat; // Copy of this pointer so we don't trash it |
if (addr & 0x3) // not perfectly aligned at beginning - fix |
{ |
if (DEBUG_GDB) printf("rsp_write_mem_bin: address not word aligned: 0x%.8x\n", addr);fflush (stdout); |
// Write enough to align us |
int bytes_to_write = bytes_per_word - (addr&0x3); |
if (bytes_to_write > len) bytes_to_write = len; // case of writing 1 byte to adr 0x1 |
if (DEBUG_GDB) printf("rsp_write_mem_bin: writing %d bytes of len (%d)\n", |
bytes_to_write, len);fflush (stdout); |
|
for (i=0;i<bytes_to_write;i++) err = gdb_write_byte(addr+i, (uint8_t) bindat_ptr[i]); |
addr += bytes_to_write; bindat_ptr += bytes_to_write; len -= bytes_to_write; |
if (DEBUG_GDB) printf("rsp_write_mem_bin: address should now be word aligned: 0x%.8x\n", addr);fflush (stdout); |
|
} |
if ((len > 3) && !err) // now write full words, if we can |
{ |
int words_to_write = len/bytes_per_word; |
if (DEBUG_GDB) printf("rsp_write_mem_bin: writing %d words from 0x%x, len %d bytes\n", |
words_to_write, addr, len);fflush (stdout); |
|
err = gdb_write_block(addr, (uint32_t*)bindat_ptr, (words_to_write*bytes_per_word)); |
addr+=(words_to_write*bytes_per_word); bindat_ptr+=(words_to_write*bytes_per_word); |
len-=(words_to_write*bytes_per_word); |
} |
if (len && !err) // leftover words. Write them out |
{ |
if (DEBUG_GDB) printf("rsp_write_mem_bin: writing remainder %d bytes to 0x%.8x\n", |
len, addr);fflush (stdout); |
|
for (i=0;i<len;i++) err = gdb_write_byte(addr+i, (uint8_t) bindat_ptr[i]); |
} |
if(err){ |
put_str_packet ("E01"); |
return; |
3380,6 → 3503,7
|
|
int gdb_read_reg(uint32_t adr, uint32_t *data) { |
if (DEBUG_CMDS) printf("rreg %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ? |
3390,7 → 3514,26
} |
} |
|
int gdb_write_byte(uint32_t adr, uint8_t data) { |
if (DEBUG_CMDS) printf("wbyte %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_write8(adr, data) ? |
ERR_CRC : ERR_NONE; |
default: return JTAG_PROXY_INVALID_CHAIN; |
} |
} |
|
int gdb_write_short(uint32_t adr, uint16_t data) { |
if (DEBUG_CMDS) printf("wshort %d\n", gdb_chain); fflush (stdout); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_write16(adr, data) ? |
ERR_CRC : ERR_NONE; |
default: return JTAG_PROXY_INVALID_CHAIN; |
} |
} |
|
int gdb_write_reg(uint32_t adr, uint32_t data) { |
if (DEBUG_CMDS) printf("wreg %d\n", gdb_chain); fflush (stdout); |
switch (gdb_chain) { /* remap registers, to be compatible with jp1 */ |
case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00; |
return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE; |
3402,7 → 3545,7
} |
|
int gdb_read_block(uint32_t adr, uint32_t *data, int len) { |
if (DEBUG_CMDS) printf("rb %d\n", gdb_chain); |
if (DEBUG_CMDS) printf("rb %d\n", gdb_chain); fflush (stdout); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? |
ERR_CRC : ERR_NONE; |
3411,7 → 3554,7
} |
|
int gdb_write_block(uint32_t adr, uint32_t *data, int len) { |
if (DEBUG_CMDS) printf("wb %d\n", gdb_chain); |
if (DEBUG_CMDS) printf("wb %d\n", gdb_chain); fflush (stdout); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? |
ERR_CRC : ERR_NONE; |
3434,569 → 3577,7
return rv; |
} |
|
/* Added by CZ 24/05/01 */ |
int GetServerSocket(const char* name, const char* proto, int port) { |
struct servent *service; |
struct protoent *protocol; |
struct sockaddr_in sa; |
struct hostent *hp; |
int sockfd; |
char myname[256]; |
//int flags; --changed to socklen_t for c++?! -- Julius |
socklen_t flags; |
char sTemp[256]; |
|
/* First, get the protocol number of TCP */ |
if (!(protocol = getprotobyname(proto))) { |
sprintf(sTemp, "Unable to load protocol \"%s\"", proto); |
perror(sTemp); |
return 0; |
} |
tcp_level = protocol->p_proto; /* Save for later */ |
|
/* If we weren't passed a non standard port, get the port |
from the services directory. */ |
if (!port && (service = getservbyname(name, protocol->p_name))) |
port = ntohs(service->s_port); |
|
/* Create the socket using the TCP protocol */ |
if ((sockfd = socket(PF_INET, SOCK_STREAM, protocol->p_proto)) < 0) { |
perror("Unable to create socket"); |
return 0; |
} |
|
flags = 1; |
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, |
(const char*)&flags, sizeof(int)) < 0) { |
sprintf(sTemp, "Can not set SO_REUSEADDR option on socket %d", sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* The server should also be non blocking. Get the current flags. */ |
if(fcntl(sockfd, F_GETFL, &flags) < 0) { |
sprintf(sTemp, "Unable to get flags for socket %d", sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* Set the nonblocking flag */ |
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { |
sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x", |
sockfd, flags | O_NONBLOCK); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* Find out what our address is */ |
memset(&sa, 0, sizeof(struct sockaddr_in)); |
gethostname(myname, sizeof(myname)); |
if(!(hp = gethostbyname(myname))) { |
perror("Unable to read hostname"); |
close(sockfd); |
return 0; |
} |
|
/* Bind our socket to the appropriate address */ |
sa.sin_family = hp->h_addrtype; |
sa.sin_port = htons(port); |
if(bind(sockfd, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)) < 0) { |
sprintf(sTemp, "Unable to bind socket %d to port %d", sockfd, port); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
serverIP = sa.sin_addr.s_addr; |
flags = sizeof(struct sockaddr_in); |
if(getsockname(sockfd, (struct sockaddr*)&sa, &flags) < 0) { |
sprintf(sTemp, "Unable to get socket information for socket %d", sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
serverPort = ntohs(sa.sin_port); |
|
/* Set the backlog to 1 connections */ |
if(listen(sockfd, 1) < 0) { |
sprintf(sTemp, "Unable to set backlog on socket %d to %d", sockfd, 1); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
return sockfd; |
} |
|
//void HandleServerSocket(Boolean block) { |
void HandleServerSocket(void) { |
struct pollfd fds[2]; |
int n; |
uint32_t temp_uint32; |
|
rebuild: |
n = 0; |
if(!server_fd && !gdb_fd) return; |
|
if(server_fd) { |
fds[n].fd = server_fd; |
fds[n].events = POLLIN; |
fds[n++].revents = 0; |
} |
if(gdb_fd) { |
fds[n].fd = gdb_fd; |
fds[n].events = POLLIN; |
fds[n++].revents = 0; |
} |
|
while(1) { |
switch(poll(fds, n, -1)) { |
case 0: |
case -1: |
if(errno == EINTR) continue; |
perror("poll"); |
server_fd = 0; |
return; |
default: |
/* Make sure to handle the gdb port first! */ |
if (gdb_fd && ((fds[0].revents && !server_fd) || (fds[1].revents && server_fd))) |
{ |
int revents = server_fd ? fds[1].revents : fds[0].revents; |
if (revents & POLLIN){ |
/* If we have an unacknowledged exception tell the GDB client. If this |
exception was a trap due to a memory breakpoint, then adjust the NPC. */ |
if (rsp.client_waiting) |
{ |
err = gdb_read_reg(PPC_CPU_REG_ADD, &temp_uint32); |
if(err) printf("Error read from PPC register\n"); |
if ((TARGET_SIGNAL_TRAP == rsp.sigval) && |
(NULL != mp_hash_lookup (BP_MEMORY, temp_uint32))) |
{ |
set_npc (temp_uint32); |
} |
|
rsp_report_exception(); |
rsp.client_waiting = 0; /* No longer waiting */ |
} |
GDBRequest(); |
} |
else {/* Error Occurred */ |
printf("\n%sSocket closed.\n",printTime()); |
//fprintf(stderr, |
//"Received flags 0x%08x on gdb socket. Shutting down.\n", revents); |
close(gdb_fd); |
gdb_fd = 0; |
} |
} |
|
// Go to blocking accept() instead of looping around through poll(), |
// takes a loot of CPU resources and it doesn't work when |
|
if(!gdb_fd) |
{ |
JTAGRequest(); |
rsp.client_waiting = 0; /* No longer waiting */ |
goto rebuild; |
} |
|
if(fds[0].revents && server_fd) { |
if(fds[0].revents & POLLIN) { |
JTAGRequest(); |
rsp.client_waiting = 0; /* No longer waiting */ |
goto rebuild; |
} else { /* Error Occurred */ |
fprintf(stderr, |
"Received flags 0x%08x on server. Shutting down.\n", |
fds[0].revents); |
close(server_fd); |
server_fd = 0; |
serverPort = 0; |
serverIP = 0; |
return; |
} |
} |
break; |
} /* End of switch statement */ |
} /* End of while statement */ |
} |
|
void JTAGRequest(void) { |
struct sockaddr_in sa; |
struct sockaddr* addr = (struct sockaddr*)&sa; |
//int n = sizeof(struct sockaddr_in); --changed to socklen_t from int type |
socklen_t n = sizeof(struct sockaddr_in); |
int fd = accept(server_fd, addr, &n); |
int on_off = 0; /* Turn off Nagel's algorithm on the socket */ |
int flags; |
char sTemp[256]; |
if (DEBUG_GDB) printf("JTAGRequest\n"); |
|
if(fd < 0) { |
/* This is valid, because a connection could have started, |
and then terminated due to a protocol error or user |
initiation before the accept could take place. */ |
if(errno != EWOULDBLOCK && errno != EAGAIN) { |
perror("accept"); |
close(server_fd); |
server_fd = 0; |
serverPort = 0; |
serverIP = 0; |
} |
return; |
} |
|
if(gdb_fd) { |
close(fd); |
return; |
} |
|
if(fcntl(fd, F_GETFL, &flags) < 0) { |
sprintf(sTemp, "Unable to get flags for gdb socket %d", fd); |
perror(sTemp); |
close(fd); |
return; |
} |
|
/* Rene |
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { |
sprintf(sTemp, "Unable to set flags for gdb socket %d to value 0x%08x", |
fd, flags | O_NONBLOCK); |
perror(sTemp); |
close(fd); |
return; |
} Rene */ |
|
if(setsockopt(fd, tcp_level, TCP_NODELAY, &on_off, sizeof(int)) < 0) { |
sprintf(sTemp, "Unable to disable Nagel's algorithm for socket %d.\nsetsockopt", fd); |
perror(sTemp); |
close(fd); |
return; |
} |
|
printf("\n%sConnection established from %s on port %d\n", printTime(),inet_ntoa(sa.sin_addr),ntohs(sa.sin_port)); |
gdb_fd = fd; |
} |
|
|
/*--------------------------------------------------------------------------- |
* Decode the GDB command. |
* |
*---------------------------------------------------------------------------*/ |
static void GDBRequest(void) { |
JTAGProxyWriteMessage msg_write; |
JTAGProxyReadMessage msg_read; |
JTAGProxyChainMessage msg_chain; |
JTAGProxyWriteResponse resp_write; |
JTAGProxyReadResponse resp_read; |
JTAGProxyChainResponse resp_chain; |
JTAGProxyBlockWriteMessage *msg_bwrite; |
JTAGProxyBlockReadMessage msg_bread; |
JTAGProxyBlockWriteResponse resp_bwrite; |
JTAGProxyBlockReadResponse *resp_bread; |
char *p_buf; |
uint32_t command; |
uint32_t length; |
int len, i; |
|
/* First, we must read the incomming command */ |
if(gdb_read(&command, sizeof(uint32_t)) < 0) { |
client_close ('1'); |
return; |
} |
command = ntohl(command); |
|
if(gdb_read(&length, sizeof(uint32_t)) < 0) { |
client_close ('2'); |
return; |
} |
length = ntohl(length); |
if (DEBUG_GDB) printf("\n%s-----------------------------------------------------\nCommand %d Length %d ", printTime(), command, length); |
|
if (DEBUG_GDB){ |
switch(command){ |
case JTAG_COMMAND_READ: |
printf("JTAG_COMMAND_READ \n"); |
break; |
case JTAG_COMMAND_WRITE: |
printf("JTAG_COMMAND_WRITE \n"); |
break; |
case JTAG_COMMAND_BLOCK_READ: |
printf("JTAG_COMMAND_BLOCK_READ \n"); |
break; |
case JTAG_COMMAND_BLOCK_WRITE: |
printf("JTAG_COMMAND_BLOCK_WRITE\n"); |
break; |
case JTAG_COMMAND_CHAIN: |
printf("JTAG_COMMAND_CHAIN \n"); |
break; |
} |
} |
|
/* Now, verify the protocol and implement the command */ |
switch(command) { |
case JTAG_COMMAND_WRITE: |
if(length != sizeof(msg_write) - 8) { |
ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); |
return; |
} |
p_buf = (char*)&msg_write; |
if(gdb_read(&p_buf[8], length) < 0) { |
client_close ('3'); |
return; |
} |
msg_write.address = ntohl(msg_write.address); |
msg_write.data_H = ntohl(msg_write.data_H); |
msg_write.data_L = ntohl(msg_write.data_L); |
err = gdb_write_reg(msg_write.address, msg_write.data_L); |
resp_write.status = htonl(err); |
if (DEBUG_GDB) printf("Write Reg to Chain %d at add 0x%08x -> H-Data 0x%08x L-Data 0x%08x Error %d", |
gdb_chain, msg_write.address, msg_write.data_H, msg_write.data_L, err);fflush (stdout); |
if(gdb_write(&resp_write, sizeof(resp_write)) < 0) { |
client_close ('4'); |
return; |
} |
break; |
case JTAG_COMMAND_READ: |
if(length != sizeof(msg_read) - 8) { |
ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); |
return; |
} |
p_buf = (char*)&msg_read; |
if(gdb_read(&p_buf[8], length) < 0) { |
client_close ('5'); |
return; |
} |
msg_read.address = ntohl(msg_read.address); |
err = gdb_read_reg(msg_read.address, (uint32_t *)&resp_read.data_L); |
if (DEBUG_GDB) printf("Read Reg from Chain %d at add 0x%08x", gdb_chain, msg_read.address); |
resp_read.status = htonl(err); |
resp_read.data_H = 0; |
resp_read.data_L = htonl(resp_read.data_L); |
if(gdb_write(&resp_read, sizeof(resp_read)) < 0) { |
client_close ('6'); |
return; |
} |
if (DEBUG_GDB) printf(" --> Data 0x%08x Error %d\n", htonl(resp_read.data_L), err);fflush (stdout); |
break; |
case JTAG_COMMAND_BLOCK_WRITE: |
if(length < sizeof(JTAGProxyBlockWriteMessage)-8) { |
ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); |
return; |
} |
if(!(p_buf = (char*)malloc(8+length))) { |
ProtocolClean(length, JTAG_PROXY_OUT_OF_MEMORY); |
return; |
} |
msg_bwrite = (JTAGProxyBlockWriteMessage*)p_buf; |
if(gdb_read(&p_buf[8], length) < 0) { |
client_close ('5'); |
free(p_buf); |
return; |
} |
msg_bwrite->address = ntohl(msg_bwrite->address); |
msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters); |
if (DEBUG_GDB) printf("Block Write to Chain %d start add 0x%08x Write %d (32 bit words):\n\n", gdb_chain, msg_bwrite->address, msg_bwrite->nRegisters); |
for(i=0;i<msg_bwrite->nRegisters;i++) { |
msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]); |
if (DEBUG_GDB_BLOCK_DATA){ |
if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bwrite->address + (i * 4), msg_bwrite->data[i]); |
else if ((i % 4) == 3) printf("0x%08x\n", msg_bwrite->data[i]); |
else printf("0x%08x ", msg_bwrite->data[i]); |
|
// add a new line on the last data, but not if it is the last one in the colum |
if ((msg_bwrite->nRegisters - i == 1) && (i % 4) < 3) printf("\n"); |
} |
} |
err = gdb_write_block(msg_bwrite->address, (uint32_t*)msg_bwrite->data, msg_bwrite->nRegisters * 4); |
if (DEBUG_GDB) printf("Error %x\n", err);fflush (stdout); |
resp_bwrite.status = htonl(err); |
free(p_buf); |
msg_bwrite = (JTAGProxyBlockWriteMessage *)NULL; |
p_buf = (char *)msg_bwrite; |
if(gdb_write(&resp_bwrite, sizeof(resp_bwrite)) < 0) { |
client_close ('4'); |
return; |
} |
break; |
case JTAG_COMMAND_BLOCK_READ: |
if(length != sizeof(msg_bread) - 8) { |
ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); |
return; |
} |
p_buf = (char*)&msg_bread; |
if(gdb_read(&p_buf[8], length) < 0) { |
client_close ('5'); |
return; |
} |
msg_bread.address = ntohl(msg_bread.address); |
msg_bread.nRegisters = ntohl(msg_bread.nRegisters); |
if (DEBUG_GDB) printf("Block Read from Chain %d start add 0x%08x Read %d (32 bit words):\n\n", gdb_chain, msg_bread.address, msg_bread.nRegisters); |
len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1); |
if(!(p_buf = (char*)malloc(len))) { |
ProtocolClean(0, JTAG_PROXY_OUT_OF_MEMORY); |
return; |
} |
resp_bread = (JTAGProxyBlockReadResponse*)p_buf; |
err = gdb_read_block(msg_bread.address, (uint32_t*)resp_bread->data, msg_bread.nRegisters * 4); |
for(i=0;i<msg_bread.nRegisters;i++) { |
/* Read previous, address next one. */ |
resp_bread->data[i] = htonl(resp_bread->data[i]); |
if (DEBUG_GDB_BLOCK_DATA){ |
if ((i % 4) == 0) printf("Add 0x%08x Data 0x%08x ", msg_bread.address + (i * 4), htonl(resp_bread->data[i])); |
else if ((i % 4) == 3) printf("0x%08x\n", htonl(resp_bread->data[i])); |
else printf("0x%08x ", htonl(resp_bread->data[i])); |
} |
// add a new line on the last data, but not if it is the last one in the colum |
if ((msg_bread.nRegisters - i == 1) && (i % 4) < 3) printf("\n"); |
} |
resp_bread->status = htonl(err); |
resp_bread->nRegisters = htonl(msg_bread.nRegisters); |
if (DEBUG_GDB) printf("\nError %x\n", err);fflush (stdout); |
if(gdb_write(resp_bread, len) < 0) { |
client_close ('6'); |
free(p_buf); |
return; |
} |
free(p_buf); |
resp_bread = (JTAGProxyBlockReadResponse *)NULL; |
p_buf = (char *)resp_bread; |
break; |
case JTAG_COMMAND_CHAIN: |
if(length != sizeof(msg_chain) - 8) { |
ProtocolClean(length, JTAG_PROXY_PROTOCOL_ERROR); |
return; |
} |
p_buf = (char*)&msg_chain; |
if(gdb_read(&p_buf[8], sizeof(msg_chain)-8) < 0) { |
client_close ('7'); |
return; |
} |
msg_chain.chain = htonl(msg_chain.chain); |
err = gdb_set_chain(msg_chain.chain); |
resp_chain.status = htonl(err); |
if (DEBUG_GDB){ |
switch(msg_chain.chain){ |
case SC_GLOBAL: /* 0 Global BS Chain */ |
printf("Set Chain %d Global BS Chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_RISC_DEBUG: /* 1 RISC Debug Interface chain */ |
printf("Set Chain %d RISC Debug Interface chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_RISC_TEST: /* 2 RISC Test Chain */ |
printf("Set Chain %d RISC Test Chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_TRACE: /* 3 Trace Chain */ |
printf("Set Chain %d Trace Chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_REGISTER: /* 4 Register Chain */ |
printf("Set Chain %d Register Chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_WISHBONE: /* 5 Memory chain */ |
printf("Set Chain %d Wishbone Memory chain Error %x\n", msg_chain.chain, err); |
break; |
case SC_BLOCK: /* 6 Block Chains */ |
printf("Set Chain %d Block Chains Error %x\n", msg_chain.chain, err); |
break; |
default: /* Invalid chain */ |
printf("Set Chain %d Invalid chain Error %x\n", msg_chain.chain, err); |
break; |
} |
fflush (stdout); |
} |
if(gdb_write(&resp_chain, sizeof(resp_chain)) < 0) { |
client_close ('8'); |
return; |
} |
break; |
default: |
perror("Unknown JTAG command.");fflush (stdout); |
ProtocolClean(length, JTAG_PROXY_COMMAND_NOT_IMPLEMENTED); |
break; |
} |
} |
|
static void ProtocolClean(int length, int32_t err) { |
char buffer[4096]; |
|
err = htonl(err); |
if(((gdb_read(buffer, length) < 0) || (gdb_write(&err, sizeof(err)) < 0)) && gdb_fd) { |
perror("gdb socket - 9"); |
close(gdb_fd); |
gdb_fd = 0; |
} |
} |
|
static int gdb_write(void* p_buf, int len) { |
int n; |
char* w_buf = (char*)p_buf; |
struct pollfd block; |
|
while(len) { |
if((n = write(gdb_fd, w_buf, len)) < 0) { |
switch(errno) { |
case EWOULDBLOCK: /* or EAGAIN */ |
/* We've been called on a descriptor marked |
for nonblocking I/O. We better simulate |
blocking behavior. */ |
block.fd = gdb_fd; |
block.events = POLLOUT; |
block.revents = 0; |
poll(&block, 1, -1); |
continue; |
case EINTR: |
continue; |
case EPIPE: |
close(gdb_fd); |
gdb_fd = 0; |
return -1; |
default: |
return -1; |
} |
} else { |
len -= n; |
w_buf += n; |
} |
} |
return 0; |
} |
|
static int gdb_read(void* p_buf, int len) { |
int n; |
char* r_buf = (char*)p_buf; |
struct pollfd block; |
|
while(len) { |
if((n = read(gdb_fd, r_buf, len)) < 0) { |
switch(errno) { |
case EWOULDBLOCK: /* or EAGAIN */ |
/* We've been called on a descriptor marked |
for nonblocking I/O. We better simulate |
blocking behavior. */ |
block.fd = gdb_fd; |
block.events = POLLIN; |
block.revents = 0; |
poll(&block, 1, -1); |
continue; |
case EINTR: |
continue; |
default: |
return -1; |
} |
} else if(n == 0) { |
close(gdb_fd); |
gdb_fd = 0; |
return -1; |
} else { |
len -= n; |
r_buf += n; |
} |
} |
return 0; |
} |
|
|
/***************************************************************************** |
* Close the connection to the client if it is open |
******************************************************************************/ |
/bench/verilog/vpi/verilog/vpi_debug_defines.v
191,7 → 191,7
`define CMD_CPU_CTRL_RD 4'h4 |
`define CMD_CPU_WR_REG 4'h5 |
`define CMD_CPU_RD_REG 4'h6 |
`define CMD_WB_WR32 4'h7 |
`define CMD_WB_WR 4'h7 |
`define CMD_WB_RD32 4'h8 |
`define CMD_WB_BLOCK_WR32 4'h9 |
`define CMD_WB_BLOCK_RD32 4'ha |
206,7 → 206,7
// 4'h4 cpu_ctrl_rd (output: ctrl value (2bits)) |
// 4'h5 cpu wr reg (inputs: address, data) |
// 4'h6 cpu rd reg (input: address; output: data) |
// 4'h7 wb wr 32 (inputs: address, data) |
// 4'h7 wb wr (inputs: address, size, data) |
// 4'h8 wb rd 32 (input: address; output: data) |
// 4'h9 wb wr block 32 (inputs: address, length, data) |
// 4'ha wb rd block 32 (inputs: address, length; output: data) |
/bench/verilog/vpi/verilog/vpi_debug_module.v
98,6 → 98,7
|
reg [1:0] cpu_ctrl_val; // two important bits for the ctrl reg |
reg [31:0] cmd_adr; |
reg [31:0] cmd_size; |
reg [31:0] cmd_data; |
|
|
228,15 → 229,34
|
end |
|
`CMD_WB_WR32 : |
`CMD_WB_WR : |
begin |
|
$get_command_address(cmd_adr); |
|
$get_command_data(cmd_size); |
|
$get_command_data(cmd_data); |
|
wb_write_32(cmd_data, cmd_adr, 16'h3); |
|
case (cmd_size) |
4 : |
begin |
wb_write_32(cmd_data, cmd_adr, 16'h3); |
end |
2 : |
begin |
wb_write_16(cmd_data[15:0], cmd_adr, 16'h1); |
end |
1 : |
begin |
wb_write_8(cmd_data[7:0], cmd_adr, 16'h0); |
end |
default: |
begin |
$display("* vpi_debug_module: CMD_WB_WR size incorrect: %d\n", cmd_size); |
end |
endcase // case (cmd_size) |
|
end |
|
`CMD_WB_RD32 : |
/rtl/verilog/components/debug_if/dbg_wb.v
337,7 → 337,8
end |
else |
begin |
dr[31:24] <= #1 {dr[30:24], 1'b0}; |
if (enable) // jb |
dr[31:24] <= #1 {dr[30:24], 1'b0}; |
latch_data <= #1 1'b0; |
end |
end |
353,7 → 354,8
end |
else |
begin |
dr[31:16] <= #1 {dr[30:16], 1'b0}; |
if (enable) // jb |
dr[31:16] <= #1 {dr[30:16], 1'b0}; |
latch_data <= #1 1'b0; |
end |
end |
366,7 → 368,8
end |
else |
begin |
dr[31:0] <= #1 {dr[30:0], 1'b0}; |
if (enable) // jb |
dr[31:0] <= #1 {dr[30:0], 1'b0}; |
latch_data <= #1 1'b0; |
end |
end |
499,8 → 502,8
else |
crc_cnt_en = 1'b0; |
end |
|
|
|
// crc counter |
always @ (posedge tck_i or posedge rst_i) |
begin |
606,7 → 609,6
crc_match_reg <= #1 crc_match_i; |
end |
|
|
// Length counter |
always @ (posedge tck_i or posedge rst_i) |
begin |
/sw/utils/bin2vmem.c
81,6 → 81,7
int write_size_word=0; // Disabled by default |
unsigned int image_size; |
int output_fmt = FMT_WITH_ADDR; // 0 - standard 4 per line with address, 1 - synfmt |
int bytes_per_word = BYTES_PER_WORD; |
|
// Counters keeping track of what we've printed |
int current_addr = 0; |
94,9 → 95,14
fprintf(stderr,"\n\tBy default the output is word addressed 32-bit words\n"); |
fprintf(stderr,"\tSpecify -synfmt on the command line after the filename\n"); |
fprintf(stderr,"\tto output in the alterative format, which is a simple\n"); |
fprintf(stderr,"\tlist of the data words.\n"); |
fprintf(stderr,"\tlist of the data words. The default bytes per word is 4.\n"); |
|
fprintf(stderr,"\n"); |
fprintf(stderr,"\tAdditionally, to specify the bytes per word (per line)\n"); |
fprintf(stderr,"\twhen specifying the -synfmt simple list format, use the\n"); |
fprintf(stderr,"\tswitch -bpw=N after specifying the -synfmt option. Example:\n"); |
fprintf(stderr,"\t\t./bin2vmem prog.bin -synfmt -bpw=2 > prog.vmem\n"); |
fprintf(stderr,"\n"); |
exit(1); |
} |
|
105,7 → 111,21
if (argc > 2) // check for the -synfmt switch |
{ |
if (strcmp("-synfmt", argv[FMT_CMDLINE_INDEX]) == 0) |
output_fmt = FMT_SYN; // synthesis friendly format - single column, no addr |
{ |
output_fmt = FMT_SYN; // synthesis friendly format - single column, no addr |
int bytes_per_word_tmp; |
if (argc > 3) // Check for extra bytes per word option |
if (1 == sscanf(argv[FMT_CMDLINE_INDEX+1], "-bpw=%d", &bytes_per_word_tmp)) |
{ |
if(bytes_per_word_tmp < 4 && bytes_per_word_tmp > 0) |
{ |
//printf("# Bytes per word: %d\n", bytes_per_word_tmp); |
bytes_per_word = bytes_per_word_tmp; |
} |
|
} |
} |
|
} |
|
if (fd == NULL) { |
138,7 → 158,7
// Now write out the image size |
printf("@%8x", current_addr); |
printf("%8x", image_size); |
current_addr += WORDS_PER_LINE * BYTES_PER_WORD; |
current_addr += WORDS_PER_LINE * bytes_per_word; |
} |
|
|
173,7 → 193,7
|
byte_counter++; |
|
if (byte_counter == BYTES_PER_WORD) |
if (byte_counter == bytes_per_word) |
{ |
word_counter++; |
byte_counter=0; |
189,7 → 209,7
{ |
printf("%.2x", (unsigned int) c); // now print the actual char |
byte_counter++; |
if (byte_counter == BYTES_PER_WORD) |
if (byte_counter == bytes_per_word) |
{ |
printf("\n"); |
byte_counter=0; |