Changeset 2f89140 in rtems


Ignore:
Timestamp:
Mar 8, 2002, 4:32:07 PM (19 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
34f5067
Parents:
ffdc659
Message:

2001-03-05 Greg Menke <gregory.menke@…>

  • mips-stub.c: Debugged & tweaked the gdb command processing, zbreak stuff, breakpoint and step code. Implemented 'T' command support and debugged remote gdb support w/ the Mongoose bsp. Added the memory segment support.
  • memlimits.h: Disabled all contents in favor of memory sement support. This file could probably go away.
  • rtems-stub-glue.c (rtems_gdb_index_to_stub_id()): New routine. rtems_gdb_stub_get_register_from_context(): Implemented MIPS version. rtems_gdb_stub_get_offsets(): Implemented MIPS version.
  • README: Updated.
Location:
c/src/lib/libbsp
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/mips/shared/gdbstub/ChangeLog

    rffdc659 r2f89140  
     12001-03-05      Greg Menke <gregory.menke@gsfc.nasa.gov>
     2
     3        * mips-stub.c: Debugged & tweaked the gdb command processing,
     4        zbreak stuff, breakpoint and step code.  Implemented 'T' command
     5        support and debugged remote gdb support w/ the Mongoose bsp.
     6        Added the memory segment support.
     7        * memlimits.h: Disabled all contents in favor of memory sement
     8        support.  This file could probably go away.
     9        * rtems-stub-glue.c (rtems_gdb_index_to_stub_id()): New routine.
     10        rtems_gdb_stub_get_register_from_context(): Implemented MIPS version.
     11        rtems_gdb_stub_get_offsets(): Implemented MIPS version.
     12        * README: Updated.
     13
    1142001-03-01      Joel Sherrill <joel@OARcorp.com>
    215
  • c/src/lib/libbsp/mips/shared/gdbstub/README

    rffdc659 r2f89140  
    22#  $Id$
    33#
     4
     5/*****************************************************/
     6
     7Debugged this stub against the MongooseV bsp.  Relies on putting break
     8instructions on breakpoints and step targets- normal stuff, and does not
     9employ hardware breakpoint support at this time.  As written, a single
     10breakpoint in a loop will not be reasserted unless the user steps or has
     11a 2nd one, since breakpoints are only reset when the gdb stub is
     12re-entered.  A useful enhancement would be to fix the break instruction
     13management so the stub could invisibly put a 2nd break after the 1st
     14"official" one so it can silently reset breakpoints.  Shouldn't be too
     15hard, mostly a matter of working it out.
     16
     17This was tested only against an R3000 MIPS.  It should work OK on a
     18R4000.  Needs to be tested at some point.
     19
     20This stub supports threads as implemented by gdb 5 and doesn't have any
     21bugs I'm aware of.
     22
     23Greg Menke
     243/5/2002
     25
     26/*****************************************************/
    427
    528
  • c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h

    rffdc659 r2f89140  
    5050int   hstr2nibble(const char *buf, int *nibble);
    5151
     52Thread_Control *rtems_gdb_index_to_stub_id(int);
    5253int rtems_gdb_stub_thread_support_ok(void);
    5354int rtems_gdb_stub_get_current_thread(void);
     
    160161#define NUM_REGS        72
    161162
     163
     164
     165
     166
     167
     168void mips_gdb_stub_install(int enableThreads) ;
     169
     170
     171#define MEMOPT_READABLE   1
     172#define MEMOPT_WRITEABLE  2
     173
     174#define NUM_MEMSEGS     10
     175
     176int gdbstub_add_memsegment(unsigned,unsigned,int);
     177
     178
     179
    162180#endif /* _GDB_IF_H */
  • c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h

    rffdc659 r2f89140  
    1313 */
    1414
    15 #ifndef _LIMITS_H_
    16 #define _LIMITS_H_
     15#ifndef _MEMLIMITS_H_
     16#define _MEMLIMITS_H_
    1717
    1818/*
     
    4646 */
    4747
     48/*
    4849#define K0_LIMIT_FOR_READ  (K0BASE+0x18000000)
    4950#define K1_LIMIT_FOR_READ  (K1BASE+K1SIZE)
     
    6869      || ((K1BASE <= (int)ptr) && ((int)ptr < K1_LIMIT_FOR_STEP))))
    6970
    70 #endif  /* _LIMITS_H_ */
     71struct memseg
     72{
     73      unsigned begin, end, opts;
     74};
     75
     76#define MEMOPT_READABLE   1
     77#define MEMOPT_WRITEABLE  2
     78
     79#define NUM_MEMSEGS     10
     80
     81
     82int add_memsegment(unsigned,unsigned,int);
     83int is_readable(unsigned,unsigned);
     84int is_writeable(unsigned,unsigned);
     85int is_steppable(unsigned);
     86*/
     87
     88#endif  /* _MEMLIMITS_H_ */
  • c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c

    rffdc659 r2f89140  
    125125#include <signal.h>
    126126#include "mips_opcode.h"
    127 #include "memlimits.h"
     127/* #include "memlimits.h" */
    128128#include <rtems.h>
    129129#include "gdb_if.h"
     
    210210 */
    211211extern char getDebugChar (void);
    212 
    213212extern void putDebugChar (char);
     213
     214
     215
     216/*
     217 * The following definitions are used for the gdb stub memory map
     218 */
     219struct memseg
     220{
     221      unsigned begin, end, opts;
     222};
     223
     224static int is_readable(unsigned,unsigned);
     225static int is_writeable(unsigned,unsigned);
     226static int is_steppable(unsigned);
     227
     228
     229
     230
    214231
    215232
     
    226243/* Structure to keep info on a z-breaks */
    227244#define BREAKNUM 32
     245
    228246struct z0break
    229247{
     
    233251
    234252  /* Location, preserved data */
    235   unsigned char *address;
    236   char     buf[2];
     253  unsigned *address;
     254  unsigned instr;
    237255};
    238256
     
    630648
    631649
     650
     651
     652
     653
     654
    632655/*
    633656 * Saved instruction data for single step support
     
    669692doSStep (void)
    670693{
    671   InstFmt inst;
    672 
    673   instrBuffer.targetAddr = (unsigned *)(registers[PC]+4);    /* set default */
    674 
    675   inst.word = *(unsigned *)registers[PC];     /* read the next instruction  */
    676 
    677   switch (inst.RType.op) {                    /* override default if branch */
    678     case OP_SPECIAL:
    679       switch (inst.RType.func) {
    680         case OP_JR:
    681         case OP_JALR:
    682           instrBuffer.targetAddr =
    683             (unsigned *)registers[inst.RType.rs];
    684           break;
    685       };
    686       break;
    687 
    688     case OP_REGIMM:
    689       switch (inst.IType.rt) {
    690         case OP_BLTZ:
    691         case OP_BLTZL:
    692         case OP_BLTZAL:
    693         case OP_BLTZALL:
    694           if (registers[inst.IType.rs] < 0 )
     694   struct z0break *z0;
     695   InstFmt inst;
     696
     697   instrBuffer.targetAddr = (unsigned *)(registers[PC]+4);    /* set default */
     698
     699   inst.word = *(unsigned *)registers[PC];     /* read the next instruction  */
     700
     701   switch (inst.RType.op) {                    /* override default if branch */
     702      case OP_SPECIAL:
     703         switch (inst.RType.func) {
     704            case OP_JR:
     705            case OP_JALR:
     706               instrBuffer.targetAddr =
     707                  (unsigned *)registers[inst.RType.rs];
     708               break;
     709         };
     710         break;
     711
     712      case OP_REGIMM:
     713         switch (inst.IType.rt) {
     714            case OP_BLTZ:
     715            case OP_BLTZL:
     716            case OP_BLTZAL:
     717            case OP_BLTZALL:
     718               if (registers[inst.IType.rs] < 0 )
     719                  instrBuffer.targetAddr =
     720                     (unsigned *)(((signed short)inst.IType.imm<<2)
     721                                  + (registers[PC]+4));
     722               else
     723                  instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     724               break;
     725            case OP_BGEZ:
     726            case OP_BGEZL:
     727            case OP_BGEZAL:
     728            case OP_BGEZALL:
     729               if (registers[inst.IType.rs] >= 0 )
     730                  instrBuffer.targetAddr =
     731                     (unsigned *)(((signed short)inst.IType.imm<<2)
     732                                  + (registers[PC]+4));
     733               else
     734                  instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     735               break;
     736         };
     737         break;
     738
     739      case OP_J:
     740      case OP_JAL:
     741         instrBuffer.targetAddr =
     742            (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000));
     743         break;
     744
     745      case OP_BEQ:
     746      case OP_BEQL:
     747         if (registers[inst.IType.rs] == registers[inst.IType.rt])
    695748            instrBuffer.targetAddr =
    696               (unsigned *)(((signed short)inst.IType.imm<<2)
    697                                         + (registers[PC]+4));
    698           else
     749               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
     750         else
    699751            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    700           break;
    701         case OP_BGEZ:
    702         case OP_BGEZL:
    703         case OP_BGEZAL:
    704         case OP_BGEZALL:
    705           if (registers[inst.IType.rs] >= 0 )
     752         break;
     753      case OP_BNE:
     754      case OP_BNEL:
     755         if (registers[inst.IType.rs] != registers[inst.IType.rt])
    706756            instrBuffer.targetAddr =
    707               (unsigned *)(((signed short)inst.IType.imm<<2)
    708                                         + (registers[PC]+4));
    709           else
     757               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
     758         else
    710759            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    711           break;
    712       };
    713       break;
    714 
    715     case OP_J:
    716     case OP_JAL:
    717       instrBuffer.targetAddr =
    718         (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000));
    719       break;
    720 
    721     case OP_BEQ:
    722     case OP_BEQL:
    723       if (registers[inst.IType.rs] == registers[inst.IType.rt])
    724         instrBuffer.targetAddr =
    725           (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
    726       else
    727         instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    728       break;
    729     case OP_BNE:
    730     case OP_BNEL:
    731       if (registers[inst.IType.rs] != registers[inst.IType.rt])
    732         instrBuffer.targetAddr =
    733           (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
    734       else
    735         instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    736       break;
    737     case OP_BLEZ:
    738     case OP_BLEZL:
    739       if (registers[inst.IType.rs] <= 0)
    740         instrBuffer.targetAddr =
    741           (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
    742       else
    743         instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    744       break;
    745     case OP_BGTZ:
    746     case OP_BGTZL:
    747       if (registers[inst.IType.rs] > 0)
    748         instrBuffer.targetAddr =
    749           (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
    750       else
    751         instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    752       break;
    753 
    754     case OP_COP1:
    755       if (inst.RType.rs == OP_BC)
    756           switch (inst.RType.rt) {
    757             case COPz_BCF:
    758             case COPz_BCFL:
    759               if (registers[FCSR] & CSR_C)
    760                 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    761               else
    762                 instrBuffer.targetAddr =
    763                   (unsigned *)(((signed short)inst.IType.imm<<2)
    764                                             + (registers[PC]+4));
    765               break;
    766             case COPz_BCT:
    767             case COPz_BCTL:
    768               if (registers[FCSR] & CSR_C)
    769                 instrBuffer.targetAddr =
    770                   (unsigned *)(((signed short)inst.IType.imm<<2)
    771                                             + (registers[PC]+4));
    772               else
    773                 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
    774               break;
    775           };
    776       break;
    777   }
    778 
    779   if is_steppable (instrBuffer.targetAddr)
    780     {
     760         break;
     761      case OP_BLEZ:
     762      case OP_BLEZL:
     763         if (registers[inst.IType.rs] <= 0)
     764            instrBuffer.targetAddr =
     765               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
     766         else
     767            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     768         break;
     769      case OP_BGTZ:
     770      case OP_BGTZL:
     771         if (registers[inst.IType.rs] > 0)
     772            instrBuffer.targetAddr =
     773               (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
     774         else
     775            instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     776         break;
     777
     778      case OP_COP1:
     779         if (inst.RType.rs == OP_BC)
     780            switch (inst.RType.rt) {
     781               case COPz_BCF:
     782               case COPz_BCFL:
     783                  if (registers[FCSR] & CSR_C)
     784                     instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     785                  else
     786                     instrBuffer.targetAddr =
     787                        (unsigned *)(((signed short)inst.IType.imm<<2)
     788                                     + (registers[PC]+4));
     789                  break;
     790               case COPz_BCT:
     791               case COPz_BCTL:
     792                  if (registers[FCSR] & CSR_C)
     793                     instrBuffer.targetAddr =
     794                        (unsigned *)(((signed short)inst.IType.imm<<2)
     795                                     + (registers[PC]+4));
     796                  else
     797                     instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
     798                  break;
     799            };
     800         break;
     801   }
     802
     803
     804   if( is_steppable((unsigned)instrBuffer.targetAddr) && *(instrBuffer.targetAddr) != BREAK_INSTR )
     805   {
    781806      instrBuffer.savedInstr = *instrBuffer.targetAddr;
    782807      *instrBuffer.targetAddr = BREAK_INSTR;
    783     }
    784   else
    785     {
     808   }
     809   else
     810   {
    786811      instrBuffer.targetAddr = NULL;
    787812      instrBuffer.savedInstr = NOP_INSTR;
    788     }
    789   return;
    790 }
     813   }
     814   return;
     815}
     816
     817
     818
     819
    791820
    792821
     
    862891)
    863892{
    864   char *optr;
    865   int sigval;
    866 
    867   optr = outBuffer;
    868   *optr++ = 'T';
    869   sigval = computeSignal ();
    870   *optr++ = highhex (sigval);
    871   *optr++ = lowhex (sigval);
    872 
    873   *optr++ = gdb_hexchars[SP];
    874   *optr++ = ':';
    875   optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
    876   *optr++ = ';';
     893   char *optr;
     894   int sigval;
     895
     896   optr = outBuffer;
     897   *optr++ = 'T';
     898   sigval = computeSignal ();
     899   *optr++ = highhex (sigval);
     900   *optr++ = lowhex (sigval);
     901
     902   *optr++ = highhex(SP); /*gdb_hexchars[SP]; */
     903   *optr++ = lowhex(SP);
     904   *optr++ = ':';
     905   optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
     906   *optr++ = ';';
    877907 
    878   *optr++ = gdb_hexchars[PC];
    879   *optr++ = ':';
    880   optr    = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
    881   *optr++ = ';';
     908   *optr++ = highhex(PC); /*gdb_hexchars[PC]; */
     909   *optr++ = lowhex(PC);
     910   *optr++ = ':';
     911   optr    = mem2hstr(optr, (unsigned char *)&frame->epc, R_SZ );
     912   *optr++ = ';';
    882913
    883914#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    884   if (do_threads) {
    885     *optr++ = 't';
    886     *optr++ = 'h';
    887     *optr++ = 'r';
    888     *optr++ = 'e';
    889     *optr++ = 'a';
    890     *optr++ = 'd';
    891     *optr++ = ':';
    892     optr   = thread2vhstr(optr, thread);
    893     *optr++ = ';';
    894   }
     915   if (do_threads)
     916   {
     917      *optr++ = 't';
     918      *optr++ = 'h';
     919      *optr++ = 'r';
     920      *optr++ = 'e';
     921      *optr++ = 'a';
     922      *optr++ = 'd';
     923      *optr++ = ':';
     924      optr   = thread2vhstr(optr, thread);
     925      *optr++ = ';';
     926   }
    895927#endif
    896   putpacket (outBuffer);
    897  
    898   *optr++ = '\0';
    899 }
    900 
     928   *optr++ = '\0';
     929}
     930
     931
     932
     933
     934
     935/*
     936 * Scratch frame used to retrieve contexts for different threads, so as
     937 * not to disrupt our current context on the stack
     938 */
     939CPU_Interrupt_frame current_thread_registers;
    901940
    902941
     
    908947 */
    909948
    910 CPU_Interrupt_frame current_thread_registers;
    911949
    912950void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame)
    913951{
    914   int host_has_detached = 0;
    915   int regno, addr, length;
    916   long long regval;
    917   char *ptr;
    918   int  current_thread;  /* current generic thread */
    919   int  thread;          /* stopped thread: context exception happened in */
    920   void *regptr;
    921   int  binary;
    922 
    923   registers = (mips_register_t *)frame;
    924 
    925   thread = 0;
     952   int          host_has_detached = 0;
     953   int          regno, addr, length;
     954   char         *ptr;
     955   int          current_thread;  /* current generic thread */
     956   int          thread;          /* stopped thread: context exception happened in */
     957
     958   long long    regval;
     959   void         *regptr;
     960   int          binary;
     961   
     962
     963   registers = (mips_register_t *)frame;
     964
     965   thread = 0;
    926966#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    927   if (do_threads) {
    928     thread = rtems_gdb_stub_get_current_thread();
    929   }
     967   if (do_threads) {
     968      thread = rtems_gdb_stub_get_current_thread();
     969   }
    930970#endif
    931   current_thread = thread;
    932 
    933   /* reply to host that an exception has occurred with some basic info */
    934   gdb_stub_report_exception_info(vector, frame, thread);
    935 
    936 
    937   /*
    938    * Restore the saved instruction at
    939    * the single-step target address.
    940    */
    941   undoSStep ();
    942 
    943   while (!(host_has_detached)) {
     971   current_thread = thread;
     972
     973
     974   {
     975      /* reapply all breakpoints regardless of how we came in */
     976      struct z0break *z0, *zother;
     977
     978      for (zother=z0break_list; zother!=NULL; zother=zother->next)
     979      {
     980         if( zother->instr == 0xffffffff )
     981         {
     982            /* grab the instruction */
     983            zother->instr = *(zother->address);
     984            /* and insert the breakpoint */
     985            *(zother->address) = BREAK_INSTR;
     986         }
     987      }
     988
     989
     990
     991      /* see if we're coming from a breakpoint */
     992      if( *((unsigned *)frame->epc) == BREAK_INSTR )
     993      {
     994         /* see if its one of our zbreaks */
     995         for (z0=z0break_list; z0!=NULL; z0=z0->next)
     996         {
     997            if( (unsigned)z0->address == frame->epc)
     998               break;
     999         }
     1000         if( z0 )
     1001         {
     1002            /* restore the original instruction */
     1003            *(z0->address) = z0->instr;
     1004            /* flag the breakpoint */
     1005            z0->instr = 0xffffffff;
     1006
     1007            /*
     1008               now when we return, we'll execute the original code in
     1009               the original state.  This leaves our breakpoint inactive
     1010               since the break instruction isn't there, but we'll reapply
     1011               it the next time we come in via step or breakpoint
     1012            */
     1013         }
     1014         else
     1015         {
     1016            /* not a zbreak, see if its our trusty stepping code */
     1017
     1018            /*
     1019             * Restore the saved instruction at
     1020             * the single-step target address.
     1021             */
     1022            undoSStep();
     1023         }
     1024      }
     1025   }
     1026
     1027
     1028
     1029
     1030
     1031   /* reply to host that an exception has occurred with some basic info */
     1032   gdb_stub_report_exception_info(vector, frame, thread);
     1033   putpacket (outBuffer);
     1034
     1035
     1036
     1037   while (!(host_has_detached)) {
    9441038      outBuffer[0] = '\0';
    9451039      getpacket (inBuffer);
     
    9471041
    9481042      switch (inBuffer[0]) {
    949         case '?':
    950           gdb_stub_report_exception_info(vector, frame, thread);
    951           break;
    952 
    953         case 'd': /* toggle debug flag */
    954           /* can print ill-formed commands in valid packets & checksum errors */
    955           break;
    956 
    957         case 'D':
    958           /* remote system is detaching - return OK and exit from debugger */
    959           strcpy (outBuffer, "OK");
    960           host_has_detached = 1;
    961           break;
    962 
    963         case 'g':               /* return the values of the CPU registers */
    964           regptr = registers;
     1043         case '?':
     1044            gdb_stub_report_exception_info(vector, frame, thread);
     1045            break;
     1046
     1047         case 'd': /* toggle debug flag */
     1048            /* can print ill-formed commands in valid packets & checksum errors */
     1049            break;
     1050
     1051         case 'D':
     1052            /* remote system is detaching - return OK and exit from debugger */
     1053            strcpy (outBuffer, "OK");
     1054            host_has_detached = 1;
     1055            break;
     1056
     1057         case 'g':               /* return the values of the CPU registers */
     1058            regptr = registers;
    9651059#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    966           if (do_threads && current_thread != thread )
    967              regptr = &current_thread_registers;
     1060            if (do_threads && current_thread != thread )
     1061               regptr = &current_thread_registers;
    9681062#endif
    969           mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
    970 
    971           break;
    972 
    973         case 'G':       /* set the values of the CPU registers - return OK */
    974           regptr = registers;
     1063            mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
     1064            break;
     1065
     1066
     1067         case 'G':       /* set the values of the CPU registers - return OK */
     1068            regptr = registers;
    9751069#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    976           if (do_threads && current_thread != thread )
    977              regptr = &current_thread_registers;
     1070            if (do_threads && current_thread != thread )
     1071               regptr = &current_thread_registers;
    9781072#endif
    979           if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
    980               strcpy (outBuffer, "OK");
    981           else
    982               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
    983           break;
    984 
    985         case 'P':
    986           /* Pn...=r...  Write register n... with value r... - return OK */
    987           ptr = &inBuffer[1];
    988           if (hexToInt(&ptr, &regno) &&
    989               *ptr++ == '=' &&
    990               hexToLongLong(&ptr, &regval))
     1073            if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
     1074               strcpy (outBuffer, "OK");
     1075            else
     1076               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
     1077            break;
     1078
     1079
     1080         case 'P':
     1081            /* Pn...=r...  Write register n... with value r... - return OK */
     1082            ptr = &inBuffer[1];
     1083            if (hexToInt(&ptr, &regno) &&
     1084                *ptr++ == '=' &&
     1085                hexToLongLong(&ptr, &regval))
    9911086            {
    992               registers[regno] = regval;
    993               strcpy (outBuffer, "OK");
    994             }
    995           else
    996               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
    997           break;
    998 
    999         case 'm':
    1000           /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
    1001           ptr = &inBuffer[1];
    1002           if (hexToInt (&ptr, &addr)
    1003               && *ptr++ == ','
    1004               && hexToInt (&ptr, &length)
    1005               && is_readable (addr, length)
    1006               && (length < (BUFMAX - 4)/2))
    1007             mem2hex ((void *)addr, length, outBuffer);
    1008           else
    1009             strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */
    1010           break;
    1011 
    1012         case 'X':  /* XAA..AA,LLLL:<binary data>#cs */
    1013           binary = 1;
    1014         case 'M':
    1015           /* MAA..AA,LLLL:  Write LLLL bytes at address AA..AA - return OK */
    1016           ptr = &inBuffer[1];
    1017           if (hexToInt (&ptr, &addr)
    1018               && *ptr++ == ','
    1019               && hexToInt (&ptr, &length)
    1020               && *ptr++ == ':'
    1021               && is_writeable (addr, length) ) {
    1022               if ( binary )
    1023                 hex2mem (ptr, (void *)addr, length);
    1024               else
    1025                 bin2mem (ptr, (void *)addr, length);
    1026               strcpy (outBuffer, "OK");
    1027           }
    1028           else
    1029             strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */
    1030           break;
    1031 
    1032         case 'c':
    1033           /* cAA..AA    Continue at address AA..AA(optional) */
    1034         case 's':
    1035           /* sAA..AA    Step one instruction from AA..AA(optional) */
    1036           {
     1087               registers[regno] = regval;
     1088               strcpy (outBuffer, "OK");
     1089            }
     1090            else
     1091               strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
     1092            break;
     1093
     1094
     1095         case 'm':
     1096            /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
     1097            ptr = &inBuffer[1];
     1098            if (hexToInt (&ptr, &addr)
     1099                && *ptr++ == ','
     1100                && hexToInt (&ptr, &length)
     1101                && is_readable (addr, length)
     1102                && (length < (BUFMAX - 4)/2))
     1103               mem2hex ((void *)addr, length, outBuffer);
     1104            else
     1105               strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */
     1106            break;
     1107
     1108
     1109         case 'X':  /* XAA..AA,LLLL:<binary data>#cs */
     1110            binary = 1;
     1111         case 'M':
     1112            /* MAA..AA,LLLL:  Write LLLL bytes at address AA..AA - return OK */
     1113            ptr = &inBuffer[1];
     1114            if (hexToInt (&ptr, &addr)
     1115                && *ptr++ == ','
     1116                && hexToInt (&ptr, &length)
     1117                && *ptr++ == ':'
     1118                && is_writeable (addr, length) ) {
     1119               if ( binary )
     1120                  hex2mem (ptr, (void *)addr, length);
     1121               else
     1122                  bin2mem (ptr, (void *)addr, length);
     1123               strcpy (outBuffer, "OK");
     1124            }
     1125            else
     1126               strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */
     1127            break;
     1128
     1129
     1130
     1131         case 'c':
     1132            /* cAA..AA    Continue at address AA..AA(optional) */
     1133         case 's':
     1134            /* sAA..AA    Step one instruction from AA..AA(optional) */
     1135         {
    10371136            /* try to read optional parameter, pc unchanged if no parm */
    10381137            ptr = &inBuffer[1];
    10391138            if (hexToInt (&ptr, &addr))
    1040               registers[PC] = addr;
     1139               registers[PC] = addr;
    10411140
    10421141            if (inBuffer[0] == 's')
    1043               doSStep ();
    1044           }
    1045           return;
    1046 
    1047         case 'k':  /* remove all zbreaks if any */
    1048           {
    1049             int ret;
    1050             struct z0break *z0, *z0last;
    1051 
    1052             ret = 1;
    1053             z0last = NULL;
    1054 
    1055             for (z0=z0break_list; z0!=NULL; z0=z0->next) {
    1056                 if (!hstr2mem(z0->address, z0->buf, 1)) {
    1057                    ret = 0;
    1058                 }
    1059 
    1060                 z0last = z0;
    1061             }
    1062 
    1063             /* Free entries if any */
    1064             if (z0last != NULL) {
    1065               z0last->next  = z0break_avail;
    1066               z0break_avail = z0break_list;
    1067               z0break_list  = NULL;
    1068             }
    1069           }
    1070 
    1071           break;
    1072 
    1073         case 'q':   /* queries */
     1142               doSStep ();
     1143         }
     1144         goto stubexit;
     1145
     1146
     1147
     1148
     1149
     1150         case 'k':  /* remove all zbreaks if any */
     1151        dumpzbreaks:
     1152         {
     1153            {
     1154               /* Unlink the entire list */
     1155               struct z0break *z0, *znxt;
     1156
     1157               while( (z0= z0break_list) )
     1158               {
     1159
     1160                  /* put back the instruction */
     1161                  if( z0->instr != 0xffffffff )
     1162                     *(z0->address) = z0->instr;
     1163
     1164                  /* pop off the top entry */
     1165                  znxt = z0->next;
     1166                  if( znxt ) znxt->prev = NULL;
     1167                  z0break_list = znxt;
     1168
     1169                  /* and put it on the free list */
     1170                  z0->prev = NULL;
     1171                  z0->next = z0break_avail;
     1172                  z0break_avail = z0;
     1173               }
     1174            }
     1175
     1176            strcpy(outBuffer, "OK");
     1177         }
     1178         break;
     1179
     1180
     1181
     1182
     1183
     1184         case 'q':   /* queries */
    10741185#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    1075           rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
     1186            rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
    10761187#endif
    1077           break;
     1188            break;
     1189
     1190#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     1191         case 'T':
     1192         {
     1193            int testThread;
     1194
     1195            if( vhstr2thread(&inBuffer[1], &testThread) == NULL )
     1196            {
     1197               strcpy(outBuffer, "E01");
     1198               break;
     1199            }
     1200
     1201            if( rtems_gdb_index_to_stub_id(testThread) == NULL )
     1202            {
     1203               strcpy(outBuffer, "E02");
     1204            }
     1205            else
     1206            {
     1207               strcpy(outBuffer, "OK");
     1208            }
     1209         }
     1210         break;
     1211#endif
    10781212       
    1079         case 'H':  /* set new thread */
     1213         case 'H':  /* set new thread */
    10801214#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
    1081           if (inBuffer[1] != 'g') {
    1082             break;
    1083           }
     1215            if (inBuffer[1] != 'g') {
     1216               break;
     1217            }
    10841218         
    1085           if (!do_threads) {
    1086             break;
    1087           }
     1219            if (!do_threads) {
     1220               break;
     1221            }
    10881222         
    1089           {
    1090             int tmp, ret;
     1223            {
     1224               int tmp, ret;
    10911225           
    1092             /* Set new generic thread */
    1093             if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
    1094               strcpy(outBuffer, "E01");
    1095               break;
    1096             }
    1097 
    1098             /* 0 means `thread' */
    1099             if (tmp == 0) {
    1100               tmp = thread;
    1101             }
    1102 
    1103             if (tmp == current_thread) {
    1104               /* No changes */
    1105               strcpy(outBuffer, "OK");
    1106               break;
    1107             }
    1108 
    1109             /* Save current thread registers if necessary */
    1110             if (current_thread != thread) {
    1111               ret = rtems_gdb_stub_set_thread_regs(
    1112                    current_thread, (unsigned int *) &current_thread_registers);
    1113               ASSERT(ret);
    1114             }
    1115 
    1116             /* Read new registers if necessary */
    1117             if (tmp != thread) {
    1118                 ret = rtems_gdb_stub_get_thread_regs(
    1119                     tmp, (unsigned int *) &current_thread_registers);
    1120 
    1121                 if (!ret) {
    1122                   /* Thread does not exist */
    1123                   strcpy(outBuffer, "E02");
    1124                   break;
    1125                 }
    1126             }
     1226               /* Set new generic thread */
     1227               if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
     1228                  strcpy(outBuffer, "E01");
     1229                  break;
     1230               }
     1231
     1232               /* 0 means `thread' */
     1233               if (tmp == 0) {
     1234                  tmp = thread;
     1235               }
     1236
     1237               if (tmp == current_thread) {
     1238                  /* No changes */
     1239                  strcpy(outBuffer, "OK");
     1240                  break;
     1241               }
     1242
     1243               /* Save current thread registers if necessary */
     1244               if (current_thread != thread) {
     1245                  ret = rtems_gdb_stub_set_thread_regs(
     1246                     current_thread, (unsigned int *) &current_thread_registers);
     1247                  ASSERT(ret);
     1248               }
     1249
     1250               /* Read new registers if necessary */
     1251               if (tmp != thread) {
     1252                  ret = rtems_gdb_stub_get_thread_regs(
     1253                     tmp, (unsigned int *) &current_thread_registers);
     1254
     1255                  if (!ret) {
     1256                     /* Thread does not exist */
     1257                     strcpy(outBuffer, "E02");
     1258                     break;
     1259                  }
     1260               }
    11271261           
    1128             current_thread = tmp;
    1129             strcpy(outBuffer, "OK");
    1130           }
    1131 
     1262               current_thread = tmp;
     1263               strcpy(outBuffer, "OK");
     1264            }
    11321265#endif
    1133           break;
    1134 
    1135         case 'Z':  /* Add breakpoint */
    1136           {
     1266            break;
     1267
     1268
     1269
     1270
     1271         case 'Z':  /* Add breakpoint */
     1272         {
    11371273            int ret, type, len;
    1138             unsigned char *address;
     1274            unsigned *address;
    11391275            struct z0break *z0;
    11401276
    11411277            ret = parse_zbreak(inBuffer, &type, &address, &len);
    11421278            if (!ret) {
    1143               strcpy(outBuffer, "E01");
    1144               break;
     1279               strcpy(outBuffer, "E01");
     1280               break;
    11451281            }
    11461282
    11471283            if (type != 0) {
    1148               /* We support only software break points so far */
    1149               break;
    1150             }
    1151 
    1152             if (len != 1) {
     1284               /* We support only software break points so far */
    11531285               strcpy(outBuffer, "E02");
    11541286               break;
    11551287            }
    11561288
     1289            if (len != R_SZ) {     /* was 1 */
     1290               strcpy(outBuffer, "E03");
     1291               break;
     1292            }
     1293
    11571294            /* Let us check whether this break point already set */
    11581295            for (z0=z0break_list; z0!=NULL; z0=z0->next) {
    1159                 if (z0->address == address) {
     1296               if (z0->address == address) {
    11601297                  break;
    1161                 }
     1298               }
    11621299            }
    11631300
    11641301            if (z0 != NULL) {
    1165               /* Repeated packet */
    1166               strcpy(outBuffer, "OK");
    1167               break;
     1302               /* we already have a breakpoint for this address */
     1303               strcpy(outBuffer, "E04");
     1304               break;
    11681305            }
    11691306
    11701307            /* Let us allocate new break point */
    11711308            if (z0break_avail == NULL) {
    1172               strcpy(outBuffer, "E03");
    1173               break;
    1174             }
     1309               strcpy(outBuffer, "E05");
     1310               break;
     1311            }
     1312
    11751313
    11761314            /* Get entry */
     
    11791317
    11801318            /* Let us copy memory from address add stuff the break point in */
    1181             if (mem2hstr(z0->buf, address, 1) == NULL ||
    1182                 !hstr2mem(address, "cc" , 1)) {
    1183               /* Memory error */
    1184               z0->next = z0break_avail;
    1185               z0break_avail = z0;
    1186               strcpy(outBuffer, "E03");
    1187               break;
    1188             }
     1319            /*
     1320            *if (mem2hstr(z0->buf, address, 1) == NULL ||
     1321              !hstr2mem(address, "cc" , 1)) {
     1322
     1323               * Memory error *
     1324               z0->next = z0break_avail;
     1325               z0break_avail = z0;
     1326               strcpy(outBuffer, "E05");
     1327               break;
     1328            }*/
    11891329
    11901330            /* Fill it */
    11911331            z0->address = address;
    11921332
     1333            if( z0->address == frame->epc )
     1334            {
     1335               /* re-asserting the breakpoint that put us in here, so
     1336               we'll add the breakpoint but leave the code in place
     1337               since we'll be returning to it when the user continues */
     1338               z0->instr = 0xffffffff;
     1339            }
     1340            else
     1341            {
     1342               /* grab the instruction */
     1343               z0->instr = *(z0->address);
     1344               /* and insert the break */
     1345               *(z0->address) = BREAK_INSTR;
     1346            }
     1347
    11931348            /* Add to the list */
    1194             z0->next = z0break_list;
    1195             z0->prev = NULL;
    1196 
    1197             if (z0break_list != NULL) {
    1198               z0break_list->prev = z0;
    1199             }
    1200 
    1201             z0break_list = z0;
     1349            {
     1350               struct z0break *znxt = z0break_list;
     1351
     1352               z0->prev = NULL;
     1353               z0->next = znxt;
     1354               
     1355               if( znxt ) znxt->prev = z0;
     1356               z0break_list = z0;
     1357            }
    12021358
    12031359            strcpy(outBuffer, "OK");
    1204           }
    1205 
    1206         case 'z': /* remove breakpoint */
    1207           {
    1208             int ret, type, len;
    1209             unsigned char  *address;
    1210             struct z0break *z0, *z0last;
    1211 
    1212             if (inBuffer[1] == 'z') {
    1213                 /* zz packet - remove all breaks */
    1214                 ret = 1;
     1360         }
     1361         break;
     1362
     1363
     1364         case 'z': /* remove breakpoint */
     1365            if (inBuffer[1] == 'z')
     1366            {
     1367               goto dumpzbreaks;
     1368               
     1369
     1370               /*
     1371                * zz packet - remove all breaks *
    12151372                z0last = NULL;
    1216                 for (z0=z0break_list; z0!=NULL; z0=z0->next) {
    1217                     if(!hstr2mem(z0->address, z0->buf, 1)) {
    1218                         ret = 0;
    1219                       }
    1220                      
    1221                      z0last = z0;
    1222                    }
    1223 
    1224                 /* Free entries if any */
     1373
     1374                for (z0=z0break_list; z0!=NULL; z0=z0->next)
     1375                {
     1376                if(!hstr2mem(z0->address, z0->buf, R_SZ))
     1377                {
     1378                ret = 0;
     1379                }
     1380                z0last = z0;
     1381                }
     1382
     1383                * Free entries if any *
    12251384                if (z0last != NULL) {
    1226                     z0last->next  = z0break_avail;
    1227                     z0break_avail = z0break_list;
    1228                     z0break_list  = NULL;
     1385                z0last->next  = z0break_avail;
     1386                z0break_avail = z0break_list;
     1387                z0break_list  = NULL;
     1388                }
     1389
     1390                if (ret) {
     1391                strcpy(outBuffer, "OK");
     1392                } else {
     1393                strcpy(outBuffer, "E04");
     1394                }
     1395                break;
     1396               */
     1397            }
     1398            else
     1399            {
     1400               int ret, type, len;
     1401               unsigned   *address;
     1402               struct z0break *z0;
     1403             
     1404               ret = parse_zbreak(inBuffer, &type, &address, &len);
     1405               if (!ret) {
     1406                  strcpy(outBuffer, "E01");
     1407                  break;
     1408               }
     1409
     1410               if (type != 0) {
     1411                  /* We support only software break points so far */
     1412                  break;
     1413               }
     1414
     1415               if (len != R_SZ) {
     1416                  strcpy(outBuffer, "E02");
     1417                  break;
     1418               }
     1419           
     1420               /* Let us check whether this break point set */
     1421               for (z0=z0break_list; z0!=NULL; z0=z0->next) {
     1422                  if (z0->address == address) {
     1423                     break;
    12291424                  }
    1230 
    1231                 if (ret) {
    1232                   strcpy(outBuffer, "OK");
    1233                 } else {
    1234                   strcpy(outBuffer, "E04");
    1235                 }
    1236 
    1237                 break;
    1238               }
     1425               }
    12391426             
    1240             ret = parse_zbreak(inBuffer, &type, &address, &len);
    1241             if (!ret) {
    1242                 strcpy(outBuffer, "E01");
    1243                 break;
    1244               }
     1427               if (z0 == NULL) {
     1428                  /* Unknown breakpoint */
     1429                  strcpy(outBuffer, "E03");
     1430                  break;
     1431               }
    12451432           
    1246             if (type != 0) {
    1247               /* We support only software break points so far */
    1248               break;
    1249             }
    1250 
    1251             if (len != 1) {
    1252               strcpy(outBuffer, "E02");
    1253               break;
    1254             }
    1255            
    1256             /* Let us check whether this break point set */
    1257             for (z0=z0break_list; z0!=NULL; z0=z0->next) {
    1258               if (z0->address == address) {
    1259                 break;
    1260               }
    1261             }
    1262              
    1263             if (z0 == NULL) {
    1264               /* Unknown breakpoint */
    1265               strcpy(outBuffer, "E03");
    1266               break;
    1267             }
    1268            
    1269             if (!hstr2mem(z0->address, z0->buf, 1)) {
    1270               strcpy(outBuffer, "E04");
    1271               break;
    1272             }
     1433               /*
     1434               if (!hstr2mem(z0->address, z0->buf, R_SZ)) {
     1435                  strcpy(outBuffer, "E04");
     1436                  break;
     1437                  }*/
     1438
     1439               if( z0->instr != 0xffffffff )
     1440               {
     1441                  /* put the old instruction back  */
     1442                  *(z0->address) = z0->instr;
     1443               }
    12731444   
    1274             /* Unlink entry */
    1275             if (z0->prev == NULL) {
    1276               z0break_list = z0->next;
    1277               if (z0break_list != NULL) {
    1278                 z0break_list->prev = NULL;
    1279               }
    1280             } else if (z0->next == NULL) {
    1281               z0->prev->next = NULL;
    1282             } else {
    1283               z0->prev->next = z0->next;
    1284               z0->next->prev = z0->prev;
    1285            }
    1286 
    1287            z0->next = z0break_avail;
    1288            z0break_avail = z0;
    1289            
    1290            strcpy(outBuffer, "OK");
    1291          }
    1292 
    1293           break;
    1294         default: /* do nothing */
    1295           break;
     1445               /* Unlink entry */
     1446               {
     1447                  struct z0break *zprv = z0->prev, *znxt = z0->next;
     1448
     1449                  if( zprv ) zprv->next = znxt;
     1450                  if( znxt ) znxt->prev = zprv;
     1451
     1452                  if( !zprv ) z0break_list = znxt;
     1453
     1454                  znxt = z0break_avail;
     1455
     1456                  z0break_avail = z0;
     1457                  z0->prev = NULL;
     1458                  z0->next = znxt;
     1459               }
     1460   
     1461               strcpy(outBuffer, "OK");
     1462            }
     1463            break;
     1464
     1465
     1466         default: /* do nothing */
     1467            break;
    12961468      }
    12971469
    12981470      /* reply to the request */
    12991471      putpacket (outBuffer);
    1300     }
     1472   }
     1473
     1474  stubexit:
    13011475
    13021476   /*
     
    13071481    *  and write back each dirty line in the D-cache.  This needs to be done
    13081482    *  before the target program is resumed in order to ensure that software
    1309     *  breakpoints and downloaded code will actually take effect.
     1483    *  breakpoints and downloaded code will actually take effect.  This
     1484    *  is because modifications to code in ram will affect the D-cache,
     1485    *  but not necessarily the I-cache.
    13101486    */
    13111487
    1312   return;
    1313 }
    1314 
    1315 static char initialized;   /* 0 means we are not initialized */
    1316 
    1317 void mips_gdb_stub_install(void)
     1488   {
     1489      extern void clear_cache();
     1490      clear_cache();
     1491   }
     1492
     1493   return;
     1494}
     1495
     1496
     1497
     1498
     1499
     1500
     1501
     1502
     1503
     1504
     1505static int numsegs;
     1506static struct memseg   memsegments[NUM_MEMSEGS];
     1507
     1508int gdbstub_add_memsegment( unsigned base, unsigned end, int opts )
     1509{
     1510   if( numsegs == NUM_MEMSEGS ) return -1;
     1511
     1512   memsegments[numsegs].begin = base;
     1513   memsegments[numsegs].end   = end;
     1514   memsegments[numsegs].opts   = opts;
     1515
     1516   ++numsegs;
     1517   return RTEMS_SUCCESSFUL;
     1518}
     1519
     1520
     1521
     1522
     1523static int is_readable(unsigned ptr, unsigned len)
     1524{
     1525   struct memseg *ms;
     1526   int i;
     1527
     1528   if( (ptr & 0x3) ) return -1;
     1529
     1530   for(i=0; i<numsegs; i++)
     1531   {
     1532      ms= &memsegments[i];
     1533
     1534      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) )
     1535         return -1;
     1536   }
     1537   return 0;
     1538}
     1539
     1540
     1541static int is_writeable(unsigned ptr, unsigned len)
     1542{
     1543   struct memseg *ms;
     1544   int i;
     1545
     1546   if( (ptr & 0x3) ) return -1;
     1547
     1548   for(i=0; i<numsegs; i++)
     1549   {
     1550      ms= &memsegments[i];
     1551
     1552      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
     1553         return -1;
     1554   }
     1555   return 0;
     1556}
     1557
     1558
     1559static int is_steppable(unsigned ptr)
     1560{
     1561   struct memseg *ms;
     1562   int i;
     1563
     1564   if( (ptr & 0x3) ) return -1;
     1565
     1566   for(i=0; i<numsegs; i++)
     1567   {
     1568      ms= &memsegments[i];
     1569
     1570      if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
     1571         return -1;
     1572   }
     1573   return 0;
     1574}
     1575
     1576
     1577
     1578
     1579
     1580
     1581
     1582
     1583
     1584
     1585
     1586
     1587
     1588
     1589static char initialized = 0;   /* 0 means we are not initialized */
     1590
     1591void mips_gdb_stub_install(int enableThreads)
    13181592{
    13191593   /*
     
    13421616   rtems_isr_entry old;
    13431617
    1344    if (initialized) {
     1618   if (initialized)
     1619   {
    13451620      ASSERT(0);
    13461621      return;
    13471622   }
    13481623
    1349    /* z0breaks */
    1350    for (i=0; i<(sizeof(z0break_arr)/sizeof(z0break_arr[0]))-1; i++) {
    1351       z0break_arr[i].next = &z0break_arr[i+1];
    1352    }
    1353 
    1354    z0break_arr[i].next = NULL;
    1355    z0break_avail       = &z0break_arr[0];
    1356    z0break_list        = NULL;
    1357 
     1624   memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS );
     1625   numsegs = 0;
     1626
     1627#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
     1628   if( enableThreads )
     1629      do_threads = 1;
     1630   else
     1631      do_threads = 0;
     1632#endif
     1633
     1634   {
     1635      struct z0break *z0;
     1636
     1637      z0break_avail = NULL;
     1638      z0break_list  = NULL;
     1639   
     1640      /* z0breaks list init, now we'll do it so it makes sense... */
     1641      for (i=0; i<BREAKNUM; i++)
     1642      {
     1643         memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break));
     1644
     1645         z0->next = z0break_avail;
     1646         z0break_avail = z0;
     1647      }
     1648   }     
    13581649
    13591650   for(i=0; exceptionVector[i] > -1; i++)
     
    13631654
    13641655   initialized = 1;
     1656
    13651657   /* get the attention of gdb */
    1366    mips_break(1);
    1367 }
    1368 
    1369 
    1370 
     1658   /* mips_break(1);  disabled so user code can choose to invoke it or not */
     1659}
     1660
     1661
     1662
  • c/src/lib/libbsp/mips/shared/gdbstub/rtems-stub-glue.c

    rffdc659 r2f89140  
    3030
    3131#include <rtems.h>
    32 
    3332#include <string.h>
    3433
     
    4039
    4140extern const char gdb_hexchars[];
     41
    4242
    4343/*
     
    5151);
    5252
     53
     54
     55
     56
     57
     58
    5359/* Check whether it is OK to enable thread support */
    5460int rtems_gdb_stub_thread_support_ok(void)
     
    5965  return 0;
    6066}
     67
     68
     69
     70
    6171
    6272/*
     
    102112}
    103113
     114
     115
     116/* Return the RTEMS thread id from a gdb thread id */
     117Thread_Control *rtems_gdb_index_to_stub_id(
     118  int thread
     119)
     120{
     121   Objects_Id thread_obj_id;
     122   Objects_Id min_id, max_id;
     123   int first_posix_id, first_rtems_id;
     124   Objects_Information *obj_info;
     125   Thread_Control *th;
     126
     127   ASSERT(registers != NULL);
     128
     129   if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) {
     130      /* Should not happen */
     131      return NULL;
     132   }
     133
     134   if (thread == 1) {
     135      th = _Thread_Idle;
     136      goto found;
     137   }
     138
     139   /* Let us get object associtated with current thread */
     140   first_rtems_id = 2;
     141
     142   thread_obj_id = _Thread_Executing->Object.id;
     143
     144   /* Let us figure out thread_id for gdb */
     145   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
     146
     147   min_id = obj_info->minimum_id;
     148   max_id = obj_info->maximum_id;
     149
     150   if (thread <= (first_rtems_id + (max_id - min_id))) {
     151      th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]);
     152
     153      if (th != NULL) {
     154         goto found;
     155      }
     156
     157      /* Thread does not exist */
     158      return NULL;
     159   }
     160
     161   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
     162
     163   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
     164
     165   min_id = obj_info->minimum_id;
     166   max_id = obj_info->maximum_id;
     167
     168   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
     169   if (th == NULL) {
     170      /* Thread does not exist */
     171      return NULL;
     172   }
     173
     174  found:
     175   return th;
     176}
     177
     178
     179
     180
     181
     182
    104183/* Get id of the thread stopped by exception */
    105184int rtems_gdb_stub_get_current_thread(void)
     
    107186  return rtems_gdb_stub_id_to_index( _Thread_Executing->Object.id );
    108187}
     188
     189
     190
    109191
    110192/* Get id of the next thread after athread, if argument <= 0 find the
     
    175257  return 0;
    176258}
     259
     260
     261
     262
    177263
    178264
     
    184270)
    185271{
    186   Objects_Id thread_obj_id;
    187   Objects_Id min_id, max_id;
    188   int first_posix_id, first_rtems_id;
    189   Objects_Information *obj_info;
    190   Thread_Control *th;
    191 
    192   ASSERT(registers != NULL);
    193 
    194   if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) {
    195     /* Should not happen */
    196     return 0;
    197   }
    198 
    199   if (thread == 1) {
    200     th = _Thread_Idle;
    201     goto found;
    202   }
    203 
    204   /* Let us get object associtated with current thread */
    205   first_rtems_id = 2;
    206 
    207   thread_obj_id = _Thread_Executing->Object.id;
    208 
    209   /* Let us figure out thread_id for gdb */
    210   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
    211 
    212   min_id = obj_info->minimum_id;
    213   max_id = obj_info->maximum_id;
    214 
    215   if (thread <= (first_rtems_id + (max_id - min_id))) {
    216     th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]);
    217 
    218     if (th != NULL) {
    219       goto found;
    220     }
    221 
    222     /* Thread does not exist */
    223     return 0;
    224   }
    225 
    226   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
    227 
    228   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
    229 
    230   min_id = obj_info->minimum_id;
    231   max_id = obj_info->maximum_id;
    232 
    233   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
    234   if (th == NULL) {
    235     /* Thread does not exist */
    236     return 0;
    237   }
    238 
    239 found:
    240 
    241   rtems_gdb_stub_get_registers_from_context( registers, th );
    242 
    243   return 1;
    244 }
     272   Thread_Control *th;
     273
     274   th= rtems_gdb_index_to_stub_id(thread);
     275
     276   if( th )
     277   {
     278      rtems_gdb_stub_get_registers_from_context( registers, th );
     279      return 1;
     280   }
     281   return 0;
     282}
     283
     284
     285
     286
    245287
    246288
     
    248290   exist or register values will screw up the threads,
    249291   and 1 otherwise */
     292
    250293int rtems_gdb_stub_set_thread_regs(
    251294  int thread,
     
    259302  return 1;
    260303}
     304
     305
     306
     307
    261308
    262309
     
    268315)
    269316{
    270   Objects_Id thread_obj_id;
    271   Objects_Id min_id, max_id;
    272   int first_posix_id, first_rtems_id;
    273   Objects_Information *obj_info;
    274   Thread_Control *th;
    275   unsigned32 name;
    276   char tmp_buf[20];
    277 
    278   ASSERT(info != NULL);
    279 
    280   if (thread <= 0) {
    281     return 0;
    282   }
    283 
    284   if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {
    285     /* We have one thread let us use value
     317   Objects_Id thread_obj_id;
     318   Objects_Id min_id, max_id;
     319   int first_posix_id, first_rtems_id;
     320   Objects_Information *obj_info;
     321   Thread_Control *th;
     322   unsigned32 name;
     323   char tmp_buf[20];
     324
     325   ASSERT(info != NULL);
     326
     327   if (thread <= 0) {
     328      return 0;
     329   }
     330
     331   if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {
     332      /* We have one thread let us use value
    286333         which will never happen for real thread */
    287     strcpy(info->display, "idle thread");
    288     strcpy(info->name, "IDLE");
    289     info->more_display[0] = 0; /* Nothing */
    290 
    291     return 1;
    292   }
    293 
    294   /* Let us get object associtated with current thread */
    295   thread_obj_id = _Thread_Executing->Object.id;
    296 
    297   /* Let us figure out thread_id for gdb */
    298   first_rtems_id = 2;
     334      strcpy(info->display, "idle thread");
     335      strcpy(info->name, "IDLE");
     336      info->more_display[0] = 0; /* Nothing */
     337
     338      return 1;
     339   }
     340
     341   /* Let us get object associtated with current thread */
     342   thread_obj_id = _Thread_Executing->Object.id;
     343
     344   /* Let us figure out thread_id for gdb */
     345   first_rtems_id = 2;
    299346 
    300   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
    301 
    302   min_id = obj_info->minimum_id;
    303   max_id = obj_info->maximum_id;
    304 
    305   if (thread <= (first_rtems_id + (max_id - min_id))) {
     347   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
     348
     349   min_id = obj_info->minimum_id;
     350   max_id = obj_info->maximum_id;
     351
     352   if (thread <= (first_rtems_id + (max_id - min_id))) {
    306353      th = (Thread_Control *)(obj_info->local_table[thread -
    307354                                                    first_rtems_id + 1]);
    308355
    309   if (th == NULL) {
    310     /* Thread does not exist */
    311     return 0;
    312   }
    313 
    314   strcpy(info->display, "rtems task:   control at 0x");
    315 
    316   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
    317   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
    318   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
    319   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
    320   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
    321   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
    322   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
    323   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
    324   tmp_buf[8] = 0;
    325 
    326   strcat(info->display, tmp_buf);
     356      if (th == NULL) {
     357         /* Thread does not exist */
     358         return 0;
     359      }
     360
     361      strcpy(info->display, "rtems task:   control at 0x");
     362
     363      tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
     364      tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
     365      tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
     366      tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
     367      tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
     368      tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
     369      tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
     370      tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
     371      tmp_buf[8] = 0;
     372
     373      strcat(info->display, tmp_buf);
    327374 
    328   name = *(unsigned32 *)(obj_info->local_table[thread]->name);
     375      name = *(unsigned32 *)(obj_info->local_table[thread]->name);
    329376     
    330   info->name[0] = (name >> 24) & 0xff;
    331   info->name[1] = (name >> 16) & 0xff;
    332   info->name[2] = (name >> 8) & 0xff;
    333   info->name[3] = name & 0xff;
    334   info->name[4] = 0;
    335 
    336   info->more_display[0] = 0; /* Nothing */
    337 
    338   return 1;
    339 }
    340 
    341   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
    342 
    343   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
    344 
    345   min_id = obj_info->minimum_id;
    346   max_id = obj_info->maximum_id;
    347 
    348   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
    349   if (th == NULL)
    350     {
     377      info->name[0] = (name >> 24) & 0xff;
     378      info->name[1] = (name >> 16) & 0xff;
     379      info->name[2] = (name >> 8) & 0xff;
     380      info->name[3] = name & 0xff;
     381      info->name[4] = 0;
     382
     383      info->more_display[0] = 0; /* Nothing */
     384
     385      return 1;
     386   }
     387
     388   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
     389
     390   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
     391
     392   min_id = obj_info->minimum_id;
     393   max_id = obj_info->maximum_id;
     394
     395   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
     396   if (th == NULL)
     397   {
    351398      /* Thread does not exist */
    352399      return 0;
    353     }
    354 
    355   strcpy(info->display, "posix thread: control at 0x");
    356 
    357   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
    358   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
    359   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
    360   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
    361   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
    362   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
    363   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
    364   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
    365   tmp_buf[8] = 0;
    366 
    367   strcat(info->display, tmp_buf);
    368 
    369   name = *(unsigned32 *)(obj_info->local_table[thread -
    370                                                first_posix_id + 1]->name);
    371 
    372   info->name[0] = (name >> 24) & 0xff;
    373   info->name[1] = (name >> 16) & 0xff;
    374   info->name[2] = (name >> 8) & 0xff;
    375   info->name[3] = name & 0xff;
    376   info->name[4] = 0;
    377 
    378   info->more_display[0] = 0; /* Nothing */
     400   }
     401
     402   strcpy(info->display, "posix thread: control at 0x");
     403
     404   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
     405   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
     406   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
     407   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
     408   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
     409   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
     410   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
     411   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
     412   tmp_buf[8] = 0;
     413
     414   strcat(info->display, tmp_buf);
     415
     416   name = *(unsigned32 *)(obj_info->local_table[thread -
     417                                                first_posix_id + 1]->name);
     418
     419   info->name[0] = (name >> 24) & 0xff;
     420   info->name[1] = (name >> 16) & 0xff;
     421   info->name[2] = (name >> 8) & 0xff;
     422   info->name[3] = name & 0xff;
     423   info->name[4] = 0;
     424
     425   info->more_display[0] = 0; /* Nothing */
    379426 
    380   return 1;
     427   return 1;
    381428}
    382429
    383430/*******************************************************/
     431
     432
     433
     434
    384435
    385436
     
    598649pack_qm_header(char *out, int count, int done, int athread)
    599650{
    600   ASSERT(out != 0);
    601   ASSERT(count >= 0 && count < 256);
    602 
    603   *out++ = 'q';
    604   *out++ = 'M';
    605 
    606   *out++ = gdb_hexchars[(count >> 4) & 0x0f];
    607   *out++ = gdb_hexchars[count & 0x0f];
    608 
    609   if (done) {
    610     *out++ = '1';
    611   } else {
    612     *out++ = '0';
    613   }
    614 
    615   thread2fhstr(out, athread);
    616 
    617   return;
    618 }
     651   ASSERT(out != 0);
     652   ASSERT(count >= 0 && count < 256);
     653
     654   *out++ = 'q';
     655   *out++ = 'M';
     656
     657   *out++ = gdb_hexchars[(count >> 4) & 0x0f];
     658   *out++ = gdb_hexchars[count & 0x0f];
     659
     660   if (done) {
     661      *out++ = '1';
     662   } else {
     663      *out++ = '0';
     664   }
     665
     666   thread2fhstr(out, athread);
     667   return;
     668}
     669
     670
     671
     672
     673
     674
     675
     676
     677
     678
    619679
    620680
     
    643703      break;
    644704
     705
     706
     707
    645708    case 'P':
    646709      /* Thread info query */
     
    670733        pack_qq(outbuffer, mask, rthread, &info);
    671734      }
    672 
    673735      break;
     736
     737
     738
     739
     740
    674741    case 'L':
    675       /* Thread info query */
     742      /* Thread list query */
    676743      if (!do_threads) {
    677744        break;
     
    725792        /* Fill header */
    726793        pack_qm_header(outbuffer, i, done, athread);
    727 
    728794      }
    729795      break;
     796
     797
     798
     799
     800
     801
    730802    default:
    731803      if (memcmp(inbuffer, "qOffsets", 8) == 0) {
     
    773845      break;
    774846    }
    775 
    776 }
     847}
     848
     849
     850
     851
     852
    777853
    778854/* Present thread in the variable length string format */
     
    11971273   to mem_fault, they won't get restored, so there better not be any
    11981274   saved).  */
     1275
    11991276unsigned char
    12001277get_byte (const unsigned char *addr)
     
    12081285  *addr = val;
    12091286}
     1287
     1288
     1289
     1290
     1291
     1292
    12101293
    12111294
     
    12741357}
    12751358
     1359
     1360
     1361
     1362
    12761363#elif defined(__mips__)
     1364
     1365
    12771366void rtems_gdb_stub_get_registers_from_context(
    12781367  int            *registers,
     
    12801369)
    12811370{
    1282 }
     1371   registers[S0] = (unsigned)th->Registers.s0;
     1372   registers[S1] = (unsigned)th->Registers.s1;
     1373   registers[S2] = (unsigned)th->Registers.s2;
     1374   registers[S3] = (unsigned)th->Registers.s3;
     1375   registers[S4] = (unsigned)th->Registers.s4;
     1376   registers[S5] = (unsigned)th->Registers.s5;
     1377   registers[S6] = (unsigned)th->Registers.s6;
     1378   registers[S7] = (unsigned)th->Registers.s7;
     1379
     1380   registers[SP] = (unsigned)th->Registers.sp;
     1381   registers[RA] = (unsigned)th->Registers.ra;
     1382
     1383   registers[SR] = (unsigned)th->Registers.c0_sr;
     1384   registers[PC] = (unsigned)th->Registers.c0_epc;
     1385}
     1386
    12831387
    12841388int rtems_gdb_stub_get_offsets(
     
    12871391  unsigned char **bss_addr
    12881392)
    1289 {
     1393{
     1394/*
     1395  extern unsigned32 _ftext;
     1396  extern unsigned32 _fdata;
     1397  extern unsigned32 _bss_start;
     1398
     1399  *text_addr = &_ftext;
     1400  *data_addr = &_fdata;
     1401  *bss_addr  = &_bss_start;
     1402*/
    12901403  *text_addr = 0;
    12911404  *data_addr = 0;
    12921405  *bss_addr  = 0;
    1293 
    12941406  return 1;
    12951407}
  • c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c

    rffdc659 r2f89140  
    3030
    3131#include <rtems.h>
    32 
    3332#include <string.h>
    3433
     
    4039
    4140extern const char gdb_hexchars[];
     41
    4242
    4343/*
     
    5151);
    5252
     53
     54
     55
     56
     57
     58
    5359/* Check whether it is OK to enable thread support */
    5460int rtems_gdb_stub_thread_support_ok(void)
     
    5965  return 0;
    6066}
     67
     68
     69
     70
    6171
    6272/*
     
    102112}
    103113
     114
     115
     116/* Return the RTEMS thread id from a gdb thread id */
     117Thread_Control *rtems_gdb_index_to_stub_id(
     118  int thread
     119)
     120{
     121   Objects_Id thread_obj_id;
     122   Objects_Id min_id, max_id;
     123   int first_posix_id, first_rtems_id;
     124   Objects_Information *obj_info;
     125   Thread_Control *th;
     126
     127   ASSERT(registers != NULL);
     128
     129   if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) {
     130      /* Should not happen */
     131      return NULL;
     132   }
     133
     134   if (thread == 1) {
     135      th = _Thread_Idle;
     136      goto found;
     137   }
     138
     139   /* Let us get object associtated with current thread */
     140   first_rtems_id = 2;
     141
     142   thread_obj_id = _Thread_Executing->Object.id;
     143
     144   /* Let us figure out thread_id for gdb */
     145   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
     146
     147   min_id = obj_info->minimum_id;
     148   max_id = obj_info->maximum_id;
     149
     150   if (thread <= (first_rtems_id + (max_id - min_id))) {
     151      th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]);
     152
     153      if (th != NULL) {
     154         goto found;
     155      }
     156
     157      /* Thread does not exist */
     158      return NULL;
     159   }
     160
     161   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
     162
     163   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
     164
     165   min_id = obj_info->minimum_id;
     166   max_id = obj_info->maximum_id;
     167
     168   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
     169   if (th == NULL) {
     170      /* Thread does not exist */
     171      return NULL;
     172   }
     173
     174  found:
     175   return th;
     176}
     177
     178
     179
     180
     181
     182
    104183/* Get id of the thread stopped by exception */
    105184int rtems_gdb_stub_get_current_thread(void)
     
    107186  return rtems_gdb_stub_id_to_index( _Thread_Executing->Object.id );
    108187}
     188
     189
     190
    109191
    110192/* Get id of the next thread after athread, if argument <= 0 find the
     
    175257  return 0;
    176258}
     259
     260
     261
     262
    177263
    178264
     
    184270)
    185271{
    186   Objects_Id thread_obj_id;
    187   Objects_Id min_id, max_id;
    188   int first_posix_id, first_rtems_id;
    189   Objects_Information *obj_info;
    190   Thread_Control *th;
    191 
    192   ASSERT(registers != NULL);
    193 
    194   if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) {
    195     /* Should not happen */
    196     return 0;
    197   }
    198 
    199   if (thread == 1) {
    200     th = _Thread_Idle;
    201     goto found;
    202   }
    203 
    204   /* Let us get object associtated with current thread */
    205   first_rtems_id = 2;
    206 
    207   thread_obj_id = _Thread_Executing->Object.id;
    208 
    209   /* Let us figure out thread_id for gdb */
    210   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
    211 
    212   min_id = obj_info->minimum_id;
    213   max_id = obj_info->maximum_id;
    214 
    215   if (thread <= (first_rtems_id + (max_id - min_id))) {
    216     th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]);
    217 
    218     if (th != NULL) {
    219       goto found;
    220     }
    221 
    222     /* Thread does not exist */
    223     return 0;
    224   }
    225 
    226   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
    227 
    228   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
    229 
    230   min_id = obj_info->minimum_id;
    231   max_id = obj_info->maximum_id;
    232 
    233   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
    234   if (th == NULL) {
    235     /* Thread does not exist */
    236     return 0;
    237   }
    238 
    239 found:
    240 
    241   rtems_gdb_stub_get_registers_from_context( registers, th );
    242 
    243   return 1;
    244 }
     272   Thread_Control *th;
     273
     274   th= rtems_gdb_index_to_stub_id(thread);
     275
     276   if( th )
     277   {
     278      rtems_gdb_stub_get_registers_from_context( registers, th );
     279      return 1;
     280   }
     281   return 0;
     282}
     283
     284
     285
     286
    245287
    246288
     
    248290   exist or register values will screw up the threads,
    249291   and 1 otherwise */
     292
    250293int rtems_gdb_stub_set_thread_regs(
    251294  int thread,
     
    259302  return 1;
    260303}
     304
     305
     306
     307
    261308
    262309
     
    268315)
    269316{
    270   Objects_Id thread_obj_id;
    271   Objects_Id min_id, max_id;
    272   int first_posix_id, first_rtems_id;
    273   Objects_Information *obj_info;
    274   Thread_Control *th;
    275   unsigned32 name;
    276   char tmp_buf[20];
    277 
    278   ASSERT(info != NULL);
    279 
    280   if (thread <= 0) {
    281     return 0;
    282   }
    283 
    284   if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {
    285     /* We have one thread let us use value
     317   Objects_Id thread_obj_id;
     318   Objects_Id min_id, max_id;
     319   int first_posix_id, first_rtems_id;
     320   Objects_Information *obj_info;
     321   Thread_Control *th;
     322   unsigned32 name;
     323   char tmp_buf[20];
     324
     325   ASSERT(info != NULL);
     326
     327   if (thread <= 0) {
     328      return 0;
     329   }
     330
     331   if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {
     332      /* We have one thread let us use value
    286333         which will never happen for real thread */
    287     strcpy(info->display, "idle thread");
    288     strcpy(info->name, "IDLE");
    289     info->more_display[0] = 0; /* Nothing */
    290 
    291     return 1;
    292   }
    293 
    294   /* Let us get object associtated with current thread */
    295   thread_obj_id = _Thread_Executing->Object.id;
    296 
    297   /* Let us figure out thread_id for gdb */
    298   first_rtems_id = 2;
     334      strcpy(info->display, "idle thread");
     335      strcpy(info->name, "IDLE");
     336      info->more_display[0] = 0; /* Nothing */
     337
     338      return 1;
     339   }
     340
     341   /* Let us get object associtated with current thread */
     342   thread_obj_id = _Thread_Executing->Object.id;
     343
     344   /* Let us figure out thread_id for gdb */
     345   first_rtems_id = 2;
    299346 
    300   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
    301 
    302   min_id = obj_info->minimum_id;
    303   max_id = obj_info->maximum_id;
    304 
    305   if (thread <= (first_rtems_id + (max_id - min_id))) {
     347   obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];
     348
     349   min_id = obj_info->minimum_id;
     350   max_id = obj_info->maximum_id;
     351
     352   if (thread <= (first_rtems_id + (max_id - min_id))) {
    306353      th = (Thread_Control *)(obj_info->local_table[thread -
    307354                                                    first_rtems_id + 1]);
    308355
    309   if (th == NULL) {
    310     /* Thread does not exist */
    311     return 0;
    312   }
    313 
    314   strcpy(info->display, "rtems task:   control at 0x");
    315 
    316   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
    317   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
    318   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
    319   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
    320   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
    321   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
    322   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
    323   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
    324   tmp_buf[8] = 0;
    325 
    326   strcat(info->display, tmp_buf);
     356      if (th == NULL) {
     357         /* Thread does not exist */
     358         return 0;
     359      }
     360
     361      strcpy(info->display, "rtems task:   control at 0x");
     362
     363      tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
     364      tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
     365      tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
     366      tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
     367      tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
     368      tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
     369      tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
     370      tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
     371      tmp_buf[8] = 0;
     372
     373      strcat(info->display, tmp_buf);
    327374 
    328   name = *(unsigned32 *)(obj_info->local_table[thread]->name);
     375      name = *(unsigned32 *)(obj_info->local_table[thread]->name);
    329376     
    330   info->name[0] = (name >> 24) & 0xff;
    331   info->name[1] = (name >> 16) & 0xff;
    332   info->name[2] = (name >> 8) & 0xff;
    333   info->name[3] = name & 0xff;
    334   info->name[4] = 0;
    335 
    336   info->more_display[0] = 0; /* Nothing */
    337 
    338   return 1;
    339 }
    340 
    341   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
    342 
    343   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
    344 
    345   min_id = obj_info->minimum_id;
    346   max_id = obj_info->maximum_id;
    347 
    348   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
    349   if (th == NULL)
    350     {
     377      info->name[0] = (name >> 24) & 0xff;
     378      info->name[1] = (name >> 16) & 0xff;
     379      info->name[2] = (name >> 8) & 0xff;
     380      info->name[3] = name & 0xff;
     381      info->name[4] = 0;
     382
     383      info->more_display[0] = 0; /* Nothing */
     384
     385      return 1;
     386   }
     387
     388   first_posix_id = first_rtems_id + (max_id - min_id) + 1;
     389
     390   obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];
     391
     392   min_id = obj_info->minimum_id;
     393   max_id = obj_info->maximum_id;
     394
     395   th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);
     396   if (th == NULL)
     397   {
    351398      /* Thread does not exist */
    352399      return 0;
    353     }
    354 
    355   strcpy(info->display, "posix thread: control at 0x");
    356 
    357   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
    358   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
    359   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
    360   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
    361   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
    362   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
    363   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
    364   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
    365   tmp_buf[8] = 0;
    366 
    367   strcat(info->display, tmp_buf);
    368 
    369   name = *(unsigned32 *)(obj_info->local_table[thread -
    370                                                first_posix_id + 1]->name);
    371 
    372   info->name[0] = (name >> 24) & 0xff;
    373   info->name[1] = (name >> 16) & 0xff;
    374   info->name[2] = (name >> 8) & 0xff;
    375   info->name[3] = name & 0xff;
    376   info->name[4] = 0;
    377 
    378   info->more_display[0] = 0; /* Nothing */
     400   }
     401
     402   strcpy(info->display, "posix thread: control at 0x");
     403
     404   tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];
     405   tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];
     406   tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];
     407   tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];
     408   tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];
     409   tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];
     410   tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];
     411   tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];
     412   tmp_buf[8] = 0;
     413
     414   strcat(info->display, tmp_buf);
     415
     416   name = *(unsigned32 *)(obj_info->local_table[thread -
     417                                                first_posix_id + 1]->name);
     418
     419   info->name[0] = (name >> 24) & 0xff;
     420   info->name[1] = (name >> 16) & 0xff;
     421   info->name[2] = (name >> 8) & 0xff;
     422   info->name[3] = name & 0xff;
     423   info->name[4] = 0;
     424
     425   info->more_display[0] = 0; /* Nothing */
    379426 
    380   return 1;
     427   return 1;
    381428}
    382429
    383430/*******************************************************/
     431
     432
     433
     434
    384435
    385436
     
    598649pack_qm_header(char *out, int count, int done, int athread)
    599650{
    600   ASSERT(out != 0);
    601   ASSERT(count >= 0 && count < 256);
    602 
    603   *out++ = 'q';
    604   *out++ = 'M';
    605 
    606   *out++ = gdb_hexchars[(count >> 4) & 0x0f];
    607   *out++ = gdb_hexchars[count & 0x0f];
    608 
    609   if (done) {
    610     *out++ = '1';
    611   } else {
    612     *out++ = '0';
    613   }
    614 
    615   thread2fhstr(out, athread);
    616 
    617   return;
    618 }
     651   ASSERT(out != 0);
     652   ASSERT(count >= 0 && count < 256);
     653
     654   *out++ = 'q';
     655   *out++ = 'M';
     656
     657   *out++ = gdb_hexchars[(count >> 4) & 0x0f];
     658   *out++ = gdb_hexchars[count & 0x0f];
     659
     660   if (done) {
     661      *out++ = '1';
     662   } else {
     663      *out++ = '0';
     664   }
     665
     666   thread2fhstr(out, athread);
     667   return;
     668}
     669
     670
     671
     672
     673
     674
     675
     676
     677
     678
    619679
    620680
     
    643703      break;
    644704
     705
     706
     707
    645708    case 'P':
    646709      /* Thread info query */
     
    670733        pack_qq(outbuffer, mask, rthread, &info);
    671734      }
    672 
    673735      break;
     736
     737
     738
     739
     740
    674741    case 'L':
    675       /* Thread info query */
     742      /* Thread list query */
    676743      if (!do_threads) {
    677744        break;
     
    725792        /* Fill header */
    726793        pack_qm_header(outbuffer, i, done, athread);
    727 
    728794      }
    729795      break;
     796
     797
     798
     799
     800
     801
    730802    default:
    731803      if (memcmp(inbuffer, "qOffsets", 8) == 0) {
     
    773845      break;
    774846    }
    775 
    776 }
     847}
     848
     849
     850
     851
     852
    777853
    778854/* Present thread in the variable length string format */
     
    11971273   to mem_fault, they won't get restored, so there better not be any
    11981274   saved).  */
     1275
    11991276unsigned char
    12001277get_byte (const unsigned char *addr)
     
    12081285  *addr = val;
    12091286}
     1287
     1288
     1289
     1290
     1291
     1292
    12101293
    12111294
     
    12741357}
    12751358
     1359
     1360
     1361
     1362
    12761363#elif defined(__mips__)
     1364
     1365
    12771366void rtems_gdb_stub_get_registers_from_context(
    12781367  int            *registers,
     
    12801369)
    12811370{
    1282 }
     1371   registers[S0] = (unsigned)th->Registers.s0;
     1372   registers[S1] = (unsigned)th->Registers.s1;
     1373   registers[S2] = (unsigned)th->Registers.s2;
     1374   registers[S3] = (unsigned)th->Registers.s3;
     1375   registers[S4] = (unsigned)th->Registers.s4;
     1376   registers[S5] = (unsigned)th->Registers.s5;
     1377   registers[S6] = (unsigned)th->Registers.s6;
     1378   registers[S7] = (unsigned)th->Registers.s7;
     1379
     1380   registers[SP] = (unsigned)th->Registers.sp;
     1381   registers[RA] = (unsigned)th->Registers.ra;
     1382
     1383   registers[SR] = (unsigned)th->Registers.c0_sr;
     1384   registers[PC] = (unsigned)th->Registers.c0_epc;
     1385}
     1386
    12831387
    12841388int rtems_gdb_stub_get_offsets(
     
    12871391  unsigned char **bss_addr
    12881392)
    1289 {
     1393{
     1394/*
     1395  extern unsigned32 _ftext;
     1396  extern unsigned32 _fdata;
     1397  extern unsigned32 _bss_start;
     1398
     1399  *text_addr = &_ftext;
     1400  *data_addr = &_fdata;
     1401  *bss_addr  = &_bss_start;
     1402*/
    12901403  *text_addr = 0;
    12911404  *data_addr = 0;
    12921405  *bss_addr  = 0;
    1293 
    12941406  return 1;
    12951407}
Note: See TracChangeset for help on using the changeset viewer.