oops - omitted from previous delta
[deliverable/binutils-gdb.git] / gdb / sparcl-stub.c
index 7a435f35cf0f94ba7b62820431b6e35ce2398519..3fcdc0ad7c1d3e156595bf4238ff6a2bb9b239bc 100644 (file)
@@ -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 $<data>#<checksum>     */
 
-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 *)&registers[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;
This page took 0.032713 seconds and 4 git commands to generate.