X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fsparcl-stub.c;h=3fcdc0ad7c1d3e156595bf4238ff6a2bb9b239bc;hb=1d9d99f32d861ae85dd59689ada801cc51d3ac91;hp=7a435f35cf0f94ba7b62820431b6e35ce2398519;hpb=625559e74241061b25ed000c9d8d0e2e7735f810;p=binutils-gdb.git diff --git a/gdb/sparcl-stub.c b/gdb/sparcl-stub.c index 7a435f35cf0..3fcdc0ad7c1 100644 --- a/gdb/sparcl-stub.c +++ b/gdb/sparcl-stub.c @@ -50,6 +50,7 @@ * * g return the value of the CPU registers hex data or ENN * G set the value of the CPU registers OK or ENN + * P set the value of a single CPU register OK or ENN * * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN @@ -64,9 +65,6 @@ * * ? What was the last sigval ? SNN (signal NN) * - * bBB..BB Set baud rate to BB..BB OK or BNN, then sets - * baud rate - * * All commands and responses are sent with a packet which includes a * checksum. A packet consists of * @@ -95,8 +93,8 @@ * external low-level support routines */ -extern putDebugChar(); /* write a single character */ -extern getDebugChar(); /* read and return a single char */ +extern void putDebugChar (int c); /* write a single character */ +extern int getDebugChar (void); /* read and return a single char */ /************************************************************************/ /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ @@ -105,10 +103,9 @@ extern getDebugChar(); /* read and return a single char */ static int initialized = 0; /* !0 means we've been initialized */ -extern void breakinst(); -static void hw_breakpoint(); -static void set_mem_fault_trap(); -static void get_in_break_mode(); +extern void breakinst (); +static void set_mem_fault_trap (int enable); +static void get_in_break_mode (void); static const char hexchars[]="0123456789abcdef"; @@ -133,6 +130,33 @@ enum regnames {G0, G1, G2, G3, G4, G5, G6, G7, extern void trap_low(); +/* Create private copies of common functions used by the stub. This prevents + nasty interactions between app code and the stub (for instance if user steps + into strlen, etc..) */ + +static char * +strcpy (char *dst, const char *src) +{ + char *retval = dst; + + while ((*dst++ = *src++) != '\000'); + + return retval; +} + +static void * +memcpy (void *vdst, const void *vsrc, int n) +{ + char *dst = vdst; + const char *src = vsrc; + char *retval = dst; + + while (n-- > 0) + *dst++ = *src++; + + return retval; +} + asm(" .reserve trapstack, 1000 * 4, \"bss\", 8 @@ -149,6 +173,18 @@ in_trap_handler: ! underflow) occurs. It makes sure that the invalid register window is still ! available before jumping into C code. It will also restore the world if you ! return from handle_exception. +! +! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly. +! Register usage throughout the routine is as follows: +! +! l0 - psr +! l1 - pc +! l2 - npc +! l3 - wim +! l4 - scratch and y reg +! l5 - scratch and tbr +! l6 - unused +! l7 - unused .globl _trap_low _trap_low: @@ -239,9 +275,6 @@ recursive_trap: or %l0, 0xf20, %l4 mov %l4, %psr ! Turn on traps, disable interrupts - nop - nop - nop set 0x1000, %l1 btst %l1, %l0 ! FP enabled? @@ -271,26 +304,6 @@ recursive_trap: std %f30, [%sp + (24 + 62) * 4] no_fpstore: - call _get_in_break_mode - nop - - set 0xff00, %l3 - ldda [%l3]0x1, %l4 - std %l4, [%sp + (24 + 72) * 4] ! DIA1, debug instr addr 1 - ! DIA2, debug instr addr 2 - inc 8, %l3 - ldda [%l3]0x1, %l4 - std %l4, [%sp + (24 + 74) * 4] ! DDA1, debug data addr 1 - ! DDA2, debug data addr 2 - inc 8, %l3 - ldda [%l3]0x1, %l4 - std %l4, [%sp + (24 + 76) * 4] ! DDV1, debug data val 1 - ! DDV2, debug data val 2 - inc 8, %l3 - ldda [%l3]0x1, %l4 - std %l4, [%sp + (24 + 78) * 4] ! DCR, debug control reg - ! DSR, debug status reg - call _handle_exception add %sp, 24 * 4, %o0 ! Pass address of registers @@ -306,24 +319,6 @@ no_fpstore: ldd [%sp + (24 + 12) * 4], %i4 ldd [%sp + (24 + 14) * 4], %i6 - set 0xff00, %l2 - ldd [%sp + (24 + 72) * 4], %l4 - stda %l4, [%l2]0x1 ! DIA1, debug instr addr 1 - ! DIA2, debug instr addr 2 - inc 8, %l2 - ldd [%sp + (24 + 74) * 4], %l4 - stda %l4, [%l2]0x1 ! DDA1, debug data addr 1 - ! DDA2, debug data addr 2 - inc 8, %l2 - ldd [%sp + (24 + 76) * 4], %l4 - stda %l4, [%l2]0x1 ! DDV1, debug data value 1 - ! DDV2, debug data val 2 - inc 8, %l2 - ldd [%sp + (24 + 78) * 4], %l4 - bset 0x200, %l4 - stda %l4, [%l2]0x1 ! DCR, debug control reg - ! DSR, debug control reg - ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC @@ -371,8 +366,7 @@ no_fpreload: /* Convert ch from a hex digit to an int */ static int -hex(ch) - unsigned char ch; +hex (unsigned char ch) { if (ch >= 'a' && ch <= 'f') return ch-'a'+10; @@ -383,79 +377,79 @@ hex(ch) return -1; } +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; + /* scan for the sequence $# */ -static void -getpacket(buffer) - char *buffer; +unsigned char * +getpacket (void) { + unsigned char *buffer = &remcomInBuffer[0]; unsigned char checksum; unsigned char xmitcsum; - int i; int count; - unsigned char ch; + char ch; - do + while (1) { /* wait around for the start character, ignore all other characters */ - while ((ch = (getDebugChar() & 0x7f)) != '$') ; + while ((ch = getDebugChar ()) != '$') + ; +retry: checksum = 0; xmitcsum = -1; - count = 0; /* now, read until a # or end of buffer is found */ while (count < BUFMAX) { - ch = getDebugChar() & 0x7f; + ch = getDebugChar (); + if (ch == '$') + goto retry; if (ch == '#') break; checksum = checksum + ch; buffer[count] = ch; count = count + 1; } - - if (count >= BUFMAX) - continue; - buffer[count] = 0; if (ch == '#') { - xmitcsum = hex(getDebugChar() & 0x7f) << 4; - xmitcsum |= hex(getDebugChar() & 0x7f); -#if 0 - /* Humans shouldn't have to figure out checksums to type to it. */ - putDebugChar ('+'); - return; -#endif + ch = getDebugChar (); + xmitcsum = hex (ch) << 4; + ch = getDebugChar (); + xmitcsum += hex (ch); + if (checksum != xmitcsum) - putDebugChar('-'); /* failed checksum */ + { + putDebugChar ('-'); /* failed checksum */ + } else { - putDebugChar('+'); /* successful transfer */ + putDebugChar ('+'); /* successful transfer */ + /* if a sequence char is present, reply the sequence ID */ if (buffer[2] == ':') { - putDebugChar(buffer[0]); - putDebugChar(buffer[1]); - /* remove sequence chars from buffer */ - count = strlen(buffer); - for (i=3; i <= count; i++) - buffer[i-3] = buffer[i]; + putDebugChar (buffer[0]); + putDebugChar (buffer[1]); + + return &buffer[3]; } + + return &buffer[0]; } } } - while (checksum != xmitcsum); } /* send the packet in buffer. */ static void -putpacket(buffer) - unsigned char *buffer; +putpacket (unsigned char *buffer) { unsigned char checksum; int count; @@ -470,8 +464,7 @@ putpacket(buffer) while (ch = buffer[count]) { - if (! putDebugChar(ch)) - return; + putDebugChar (ch); checksum += ch; count += 1; } @@ -481,12 +474,9 @@ putpacket(buffer) putDebugChar(hexchars[checksum & 0xf]); } - while ((getDebugChar() & 0x7f) != '+'); + while (getDebugChar() != '+'); } -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - /* Indicate to caller of mem2hex or hex2mem that there has been an error. */ static volatile int mem_err = 0; @@ -499,11 +489,7 @@ static volatile int mem_err = 0; */ static unsigned char * -mem2hex(mem, buf, count, may_fault) - unsigned char *mem; - unsigned char *buf; - int count; - int may_fault; +mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) { unsigned char ch; @@ -529,11 +515,7 @@ mem2hex(mem, buf, count, may_fault) * return a pointer to the character AFTER the last byte written */ static char * -hex2mem(buf, mem, count, may_fault) - unsigned char *buf; - unsigned char *mem; - int count; - int may_fault; +hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) { int i; unsigned char ch; @@ -584,7 +566,7 @@ static struct hard_trap_info /* Set up exception handlers for tracing and breakpoints */ void -set_debug_traps() +set_debug_traps (void) { struct hard_trap_info *ht; @@ -596,11 +578,6 @@ set_debug_traps() if (ht->tt != 4 || ! (read_psr () & 0x1000)) exceptionHandler(ht->tt, trap_low); - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - - putDebugChar ('+'); - initialized = 1; } @@ -621,8 +598,7 @@ _fltr_set_mem_err: "); static void -set_mem_fault_trap(enable) - int enable; +set_mem_fault_trap (int enable) { extern void fltr_set_mem_err(); mem_err = 0; @@ -645,13 +621,13 @@ _dummy_hw_breakpoint: "); static void -get_in_break_mode() +get_in_break_mode (void) { extern void dummy_hw_breakpoint(); exceptionHandler (255, dummy_hw_breakpoint); - write_asi (1, 0xff10, 0); + asm ("ta 255"); exceptionHandler (255, trap_low); } @@ -659,8 +635,7 @@ get_in_break_mode() /* Convert the SPARC hardware trap type code to a unix signal number. */ static int -computeSignal(tt) - int tt; +computeSignal (int tt) { struct hard_trap_info *ht; @@ -705,10 +680,8 @@ hexToInt(char **ptr, int *intValue) * otherwise. */ - static void -handle_exception (registers) - unsigned long *registers; +handle_exception (unsigned long *registers) { int tt; /* Trap type */ int sigval; @@ -738,6 +711,17 @@ handle_exception (registers) restore "); + get_in_break_mode (); /* Enable DSU register writes */ + + registers[DIA1] = read_asi (1, 0xff00); + registers[DIA2] = read_asi (1, 0xff04); + registers[DDA1] = read_asi (1, 0xff08); + registers[DDA2] = read_asi (1, 0xff0c); + registers[DDV1] = read_asi (1, 0xff10); + registers[DDV2] = read_asi (1, 0xff14); + registers[DCR] = read_asi (1, 0xff18); + registers[DSR] = read_asi (1, 0xff1c); + if (registers[PC] == (unsigned long)breakinst) { registers[PC] = registers[NPC]; @@ -797,8 +781,8 @@ handle_exception (registers) { remcomOutBuffer[0] = 0; - getpacket(remcomInBuffer); - switch (remcomInBuffer[0]) + ptr = getpacket(); + switch (*ptr++) { case '?': remcomOutBuffer[0] = 'S'; @@ -823,9 +807,7 @@ handle_exception (registers) psr = registers[PSR]; - ptr = &remcomInBuffer[1]; - - if (remcomInBuffer[0] == 'P') + if (ptr[-1] == 'P') { int regno; @@ -837,7 +819,7 @@ handle_exception (registers) hex2mem (ptr, (char *)®isters[regno], 4, 0); else { - strcpy (remcomOutBuffer, "P01"); + strcpy (remcomOutBuffer, "E01"); break; } } @@ -867,8 +849,6 @@ handle_exception (registers) case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ /* Try to read %x,%x. */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length)) @@ -885,8 +865,6 @@ handle_exception (registers) case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ /* Try to read '%x,%x:'. */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length) @@ -903,8 +881,6 @@ handle_exception (registers) case 'c': /* cAA..AA Continue at address AA..AA(optional) */ /* try to read optional parameter, pc unchanged if no parm */ - - ptr = &remcomInBuffer[1]; if (hexToInt(&ptr, &addr)) { registers[PC] = addr; @@ -916,7 +892,21 @@ handle_exception (registers) some location may have changed something that is in the instruction cache. */ - flush_i_cache(); + flush_i_cache (); + + if (!(registers[DSR] & 0x1) /* DSU enabled? */ + && !(registers[DCR] & 0x200)) /* Are we in break state? */ + { /* Yes, set the DSU regs */ + write_asi (1, 0xff00, registers[DIA1]); + write_asi (1, 0xff04, registers[DIA2]); + write_asi (1, 0xff08, registers[DDA1]); + write_asi (1, 0xff0c, registers[DDA2]); + write_asi (1, 0xff10, registers[DDV1]); + write_asi (1, 0xff14, registers[DDV2]); + write_asi (1, 0xff1c, registers[DSR]); + write_asi (1, 0xff18, registers[DCR] | 0x200); /* Clear break */ + } + return; /* kill the program */ @@ -931,44 +921,6 @@ handle_exception (registers) asm ("call 0 nop "); break; - -#if 0 -Disabled until we can unscrew this properly - - case 'b': /* bBB... Set baud rate to BB... */ - { - int baudrate; - extern void set_timer_3(); - - ptr = &remcomInBuffer[1]; - if (!hexToInt(&ptr, &baudrate)) - { - strcpy(remcomOutBuffer,"B01"); - break; - } - - /* Convert baud rate to uart clock divider */ - switch (baudrate) - { - case 38400: - baudrate = 16; - break; - case 19200: - baudrate = 33; - break; - case 9600: - baudrate = 65; - break; - default: - strcpy(remcomOutBuffer,"B02"); - goto x1; - } - - putpacket("OK"); /* Ack before changing speed */ - set_timer_3(baudrate); /* Set it */ - } -x1: break; -#endif } /* switch */ /* reply to the request */ @@ -982,7 +934,7 @@ x1: break; the debugger. */ void -breakpoint() +breakpoint (void) { if (!initialized) return;