diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/sparc-stub.c | 669 |
2 files changed, 294 insertions, 386 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 68e741f..46336ef 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +Fri Aug 21 15:17:03 1992 Stu Grossman (grossman at cygnus.com) + + * remote.c (remote_open): Fix baud rate setting to make -b flag + work. (remote_wait): Change 'T' message parser to deal with new + improved format which allows stub to send an arbitrary bunch of + registers. + * sparc-stub.c: General cleanups. (trap_low, handle_exception): + make all this re-entrant by storing all state on the stack. Clean + up memory error trapping. (computeSignal, set_debug_traps): + make it all table driven. Make a start at a baud rate setting command. + Wed Aug 19 10:23:27 1992 Ian Lance Taylor (ian@cygnus.com) * m68k-pinsn.c: handle new operand type 'r', introduced for cas2. diff --git a/gdb/sparc-stub.c b/gdb/sparc-stub.c index d81b6e5..461b9cd 100644 --- a/gdb/sparc-stub.c +++ b/gdb/sparc-stub.c @@ -60,6 +60,9 @@ * * ? 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 * @@ -79,7 +82,6 @@ * ****************************************************************************/ -#include <stdio.h> #include <string.h> #include <signal.h> #include <memory.h> @@ -101,9 +103,6 @@ static int initialized; /* boolean flag. != 0 means we've been initialized */ static void set_mem_fault_trap(); -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - static const char hexchars[]="0123456789abcdef"; #define NUMREGS 72 @@ -121,8 +120,6 @@ enum regnames {G0, G1, G2, G3, G4, G5, G6, G7, F24, F25, F26, F27, F28, F29, F30, F31, Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR }; -static unsigned long registers[NUMREGS] __attribute__ ((aligned (8))); - /*************************** ASSEMBLY CODE MACROS *************************/ /* */ @@ -132,52 +129,40 @@ extern unsigned long rdtbr(); asm(" .text -! -! FUNCTION -! _chk4ovflo -! -! DESCRIPTION -! This code is branched to before each trap (except reset, -! _win_unf, and _win_ovf) handler. -! It checks to see if we've moved into the invalid window -! and performs fixup ala _win_ovf. -! -! INPUTS -! - %l1 = pc at trap time. -! - %l2 = npc at trap time. -! - %l7 = return address. -! -! INTERNAL DESCRIPTION -! -! RETURNS -! - None. -! - .align 4 -_chk4ovflo: - mov %psr, %l0 ! get the psr - and %l0, 0x1F, %l3 ! get the cwp - mov 1, %l4 ! compare cwp with the wim - sll %l4, %l3, %l3 ! compare - mov %wim, %l4 ! read the wim - btst %l4, %l3 - bz _retsave ! not invalid window, just return +! Read the TBR. + + .globl _rdtbr +_rdtbr: + retl + mov %tbr, %o0 + +! This function is called when any SPARC trap (except window overflow or +! 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. + +trap_low: + mov %psr, %l0 + mov %wim, %l3 + + srl %l3, %l0, %l4 ! wim >> cwp + cmp %l4, 1 + bne window_fine ! Branch if not in the invalid window nop - ! in line version of _win_ovf - or %l0, 0xf20, %l3 ! enable traps, disable interrupts. - mov %l3, %psr - mov %g1, %l0 ! Save %g1. - srl %l4, 1, %g1 ! Next WIM = %g1 = rol(WIM, 1, NWINDOW) - sll %l4, 8-1, %l3 - bset %l3, %g1 - save %g0, %g0, %g0 ! Get into window to be saved. - mov %g1, %wim ! Install new wim. - nop ! must delay three instructions - nop ! before using these registers, so - nop ! put nops in just to be safe - - std %l0, [%sp + 0 * 4] ! save all local registers + +! Handle window overflow + + mov %g1, %l4 ! Save g1, we use it to hold the wim + srl %l3, 1, %g1 ! Rotate wim right + sll %l3, 8-1, %l5 + or %l5, %g1, %g1 + + save %g0, %g0, %g0 ! Slip into next window + mov %g1, %wim ! Install the new wim + + std %l0, [%sp + 0 * 4] ! save L & I registers std %l2, [%sp + 2 * 4] std %l4, [%sp + 4 * 4] std %l6, [%sp + 6 * 4] @@ -188,104 +173,63 @@ _chk4ovflo: std %i6, [%sp + 14 * 4] restore ! Go back to trap window. - mov %l0, %g1 ! Restore %g1. + mov %l4, %g1 ! Restore %g1 -_retsave: - ! It is safe now to allocate a stack frame for this window - ! because all overflow handling will have been accomplished - ! in the event we trapped into the invalid window. - ! ie. all of this window's %o regs (next window's %i regs) - ! will have been safely stored to the stack before we overwrite %sp. - - jmpl %l7+8, %g0 ! Window is valid, just return - sub %fp, (16+1+6+1)*4, %sp ! Make room for input & locals +window_fine: + sub %fp, (16+1+6+1+72)*4, %sp ! Make room for input & locals ! + hidden arg + arg spill ! + doubleword alignment + ! + registers[72] local var -! Read the TBR. + std %g0, [%fp + (-72 + 0) * 4] ! registers[Gx] + std %g2, [%fp + (-72 + 2) * 4] + std %g4, [%fp + (-72 + 4) * 4] + std %g6, [%fp + (-72 + 6) * 4] - .globl _rdtbr -_rdtbr: - retl - mov %tbr, %o0 - -! This function is called when any SPARC trap (except window overflow or -! 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. - -_trap_low: - set _registers, %l0 - - std %g0, [%l0 + 0 * 4] ! registers[Gx] - std %g2, [%l0 + 2 * 4] - std %g4, [%l0 + 4 * 4] - std %g6, [%l0 + 6 * 4] - - std %i0, [%l0 + 8 * 4] ! registers[Ox] - std %i2, [%l0 + 10 * 4] - std %i4, [%l0 + 12 * 4] - std %i6, [%l0 + 14 * 4] + std %i0, [%fp + (-72 + 8) * 4] ! registers[Ox] + std %i2, [%fp + (-72 + 10) * 4] + std %i4, [%fp + (-72 + 12) * 4] + std %i6, [%fp + (-72 + 14) * 4] ! F0->F31 not implemented mov %y, %l4 - mov %psr, %l5 - mov %wim, %l6 - mov %tbr, %l7 - std %l4, [%l0 + 64 * 4] ! Y & PSR - std %l6, [%l0 + 66 * 4] ! WIM & TBR - st %l1, [%l0 + 68 * 4] ! PC - st %l2, [%l0 + 69 * 4] ! NPC + mov %tbr, %l5 + st %l4, [%fp + (-72 + 64) * 4] ! Y + st %l0, [%fp + (-72 + 65) * 4] ! PSR + st %l3, [%fp + (-72 + 66) * 4] ! WIM + st %l5, [%fp + (-72 + 67) * 4] ! TBR + st %l1, [%fp + (-72 + 68) * 4] ! PC + st %l2, [%fp + (-72 + 69) * 4] ! NPC ! CPSR and FPSR not impl - sethi %hi(_chk4ovflo), %l7 ! Must call this routine via %l7 - jmpl %l7+%lo(_chk4ovflo), %l7 ! because o regs may not be available yet - nop - mov %psr, %o1 - bset 0xf20, %o1 - mov %o1, %psr ! Turn on traps, disable interrupts + or %l0, 0xf20, %l4 + mov %l4, %psr ! Turn on traps, disable interrupts call _handle_exception - nop - mov %o0, %l7 ! Save return value - -! Reload all of the registers that aren't on the stack - - set _registers, %l0 ! Need to use reg immune from save/rest - - ld [%l0 + 1 * 4], %g1 ! registers[Gx] - ldd [%l0 + 2 * 4], %g2 - ldd [%l0 + 4 * 4], %g4 - ldd [%l0 + 6 * 4], %g6 - - ldd [%l0 + 8 * 4], %o0 ! registers[Ox] - ldd [%l0 + 10 * 4], %o2 - ldd [%l0 + 12 * 4], %o4 - ldd [%l0 + 14 * 4], %o6 + add %fp, -72 * 4, %o0 ! Pass address of registers restore ! Ensure that previous window is valid save %g0, %g0, %g0 ! by causing a window_underflow trap - ld [%l0 + 64 * 4], %l3 ! registers[Y] - mov %l3, %y - ld [%l0 + 65 * 4], %l3 ! registers[PSR] - ld [%l0 + 68 * 4], %l1 ! registers[PC] - ld [%l0 + 69 * 4], %l2 ! registers[NPC] +! Reload all of the registers that aren't on the stack - tst %l7 ! Did handle_exception tell - bg retskip ! us to skip the next inst? - nop + ld [%fp + (-72 + 1) * 4], %g1 ! registers[Gx] + ldd [%fp + (-72 + 2) * 4], %g2 + ldd [%fp + (-72 + 4) * 4], %g4 + ldd [%fp + (-72 + 6) * 4], %g6 - mov %l3, %psr ! Make sure that traps are disabled - ! for rett - jmpl %l1, %g0 ! Restore old PC - rett %l2 ! Restore old nPC + ldd [%fp + (-72 + 8) * 4], %o0 ! registers[Ox] + ldd [%fp + (-72 + 10) * 4], %o2 + ldd [%fp + (-72 + 12) * 4], %o4 + ldd [%fp + (-72 + 14) * 4], %o6 - mov %l3, %psr ! Make sure that traps are disabled + ldd [%fp + (-72 + 64) * 4], %l0 ! Y & PSR + ldd [%fp + (-72 + 68) * 4], %l2 ! PC & NPC + mov %l0, %y + mov %l1, %psr ! Make sure that traps are disabled ! for rett -retskip: ! Come here to skip the next instruction - jmpl %l2, %g0 ! Old nPC - rett %l2+4 ! Old nPC+4 + jmpl %l2, %g0 ! Restore old PC + rett %l3 ! Restore old nPC "); /* Convert ch from a hex digit to an int */ @@ -345,13 +289,6 @@ getpacket(buffer) { xmitcsum = hex(getDebugChar()) << 4; xmitcsum |= hex(getDebugChar()); -#ifdef DEBUG - if (remote_debug && checksum != xmitcsum) - { - fprintf(stderr, "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", - checksum,xmitcsum,buffer); - } -#endif #if 1 /* Humans shouldn't have to figure out checksums to type to it. */ putDebugChar ('+'); @@ -411,48 +348,13 @@ putpacket(buffer) while (getDebugChar() != '+'); } -static unsigned char remcomInBuffer[BUFMAX]; -static unsigned char remcomOutBuffer[BUFMAX]; -static short error; - -static void -debug_error(format, parm) - char *format; - char *parm; -{ -#ifdef DEBUG - if (remote_debug) - fprintf(stderr,format,parm); -#endif -} - -/* Address of a routine to RTE to if we get a memory fault. */ -static void (*mem_fault_routine)() = NULL; +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; -/* These are separate functions so that they are so short and sweet - that the compiler won't save any registers (if there is a fault - to mem_fault, they won't get restored, so there better not be any - saved). */ -static int -get_char (addr) - char *addr; -{ - return *addr; -} - -static void -set_char (addr, val) - char *addr; - int val; -{ - *addr = val; -} - /* Convert the memory pointed to by mem into hex, placing result in buf. * Return a pointer to the last char put in buf (null), in case of mem fault, * return 0. @@ -473,7 +375,7 @@ mem2hex(mem, buf, count, may_fault) while (count-- > 0) { - ch = get_char(mem++); + ch = *mem++; if (mem_err) return 0; *buf++ = hexchars[ch >> 4]; @@ -506,7 +408,7 @@ hex2mem(buf, mem, count, may_fault) { ch = hex(*buf++) << 4; ch |= hex(*buf++); - set_char(mem++, ch); + *mem++ = ch; if (mem_err) return 0; } @@ -516,40 +418,110 @@ hex2mem(buf, mem, count, may_fault) return mem; } -/* this function takes the SPARC trap type code and attempts to - translate this number into a unix compatible signal value */ +/* This table contains the mapping between SPARC hardware trap types, and + signals, which are primarily what GDB understands. It also indicates + which hardware traps we need to commandeer when initializing the stub. */ + +static struct hard_trap_info +{ + unsigned char tt; /* Trap type code for SPARClite */ + unsigned char signo; /* Signal that we map this trap into */ +} hard_trap_info[] = { + {1, SIGSEGV}, /* instruction access error */ + {2, SIGILL}, /* privileged instruction */ + {3, SIGILL}, /* illegal instruction */ + {4, SIGEMT}, /* fp disabled */ + {36, SIGEMT}, /* cp disabled */ + {7, SIGBUS}, /* mem address not aligned */ + {9, SIGSEGV}, /* data access exception */ + {10, SIGEMT}, /* tag overflow */ + {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */ + {0, 0} /* Must be last */ +}; + +/* Each entry in the trap vector occupies four words. */ + +struct trap_entry +{ + unsigned long ti[4]; +}; + +extern struct trap_entry fltr_proto; +extern struct trap_entry fltr_set_mem_err; +asm (" + .data + .globl _fltr_proto + .align 4 +_fltr_proto: ! First level trap routine prototype + sethi %hi(trap_low), %l0 + jmpl %lo(trap_low)+%l0, %g0 + nop + nop + +! Trap handler for memory errors. This just sets mem_err to be non-zero. It +! assumes that %l1 is non-zero. This should be safe, as it is doubtful that +! 0 would ever contain code that could mem fault. This routine will skip +! past the faulting instruction after setting mem_err. + +_fltr_set_mem_err: + sethi %hi(_mem_err), %l0 + st %l1, [%l0 + %lo(_mem_err)] + jmpl %l2, %g0 + rett %l2+4 + + .text +"); + +/* Set up exception handlers for tracing and breakpoints */ + +void +set_debug_traps() +{ + struct trap_entry *tb; /* Trap vector base address */ + struct hard_trap_info *ht; + + tb = (struct trap_entry *)(rdtbr() & ~0xfff); + + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + tb[ht->tt] = fltr_proto; + + /* In case GDB is started before us, ack any packets (presumably + "$?#xx") sitting there. */ + + putDebugChar ('+'); + + initialized = 1; +} + +static void +set_mem_fault_trap(enable) + int enable; +{ + struct trap_entry *tb; /* Trap vector base address */ + + mem_err = 0; + + tb = (struct trap_entry *)(rdtbr() & ~0xfff); + + if (enable) + tb[9] = fltr_set_mem_err; + else + tb[9] = fltr_proto; +} + +/* Convert the SPARC hardware trap type code to a unix signal number. */ static int computeSignal(tt) int tt; { - int sigval; + struct hard_trap_info *ht; - switch (tt) - { - case 1: - sigval = SIGSEGV; break; /* instruction access error */ - case 2: - sigval = SIGILL; break; /* privileged instruction */ - case 3: - sigval = SIGILL; break; /* illegal instruction */ - case 4: - sigval = SIGEMT; break; /* fp disabled */ - case 36: - sigval = SIGEMT; break; /* cp disabled */ - case 7: - sigval = SIGBUS; break; /* mem address not aligned */ - case 9: - sigval = SIGSEGV; break; /* data access exception */ - case 10: - sigval = SIGEMT; break; /* tag overflow */ - case 128+1: /* ta 1 - normal breakpoint instruction */ - case 255: /* breakpoint hardware unique to SPARClite */ - sigval = SIGTRAP; break; /* breakpoint trap */ - default: - sigval = SIGHUP; /* "software generated"*/ - } - return (sigval); + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + if (ht->tt == tt) + return ht->signo; + + return SIGHUP; /* default for things we don't know about */ } /* @@ -568,15 +540,13 @@ hexToInt(char **ptr, int *intValue) while (**ptr) { hexValue = hex(**ptr); - if (hexValue >=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else + if (hexValue < 0) break; - (*ptr)++; + *intValue = (*intValue << 4) | hexValue; + numChars ++; + + *ptr++; } return (numChars); @@ -588,28 +558,27 @@ hexToInt(char **ptr, int *intValue) * otherwise. */ -static int -handle_exception () +static void +handle_exception (registers) + unsigned long *registers; { int tt; /* Trap type */ int sigval; int addr; int length; char *ptr; - int newPC; - unsigned char *sp; - unsigned char *com; + unsigned long *sp; /* First, we must force all of the windows to be spilled out */ - asm(" save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 - save %g0, -64, %g0 + asm(" save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp + save %sp, -64, %sp restore restore restore @@ -620,61 +589,54 @@ handle_exception () restore "); -#if 0 - writez(1, "Got to handle_exception()\r\n "); - - writez(1, "psr = 0x"); - numout(registers[PSR], 16); - writez(1, " tbr = 0x"); - numout(registers[TBR], 16); - writez(1, " oldpc = 0x"); - numout(registers[PC], 16); - writez(1, " oldnpc = 0x"); - numout(registers[NPC], 16); - writez(1, "\r\n"); -#endif - - sp = (unsigned char *)registers[SP]; + sp = (unsigned long *)registers[SP]; tt = (registers[TBR] >> 4) & 0xff; -#ifdef DEBUG - if (remote_debug) - printf("tbr=0x%x, tt=%d, psr=0x%x, pc=0x%x, npc=0x%x\n", - registers[TBR], (registers[TBR] >> 4) & 0xff, registers[PSR], registers[PC], registers[NPC]); -#endif - /* reply to host that an exception has occurred */ sigval = computeSignal(tt); - com = remcomOutBuffer; - - *com++ = 'T'; - *com++ = hexchars[sigval >> 4]; - *com++ = hexchars[sigval & 0xf]; - - *com++ = hexchars[PC >> 4]; - *com++ = hexchars[PC & 0xf]; - com = mem2hex((char *)®isters[PC], com, 4, 0); - - *com++ = hexchars[FP >> 4]; - *com++ = hexchars[FP & 0xf]; - com = mem2hex(sp + (8 + 6) * 4, com, 4, 0); /* FP */ - - *com++ = hexchars[SP >> 4]; - *com++ = hexchars[SP & 0xf]; - com = mem2hex((char *)®isters[SP], com, 4, 0); - - *com++ = hexchars[NPC >> 4]; - *com++ = hexchars[NPC & 0xf]; - com = mem2hex((char *)®isters[NPC], com, 4, 0); - - *com++ = 0; + ptr = remcomOutBuffer; + + *ptr++ = 'T'; + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + *ptr++ = hexchars[PC >> 4]; + *ptr++ = hexchars[PC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); + *ptr++ = ';'; + + *ptr++ = hexchars[FP >> 4]; + *ptr++ = hexchars[FP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */ + *ptr++ = ';'; + + *ptr++ = hexchars[SP >> 4]; + *ptr++ = hexchars[SP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)&sp, ptr, 4, 0); + *ptr++ = ';'; + + *ptr++ = hexchars[NPC >> 4]; + *ptr++ = hexchars[NPC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0); + *ptr++ = ';'; + + *ptr++ = hexchars[O7 >> 4]; + *ptr++ = hexchars[O7 & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®isters[O7], ptr, 4, 0); + *ptr++ = ';'; + + *ptr++ = 0; putpacket(remcomOutBuffer); while (1) { - error = 0; remcomOutBuffer[0] = 0; getpacket(remcomInBuffer); @@ -688,18 +650,18 @@ handle_exception () break; case 'd': - remote_debug = !remote_debug; /* toggle debug flag */ + /* toggle debug flag */ break; case 'g': /* return the value of the CPU registers */ { - com = remcomOutBuffer; - com = mem2hex((char *)registers, com, 16 * 4, 0); /* G & O regs */ - com = mem2hex(sp + 0 * 4, com, 8 * 4, 0); /* L regs */ - com = mem2hex(sp + 8 * 4, com, 8 * 4, 0); /* I regs */ - memset(com, '0', 32 * 8); /* Floating point */ + ptr = remcomOutBuffer; + ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */ + ptr = mem2hex(sp + 0, ptr, 8 * 4, 0); /* L regs */ + ptr = mem2hex(sp + 8, ptr, 8 * 4, 0); /* I regs */ + memset(ptr, '0', 32 * 8); /* Floating point */ mem2hex((char *)®isters[Y], - com + 32 * 4 * 2, + ptr + 32 * 4 * 2, 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ } @@ -707,18 +669,18 @@ handle_exception () case 'G': /* set the value of the CPU registers - return OK */ { - com = &remcomInBuffer[1]; - hex2mem(com, (char *)registers, 16 * 4, 0); /* G & O regs */ - hex2mem(com + 16 * 4 * 2, sp + 0 * 4, 8 * 4, 0); /* L regs */ - hex2mem(com + 24 * 4 * 2, sp + 8 * 4, 8 * 4, 0); /* I regs */ - hex2mem(com + 64 * 4 * 2, (char *)®isters[Y], + ptr = &remcomInBuffer[1]; + hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ + hex2mem(ptr + 16 * 4 * 2, sp + 0, 8 * 4, 0); /* L regs */ + hex2mem(ptr + 24 * 4 * 2, sp + 8, 8 * 4, 0); /* I regs */ + hex2mem(ptr + 64 * 4 * 2, (char *)®isters[Y], 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ strcpy(remcomOutBuffer,"OK"); } break; case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + /* Try to read %x,%x. */ ptr = &remcomInBuffer[1]; @@ -730,17 +692,13 @@ handle_exception () break; strcpy (remcomOutBuffer, "E03"); - debug_error ("memory fault"); } else - { - strcpy(remcomOutBuffer,"E01"); - debug_error("malformed read memory command: %s",remcomInBuffer); - } + strcpy(remcomOutBuffer,"E01"); break; case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + /* Try to read '%x,%x:'. */ ptr = &remcomInBuffer[1]; @@ -752,16 +710,10 @@ handle_exception () if (hex2mem(ptr, (char *)addr, length, 1)) strcpy(remcomOutBuffer, "OK"); else - { - strcpy(remcomOutBuffer, "E03"); - debug_error("memory fault"); - } + strcpy(remcomOutBuffer, "E03"); } else - { - strcpy(remcomOutBuffer, "E02"); - debug_error("malformed write memory command: %s",remcomInBuffer); - } + strcpy(remcomOutBuffer, "E02"); break; case 'c': /* cAA..AA Continue at address AA..AA(optional) */ @@ -775,107 +727,53 @@ handle_exception () registers[NPC] = addr + 4; } - return 0; + return; /* kill the program */ case 'k' : /* do nothing */ break; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -/* Each entry in the trap vector occupies four words. */ - -struct trap_entry -{ - unsigned long ti[4]; -}; - -#define NUMTRAPS 256 - -/* static struct trap_entry oldvec[NUMTRAPS];*/ - -extern struct trap_entry fltr_proto; -extern struct trap_entry fltr_set_mem_err; -asm (" - .data - .globl _fltr_proto - .align 4 -_fltr_proto: ! First level trap routine prototype - sethi %hi(_trap_low), %l0 - jmpl %lo(_trap_low)+%l0, %g0 - nop - nop - -! Trap handler for memory errors. This just sets mem_err to be non-zero. It -! assumes that %l1 is non-zero. This should be safe, as it is doubtful that -! 0 would ever contain code that could mem fault. This routine will skip -! past the faulting instruction after setting mem_err. - -_fltr_set_mem_err: - sethi %hi(_mem_err), %l0 - st %l1, [%l0 + %lo(_mem_err)] - jmpl %l2, %g0 - rett %l2+4 - - .text -"); - -/* this function is used to set up exception handlers for tracing and - breakpoints */ - -void -set_debug_traps() -{ - int exception; - struct trap_entry *tb; /* Trap vector base address */ - - writez(1, "Got to set_debug_traps\r\n"); - - tb = (struct trap_entry *)(rdtbr() & ~0xfff); - - writez(1, "tb = 0x"); - numout(tb, 16); - writez(1, " trap ins = 0x"); - numout(fltr_proto, 16); - writez(1, "\r\n"); - - tb[1] = fltr_proto; /* instruction access exception */ - tb[2] = fltr_proto; /* privileged instruction */ - tb[3] = fltr_proto; /* illegal instruction */ - tb[4] = fltr_proto; /* fp disabled */ - tb[36] = fltr_proto; /* cp disabled */ - tb[7] = fltr_proto; /* mem address not aligned */ - tb[9] = fltr_proto; /* data access exception */ - tb[10] = fltr_proto; /* tag overflow */ - tb[128+1] = fltr_proto; /* breakpoint instruction (ta 1) */ - tb[255] = fltr_proto; /* hardware breakpoint trap */ - - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - - putDebugChar ('+'); +#if 0 +Disabled until we can unscrew this properly - initialized = 1; -} + case 'b': /* bBB... Set baud rate to BB... */ + { + int baudrate; + extern void set_timer_3(); -static void -set_mem_fault_trap(enable) - int enable; -{ - struct trap_entry *tb; /* Trap vector base address */ + ptr = &remcomInBuffer[1]; + if (!hexToInt(&ptr, &baudrate)) + { + strcpy(remcomOutBuffer,"B01"); + break; + } - mem_err = 0; + /* 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; + } - tb = (struct trap_entry *)(rdtbr() & ~0xfff); + putpacket("OK"); /* Ack before changing speed */ + set_timer_3(baudrate); /* Set it */ + } +x1: break; +#endif + } /* switch */ - if (enable) - tb[9] = fltr_set_mem_err; - else - tb[9] = fltr_proto; + /* reply to the request */ + putpacket(remcomOutBuffer); + } } /* This function will generate a breakpoint exception. It is used at the @@ -886,7 +784,6 @@ set_mem_fault_trap(enable) void breakpoint() { - writez(1, "About to do a breakpoint\r\n\n"); if (initialized) BREAKPOINT(); } |