* config/m88k/{tm-delta88.h,tm-delta88v4.h}, m88k-tdep.c:
[deliverable/binutils-gdb.git] / gdb / sparc-stub.c
index d81b6e57ae4a19c8852258e3757480f7d5f97f3c..5de62a339e4e49fbe4233f301dd2d471ca59e535 100644 (file)
@@ -31,6 +31,8 @@
  *
  *  Modified for SPARC by Stu Grossman, Cygnus Support.
  *
+ *  This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
  *  To enable debugger support, two things need to happen.  One, a
  *  call to set_debug_traps() is necessary in order to allow any breakpoints
  *  or error conditions to be properly intercepted and reported to gdb.
@@ -60,6 +62,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
  *
  *
  ****************************************************************************/
 
-#include <stdio.h>
 #include <string.h>
 #include <signal.h>
-#include <memory.h>
 
 /************************************************************************
  *
@@ -97,13 +100,10 @@ extern getDebugChar();   /* read and return a single char */
 /* at least NUMREGBYTES*2 are needed for register packets */
 #define BUFMAX 2048
 
-static int initialized;  /* boolean flag. != 0 means we've been initialized */
+static int initialized = 0;    /* !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,63 +121,49 @@ 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 *************************/
 /*                                                                        */
 
-#define BREAKPOINT() asm("   ta 1");
-
-extern unsigned long rdtbr();
+extern void trap_low();
 
 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.
-!
+       .reserve trapstack, 1000 * 4, \"bss\", 8
 
+       .data
+       .align  4
+
+in_trap_handler:
+       .word   0
+
+       .text
        .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
+! 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.
+
+       .globl _trap_low
+_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 +174,80 @@ _chk4ovflo:
        std     %i6, [%sp + 14 * 4]
 
        restore                         ! Go back to trap window.
-       mov     %l0, %g1                ! Restore %g1.
+       mov     %l4, %g1                ! Restore %g1
+
+window_fine:
+       sethi   %hi(in_trap_handler), %l4
+       ld      [%lo(in_trap_handler) + %l4], %l5
+       tst     %l5
+       bg      recursive_trap
+       inc     %l5
 
-_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.
+       set     trapstack+1000*4, %sp   ! Switch to trap stack
 
-       jmpl    %l7+8, %g0              ! Window is valid, just return
-       sub     %fp, (16+1+6+1)*4, %sp  ! Make room for input & locals
+recursive_trap:
+       st      %l5, [%lo(in_trap_handler) + %l4]
+       sub     %sp,(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.
-
-       .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, [%sp + (24 + 0) * 4] ! registers[Gx]
+       std     %g2, [%sp + (24 + 2) * 4]
+       std     %g4, [%sp + (24 + 4) * 4]
+       std     %g6, [%sp + (24 + 6) * 4]
 
-       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, [%sp + (24 + 8) * 4] ! registers[Ox]
+       std     %i2, [%sp + (24 + 10) * 4]
+       std     %i4, [%sp + (24 + 12) * 4]
+       std     %i6, [%sp + (24 + 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, [%sp + (24 + 64) * 4] ! Y
+       st      %l0, [%sp + (24 + 65) * 4] ! PSR
+       st      %l3, [%sp + (24 + 66) * 4] ! WIM
+       st      %l5, [%sp + (24 + 67) * 4] ! TBR
+       st      %l1, [%sp + (24 + 68) * 4] ! PC
+       st      %l2, [%sp + (24 + 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
+       add     %sp, 24 * 4, %o0        ! Pass address of registers
 
 ! Reload all of the registers that aren't on the stack
 
-       set     _registers, %l0         ! Need to use reg immune from save/rest
+       ld      [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+       ldd     [%sp + (24 + 2) * 4], %g2
+       ldd     [%sp + (24 + 4) * 4], %g4
+       ldd     [%sp + (24 + 6) * 4], %g6
 
-       ld      [%l0 + 1 * 4], %g1      ! registers[Gx]
-       ldd     [%l0 + 2 * 4], %g2
-       ldd     [%l0 + 4 * 4], %g4
-       ldd     [%l0 + 6 * 4], %g6
+       ldd     [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+       ldd     [%sp + (24 + 10) * 4], %i2
+       ldd     [%sp + (24 + 12) * 4], %i4
+       ldd     [%sp + (24 + 14) * 4], %i6
 
-       ldd     [%l0 + 8 * 4], %o0      ! registers[Ox]
-       ldd     [%l0 + 10 * 4], %o2
-       ldd     [%l0 + 12 * 4], %o4
-       ldd     [%l0 + 14 * 4], %o6
+       ldd     [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+       ldd     [%sp + (24 + 68) * 4], %l2 ! PC & NPC
 
        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]
-
-       tst     %l7                     ! Did handle_exception tell
-       bg      retskip                 !  us to skip the next inst?
-       nop
-
-       mov     %l3, %psr               ! Make sure that traps are disabled
+       mov     %l0, %y
+       mov     %l1, %psr               ! Make sure that traps are disabled
                                        ! for rett
-       jmpl    %l1, %g0                ! Restore old PC
-       rett    %l2                     ! Restore old nPC
 
-       mov     %l3, %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
+       sethi   %hi(in_trap_handler), %l4
+       ld      [%lo(in_trap_handler) + %l4], %l5
+       dec     %l5
+       st      %l5, [%lo(in_trap_handler) + %l4]
+
+       jmpl    %l2, %g0                ! Restore old PC
+       rett    %l3                     ! Restore old nPC
 ");
 
 /* Convert ch from a hex digit to an int */
@@ -345,14 +307,7 @@ 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
+#if 0
          /* Humans shouldn't have to figure out checksums to type to it. */
          putDebugChar ('+');
          return;
@@ -411,48 +366,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 +393,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 +426,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 +436,87 @@ 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 */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps()
+{
+  struct hard_trap_info *ht;
+
+  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+    exceptionHandler(ht->tt, trap_low);
+
+  /* In case GDB is started before us, ack any packets (presumably
+     "$?#xx") sitting there.  */
+
+  putDebugChar ('+');
+
+  initialized = 1;
+}
+
+asm ("
+! 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.
+
+       .text
+       .align 4
+
+_fltr_set_mem_err:
+       sethi %hi(_mem_err), %l0
+       st %l1, [%l0 + %lo(_mem_err)]
+       jmpl %l2, %g0
+       rett %l2+4
+");
+
+static void
+set_mem_fault_trap(enable)
+     int enable;
+{
+  extern void fltr_set_mem_err();
+  mem_err = 0;
+
+  if (enable)
+    exceptionHandler(9, fltr_set_mem_err);
+  else
+    exceptionHandler(9, trap_low);
+}
+
+/* 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,14 +535,12 @@ hexToInt(char **ptr, int *intValue)
   while (**ptr)
     {
       hexValue = hex(**ptr);
-      if (hexValue >=0)
-        {
-         *intValue = (*intValue <<4) | hexValue;
-         numChars ++;
-        }
-      else
+      if (hexValue < 0)
        break;
 
+      *intValue = (*intValue << 4) | hexValue;
+      numChars ++;
+
       (*ptr)++;
     }
 
@@ -588,28 +553,29 @@ hexToInt(char **ptr, int *intValue)
  * otherwise.
  */
 
-static int
-handle_exception ()
+extern void breakinst();
+
+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 +586,60 @@ 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
+  if (registers[PC] == (unsigned long)breakinst)
+    {
+      registers[PC] = registers[NPC];
+      registers[NPC] += 4;
+    }
 
-  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 +653,17 @@ 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, 16 * 4, 0); /* L & 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 +671,35 @@ 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],
+           unsigned long *newsp, psr;
+
+           psr = registers[PSR];
+
+           ptr = &remcomInBuffer[1];
+           hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+           hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+           hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
                    8 * 4, 0);  /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+
+           /* See if the stack pointer has moved.  If so, then copy the saved
+              locals and ins to the new location.  This keeps the window
+              overflow and underflow routines happy.  */
+
+           newsp = (unsigned long *)registers[SP];
+           if (sp != newsp)
+             sp = memcpy(newsp, sp, 16 * 4);
+
+           /* Don't allow CWP to be modified. */
+
+           if (psr != registers[PSR])
+             registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
            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 +711,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,20 +729,13 @@ 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) */
-       case 's':    /* sAA..AA   Step one instruction from AA..AA(optional) */
          /* try to read optional parameter, pc unchanged if no parm */
 
          ptr = &remcomInBuffer[1];
@@ -775,107 +745,69 @@ handle_exception ()
              registers[NPC] = addr + 4;
            }
 
-         return 0;
+/* Need to flush the instruction cache here, as we may have deposited a
+   breakpoint, and the icache probably has no way of knowing that a data ref to
+   some location may have changed something that is in the instruction cache.
+ */
+
+         flush_i_cache();
+         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.  */
+#if 0
+       case 't':               /* Test feature */
+         asm (" std %f31,[%sp]");
+         break;
+#endif
+       case 'r':               /* Reset */
+         asm ("call 0
+               nop ");
+         break;
 
-  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 +818,11 @@ set_mem_fault_trap(enable)
 void
 breakpoint()
 {
-  writez(1, "About to do a breakpoint\r\n\n");
-  if (initialized)
-    BREAKPOINT();
+  if (!initialized)
+    return;
+
+  asm("        .globl _breakinst
+
+       _breakinst: ta 1
+      ");
 }
This page took 0.033058 seconds and 4 git commands to generate.