⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips-stub.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
               strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */            break;         case 'X':  /* XAA..AA,LLLL:<binary data>#cs */            binary = 1;         case 'M':            /* MAA..AA,LLLL:  Write LLLL bytes at address AA..AA - return OK */            ptr = &inBuffer[1];            if (hexToInt (&ptr, &addr)                && *ptr++ == ','                && hexToInt (&ptr, &length)                && *ptr++ == ':'                && is_writeable (addr, length) ) {               if ( binary )                  hex2mem (ptr, (void *)addr, length);               else                  bin2mem (ptr, (void *)addr, length);               strcpy (outBuffer, "OK");            }            else               strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */            break;         case 'c':            /* cAA..AA    Continue at address AA..AA(optional) */         case 's':            /* sAA..AA    Step one instruction from AA..AA(optional) */         {            /* try to read optional parameter, pc unchanged if no parm */            ptr = &inBuffer[1];            if (hexToInt (&ptr, &addr))               registers[PC] = addr;            if (inBuffer[0] == 's')               doSStep ();         }         goto stubexit;         case 'k':  /* remove all zbreaks if any */        dumpzbreaks:         {            {               /* Unlink the entire list */               struct z0break *z0, *znxt;               while( (z0= z0break_list) )               {                  /* put back the instruction */                  if( z0->instr != 0xffffffff )                     *(z0->address) = z0->instr;                  /* pop off the top entry */                  znxt = z0->next;                  if( znxt ) znxt->prev = NULL;                  z0break_list = znxt;                  /* and put it on the free list */                  z0->prev = NULL;                  z0->next = z0break_avail;                  z0break_avail = z0;               }            }            strcpy(outBuffer, "OK");         }         break;         case 'q':   /* queries */#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)            rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );#endif            break;#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)         case 'T':         {            int testThread;            if( vhstr2thread(&inBuffer[1], &testThread) == NULL )             {               strcpy(outBuffer, "E01");               break;            }            if( rtems_gdb_index_to_stub_id(testThread) == NULL )            {               strcpy(outBuffer, "E02");            }            else            {               strcpy(outBuffer, "OK");            }         }         break;#endif                 case 'H':  /* set new thread */#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)            if (inBuffer[1] != 'g') {               break;            }	              if (!do_threads) {               break;            }	              {               int tmp, ret;	                   /* Set new generic thread */               if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {                  strcpy(outBuffer, "E01");                  break;               }               /* 0 means `thread' */               if (tmp == 0) {                  tmp = thread;               }               if (tmp == current_thread) {                  /* No changes */                  strcpy(outBuffer, "OK");                  break;               }               /* Save current thread registers if necessary */                if (current_thread != thread) {                  ret = rtems_gdb_stub_set_thread_regs(                     current_thread, (unsigned int *) &current_thread_registers);                  ASSERT(ret);               }               /* Read new registers if necessary */               if (tmp != thread) {                  ret = rtems_gdb_stub_get_thread_regs(                     tmp, (unsigned int *) &current_thread_registers);                  if (!ret) {                     /* Thread does not exist */                     strcpy(outBuffer, "E02");                     break;                  }               }	                   current_thread = tmp;               strcpy(outBuffer, "OK");            }#endif            break;         case 'Z':  /* Add breakpoint */         {             int ret, type, len;            unsigned *address;            struct z0break *z0;            ret = parse_zbreak(inBuffer, &type, (unsigned char **)&address, &len);            if (!ret) {               strcpy(outBuffer, "E01");               break;            }            if (type != 0) {               /* We support only software break points so far */               strcpy(outBuffer, "E02");               break;            }            if (len != R_SZ) {     /* was 1 */               strcpy(outBuffer, "E03");               break;            }            /* Let us check whether this break point already set */            for (z0=z0break_list; z0!=NULL; z0=z0->next) {               if (z0->address == address) {                  break;               }            }            if (z0 != NULL) {               /* we already have a breakpoint for this address */               strcpy(outBuffer, "E04");               break;            }            /* Let us allocate new break point */            if (z0break_avail == NULL) {               strcpy(outBuffer, "E05");               break;            }            /* Get entry */            z0 = z0break_avail;            z0break_avail = z0break_avail->next;            /* Let us copy memory from address add stuff the break point in */            /*            *if (mem2hstr(z0->buf, address, 1) == NULL ||              !hstr2mem(address, "cc" , 1)) {                * Memory error *               z0->next = z0break_avail;               z0break_avail = z0;               strcpy(outBuffer, "E05");               break;            }*/            /* Fill it */            z0->address = address;            if( z0->address == (unsigned *) frame->epc )            {               /* re-asserting the breakpoint that put us in here, so               we'll add the breakpoint but leave the code in place               since we'll be returning to it when the user continues */               z0->instr = 0xffffffff;            }            else            {               /* grab the instruction */               z0->instr = *(z0->address);               /* and insert the break */               *(z0->address) = BREAK_INSTR;            }            /* Add to the list */            {               struct z0break *znxt = z0break_list;               z0->prev = NULL;               z0->next = znxt;                              if( znxt ) znxt->prev = z0;               z0break_list = z0;            }            strcpy(outBuffer, "OK");         }         break;         case 'z': /* remove breakpoint */            if (inBuffer[1] == 'z')             {               goto dumpzbreaks;                              /*                * zz packet - remove all breaks *                z0last = NULL;                for (z0=z0break_list; z0!=NULL; z0=z0->next)                 {                if(!hstr2mem(z0->address, z0->buf, R_SZ))                 {                ret = 0;                }                z0last = z0;                }                * Free entries if any *                if (z0last != NULL) {                z0last->next  = z0break_avail;                z0break_avail = z0break_list;                z0break_list  = NULL;                }                if (ret) {                strcpy(outBuffer, "OK");                } else {                strcpy(outBuffer, "E04");                }                break;               */            }            else            {               int ret, type, len;               unsigned *address;               struct z0break *z0;                             ret = parse_zbreak(inBuffer, &type, (unsigned char **)&address, &len);               if (!ret) {                  strcpy(outBuffer, "E01");                  break;               }               if (type != 0) {                  /* We support only software break points so far */                  break;               }               if (len != R_SZ) {                  strcpy(outBuffer, "E02");                  break;               }	                  /* Let us check whether this break point set */               for (z0=z0break_list; z0!=NULL; z0=z0->next) {                  if (z0->address == address) {                     break;                  }               }                             if (z0 == NULL) {                  /* Unknown breakpoint */                  strcpy(outBuffer, "E03");                  break;               }	                   /*               if (!hstr2mem(z0->address, z0->buf, R_SZ)) {                  strcpy(outBuffer, "E04");                  break;                  }*/               if( z0->instr != 0xffffffff )               {                  /* put the old instruction back  */                  *(z0->address) = z0->instr;               }                  /* Unlink entry */               {                  struct z0break *zprv = z0->prev, *znxt = z0->next;                  if( zprv ) zprv->next = znxt;                  if( znxt ) znxt->prev = zprv;                  if( !zprv ) z0break_list = znxt;                  znxt = z0break_avail;                  z0break_avail = z0;                  z0->prev = NULL;                  z0->next = znxt;               }                   strcpy(outBuffer, "OK");            }            break;         default: /* do nothing */            break;      }      /* reply to the request */      putpacket (outBuffer);   }  stubexit:   /*    *  The original code did this in the assembly wrapper.  We should consider    *  doing it here before we return.    *    *  On exit from the exception handler invalidate each line in the I-cache    *  and write back each dirty line in the D-cache.  This needs to be done    *  before the target program is resumed in order to ensure that software    *  breakpoints and downloaded code will actually take effect.  This    *  is because modifications to code in ram will affect the D-cache,    *  but not necessarily the I-cache.    */   {      extern void clear_cache();      clear_cache();   }   return;}static int numsegs;static struct memseg   memsegments[NUM_MEMSEGS];int gdbstub_add_memsegment( unsigned base, unsigned end, int opts ){   if( numsegs == NUM_MEMSEGS ) return -1;   memsegments[numsegs].begin = base;   memsegments[numsegs].end   = end;   memsegments[numsegs].opts   = opts;   ++numsegs;   return RTEMS_SUCCESSFUL;}static int is_readable(unsigned ptr, unsigned len){   struct memseg *ms;   int i;   if( (ptr & 0x3) ) return -1;   for(i=0; i<numsegs; i++)   {      ms= &memsegments[i];      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) )         return -1;   }   return 0;}static int is_writeable(unsigned ptr, unsigned len){   struct memseg *ms;   int i;   if( (ptr & 0x3) ) return -1;   for(i=0; i<numsegs; i++)   {      ms= &memsegments[i];      if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )         return -1;   }   return 0;}static int is_steppable(unsigned ptr){   struct memseg *ms;   int i;   if( (ptr & 0x3) ) return -1;   for(i=0; i<numsegs; i++)   {      ms= &memsegments[i];      if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )         return -1;   }   return 0;}static char initialized = 0;   /* 0 means we are not initialized */void mips_gdb_stub_install(int enableThreads) {   /*     These are the RTEMS-defined vectors for all the MIPS exceptions   */   int exceptionVector[]= { MIPS_EXCEPTION_MOD, \                            MIPS_EXCEPTION_TLBL, \                            MIPS_EXCEPTION_TLBS, \                            MIPS_EXCEPTION_ADEL, \                            MIPS_EXCEPTION_ADES, \                            MIPS_EXCEPTION_IBE, \                            MIPS_EXCEPTION_DBE, \                            MIPS_EXCEPTION_SYSCALL, \                            MIPS_EXCEPTION_BREAK, \                            MIPS_EXCEPTION_RI, \                            MIPS_EXCEPTION_CPU, \                            MIPS_EXCEPTION_OVERFLOW, \                            MIPS_EXCEPTION_TRAP, \                            MIPS_EXCEPTION_VCEI, \                            MIPS_EXCEPTION_FPE, \                            MIPS_EXCEPTION_C2E, \                            MIPS_EXCEPTION_WATCH, \                            MIPS_EXCEPTION_VCED, \                            -1 };   int  i;   rtems_isr_entry old;   if (initialized)    {      ASSERT(0);      return;   }   memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS );   numsegs = 0;#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)   if( enableThreads )      do_threads = 1;   else      do_threads = 0;#endif   {      struct z0break *z0;      z0break_avail = NULL;      z0break_list  = NULL;         /* z0breaks list init, now we'll do it so it makes sense... */      for (i=0; i<BREAKNUM; i++)       {         memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break));         z0->next = z0break_avail;         z0break_avail = z0;      }   }        for(i=0; exceptionVector[i] > -1; i++)   {      rtems_interrupt_catch( (rtems_isr_entry) handle_exception, exceptionVector[i], &old );   }   initialized = 1;   /* get the attention of gdb */   /* mips_break(1);  disabled so user code can choose to invoke it or not */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -