Root/lm32/logic/sakc/firmware/gdb-test/gdb.c

1/*
2 * Low-level support for LM32 remote debuging with GDB.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25 
26#include <string.h>
27#include <signal.h>
28#include <errno.h>
29
30#include <sys/stat.h>
31#include <sys/time.h>
32
33// #include <syscall.h>
34
35#include "gdb.h"
36#include "gdb_uart.h"
37
38/* Enable system call support */
39#undef GDB_SYSCALLS_ENABLED 1
40/* Enable open/close system calls */
41#undef GDB_OPEN_CLOSE_SYSCALLS_ENABLED
42/* Enable support for z packets */
43#undef GDB_HARDWARE_BREAKPOINTS_ENABLED
44/* Enable support for q packets */
45#undef GDB_ECLIPSE_SUPPORT
46/* Enable support for X packets */
47#define GDB_BINARY_DOWNLOAD_ENABLED
48/* Enable support for P packets */
49#define GDB_P_ENABLED
50/* Enable support for remote stub debugging */
51#undef GDB_REMOTE_DEBUG_ENABLED
52/* Enable support for run-length encoding */
53#undef GDB_RLE_ENABLED
54/* Enable support for restart packets */
55#undef GDB_RESTART_ENABLED
56
57/* Exception IDs */
58#define LM32_EXCEPTION_RESET 0x0
59#define LM32_EXCEPTION_INST_BREAKPOINT 0x1
60#define LM32_EXCEPTION_INST_BUS_ERROR 0x2
61#define LM32_EXCEPTION_DATA_BREAKPOINT 0x3
62#define LM32_EXCEPTION_DATA_BUS_ERROR 0x4
63#define LM32_EXCEPTION_DIVIDE_BY_ZERO 0x5
64#define LM32_EXCEPTION_INTERRUPT 0x6
65#define LM32_EXCEPTION_SYSTEM_CALL 0x7
66
67/* Breakpoint instruction */
68#define LM32_BREAK 0xac000002UL
69
70/* BUFMAX defines the maximum number of characters in inbound/outbound buffers */
71#define BUFMAX 400
72
73/* Function prototypes */
74#ifdef GDB_REMOTE_DEBUG_ENABLED
75static int gdb_write (char *data, int len);
76static int gdb_puts (char *str);
77static void gdb_putint (int num);
78#endif
79static unsigned char *getpacket (void);
80static unsigned char *getpacket (void);
81
82/* For integer to ASCII conversion */
83static const char hexchars[]="0123456789abcdef";
84
85/* This numbering must be consistant with GDBs numbering in gdb/lm32-tdep.c */
86enum regnames {
87  R0, R1, R2, R3, R4, R5, R6, R7,
88  R8, R9, R10, R11, R12, R13, R14, R15,
89  R16, R17, R18, R19, R20, R21, R22, R23,
90  R24, R25, GP, FP, SP, RA, EA, BE,
91  PC, EID, NUM_REGS
92};
93
94/* I/O packet buffers */
95static unsigned char remcomInBuffer[BUFMAX];
96static unsigned char remcomOutBuffer[BUFMAX];
97
98/* Set by debugger to indicate that when handling memory faults (bus errors), the
99   handler should set the mem_err flag and skip over the faulting instruction */
100static volatile int may_fault;
101
102/* Set by bus error exception handler, this indicates to caller of mem2hex,
103 * hex2mem or bin2mem that there has been an error. */
104static volatile int mem_err;
105
106/* Indicates if we're single stepping */
107static unsigned char stepping;
108static unsigned *seq_ptr;
109static unsigned seq_insn;
110static unsigned *branch_ptr;
111static unsigned branch_insn;
112static char branch_step;
113
114#ifdef GDB_REMOTE_DEBUG_ENABLED
115/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
116static int remote_debug;
117#endif
118
119/* interrupt handler */
120static void (*intr_handler)(void);
121
122/* Convert ch from a hex digit to an int */
123
124static int
125hex (unsigned char ch)
126{
127  if (ch >= 'a' && ch <= 'f')
128    return ch-'a'+10;
129  if (ch >= '0' && ch <= '9')
130    return ch-'0';
131  if (ch >= 'A' && ch <= 'F')
132    return ch-'A'+10;
133  return -1;
134}
135
136/* Scan for the sequence $<data>#<checksum> */
137
138static unsigned char *
139getpacket (void)
140{
141  unsigned char *buffer = &remcomInBuffer[0];
142  unsigned char checksum;
143  unsigned char xmitcsum;
144  int count;
145  char ch;
146
147  while (1)
148    {
149      /* wait around for the start character, ignore all other characters */
150      while ((ch = _gdb_read_char ()) != '$')
151        ;
152
153retry:
154      checksum = 0;
155      xmitcsum = -1;
156      count = 0;
157
158      /* now, read until a # or end of buffer is found */
159      while (count < BUFMAX)
160        {
161          ch = _gdb_read_char ();
162          if (ch == '$')
163            goto retry;
164          if (ch == '#')
165            break;
166          checksum = checksum + ch;
167          buffer[count] = ch;
168          count = count + 1;
169        }
170      buffer[count] = 0;
171
172      if (ch == '#')
173        {
174          ch = _gdb_read_char ();
175          xmitcsum = hex (ch) << 4;
176          ch = _gdb_read_char ();
177          xmitcsum += hex (ch);
178
179          if (checksum != xmitcsum)
180            {
181#ifdef GDB_REMOTE_DEBUG_ENABLED
182              if (remote_debug)
183                {
184                  gdb_puts ("Bad checksum: ");
185                  gdb_putint (checksum);
186                  gdb_puts (" != ");
187                  gdb_putint (xmitcsum);
188                  gdb_puts ("\n");
189                }
190#endif
191              _gdb_write_char ('-'); /* failed checksum */
192            }
193          else
194            {
195              _gdb_write_char ('+'); /* successful transfer */
196
197              /* if a sequence char is present, reply the sequence ID */
198              if (buffer[2] == ':')
199                {
200                  _gdb_write_char (buffer[0]);
201                  _gdb_write_char (buffer[1]);
202
203                  return &buffer[3];
204                }
205
206              return &buffer[0];
207            }
208        }
209    }
210}
211
212/* Send the packet in buffer. */
213#ifdef GDB_RLE_ENABLED
214static void
215putpacket (unsigned char *buffer)
216{
217  unsigned char checksum;
218  int count;
219  unsigned char ch;
220  int run_length;
221  int run_idx;
222  char run_length_char;
223
224  /* $<packet info>#<checksum>. */
225  do
226    {
227      _gdb_write_char ('$');
228      checksum = 0;
229      count = 0;
230
231      while (ch = buffer[count])
232        {
233          /* Transmit character */
234          _gdb_write_char (ch);
235          checksum += ch;
236          count += 1;
237          /* Determine how many consecutive characters there are that are the
238           * same as the character we just transmitted */
239          run_length = 0;
240          run_idx = count;
241          while ((buffer[run_idx++] == ch) && (run_length < 97))
242            run_length++;
243          /* Encode run length as an ASCII character */
244          run_length_char = (char)(run_length + 29);
245          if ( (run_length >= 3)
246              && (run_length_char != '$')
247              && (run_length_char != '#')
248              && (run_length_char != '+')
249              && (run_length_char != '-')
250             )
251            {
252              /* Transmit run-length */
253              _gdb_write_char ('*');
254              checksum += '*';
255              _gdb_write_char (run_length_char);
256              checksum += run_length_char;
257              count += run_length;
258            }
259        }
260      
261      _gdb_write_char ('#');
262      _gdb_write_char (hexchars[(checksum >> 4) & 0xf]);
263      _gdb_write_char (hexchars[checksum & 0xf]);
264    }
265  while (_gdb_read_char () != '+');
266}
267#else
268static void
269putpacket (unsigned char *buffer)
270{
271  unsigned char checksum;
272  int count;
273  unsigned char ch;
274
275  /* $<packet info>#<checksum>. */
276  do
277    {
278      _gdb_write_char ('$');
279      checksum = 0;
280      count = 0;
281
282      while (ch = buffer[count])
283        {
284          _gdb_write_char (ch);
285          checksum += ch;
286          count += 1;
287        }
288
289      _gdb_write_char ('#');
290      _gdb_write_char (hexchars[checksum >> 4]);
291      _gdb_write_char (hexchars[checksum % 16]);
292    }
293  while (_gdb_read_char () != '+');
294}
295#endif
296
297#ifdef GDB_REMOTE_DEBUG_ENABLED
298
299/* Make gdb write n bytes to stdout (not assumed to be null-terminated).
300   Returns: number of bytes written */
301
302static int
303gdb_write (char *data, int len)
304{
305  char *buf, *cpy;
306  int i;
307  char temp[100];
308
309  buf = temp;
310  buf[0] = 'O';
311  i = 0;
312  while (i < len)
313    {
314      for (cpy = buf + 1;
315       i < len && cpy < buf + sizeof (temp) - 3; i++)
316    {
317      *cpy++ = hexchars[data[i] >> 4];
318      *cpy++ = hexchars[data[i] & 0x0F];
319    }
320      *cpy = 0;
321      putpacket (buf);
322    }
323  return len;
324}
325
326/* Make gdb write a null-terminated string to stdout.
327   Returns: the length of the string */
328   
329static int
330gdb_puts (char *str)
331{
332  return gdb_write (str, strlen (str));
333}
334
335/* Make gdb write an integer to stdout. */
336   
337static void
338gdb_putint (int num)
339{
340  char buf[9];
341  int cnt;
342  char *ptr;
343  int digit;
344  
345  ptr = buf;
346  for (cnt = 7 ; cnt >= 0 ; cnt--) {
347    digit = (num >> (cnt * 4)) & 0xf;
348    
349    if (digit <= 9)
350      *ptr++ = (char) ('0' + digit);
351    else
352      *ptr++ = (char) ('a' - 10 + digit);
353  }
354
355  *ptr = (char) 0;
356  gdb_puts (buf);
357}
358
359#endif
360
361static void
362allow_nested_exception ()
363{
364  mem_err = 0;
365  may_fault = 1;
366}
367
368static void
369disallow_nested_exception ()
370{
371  mem_err = 0;
372  may_fault = 0;
373}
374
375/* Convert the memory pointed to by mem into hex, placing result in buf.
376 * Return a pointer to the last char put in buf ('\0'), in case of mem fault,
377 * return NULL.
378 */
379
380static unsigned char *
381mem2hex (unsigned char *mem, unsigned char *buf, int count)
382{
383  unsigned char ch;
384           
385#if 0
386  /* Some h/w registers require word/half-word access, so treat them as a special case */
387  if ((count == 4) && (((unsigned)mem & 3) == 0))
388    {
389      unsigned long val;
390      int i;
391      
392      /* Read 32-bit value from memory */
393      val = *(unsigned long *)mem;
394      /* Return NULL if the memory access caused an exception */
395      if (mem_err)
396        return NULL;
397      /* Convert 32-bit value to a hex string */
398      for (i = 28; i >= 0; i -= 4)
399        *buf++ = hexchars[(val >> i) & 0xf];
400    }
401  else if ((count == 2) && (((unsigned)mem & 1) == 0))
402    {
403      unsigned short val;
404      int i;
405      
406      /* Read 16-bit value from memory */
407      val = *(unsigned short *)mem;
408      /* Return NULL if the memory access caused an exception */
409      if (mem_err)
410        return NULL;
411      /* Convert 16-bit value to a hex string */
412      for (i = 12; i >= 0; i -= 4)
413        *buf++ = hexchars[(val >> i) & 0xf];
414    }
415  else
416#endif
417    {
418      while (count-- > 0)
419        {
420          ch = *mem++;
421          if (mem_err)
422            return NULL;
423          *buf++ = hexchars[(ch >> 4) & 0xf];
424          *buf++ = hexchars[ch & 0xf];
425        }
426    }
427
428  *buf = '\0';
429  return buf;
430}
431
432/* convert the hex array pointed to by buf into binary to be placed in mem
433 * return a pointer to the character AFTER the last byte written */
434
435static char *
436hex2mem (unsigned char *buf, unsigned char *mem, int count)
437{
438  int i;
439  unsigned char ch;
440
441#if 0
442  /* Some h/w registers require word/half-word access, so treat them as a special case */
443  if ((count == 4) && (((unsigned)mem & 3) == 0))
444    {
445      unsigned long val;
446      int i;
447
448      /* Convert hex data to 32-bit value */
449      val = 0;
450      for (i = 24; i >= 0; i -= 4)
451        val |= hex (*buf++) << i;
452      /* Attempt to write data to memory */
453      *(unsigned long *)mem = val;
454      /* Return NULL if write caused an exception */
455      if (mem_err)
456        return NULL;
457      mem += 4;
458    }
459  else if ((count == 2) && (((unsigned)mem & 1) == 0))
460    {
461      unsigned short val;
462      
463      /* Convert hex data to 16-bit value */
464      val = 0;
465      for (i = 12; i >= 0; i -= 4)
466        val |= hex (*buf++) << i;
467      /* Attempt to write data to memory */
468      *(unsigned short *)mem = val;
469      /* Return NULL if write caused an exception */
470      if (mem_err)
471        return NULL;
472      mem += 2;
473    }
474  else
475#endif
476    {
477      for (i = 0; i < count; i++)
478        {
479          /* Convert hex data to 8-bit value */
480          ch = hex (*buf++) << 4;
481          ch |= hex (*buf++);
482          /* Attempt to write data to memory */
483          *mem++ = ch;
484          /* Return NULL if write caused an exception */
485          if (mem_err)
486            return NULL;
487        }
488    }
489  return mem;
490}
491
492#ifdef GDB_BINARY_DOWNLOAD_ENABLED
493
494/* Copy the binary data pointed to by buf to mem and
495 * return a pointer to the character AFTER the last byte written
496 * $, # and 0x7d are escaped with 0x7d */
497
498static char *
499bin2mem (unsigned char *buf, unsigned char *mem, int count)
500{
501  int i;
502  unsigned char c;
503
504#if 0
505  /* Some h/w registers require word/half-word access, so treat them as a special case */
506  if ((count == 4) && (((unsigned)mem & 3) == 0))
507    {
508      unsigned long val;
509      int i;
510
511      /* Convert binary data to 32-bit value */
512      val = 0;
513      for (i = 24; i >= 0; i -= 8)
514        {
515          c = *buf++;
516          if (c == 0x7d)
517            c = *buf++ ^ 0x20;
518          val |= c << i;
519        }
520      /* Attempt to write value to memory */
521      *(unsigned long *)mem = val;
522      /* Return NULL if write caused an exception */
523      if (mem_err)
524        return NULL;
525      mem += 4;
526    }
527  else if ((count == 2) && (((unsigned)mem & 1) == 0))
528    {
529      unsigned short val;
530      int i;
531      
532      /* Convert binary data to 16-bit */
533      val = 0;
534      for (i = 8; i >= 0; i -= 8)
535        {
536          c = *buf++;
537          if (c == 0x7d)
538            c = *buf++ ^ 0x20;
539          val |= c << i;
540        }
541      /* Attempt to write value to memory */
542      *(unsigned short *)mem = val;
543      /* Return NULL if write caused an exception */
544      if (mem_err)
545        return NULL;
546      mem += 2;
547    }
548  else
549#endif
550    {
551      for (i = 0; i < count; i++)
552        {
553          /* Convert binary data to unsigned byte */
554          c = *buf++;
555          if (c == 0x7d)
556            c = *buf++ ^ 0x20;
557          /* Attempt to write value to memory */
558          *mem++ = c;
559          /* Return NULL if write caused an exception */
560          if (mem_err)
561            return NULL;
562        }
563    }
564  return mem;
565}
566#endif
567
568/* Convert the exception identifier to a signal number. */
569
570static int
571computeSignal (int eid)
572{
573  switch (eid)
574    {
575    case LM32_EXCEPTION_RESET:
576      return 0;
577    case LM32_EXCEPTION_INTERRUPT:
578      return SIGINT;
579    case LM32_EXCEPTION_DATA_BREAKPOINT:
580    case LM32_EXCEPTION_INST_BREAKPOINT:
581      return SIGTRAP;
582    case LM32_EXCEPTION_INST_BUS_ERROR:
583    case LM32_EXCEPTION_DATA_BUS_ERROR:
584      return SIGSEGV;
585    case LM32_EXCEPTION_DIVIDE_BY_ZERO:
586      return SIGFPE;
587    }
588  return SIGHUP; /* default for things we don't know about */
589}
590
591/* Flush the instruction cache */
592
593static void
594flush_i_cache (void)
595{
596  /* Executing this does no harm on CPUs without a cache */
597  /* We flush DCache as well incase debugger has accessed memory directly */
598  __asm__ __volatile__ ("wcsr ICC, %0\n"
599                        "nop\n"
600                        "nop\n"
601                        "nop\n"
602                        "wcsr DCC, %0\n"
603                        "nop\n"
604                        "nop\n"
605                        "nop"
606                        :
607                        : "r" (1)
608                       );
609}
610
611/*
612 * While we find nice hex chars, build an int.
613 * Return number of chars processed.
614 */
615
616static int
617hexToInt (char **ptr, int *intValue)
618{
619  int numChars = 0;
620  int hexValue;
621
622  *intValue = 0;
623
624  while (**ptr)
625    {
626      hexValue = hex(**ptr);
627      if (hexValue < 0)
628        break;
629
630      *intValue = (*intValue << 4) | hexValue;
631      numChars ++;
632
633      (*ptr)++;
634    }
635
636  return (numChars);
637}
638
639/* Convert a register to a hex string */
640
641static unsigned char *
642reg2hex (unsigned val, unsigned char *buf)
643{
644  *buf++ = hexchars[(val >> 28) & 0xf];
645  *buf++ = hexchars[(val >> 24) & 0xf];
646  *buf++ = hexchars[(val >> 20) & 0xf];
647  *buf++ = hexchars[(val >> 16) & 0xf];
648  *buf++ = hexchars[(val >> 12) & 0xf];
649  *buf++ = hexchars[(val >> 8) & 0xf];
650  *buf++ = hexchars[(val >> 4) & 0xf];
651  *buf++ = hexchars[val & 0xf];
652
653  return buf;
654}
655
656#ifdef GDB_HARDWARE_BREAKPOINTS_ENABLED
657
658/* Set a h/w breakpoint at the given address */
659
660static int
661set_hw_breakpoint(int address, int length)
662{
663  int bp;
664  
665  /* Find a free break point register and then set it */
666  __asm__ ("rcsr %0, BP0" : "=d" (bp));
667  if ((bp & 0x01) == 0)
668    {
669      __asm__ ("wcsr BP0, %0" : : "d" (address | 1));
670      return 1;
671    }
672  __asm__ ("rcsr %0, BP1" : "=d" (bp));
673  if ((bp & 0x01) == 0)
674    {
675      __asm__ ("wcsr BP1, %0" : : "d" (address | 1));
676      return 1;
677    }
678  __asm__ ("rcsr %0, BP2" : "=d" (bp));
679  if ((bp & 0x01) == 0)
680    {
681      __asm__ ("wcsr BP2, %0" : : "d" (address | 1));
682      return 1;
683    }
684  __asm__ ("rcsr %0, BP3" : "=d" (bp));
685  if ((bp & 0x01) == 0)
686    {
687      __asm__ ("wcsr BP3, %0" : : "d" (address | 1));
688      return 1;
689    }
690  /* No free breakpoint registers */
691  return -1;
692}
693
694/* Remove a h/w breakpoint which should be set at the given address */
695
696static int
697disable_hw_breakpoint(int address, int length)
698{
699  int bp;
700  
701  /* Try to find matching breakpoint register */
702  __asm__ ("rcsr %0, BP0" : "=d" (bp));
703  if ((bp & 0xfffffffc) == (address & 0xfffffffc))
704    {
705      __asm__ ("wcsr BP0, %0" : : "d" (0));
706      return 1;
707    }
708  __asm__ ("rcsr %0, BP1" : "=d" (bp));
709  if ((bp & 0xfffffffc) == (address & 0xfffffffc))
710    {
711      __asm__ ("wcsr BP1, %0" : : "d" (0));
712      return 1;
713    }
714  __asm__ ("rcsr %0, BP2" : "=d" (bp));
715  if ((bp & 0xfffffffc) == (address & 0xfffffffc))
716    {
717      __asm__ ("wcsr BP2, %0" : : "d" (0));
718      return 1;
719    }
720  __asm__ ("rcsr %0, BP3" : "=d" (bp));
721  if ((bp & 0xfffffffc) == (address & 0xfffffffc))
722    {
723      __asm__ ("wcsr BP3, %0" : : "d" (0));
724      return 1;
725    }
726  /* Breakpoint not found */
727  return -1;
728}
729
730#endif
731
732/* This function does all command procesing for interfacing to gdb.
733 * The error codes we return are errno numbers */
734
735void
736_handle_exception (unsigned int *registers)
737{
738  int tt; /* Trap type */
739  int sigval;
740  int addr;
741  int length;
742  char *ptr;
743  unsigned int *sp;
744  int err;
745  unsigned int dc;
746  int pathlen;
747  int retcode;
748  int reterrno;
749  int reg;
750  unsigned char status;
751  unsigned insn;
752  unsigned opcode;
753  unsigned branch_target;
754  
755  /* Check for bus error caused by this code (rather than the program being debugged) */
756  if (may_fault && (registers[EID] == LM32_EXCEPTION_DATA_BUS_ERROR))
757    {
758#ifdef GDB_REMOTE_DEBUG_ENABLED
759      if (remote_debug)
760        gdb_puts ("Bus error in monitor\n");
761#endif
762      /* Indicate that a fault occured */
763      mem_err = 1;
764      /* Skip over faulting instruction */
765      registers[PC] += 4;
766      /* Resume execution */
767      return;
768    }
769
770  if (stepping)
771    {
772      /* Remove breakpoints */
773      *seq_ptr = seq_insn;
774      if (branch_step)
775        *branch_ptr = branch_insn;
776      stepping = 0;
777    }
778            
779  /* Convert exception ID to a signal number */
780  sigval = computeSignal(registers[EID]);
781  if (sigval == SIGINT) {
782    if (intr_handler != NULL) {
783    (*intr_handler)();
784    return;
785    } else {
786        _gdb_ack_interrupt ();
787    }
788  }
789    
790  /* Set pointer to start of output buffer */
791  ptr = remcomOutBuffer;
792  
793#ifdef GDB_SYSCALLS_ENABLED
794  if (registers[EID] == LM32_EXCEPTION_SYSTEM_CALL)
795    {
796      /*_gpio.OutData = 0x82;*/
797
798      /* Calls to strlen in the following code may cause bus errors */
799      allow_nested_exception ();
800      /* Pass system calls to the debugger */
801      switch (registers[R8])
802        {
803          case SYS_exit:
804            *ptr++ = 'W';
805            *ptr++ = hexchars[(registers[R1] >> 4) & 0xf];
806            *ptr++ = hexchars[registers[R1] & 0xf];
807            *ptr++ = 0;
808            intr_handler = NULL;
809            break;
810            
811#ifdef GDB_OPEN_CLOSE_SYSCALLS_ENABLED
812          case SYS_open:
813            memcpy (ptr, "Fopen,", 6);
814            ptr += 6;
815            ptr = reg2hex(registers[R1], ptr);
816            *ptr++ = '/';
817            pathlen = strlen((unsigned char *)registers[R1]) + 1;
818            ptr = reg2hex(pathlen, ptr);
819            *ptr++ = ',';
820            ptr = reg2hex(registers[R2], ptr);
821            *ptr++ = ',';
822            ptr = reg2hex(registers[R3], ptr);
823            *ptr++ = 0;
824            break;
825                      
826          case SYS_close:
827            memcpy (ptr, "Fclose,", 7);
828            ptr += 7;
829            ptr = reg2hex(registers[R1], ptr);
830            *ptr++ = 0;
831            break;
832#endif
833                      
834          case SYS_read:
835            memcpy (ptr, "Fread,", 6);
836            ptr += 6;
837            ptr = reg2hex(registers[R1], ptr);
838            *ptr++ = ',';
839            ptr = reg2hex(registers[R2], ptr);
840            *ptr++ = ',';
841            ptr = reg2hex(registers[R3], ptr);
842            *ptr++ = 0;
843            break;
844            
845          case SYS_write:
846            memcpy (ptr, "Fwrite,", 7);
847            ptr += 7;
848            ptr = reg2hex(registers[R1], ptr);
849            *ptr++ = ',';
850            ptr = reg2hex(registers[R2], ptr);
851            *ptr++ = ',';
852            ptr = reg2hex(registers[R3], ptr);
853            *ptr++ = 0;
854            break;
855               
856          case 231:
857            /*_gpio.OutData = 0x90;*/
858            intr_handler = registers[R1];
859            /* Skip over instruction */
860            registers[PC] += 4;
861            return;
862
863          case 232:
864            intr_handler = NULL;
865            /* Skip over instruction */
866            registers[PC] += 4;
867            return;
868
869          default: /* Unknown or unsupported system call */
870            /* Indicate to calling program that its not supported */
871            registers[R1] = -1;
872            registers[R2] = 0;
873            registers[R3] = ENOSYS;
874            /* Skip over instruction */
875            registers[PC] += 4;
876            return;
877        }
878      /* Check to see if a bus error occured */
879      if (mem_err)
880        {
881          disallow_nested_exception ();
882          /* Indicate error to calling program */
883          registers[R1] = -1;
884          registers[R2] = 0;
885          registers[R3] = ENOSYS;
886          /* Skip over scall instruction */
887          registers[PC] += 4;
888          return;
889        }
890      disallow_nested_exception ();
891    }
892  else
893#endif /* GDB_SYSCALLS_ENABLED */
894    {
895      /* reply to host that an exception has occurred */
896    
897      *ptr++ = 'T';
898      
899      *ptr++ = hexchars[(sigval >> 4) & 0xf];
900      *ptr++ = hexchars[sigval & 0xf];
901    
902      *ptr++ = hexchars[(PC >> 4) & 0xf];
903      *ptr++ = hexchars[PC & 0xf];
904      *ptr++ = ':';
905      ptr = mem2hex ((unsigned char *)&registers[PC], ptr, 4);
906      *ptr++ = ';';
907    
908      *ptr++ = hexchars[(SP >> 4) & 0xf];
909      *ptr++ = hexchars[SP & 0xf];
910      *ptr++ = ':';
911      ptr = mem2hex ((unsigned char *)&registers[SP], ptr, 4);
912      *ptr++ = ';';
913      
914      *ptr++ = 0;
915    }
916  
917  if (registers[EID])
918    putpacket (remcomOutBuffer);
919
920  while (1)
921    {
922      remcomOutBuffer[0] = 0;
923
924      ptr = getpacket();
925      
926      switch (*ptr++)
927        {
928        case '?': /* return last signal */
929          remcomOutBuffer[0] = 'S';
930          remcomOutBuffer[1] = hexchars[sigval >> 4];
931          remcomOutBuffer[2] = hexchars[sigval & 0xf];
932          remcomOutBuffer[3] = 0;
933          break;
934
935#ifdef GDB_REMOTE_DEBUG_ENABLED
936        case 'd': /* toggle debug flag */
937          remote_debug = !(remote_debug);
938          break;
939#endif
940
941        case 'g': /* return the value of the CPU registers */
942          ptr = remcomOutBuffer;
943          ptr = mem2hex ((unsigned char *)registers, ptr, NUM_REGS * 4);
944          break;
945
946        case 'G': /* set the value of the CPU registers */
947          hex2mem (ptr, (unsigned char *)registers, NUM_REGS * 4);
948          strcpy (remcomOutBuffer, "OK");
949          break;
950
951#ifdef GDB_P_ENABLED
952        case 'p': /* Return the value of the specified register */
953          if (hexToInt (&ptr, &reg))
954            {
955              ptr = remcomOutBuffer;
956              ptr = mem2hex ((unsigned char *)&registers[reg], ptr, 4);
957            }
958          else
959            strcpy (remcomOutBuffer, "E22");
960          break;
961
962        case 'P': /* Set the specified register to the given value */
963          if (hexToInt (&ptr, &reg)
964              && *ptr++ == '=')
965            {
966              hex2mem (ptr, (unsigned char *)&registers[reg], 4);
967              strcpy (remcomOutBuffer, "OK");
968            }
969          else
970            strcpy (remcomOutBuffer, "E22");
971          break;
972#endif
973
974        case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
975          /* Try to read %x,%x. */
976          if (hexToInt (&ptr, &addr)
977              && *ptr++ == ','
978              && hexToInt (&ptr, &length)
979              && length < (sizeof(remcomOutBuffer)/2))
980            {
981              allow_nested_exception ();
982              if (NULL == mem2hex((unsigned char *)addr, remcomOutBuffer, length))
983                strcpy (remcomOutBuffer, "E14");
984              disallow_nested_exception ();
985            }
986          else
987            strcpy (remcomOutBuffer,"E22");
988          break;
989
990        case 'M': /* MAA.AA,LLLL: Write LLLL bytes at address AA.AA */
991          /* Try to read '%x,%x:'. */
992          if (hexToInt (&ptr, &addr)
993              && *ptr++ == ','
994              && hexToInt (&ptr, &length)
995              && *ptr++ == ':')
996            {
997              allow_nested_exception ();
998              if (hex2mem(ptr, (char *)addr, length))
999                strcpy (remcomOutBuffer, "OK");
1000              else
1001                strcpy (remcomOutBuffer, "E14");
1002              disallow_nested_exception ();
1003            }
1004          else
1005            strcpy (remcomOutBuffer, "E22");
1006          break;
1007
1008#ifdef GDB_BINARY_DOWNLOAD_ENABLED
1009        case 'X': /* XAA.AA,LLLL: Write LLLL bytes at address AA.AA */
1010          /* Try to read '%x,%x:'. */
1011          if (hexToInt (&ptr, &addr)
1012              && *ptr++ == ','
1013              && hexToInt (&ptr, &length)
1014              && *ptr++ == ':')
1015            {
1016              allow_nested_exception ();
1017              if (bin2mem (ptr, (unsigned char *)addr, length))
1018                strcpy (remcomOutBuffer, "OK");
1019              else
1020                strcpy (remcomOutBuffer, "E14");
1021              disallow_nested_exception ();
1022            }
1023          else
1024            strcpy (remcomOutBuffer, "E22");
1025          break;
1026#endif
1027
1028#if 0
1029        case 'C': /* CSS;AA..AA Continue with signal SS at address AA..AA(optional) */
1030          /* Set signal number */
1031          if (hexToInt (&ptr, &sigval))
1032            registers[EID] = sigval;
1033          /* try to read optional parameter, pc unchanged if no parm */
1034          if (*ptr == ';')
1035            {
1036              ptr++;
1037              if (hexToInt (&ptr, &addr))
1038                registers[PC] = addr;
1039            }
1040          flush_i_cache ();
1041          return;
1042#endif
1043
1044        case 'c': /* cAA..AA Continue at address AA..AA(optional) */
1045          /* try to read optional parameter, pc unchanged if no parm */
1046          if (hexToInt (&ptr, &addr))
1047            registers[PC] = addr;
1048          flush_i_cache ();
1049          return;
1050          
1051        case 's': /* step at address AA (optional) */
1052          /* try to read optional parameter, pc unchanged if no parm */
1053          if (hexToInt (&ptr, &addr))
1054            registers[PC] = addr;
1055          stepping = 1;
1056          /* Is instruction a branch? */
1057          insn = *(unsigned *)registers[PC];
1058          opcode = insn & 0xfc000000;
1059          if ( (opcode == 0xe0000000)
1060              || (opcode == 0xf8000000)
1061             )
1062            {
1063              branch_step = 1;
1064              branch_target = registers[PC] + (((signed)insn << 6) >> 4);
1065            }
1066          else if ( (opcode == 0x44000000)
1067                   || (opcode == 0x48000000)
1068                   || (opcode == 0x4c000000)
1069                   || (opcode == 0x50000000)
1070                   || (opcode == 0x54000000)
1071                   || (opcode == 0x5c000000)
1072                  )
1073            {
1074             branch_step = 1;
1075             branch_target = registers[PC] + (((signed)insn << 16) >> 14);
1076            }
1077          else if ( (opcode == 0xd8000000)
1078                   || (opcode == 0xc0000000)
1079                  )
1080            {
1081              branch_step = 1;
1082              branch_target = registers[(insn >> 21) & 0x1f];
1083            }
1084          else
1085            branch_step = 0;
1086          /* Set breakpoint after instruction we're stepping */
1087          seq_ptr = (unsigned *)registers[PC];
1088          seq_ptr++;
1089          seq_insn = *seq_ptr;
1090          *seq_ptr = LM32_BREAK;
1091          if (branch_step)
1092            {
1093              /* Set breakpoint on branch target */
1094              branch_ptr = (unsigned *)branch_target;
1095              branch_insn = *branch_ptr;
1096              *branch_ptr = LM32_BREAK;
1097            }
1098          flush_i_cache ();
1099          return;
1100
1101#ifdef GDB_HARDWARE_BREAKPOINTS_ENABLED
1102        case 'Z':
1103          switch (*ptr++)
1104            {
1105            case '1': /* Insert h/w breakpoint */
1106              if (*ptr++ == ','
1107                  && hexToInt (&ptr, &addr)
1108                  && *ptr++ == ','
1109                  && hexToInt (&ptr, &length))
1110                {
1111                  err = set_hw_breakpoint(addr, length);
1112                  if (err > 0)
1113                    strcpy (remcomOutBuffer, "OK");
1114                  else if (err < 0)
1115                    strcpy (remcomOutBuffer, "E28");
1116                }
1117              else
1118                strcpy (remcomOutBuffer, "E22");
1119              break;
1120            }
1121          break;
1122                    
1123        case 'z':
1124          switch (*ptr++)
1125            {
1126            case '1': /* Remove h/w breakpoint */
1127              if (*ptr++ == ','
1128                  && hexToInt (&ptr, &addr)
1129                  && *ptr++ == ','
1130                  && hexToInt (&ptr, &length))
1131                {
1132                  err = disable_hw_breakpoint(addr, length);
1133                  if (err > 0)
1134                    strcpy (remcomOutBuffer, "OK");
1135                  else if (err < 0)
1136                    strcpy (remcomOutBuffer, "E28");
1137                }
1138              else
1139                strcpy (remcomOutBuffer, "E22");
1140              break;
1141            }
1142          break;
1143#endif
1144                     
1145#ifdef GDB_SYSCALLS_ENABLED
1146        case 'F': /* system call result */
1147          if ( (ptr[0] == '-')
1148              && (ptr[1] == '1')
1149              && (ptr[2] == ',')
1150             )
1151            {
1152              /* System call failed */
1153              ptr += 3;
1154              hexToInt (&ptr, &reterrno);
1155              retcode = -1;
1156            }
1157          else
1158            {
1159              /* System call was successful */
1160              hexToInt (&ptr, &retcode);
1161              allow_nested_exception ();
1162              /* Check if a bus error occured when mapping data structures */
1163              if (mem_err)
1164                {
1165                  reterrno = EFAULT;
1166                  retcode = -1;
1167                }
1168              disallow_nested_exception ();
1169            }
1170          /* Skip over scall instruction */
1171          registers[PC] += 4;
1172          /* Set return value */
1173          registers[R1] = retcode;
1174          registers[R2] = 0;
1175          registers[R3] = reterrno;
1176          return;
1177#endif /* GDB_SYSCALLS_ENABLED */
1178        
1179#ifdef GDB_ECLIPSE_SUPPORT
1180        case 'q': /* Query */
1181          if (ptr[0] == 'C')
1182            {
1183              /* Return current thread ID. We only support 1. */
1184              strcpy (remcomOutBuffer, "qC1");
1185            }
1186          else if (!strncmp (&ptr[0], "fThreadInfo", 11))
1187            {
1188              /* Return all thread IDs. We only support 1. */
1189              strcpy (remcomOutBuffer, "m1");
1190            }
1191          else if (!strncmp (&ptr[0], "sThreadInfo", 11))
1192            {
1193              /* Indicate there are no more threads. */
1194              strcpy (remcomOutBuffer, "l");
1195            }
1196          break;
1197#endif
1198
1199#ifdef GDB_RESTART_ENABLED
1200        case 'r': /* Reset */
1201        case 'R':
1202          /* We reset by branching to the reset exception handler. */
1203          registers[PC] = 0;
1204          return;
1205#endif
1206          
1207        }
1208
1209      /* reply to the request */
1210      putpacket (remcomOutBuffer);
1211    }
1212}
1213
1214
1215

Archive Download this file

Branches:
master



interactive