2000-03-28 J.T. Conklin <jtc@redback.com>
[deliverable/binutils-gdb.git] / gdb / m68k-stub.c
index 66398b3dbdd57392f4cd8ddb4583d96a674c0aa6..84c61a13aa59e3a8bd45de52d3f204af59dc9721 100644 (file)
 typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
 typedef void (*Function)();           /* pointer to a function */
 
-extern putDebugChar();   /* write a single character      */
-extern getDebugChar();   /* read and return a single char */
+extern void putDebugChar();    /* write a single character      */
+extern int getDebugChar();     /* read and return a single char */
 
 extern Function exceptionHandler();  /* assign an exception handler */
 extern ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
@@ -194,11 +194,17 @@ static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
 
 static ExceptionHook oldExceptionHook;
 
+#ifdef mc68020
 /* the size of the exception stack on the 68020 varies with the type of
  * exception.  The following table is the number of WORDS used
  * for each exception format.
  */
 const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
+#endif
+
+#ifdef mc68332
+static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
+#endif
 
 /************* jump buffer used for setjmp/longjmp **************************/
 jmp_buf remcomEnv;
@@ -274,7 +280,7 @@ asm("
 .globl __debug_level7
 __debug_level7:
        movew   d0,sp@-");
-#ifdef mc68020
+#if defined (mc68020) || defined (mc68332)
 asm("  movew   sp@(2),d0");
 #else
 asm("  movew   sp@(6),d0");
@@ -286,14 +292,14 @@ asm("     andiw   #0x700,d0
         bra     __catchException
 _already7:
        movew   sp@+,d0");
-#ifndef mc68020
+#if !defined (mc68020) && !defined (mc68332)
 asm("  lea     sp@(4),sp");     /* pull off 68000 return address */
 #endif
 asm("  rte");
 
 extern void _catchException ();
 
-#ifdef mc68020
+#if defined (mc68020) || defined (mc68332)
 /* This function is called when a 68020 exception occurs.  It saves
  * all the cpu and fpcp regs in the _registers array, creates a frame on a
  * linked list of frames which has the cpu and fpcp stack frames needed
@@ -482,7 +488,7 @@ void _returnFromException( Frame *frame )
         frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
     }
 
-#ifndef mc68020
+#if !defined (mc68020) && !defined (mc68332)
     /* a 68000 cannot use the internal info pushed onto a bus error
      * or address error frame when doing an RTE so don't put this info
      * onto the stack or the stack will creep every time this happens.
@@ -516,62 +522,82 @@ char ch;
   return (-1);
 }
 
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
 
 /* scan for the sequence $<data>#<checksum>     */
-void getpacket(buffer)
-char * buffer;
+  
+unsigned char *
+getpacket ()
 {
+  unsigned char *buffer = &remcomInBuffer[0];
   unsigned char checksum;
   unsigned char xmitcsum;
-  int  i;
-  int  count;
+  int count;
   char ch;
-  
-  do {
-    /* wait around for the start character, ignore all other characters */
-    while ((ch = getDebugChar()) != '$'); 
-    checksum = 0;
-    xmitcsum = -1;
-    
-    count = 0;
-    
-    /* now, read until a # or end of buffer is found */
-    while (count < BUFMAX) {
-      ch = getDebugChar();
-      if (ch == '#') break;
-      checksum = checksum + ch;
-      buffer[count] = ch;
-      count = count + 1;
-      }
-    buffer[count] = 0;
-
-    if (ch == '#') {
-      xmitcsum = hex(getDebugChar()) << 4;
-      xmitcsum += hex(getDebugChar());
-      if ((remote_debug ) && (checksum != xmitcsum)) {
-        fprintf(stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
-                                                    checksum,xmitcsum,buffer);
-      }
-      
-      if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */ 
-      else {
-        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];
-        } 
-      } 
-    } 
-  } while (checksum != xmitcsum);
-  
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      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 ();
+         if (ch == '$')
+            goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             if (remote_debug)
+               {
+                 fprintf (stderr,
+                     "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
+                          checksum, xmitcsum, buffer);
+               }
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
 }
 
-/* send the packet in buffer.  The host get's one chance to read it.  
-   This routine does not wait for a positive acknowledge.  */
+/* send the packet in buffer. */
 
 
 void putpacket(buffer)
@@ -588,7 +614,7 @@ char * buffer;
   count    = 0;
   
   while (ch=buffer[count]) {
-    if (! putDebugChar(ch)) return;
+    putDebugChar(ch);
     checksum += ch;
     count += 1;
   }
@@ -597,20 +623,15 @@ char * buffer;
   putDebugChar(hexchars[checksum >> 4]);
   putDebugChar(hexchars[checksum % 16]);
 
-  } while (1 == 0);  /* (getDebugChar() != '+'); */
+  } while (getDebugChar() != '+');
   
 }
 
-char  remcomInBuffer[BUFMAX];
-char  remcomOutBuffer[BUFMAX];
-static short error;
-
-
 void debug_error(format, parm)
 char * format;
 char * parm;
 {
-  if (remote_debug) fprintf(stderr,format,parm);
+  if (remote_debug) fprintf (stderr,format,parm);
 }
 
 /* convert the memory pointed to by mem into hex, placing result in buf */
@@ -667,13 +688,17 @@ int exceptionVector;
     case 3 : sigval = 10; break; /* address error       */
     case 4 : sigval = 4;  break; /* illegal instruction */
     case 5 : sigval = 8;  break; /* zero divide         */
-    case 6 : sigval = 16; break; /* chk instruction     */
-    case 7 : sigval = 16; break; /* trapv instruction   */
+    case 6 : sigval = 8; break; /* chk instruction     */
+    case 7 : sigval = 8; break; /* trapv instruction   */
     case 8 : sigval = 11; break; /* privilege violation */
     case 9 : sigval = 5;  break; /* trace trap          */
     case 10: sigval = 4;  break; /* line 1010 emulator  */
     case 11: sigval = 4;  break; /* line 1111 emulator  */
-    case 13: sigval = 8;  break; /* floating point err  */
+
+      /* Coprocessor protocol violation.  Using a standard MMU or FPU
+        this cannot be triggered by software.  Call it a SIGBUS.  */
+    case 13: sigval = 10;  break;
+
     case 31: sigval = 2;  break; /* interrupt           */
     case 33: sigval = 5;  break; /* breakpoint          */
 
@@ -729,7 +754,7 @@ int hexToInt(char **ptr, int *intValue)
  */
 void handle_exception(int exceptionVector)
 {
-  int    sigval;
+  int    sigval, stepping;
   int    addr, length;
   char * ptr;
   int    newPC;
@@ -749,11 +774,12 @@ void handle_exception(int exceptionVector)
 
   putpacket(remcomOutBuffer); 
 
+  stepping = 0;
+
   while (1==1) { 
-    error = 0;
     remcomOutBuffer[0] = 0;
-    getpacket(remcomInBuffer);
-    switch (remcomInBuffer[0]) {
+    ptr = getpacket();
+    switch (*ptr++) {
       case '?' :   remcomOutBuffer[0] = 'S';
                    remcomOutBuffer[1] =  hexchars[sigval >> 4];
                    remcomOutBuffer[2] =  hexchars[sigval % 16];
@@ -765,7 +791,7 @@ void handle_exception(int exceptionVector)
                 mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
                 break;
       case 'G' : /* set the value of the CPU registers - return OK */
-                hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
+                hex2mem(ptr, (char*) registers, NUMREGBYTES);
                 strcpy(remcomOutBuffer,"OK");
                 break;
       
@@ -776,7 +802,6 @@ void handle_exception(int exceptionVector)
                     exceptionHandler(2,handle_buserror); 
 
                    /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-                    ptr = &remcomInBuffer[1];
                     if (hexToInt(&ptr,&addr))
                         if (*(ptr++) == ',')
                             if (hexToInt(&ptr,&length)) 
@@ -788,14 +813,12 @@ void handle_exception(int exceptionVector)
                     if (ptr)
                     {
                      strcpy(remcomOutBuffer,"E01");
-                     debug_error("malformed read memory command: %s",remcomInBuffer);
-                  }     
-                } 
-               else {
+                    }     
+                } else {
                  exceptionHandler(2,_catchException);   
                  strcpy(remcomOutBuffer,"E03");
                  debug_error("bus error");
-                 }     
+               }     
                 
                /* restore handler for bus error */
                exceptionHandler(2,_catchException);   
@@ -807,7 +830,6 @@ void handle_exception(int exceptionVector)
                    exceptionHandler(2,handle_buserror); 
                     
                    /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-                    ptr = &remcomInBuffer[1];
                     if (hexToInt(&ptr,&addr))
                         if (*(ptr++) == ',')
                             if (hexToInt(&ptr,&length))
@@ -820,14 +842,12 @@ void handle_exception(int exceptionVector)
                     if (ptr)
                     {
                      strcpy(remcomOutBuffer,"E02");
-                     debug_error("malformed write memory command: %s",remcomInBuffer);
-                     }     
-                } 
-               else {
+                   }     
+                } else {
                  exceptionHandler(2,_catchException);   
                  strcpy(remcomOutBuffer,"E03");
                  debug_error("bus error");
-                 }     
+               }     
 
                 /* restore handler for bus error */
                 exceptionHandler(2,_catchException);   
@@ -835,10 +855,10 @@ void handle_exception(int exceptionVector)
      
      /* cAA..AA    Continue at address AA..AA(optional) */
      /* sAA..AA   Step one instruction from AA..AA(optional) */
-     case 'c' : 
      case 's' : 
+        stepping = 1;
+     case 'c' : 
           /* try to read optional parameter, pc unchanged if no parm */
-         ptr = &remcomInBuffer[1];
          if (hexToInt(&ptr,&addr))
              registers[ PC ] = addr;
              
@@ -848,7 +868,7 @@ void handle_exception(int exceptionVector)
           registers[ PS ] &= 0x7fff;
           
           /* set the trace bit if we're stepping */
-          if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
+          if (stepping) registers[ PS ] |= 0x8000;
           
           /*
            * look for newPC in the linked list of exception frames.
This page took 0.028191 seconds and 4 git commands to generate.