aboutsummaryrefslogtreecommitdiff
path: root/gdb/sparc-stub.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1992-08-21 22:35:35 +0000
committerStu Grossman <grossman@cygnus>1992-08-21 22:35:35 +0000
commit39a131782f3d18e316c10f5217949790cbf0c87b (patch)
treef652bcbf192c2ebdbc171d6a96bca695aa083042 /gdb/sparc-stub.c
parent4772861e5b05176b400dba7a93256a2e22416a12 (diff)
downloadfsf-binutils-gdb-39a131782f3d18e316c10f5217949790cbf0c87b.zip
fsf-binutils-gdb-39a131782f3d18e316c10f5217949790cbf0c87b.tar.gz
fsf-binutils-gdb-39a131782f3d18e316c10f5217949790cbf0c87b.tar.bz2
* 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.
Diffstat (limited to 'gdb/sparc-stub.c')
-rw-r--r--gdb/sparc-stub.c669
1 files changed, 283 insertions, 386 deletions
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 *)&registers[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 *)&registers[SP], com, 4, 0);
-
- *com++ = hexchars[NPC >> 4];
- *com++ = hexchars[NPC & 0xf];
- com = mem2hex((char *)&registers[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 *)&registers[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 *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[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 *)&registers[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 *)&registers[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 *)&registers[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();
}