source: rtems/bsps/mips/shared/gdbstub/mips-stub.c

Last change on this file was fd67814, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 10:06:14

bsps: Move GDB stubs to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 43.9 KB
Line 
1#define  GDB_STUB_ENABLE_THREAD_SUPPORT 1
2/*******************************************************************************
3
4                     THIS SOFTWARE IS NOT COPYRIGHTED
5
6    The following software is offered for use in the public domain.
7    There is no warranty with regard to this software or its performance
8    and the user must accept the software "AS IS" with all faults.
9
10    THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
11    REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
12    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13
14********************************************************************************
15*
16*   r46kstub.c -- target debugging stub for the IDT R4600 Orion processor
17*
18*   This module is based on the stub for the Hitachi SH processor written by
19*   Ben Lee and Steve Chamberlain and supplied with gdb 4.16.  The latter
20*   in turn "is originally based on an m68k software stub written by Glenn
21*   Engel at HP, but has changed quite a bit."  The changes for the R4600
22*   were written by C. M. Heard at VVNET.  They were based in part on the
23*   Algorithmics R4000 version of Phil Bunce's PMON program.
24*
25*  Remote communication protocol:
26*
27*  A debug packet whose contents are <data>
28*  is encapsulated for transmission in the form:
29*
30*       $ <data> # CSUM1 CSUM2
31*
32*       <data> must be ASCII alphanumeric and cannot include characters
33*       '$' or '#'.  If <data> starts with two characters followed by
34*       ':', then the existing stubs interpret this as a sequence number.
35*
36*       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
37*       checksum of <data>, the most significant nibble is sent first.
38*       the hex digits 0-9,a-f are used.
39*
40*  Receiver responds with:
41*
42*       +    if CSUM is correct
43*       -    if CSUM is incorrect
44*
45*  <data> is as follows.  All values are encoded in ascii hex digits.
46*
47*       Request         Packet
48*
49*       read registers  g
50*       reply           XX....X         Each byte of register data
51*                                       is described by two hex digits.
52*                                       Registers are in the internal order
53*                                       for GDB, and the bytes in a register
54*                                       are in the same order the machine uses.
55*                       or ENN          for an error.
56*
57*       write regs      GXX..XX         Each byte of register data
58*                                       is described by two hex digits.
59*       reply           OK              for success
60*                       ENN             for an error
61*
62*       write reg       Pn...=r...      Write register n... with value r....
63*       reply           OK              for success
64*                       ENN             for an error
65*
66*       read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
67*       reply           XX..XX          XX..XX is mem contents
68*                                       Can be fewer bytes than requested
69*                                       if able to read only part of the data.
70*                       or ENN          NN is errno
71*
72*       write mem       MAA..AA,LLLL:XX..XX
73*                                       AA..AA is address,
74*                                       LLLL is number of bytes,
75*                                       XX..XX is data
76*       reply           OK              for success
77*                       ENN             for an error (this includes the case
78*                                       where only part of the data was
79*                                       written).
80*
81*       cont            cAA..AA         AA..AA is address to resume
82*                                       If AA..AA is omitted,
83*                                       resume at same address.
84*
85*       step            sAA..AA         AA..AA is address to resume
86*                                       If AA..AA is omitted,
87*                                       resume at same address.
88*
89*       There is no immediate reply to step or cont.
90*       The reply comes when the machine stops.
91*       It is           SAA             AA is the "signal number"
92*
93*       last signal     ?               Reply with the reason for stopping.
94*                                       This is the same reply as is generated
95*                                       for step or cont: SAA where AA is the
96*                                       signal number.
97*
98*       detach          D               Host is detaching.  Reply OK and
99*                                       end remote debugging session.
100*
101*       reserved        <other>         On other requests, the stub should
102*                                       ignore the request and send an empty
103*                                       response ($#<checksum>).  This way
104*                                       we can extend the protocol and GDB
105*                                       can tell whether the stub it is
106*                                       talking to uses the old or the new.
107*
108*       Responses can be run-length encoded to save space.  A '*' means that
109*       the next character is an ASCII encoding giving a repeat count which
110*       stands for that many repetitions of the character preceding the '*'.
111*       The encoding is n+29, yielding a printable character when n >=3
112*       (which is where rle starts to win).  Don't use n > 99 since gdb
113*       masks each character is receives with 0x7f in order to strip off
114*       the parity bit.
115*
116*       As an example, "0* " means the same thing as "0000".
117*
118*******************************************************************************/
119
120
121#include <string.h>
122#include <signal.h>
123#include "mips_opcode.h"
124/* #include "memlimits.h" */
125#include <rtems.h>
126#include <rtems/bspIo.h>
127#include "gdb_if.h"
128
129/* Change it to something meaningful when debugging */
130#undef ASSERT
131#define ASSERT(x) if(!(x)) printk("ASSERT: stub: %d\n", __LINE__)
132
133/***************/
134/* Exception Codes */
135#define EXC_INT         0               /* External interrupt */
136#define EXC_MOD         1               /* TLB modification exception */
137#define EXC_TLBL        2               /* TLB miss (Load or Ifetch) */
138#define EXC_TLBS        3               /* TLB miss (Store) */
139#define EXC_ADEL        4               /* Address error (Load or Ifetch) */
140#define EXC_ADES        5               /* Address error (Store) */
141#define EXC_IBE         6               /* Bus error (Ifetch) */
142#define EXC_DBE         7               /* Bus error (data load or store) */
143#define EXC_SYS         8               /* System call */
144#define EXC_BP          9               /* Break point */
145#define EXC_RI          10              /* Reserved instruction */
146#define EXC_CPU         11              /* Coprocessor unusable */
147#define EXC_OVF         12              /* Arithmetic overflow */
148#define EXC_TRAP        13              /* Trap exception */
149#define EXC_FPE         15              /* Floating Point Exception */
150
151/* FPU Control/Status register fields */
152#define CSR_FS          0x01000000      /* Set to flush denormals to zero */
153#define CSR_C           0x00800000      /* Condition bit (set by FP compare) */
154
155#define CSR_CMASK       (0x3f<<12)
156#define CSR_CE          0x00020000
157#define CSR_CV          0x00010000
158#define CSR_CZ          0x00008000
159#define CSR_CO          0x00004000
160#define CSR_CU          0x00002000
161#define CSR_CI          0x00001000
162
163#define CSR_EMASK       (0x1f<<7)
164#define CSR_EV          0x00000800
165#define CSR_EZ          0x00000400
166#define CSR_EO          0x00000200
167#define CSR_EU          0x00000100
168#define CSR_EI          0x00000080
169
170#define CSR_FMASK       (0x1f<<2)
171#define CSR_FV          0x00000040
172#define CSR_FZ          0x00000020
173#define CSR_FO          0x00000010
174#define CSR_FU          0x00000008
175#define CSR_FI          0x00000004
176
177#define CSR_RMODE_MASK  (0x3<<0)
178#define CSR_RM          0x00000003
179#define CSR_RP          0x00000002
180#define CSR_RZ          0x00000001
181#define CSR_RN          0x00000000
182
183/***************/
184
185/*
186 * Saved register information.  Must be prepared by the exception
187 * preprocessor before handle_exception is invoked.
188 */
189#if (__mips == 3)
190typedef long long mips_register_t;
191#define R_SZ 8
192#elif (__mips == 1)
193typedef unsigned int mips_register_t;
194#define R_SZ 4
195#else
196#error "unknown MIPS ISA"
197#endif
198static mips_register_t *registers;
199
200#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
201static char do_threads;      /* != 0 means we are supporting threads */
202#endif
203
204/*
205 * The following external functions provide character input and output.
206 */
207extern char getDebugChar (void);
208extern void putDebugChar (char);
209
210/*
211 * Exception handler
212 */
213void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame);
214
215/*
216 * Prototype needed by this code and to keep it self contained.
217 */
218void rtems_interrupt_catch( rtems_isr_entry, int, rtems_isr_entry *);
219
220/*
221 * The following definitions are used for the gdb stub memory map
222 */
223struct memseg
224{
225      unsigned begin, end, opts;
226};
227
228static int is_readable(unsigned,unsigned);
229static int is_writeable(unsigned,unsigned);
230static int is_steppable(unsigned);
231
232/*
233 * BUFMAX defines the maximum number of characters in the inbound & outbound
234 * packet buffers.  At least 4+(sizeof registers)*2 bytes will be needed for
235 * register packets.  Memory dump packets can profitably use even more.
236 */
237#define BUFMAX 1500
238
239static char inBuffer[BUFMAX];
240static char outBuffer[BUFMAX];
241
242/* Structure to keep info on a z-breaks */
243#define BREAKNUM 32
244
245struct z0break
246{
247  /* List support */
248  struct z0break *next;
249  struct z0break *prev;
250
251  /* Location, preserved data */
252
253  /* the address pointer, really, really must be a pointer to
254  ** a 32 bit quantity (likely 64 on the R4k), so the full instruction is read &
255  ** written.  Making it a char * as on the i386 will cause
256  ** the zbreaks to mess up the breakpoint instructions
257  */
258  unsigned char *address;
259  unsigned instr;
260};
261
262static struct z0break z0break_arr[BREAKNUM];
263static struct z0break *z0break_avail = NULL;
264static struct z0break *z0break_list  = NULL;
265
266
267/*
268 * Convert an int to hex.
269 */
270const char gdb_hexchars[] = "0123456789abcdef";
271
272#define highhex(x) gdb_hexchars [(x >> 4) & 0xf]
273#define lowhex(x) gdb_hexchars [x & 0xf]
274
275/*
276 * Convert length bytes of data starting at addr into hex, placing the
277 * result in buf.  Return a pointer to the last (null) char in buf.
278 */
279static char *
280mem2hex (void *_addr, int length, char *buf)
281{
282  unsigned int addr = (unsigned int) _addr;
283
284  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */
285    {
286      long long *source = (long long *) (addr);
287      long long *limit  = (long long *) (addr + length);
288
289      while (source < limit)
290        {
291          int i;
292          long long k = *source++;
293
294          for (i = 15; i >= 0; i--)
295            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
296        }
297    }
298  else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */
299    {
300      int *source = (int *) (addr);
301      int *limit  = (int *) (addr + length);
302
303      while (source < limit)
304        {
305          int i;
306          int k = *source++;
307
308          for (i = 7; i >= 0; i--)
309            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
310        }
311    }
312  else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */
313    {
314      short *source = (short *) (addr);
315      short *limit  = (short *) (addr + length);
316
317      while (source < limit)
318        {
319          int i;
320          short k = *source++;
321
322          for (i = 3; i >= 0; i--)
323            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
324        }
325    }
326  else                                                   /* byte aligned */
327    {
328      char *source = (char *) (addr);
329      char *limit  = (char *) (addr + length);
330
331      while (source < limit)
332        {
333          int i;
334          char k = *source++;
335
336          for (i = 1; i >= 0; i--)
337            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
338        }
339    }
340
341  *buf = '\0';
342  return (buf);
343}
344
345
346/*
347 * Convert a hex character to an int.
348 */
349static int
350hex (char ch)
351{
352  if ((ch >= 'a') && (ch <= 'f'))
353    return (ch - 'a' + 10);
354  if ((ch >= '0') && (ch <= '9'))
355    return (ch - '0');
356  if ((ch >= 'A') && (ch <= 'F'))
357    return (ch - 'A' + 10);
358  return (-1);
359}
360
361/*
362 * Convert a string from hex to int until a non-hex digit
363 * is found.  Return the number of characters processed.
364 */
365static int
366hexToInt (char **ptr, int *intValue)
367{
368  int numChars = 0;
369  int hexValue;
370
371  *intValue = 0;
372
373  while (**ptr)
374    {
375      hexValue = hex (**ptr);
376      if (hexValue >= 0)
377        {
378          *intValue = (*intValue << 4) | hexValue;
379          numChars++;
380        }
381      else
382        break;
383
384      (*ptr)++;
385    }
386
387  return (numChars);
388}
389
390/*
391 * Convert a string from hex to long long until a non-hex
392 * digit is found.  Return the number of characters processed.
393 */
394static int
395hexToLongLong (char **ptr, long long *intValue)
396{
397  int numChars = 0;
398  int hexValue;
399
400  *intValue = 0;
401
402  while (**ptr)
403    {
404      hexValue = hex (**ptr);
405      if (hexValue >= 0)
406        {
407          *intValue = (*intValue << 4) | hexValue;
408          numChars++;
409        }
410      else
411        break;
412
413      (*ptr)++;
414    }
415
416  return (numChars);
417}
418
419/*
420 * Convert the hex array buf into binary, placing the result at the
421 * specified address.  If the conversion fails at any point (i.e.,
422 * if fewer bytes are written than indicated by the size parameter)
423 * then return 0;  otherwise return 1.
424 */
425static int
426hex2mem (char *buf, void *_addr, int length)
427{
428  unsigned int addr = (unsigned int) _addr;
429  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */
430    {
431      long long *target = (long long *) (addr);
432      long long *limit  = (long long *) (addr + length);
433
434      while (target < limit)
435        {
436          int i, j;
437          long long k = 0;
438
439          for (i = 0; i < 16; i++)
440            if ((j = hex(*buf++)) < 0)
441              return 0;
442            else
443              k = (k << 4) + j;
444          *target++ = k;
445        }
446    }
447  else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */
448    {
449      int *target = (int *) (addr);
450      int *limit  = (int *) (addr + length);
451
452      while (target < limit)
453        {
454          int i, j;
455          int k = 0;
456
457          for (i = 0; i < 8; i++)
458            if ((j = hex(*buf++)) < 0)
459              return 0;
460            else
461              k = (k << 4) + j;
462          *target++ = k;
463        }
464    }
465  else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */
466    {
467      short *target = (short *) (addr);
468      short *limit  = (short *) (addr + length);
469
470      while (target < limit)
471        {
472          int i, j;
473          short k = 0;
474
475          for (i = 0; i < 4; i++)
476            if ((j = hex(*buf++)) < 0)
477              return 0;
478            else
479              k = (k << 4) + j;
480          *target++ = k;
481        }
482    }
483  else                                                   /* byte aligned */
484    {
485      char *target = (char *) (addr);
486      char *limit  = (char *) (addr + length);
487
488      while (target < limit)
489        {
490          int i, j;
491          char k = 0;
492
493          for (i = 0; i < 2; i++)
494            if ((j = hex(*buf++)) < 0)
495              return 0;
496            else
497              k = (k << 4) + j;
498          *target++ = k;
499        }
500    }
501
502  return 1;
503}
504
505/* Convert the binary stream in BUF to memory.
506
507   Gdb will escape $, #, and the escape char (0x7d).
508   COUNT is the total number of bytes to write into
509   memory. */
510static unsigned char *
511bin2mem (
512  char *buf,
513  unsigned char *mem,
514  int   count
515)
516{
517  int i;
518
519  for (i = 0; i < count; i++) {
520      /* Check for any escaped characters. Be paranoid and
521         only unescape chars that should be escaped. */
522      if (*buf == 0x7d) {
523          switch (*(buf+1)) {
524            case 0x3:  /* # */
525            case 0x4:  /* $ */
526            case 0x5d: /* escape char */
527              buf++;
528              *buf |= 0x20;
529              break;
530            default:
531              /* nothing */
532              break;
533            }
534        }
535
536      *mem++ = *buf++;
537    }
538
539  return mem;
540}
541
542
543/*
544 * Scan the input stream for a sequence for the form $<data>#<checksum>.
545 */
546static void
547getpacket (char *buffer)
548{
549  unsigned char checksum;
550  unsigned char xmitcsum;
551  int i;
552  int count;
553  char ch;
554  do
555    {
556      /* wait around for the start character, ignore all other characters */
557      while ((ch = getDebugChar ()) != '$');
558      checksum = 0;
559      xmitcsum = -1;
560
561      count = 0;
562
563      /* now, read until a # or end of buffer is found */
564      while ( (count < BUFMAX-1) && ((ch = getDebugChar ()) != '#') )
565          checksum += (buffer[count++] = ch);
566
567      /* make sure that the buffer is null-terminated */
568      buffer[count] = '\0';
569
570      if (ch == '#')
571        {
572          xmitcsum = hex (getDebugChar ()) << 4;
573          xmitcsum += hex (getDebugChar ());
574          if (checksum != xmitcsum)
575            putDebugChar ('-'); /* failed checksum */
576          else
577            {
578              putDebugChar ('+');       /* successful transfer */
579              /* if a sequence char is present, reply the sequence ID */
580              if (buffer[2] == ':')
581                {
582                  putDebugChar (buffer[0]);
583                  putDebugChar (buffer[1]);
584                  /* remove sequence chars from buffer */
585                  for (i = 3; i <= count; i++)
586                    buffer[i - 3] = buffer[i];
587                }
588            }
589        }
590    }
591  while (checksum != xmitcsum);
592}
593
594/*
595 * Get a positive/negative acknowledgment for a transmitted packet.
596 */
597static char
598getAck (void)
599{
600  char c;
601
602  do
603    {
604      c = getDebugChar ();
605    }
606  while ((c != '+') && (c != '-'));
607
608  return c;
609}
610
611/*
612 * Send the packet in buffer and wait for a positive acknowledgement.
613 */
614static void
615putpacket (char *buffer)
616{
617  int checksum;
618
619  /* $<packet info>#<checksum> */
620  do
621    {
622      char *src = buffer;
623      putDebugChar ('$');
624      checksum = 0;
625
626      while (*src != '\0')
627        {
628          int runlen = 0;
629
630          /* Do run length encoding */
631          while ((src[runlen] == src[0]) && (runlen < 99))
632            runlen++;
633          if (runlen > 3)
634            {
635              int encode;
636              /* Got a useful amount */
637              putDebugChar (*src);
638              checksum += *src;
639              putDebugChar ('*');
640              checksum += '*';
641              checksum += (encode = (runlen - 4) + ' ');
642              putDebugChar (encode);
643              src += runlen;
644            }
645          else
646            {
647              putDebugChar (*src);
648              checksum += *src;
649              src++;
650             }
651        }
652
653      putDebugChar ('#');
654      putDebugChar (highhex (checksum));
655      putDebugChar (lowhex (checksum));
656    }
657  while  (getAck () != '+');
658}
659
660
661/*
662 * Saved instruction data for single step support
663 */
664static struct
665  {
666    unsigned *targetAddr;
667    unsigned savedInstr;
668  }
669instrBuffer;
670
671/*
672 * If a step breakpoint was planted restore the saved instruction.
673 */
674static void
675undoSStep (void)
676{
677  if (instrBuffer.targetAddr != NULL)
678    {
679      *instrBuffer.targetAddr = instrBuffer.savedInstr;
680      instrBuffer.targetAddr = NULL;
681    }
682  instrBuffer.savedInstr = NOP_INSTR;
683}
684
685/*
686 * If a single step is requested put a temporary breakpoint at the instruction
687 * which logically follows the next one to be executed.  If the next instruction
688 * is a branch instruction then skip the instruction in the delay slot.  NOTE:
689 * ERET instructions are NOT handled, as it is impossible to single-step through
690 * the exit code in an exception handler.  In addition, no attempt is made to
691 * do anything about BC0T and BC0F, since a condition bit for coprocessor 0
692 * is not defined on the R4600.  Finally, BC2T and BC2F are ignored since there
693 * is no coprocessor 2 on a 4600.
694 */
695static void
696doSStep (void)
697{
698   InstFmt inst;
699
700   instrBuffer.targetAddr = (unsigned *)(registers[PC]+4);    /* set default */
701
702   inst.word = *(unsigned *)registers[PC];     /* read the next instruction  */
703
704   switch (inst.RType.op) {                    /* override default if branch */
705      case OP_SPECIAL:
706         switch (inst.RType.func) {
707            case OP_JR:
708            case OP_JALR:
709               instrBuffer.targetAddr =
710                  (unsigned *)registers[inst.RType.rs];
711               break;
712         };
713         break;
714
715      case OP_REGIMM:
716         switch (inst.IType.rt) {
717            case OP_BLTZ:
718            case OP_BLTZL:
719            case OP_BLTZAL:
720            case OP_BLTZALL:
721               if (registers[inst.IType.rs] < 0 )
722                  instrBuffer.targetAddr =
723                     (unsigned *)(((signed short)inst.IType.imm<<2)
724                                  + (registers[PC]+4));
725               else
726                  instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
727               break;
728            case OP_BGEZ:
729            case OP_BGEZL:
730            case OP_BGEZAL:
731            case OP_BGEZALL:
732               if (registers[inst.IType.rs] >= 0 )
733                  instrBuffer.targetAddr =
734                     (unsigned *)(((signed short)inst.IType.imm<<2)
735                                  + (registers[PC]+4));
736               else
737                  instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
738               break;
739         };
740         break;
741
742      case OP_J:
743      case OP_JAL:
744         instrBuffer.targetAddr =
745            (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000));
746         break;
747
748      case OP_BEQ:
749      case OP_BEQL:
750         if (registers[inst.IType.rs] == registers[inst.IType.rt])
751            instrBuffer.targetAddr =
752               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
753         else
754            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
755         break;
756      case OP_BNE:
757      case OP_BNEL:
758         if (registers[inst.IType.rs] != registers[inst.IType.rt])
759            instrBuffer.targetAddr =
760               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
761         else
762            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
763         break;
764      case OP_BLEZ:
765      case OP_BLEZL:
766         if (registers[inst.IType.rs] <= 0)
767            instrBuffer.targetAddr =
768               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
769         else
770            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
771         break;
772      case OP_BGTZ:
773      case OP_BGTZL:
774         if (registers[inst.IType.rs] > 0)
775            instrBuffer.targetAddr =
776               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
777         else
778            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
779         break;
780
781      case OP_COP1:
782         if (inst.RType.rs == OP_BC)
783            switch (inst.RType.rt) {
784               case COPz_BCF:
785               case COPz_BCFL:
786                  if (registers[FCSR] & CSR_C)
787                     instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
788                  else
789                     instrBuffer.targetAddr =
790                        (unsigned *)(((signed short)inst.IType.imm<<2)
791                                     + (registers[PC]+4));
792                  break;
793               case COPz_BCT:
794               case COPz_BCTL:
795                  if (registers[FCSR] & CSR_C)
796                     instrBuffer.targetAddr =
797                        (unsigned *)(((signed short)inst.IType.imm<<2)
798                                     + (registers[PC]+4));
799                  else
800                     instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
801                  break;
802            };
803         break;
804   }
805
806   if( is_steppable((unsigned)instrBuffer.targetAddr) && *(instrBuffer.targetAddr) != BREAK_INSTR )
807   {
808      instrBuffer.savedInstr = *instrBuffer.targetAddr;
809      *instrBuffer.targetAddr = BREAK_INSTR;
810   }
811   else
812   {
813      instrBuffer.targetAddr = NULL;
814      instrBuffer.savedInstr = NOP_INSTR;
815   }
816   return;
817}
818
819
820/*
821 * Translate the R4600 exception code into a Unix-compatible signal.
822 */
823static int
824computeSignal (void)
825{
826  int exceptionCode = (registers[CAUSE] & CAUSE_EXCMASK) >> CAUSE_EXCSHIFT;
827
828  switch (exceptionCode)
829    {
830    case EXC_INT:
831      /* External interrupt */
832      return SIGINT;
833
834    case EXC_RI:
835      /* Reserved instruction */
836    case EXC_CPU:
837      /* Coprocessor unusable */
838      return SIGILL;
839
840    case EXC_BP:
841      /* Break point */
842      return SIGTRAP;
843
844    case EXC_OVF:
845      /* Arithmetic overflow */
846    case EXC_TRAP:
847      /* Trap exception */
848    case EXC_FPE:
849      /* Floating Point Exception */
850      return SIGFPE;
851
852    case EXC_IBE:
853      /* Bus error (Ifetch) */
854    case EXC_DBE:
855      /* Bus error (data load or store) */
856      return SIGBUS;
857
858    case EXC_MOD:
859      /* TLB modification exception */
860    case EXC_TLBL:
861      /* TLB miss (Load or Ifetch) */
862    case EXC_TLBS:
863      /* TLB miss (Store) */
864    case EXC_ADEL:
865      /* Address error (Load or Ifetch) */
866    case EXC_ADES:
867      /* Address error (Store) */
868      return SIGSEGV;
869
870    case EXC_SYS:
871      /* System call */
872      return SIGSYS;
873
874    default:
875      return SIGTERM;
876    }
877}
878
879/*
880 *  This support function prepares and sends the message containing the
881 *  basic information about this exception.
882 */
883static void gdb_stub_report_exception_info(
884  rtems_vector_number vector,
885  CPU_Interrupt_frame *frame,
886  int                  thread
887)
888{
889   char *optr;
890   int sigval;
891
892   optr = outBuffer;
893   *optr++ = 'T';
894   sigval = computeSignal ();
895   *optr++ = highhex (sigval);
896   *optr++ = lowhex (sigval);
897
898   *optr++ = highhex(SP); /*gdb_hexchars[SP]; */
899   *optr++ = lowhex(SP);
900   *optr++ = ':';
901   optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
902   *optr++ = ';';
903
904   *optr++ = highhex(PC); /*gdb_hexchars[PC]; */
905   *optr++ = lowhex(PC);
906   *optr++ = ':';
907   optr    = mem2hstr(optr, (unsigned char *)&frame->epc, R_SZ );
908   *optr++ = ';';
909
910#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
911   if (do_threads)
912   {
913      *optr++ = 't';
914      *optr++ = 'h';
915      *optr++ = 'r';
916      *optr++ = 'e';
917      *optr++ = 'a';
918      *optr++ = 'd';
919      *optr++ = ':';
920      optr   = thread2vhstr(optr, thread);
921      *optr++ = ';';
922   }
923#endif
924   *optr++ = '\0';
925}
926
927
928
929/*
930 * Scratch frame used to retrieve contexts for different threads, so as
931 * not to disrupt our current context on the stack
932 */
933CPU_Interrupt_frame current_thread_registers;
934
935/*
936 * This function handles all exceptions.  It only does two things:
937 * it figures out why it was activated and tells gdb, and then it
938 * reacts to gdb's requests.
939 */
940
941extern void clear_cache(void);
942void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame)
943{
944   int          host_has_detached = 0;
945   int          regno, addr, length;
946   char         *ptr;
947   int          current_thread;  /* current generic thread */
948   int          thread;          /* stopped thread: context exception happened in */
949
950   long long    regval;
951   void         *regptr;
952   int          binary;
953
954   registers = (mips_register_t *)frame;
955
956   thread = 0;
957#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
958   if (do_threads) {
959      thread = rtems_gdb_stub_get_current_thread();
960   }
961#endif
962   current_thread = thread;
963
964   {
965      /* reapply all breakpoints regardless of how we came in */
966      struct z0break *z0, *zother;
967
968      for (zother=z0break_list; zother!=NULL; zother=zother->next)
969      {
970         if( zother->instr == 0xffffffff )
971         {
972            /* grab the instruction */
973            zother->instr = *(zother->address);
974            /* and insert the breakpoint */
975            *(zother->address) = BREAK_INSTR;
976         }
977      }
978
979      /* see if we're coming from a breakpoint */
980      if( *((unsigned *)frame->epc) == BREAK_INSTR )
981      {
982         /* see if its one of our zbreaks */
983         for (z0=z0break_list; z0!=NULL; z0=z0->next)
984         {
985            if( (unsigned)z0->address == frame->epc)
986               break;
987         }
988         if( z0 )
989         {
990            /* restore the original instruction */
991            *(z0->address) = z0->instr;
992            /* flag the breakpoint */
993            z0->instr = 0xffffffff;
994
995            /*
996               now when we return, we'll execute the original code in
997               the original state.  This leaves our breakpoint inactive
998               since the break instruction isn't there, but we'll reapply
999               it the next time we come in via step or breakpoint
1000            */
1001         }
1002         else
1003         {
1004            /* not a zbreak, see if its our trusty stepping code */
1005
1006            /*
1007             * Restore the saved instruction at
1008             * the single-step target address.
1009             */
1010            undoSStep();
1011         }
1012      }
1013   }
1014
1015   /* reply to host that an exception has occurred with some basic info */
1016   gdb_stub_report_exception_info(vector, frame, thread);
1017   putpacket (outBuffer);
1018
1019   while (!(host_has_detached)) {
1020      outBuffer[0] = '\0';
1021      getpacket (inBuffer);
1022      binary = 0;
1023
1024      switch (inBuffer[0]) {
1025         case '?':
1026            gdb_stub_report_exception_info(vector, frame, thread);
1027            break;
1028
1029         case 'd': /* toggle debug flag */
1030            /* can print ill-formed commands in valid packets & checksum errors */
1031            break;
1032
1033         case 'D':
1034            /* remote system is detaching - return OK and exit from debugger */
1035            strcpy (outBuffer, "OK");
1036            host_has_detached = 1;
1037            break;
1038
1039         case 'g':               /* return the values of the CPU registers */
1040            regptr = registers;
1041#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1042            if (do_threads && current_thread != thread )
1043               regptr = &current_thread_registers;
1044#endif
1045            mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
1046            break;
1047
1048         case 'G':       /* set the values of the CPU registers - return OK */
1049            regptr = registers;
1050#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1051            if (do_threads && current_thread != thread )
1052               regptr = &current_thread_registers;
1053#endif
1054            if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
1055               strcpy (outBuffer, "OK");
1056            else
1057               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
1058            break;
1059
1060         case 'P':
1061            /* Pn...=r...  Write register n... with value r... - return OK */
1062            ptr = &inBuffer[1];
1063            if (hexToInt(&ptr, &regno) &&
1064                *ptr++ == '=' &&
1065                hexToLongLong(&ptr, &regval))
1066            {
1067               registers[regno] = regval;
1068               strcpy (outBuffer, "OK");
1069            }
1070            else
1071               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
1072            break;
1073
1074         case 'm':
1075            /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
1076            ptr = &inBuffer[1];
1077            if (hexToInt (&ptr, &addr)
1078                && *ptr++ == ','
1079                && hexToInt (&ptr, &length)
1080                && is_readable (addr, length)
1081                && (length < (BUFMAX - 4)/2))
1082               mem2hex ((void *)addr, length, outBuffer);
1083            else
1084               strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */
1085            break;
1086
1087         case 'X':  /* XAA..AA,LLLL:<binary data>#cs */
1088            binary = 1;
1089         case 'M':
1090            /* MAA..AA,LLLL:  Write LLLL bytes at address AA..AA - return OK */
1091            ptr = &inBuffer[1];
1092            if (hexToInt (&ptr, &addr)
1093                && *ptr++ == ','
1094                && hexToInt (&ptr, &length)
1095                && *ptr++ == ':'
1096                && is_writeable (addr, length) ) {
1097               if ( binary )
1098                  hex2mem (ptr, (void *)addr, length);
1099               else
1100                  bin2mem (ptr, (void *)addr, length);
1101               strcpy (outBuffer, "OK");
1102            }
1103            else
1104               strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */
1105            break;
1106
1107         case 'c':
1108            /* cAA..AA    Continue at address AA..AA(optional) */
1109         case 's':
1110            /* sAA..AA    Step one instruction from AA..AA(optional) */
1111         {
1112            /* try to read optional parameter, pc unchanged if no parm */
1113            ptr = &inBuffer[1];
1114            if (hexToInt (&ptr, &addr))
1115               registers[PC] = addr;
1116
1117            if (inBuffer[0] == 's')
1118               doSStep ();
1119         }
1120         goto stubexit;
1121
1122         case 'k':  /* remove all zbreaks if any */
1123        dumpzbreaks:
1124         {
1125            {
1126               /* Unlink the entire list */
1127               struct z0break *z0, *znxt;
1128
1129               while( (z0= z0break_list) )
1130               {
1131
1132                  /* put back the instruction */
1133                  if( z0->instr != 0xffffffff )
1134                     *(z0->address) = z0->instr;
1135
1136                  /* pop off the top entry */
1137                  znxt = z0->next;
1138                  if( znxt ) znxt->prev = NULL;
1139                  z0break_list = znxt;
1140
1141                  /* and put it on the free list */
1142                  z0->prev = NULL;
1143                  z0->next = z0break_avail;
1144                  z0break_avail = z0;
1145               }
1146            }
1147
1148            strcpy(outBuffer, "OK");
1149         }
1150         break;
1151
1152         case 'q':   /* queries */
1153#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1154            rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
1155#endif
1156            break;
1157
1158#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1159         case 'T':
1160         {
1161            int testThread;
1162
1163            if( vhstr2thread(&inBuffer[1], &testThread) == NULL )
1164            {
1165               strcpy(outBuffer, "E01");
1166               break;
1167            }
1168
1169            if( rtems_gdb_index_to_stub_id(testThread) == NULL )
1170            {
1171               strcpy(outBuffer, "E02");
1172            }
1173            else
1174            {
1175               strcpy(outBuffer, "OK");
1176            }
1177         }
1178         break;
1179#endif
1180
1181         case 'H':  /* set new thread */
1182#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1183            if (inBuffer[1] != 'g') {
1184               break;
1185            }
1186
1187            if (!do_threads) {
1188               break;
1189            }
1190
1191            {
1192               int tmp, ret;
1193
1194               /* Set new generic thread */
1195               if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
1196                  strcpy(outBuffer, "E01");
1197                  break;
1198               }
1199
1200               /* 0 means `thread' */
1201               if (tmp == 0) {
1202                  tmp = thread;
1203               }
1204
1205               if (tmp == current_thread) {
1206                  /* No changes */
1207                  strcpy(outBuffer, "OK");
1208                  break;
1209               }
1210
1211               /* Save current thread registers if necessary */
1212               if (current_thread != thread) {
1213                  ret = rtems_gdb_stub_set_thread_regs(
1214                     current_thread,
1215                     (unsigned int *) (void *)&current_thread_registers);
1216                  ASSERT(ret);
1217               }
1218
1219               /* Read new registers if necessary */
1220               if (tmp != thread) {
1221                  ret = rtems_gdb_stub_get_thread_regs(
1222                     tmp, (unsigned int *) (void *)&current_thread_registers);
1223
1224                  if (!ret) {
1225                     /* Thread does not exist */
1226                     strcpy(outBuffer, "E02");
1227                     break;
1228                  }
1229               }
1230
1231               current_thread = tmp;
1232               strcpy(outBuffer, "OK");
1233            }
1234#endif
1235            break;
1236
1237         case 'Z':  /* Add breakpoint */
1238         {
1239            int ret, type, len;
1240            unsigned char *address;
1241            struct z0break *z0;
1242
1243            ret = parse_zbreak(inBuffer, &type, &address, &len);
1244            if (!ret) {
1245               strcpy(outBuffer, "E01");
1246               break;
1247            }
1248
1249            if (type != 0) {
1250               /* We support only software break points so far */
1251               strcpy(outBuffer, "E02");
1252               break;
1253            }
1254
1255            if (len != R_SZ) {     /* was 1 */
1256               strcpy(outBuffer, "E03");
1257               break;
1258            }
1259
1260            /* Let us check whether this break point already set */
1261            for (z0=z0break_list; z0!=NULL; z0=z0->next) {
1262               if (z0->address == address) {
1263                  break;
1264               }
1265            }
1266
1267            if (z0 != NULL) {
1268               /* we already have a breakpoint for this address */
1269               strcpy(outBuffer, "E04");
1270               break;
1271            }
1272
1273            /* Let us allocate new break point */
1274            if (z0break_avail == NULL) {
1275               strcpy(outBuffer, "E05");
1276               break;
1277            }
1278
1279            /* Get entry */
1280            z0 = z0break_avail;
1281            z0break_avail = z0break_avail->next;
1282
1283            /* Let us copy memory from address add stuff the break point in */
1284            /*
1285            *if (mem2hstr(z0->buf, address, 1) == NULL ||
1286              !hstr2mem(address, "cc" , 1)) {
1287
1288               * Memory error *
1289               z0->next = z0break_avail;
1290               z0break_avail = z0;
1291               strcpy(outBuffer, "E05");
1292               break;
1293            }*/
1294
1295            /* Fill it */
1296            z0->address = address;
1297
1298            if( z0->address == (unsigned char *) frame->epc )
1299            {
1300               /* re-asserting the breakpoint that put us in here, so
1301               we'll add the breakpoint but leave the code in place
1302               since we'll be returning to it when the user continues */
1303               z0->instr = 0xffffffff;
1304            }
1305            else
1306            {
1307               /* grab the instruction */
1308               z0->instr = *(z0->address);
1309               /* and insert the break */
1310               *(z0->address) = BREAK_INSTR;
1311            }
1312
1313            /* Add to the list */
1314            {
1315               struct z0break *znxt = z0break_list;
1316
1317               z0->prev = NULL;
1318               z0->next = znxt;
1319
1320               if( znxt ) znxt->prev = z0;
1321               z0break_list = z0;
1322            }
1323
1324            strcpy(outBuffer, "OK");
1325         }
1326         break;
1327
1328         case 'z': /* remove breakpoint */
1329            if (inBuffer[1] == 'z')
1330            {
1331               goto dumpzbreaks;
1332
1333               /*
1334                * zz packet - remove all breaks *
1335                z0last = NULL;
1336
1337                for (z0=z0break_list; z0!=NULL; z0=z0->next)
1338                {
1339                if(!hstr2mem(z0->address, z0->buf, R_SZ))
1340                {
1341                ret = 0;
1342                }
1343                z0last = z0;
1344                }
1345
1346                * Free entries if any *
1347                if (z0last != NULL) {
1348                z0last->next  = z0break_avail;
1349                z0break_avail = z0break_list;
1350                z0break_list  = NULL;
1351                }
1352
1353                if (ret) {
1354                strcpy(outBuffer, "OK");
1355                } else {
1356                strcpy(outBuffer, "E04");
1357                }
1358                break;
1359               */
1360            }
1361            else
1362            {
1363               int ret, type, len;
1364               unsigned char *address;
1365               struct z0break *z0;
1366
1367               ret = parse_zbreak(inBuffer, &type, &address, &len);
1368               if (!ret) {
1369                  strcpy(outBuffer, "E01");
1370                  break;
1371               }
1372
1373               if (type != 0) {
1374                  /* We support only software break points so far */
1375                  break;
1376               }
1377
1378               if (len != R_SZ) {
1379                  strcpy(outBuffer, "E02");
1380                  break;
1381               }
1382
1383               /* Let us check whether this break point set */
1384               for (z0=z0break_list; z0!=NULL; z0=z0->next) {
1385                  if (z0->address == address) {
1386                     break;
1387                  }
1388               }
1389
1390               if (z0 == NULL) {
1391                  /* Unknown breakpoint */
1392                  strcpy(outBuffer, "E03");
1393                  break;
1394               }
1395
1396               /*
1397               if (!hstr2mem(z0->address, z0->buf, R_SZ)) {
1398                  strcpy(outBuffer, "E04");
1399                  break;
1400                  }*/
1401
1402               if( z0->instr != 0xffffffff )
1403               {
1404                  /* put the old instruction back  */
1405                  *(z0->address) = z0->instr;
1406               }
1407
1408               /* Unlink entry */
1409               {
1410                  struct z0break *zprv = z0->prev, *znxt = z0->next;
1411
1412                  if( zprv ) zprv->next = znxt;
1413                  if( znxt ) znxt->prev = zprv;
1414
1415                  if( !zprv ) z0break_list = znxt;
1416
1417                  znxt = z0break_avail;
1418
1419                  z0break_avail = z0;
1420                  z0->prev = NULL;
1421                  z0->next = znxt;
1422               }
1423
1424               strcpy(outBuffer, "OK");
1425            }
1426            break;
1427
1428         default: /* do nothing */
1429            break;
1430      }
1431
1432      /* reply to the request */
1433      putpacket (outBuffer);
1434   }
1435
1436  stubexit:
1437
1438   /*
1439    *  The original code did this in the assembly wrapper.  We should consider
1440    *  doing it here before we return.
1441    *
1442    *  On exit from the exception handler invalidate each line in the I-cache
1443    *  and write back each dirty line in the D-cache.  This needs to be done
1444    *  before the target program is resumed in order to ensure that software
1445    *  breakpoints and downloaded code will actually take effect.  This
1446    *  is because modifications to code in ram will affect the D-cache,
1447    *  but not necessarily the I-cache.
1448    */
1449
1450   clear_cache();
1451}
1452
1453static int numsegs;
1454static struct memseg   memsegments[NUM_MEMSEGS];
1455
1456int gdbstub_add_memsegment( unsigned base, unsigned end, int opts )
1457{
1458   if( numsegs == NUM_MEMSEGS ) return -1;
1459
1460   memsegments[numsegs].begin = base;
1461   memsegments[numsegs].end   = end;
1462   memsegments[numsegs].opts   = opts;
1463
1464   ++numsegs;
1465   return RTEMS_SUCCESSFUL;
1466}
1467
1468static int is_readable(unsigned ptr, unsigned len)
1469{
1470   struct memseg *ms;
1471   int i;
1472
1473   if( (ptr & 0x3) ) return -1;
1474
1475   for(i=0; i<numsegs; i++)
1476   {
1477      ms= &memsegments[i];
1478
1479      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) )
1480         return -1;
1481   }
1482   return 0;
1483}
1484
1485static int is_writeable(unsigned ptr, unsigned len)
1486{
1487   struct memseg *ms;
1488   int i;
1489
1490   if( (ptr & 0x3) ) return -1;
1491
1492   for(i=0; i<numsegs; i++)
1493   {
1494      ms= &memsegments[i];
1495
1496      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
1497         return -1;
1498   }
1499   return 0;
1500}
1501
1502static int is_steppable(unsigned ptr)
1503{
1504   struct memseg *ms;
1505   int i;
1506
1507   if( (ptr & 0x3) ) return -1;
1508
1509   for(i=0; i<numsegs; i++)
1510   {
1511      ms= &memsegments[i];
1512
1513      if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
1514         return -1;
1515   }
1516   return 0;
1517}
1518
1519static char initialized = 0;   /* 0 means we are not initialized */
1520
1521void mips_gdb_stub_install(int enableThreads)
1522{
1523   /*
1524     These are the RTEMS-defined vectors for all the MIPS exceptions
1525   */
1526   int exceptionVector[]= { MIPS_EXCEPTION_MOD, \
1527                            MIPS_EXCEPTION_TLBL, \
1528                            MIPS_EXCEPTION_TLBS, \
1529                            MIPS_EXCEPTION_ADEL, \
1530                            MIPS_EXCEPTION_ADES, \
1531                            MIPS_EXCEPTION_IBE, \
1532                            MIPS_EXCEPTION_DBE, \
1533                            MIPS_EXCEPTION_SYSCALL, \
1534                            MIPS_EXCEPTION_BREAK, \
1535                            MIPS_EXCEPTION_RI, \
1536                            MIPS_EXCEPTION_CPU, \
1537                            MIPS_EXCEPTION_OVERFLOW, \
1538                            MIPS_EXCEPTION_TRAP, \
1539                            MIPS_EXCEPTION_VCEI, \
1540                            MIPS_EXCEPTION_FPE, \
1541                            MIPS_EXCEPTION_C2E, \
1542                            MIPS_EXCEPTION_WATCH, \
1543                            MIPS_EXCEPTION_VCED, \
1544                            -1 };
1545   int  i;
1546   rtems_isr_entry old;
1547
1548   if (initialized)
1549   {
1550      ASSERT(0);
1551      return;
1552   }
1553
1554   memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS );
1555   numsegs = 0;
1556
1557#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1558   if( enableThreads )
1559      do_threads = 1;
1560   else
1561      do_threads = 0;
1562#endif
1563
1564   {
1565      struct z0break *z0;
1566
1567      z0break_avail = NULL;
1568      z0break_list  = NULL;
1569
1570      /* z0breaks list init, now we'll do it so it makes sense... */
1571      for (i=0; i<BREAKNUM; i++)
1572      {
1573         memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break));
1574
1575         z0->next = z0break_avail;
1576         z0break_avail = z0;
1577      }
1578   }
1579
1580   for(i=0; exceptionVector[i] > -1; i++)
1581   {
1582      rtems_interrupt_catch( (rtems_isr_entry) handle_exception, exceptionVector[i], &old );
1583   }
1584
1585   initialized = 1;
1586
1587   /* get the attention of gdb */
1588   /* mips_break(1);  disabled so user code can choose to invoke it or not */
1589}
Note: See TracBrowser for help on using the repository browser.