source: rtems/c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c @ 3a3f302

4.104.114.95
Last change on this file since 3a3f302 was 3a3f302, checked in by Ralf Corsepius <ralf.corsepius@…>, on 08/18/08 at 07:32:10

Add missing prototypes.

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