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

📄 mips-stub.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
#define  GDB_STUB_ENABLE_THREAD_SUPPORT 1/*******************************************************************************                     THIS SOFTWARE IS NOT COPYRIGHTED    The following software is offered for use in the public domain.    There is no warranty with regard to this software or its performance    and the user must accept the software "AS IS" with all faults.    THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH    REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.    $Id: mips-stub.c,v 1.8.2.1 2003/07/17 21:59:00 joel Exp $**********************************************************************************   r46kstub.c -- target debugging stub for the IDT R4600 Orion processor**   This module is based on the stub for the Hitachi SH processor written by*   Ben Lee and Steve Chamberlain and supplied with gdb 4.16.  The latter*   in turn "is originally based on an m68k software stub written by Glenn*   Engel at HP, but has changed quite a bit."  The changes for the R4600*   were written by C. M. Heard at VVNET.  They were based in part on the*   Algorithmics R4000 version of Phil Bunce's PMON program.**  Remote communication protocol:**  A debug packet whose contents are <data>*  is encapsulated for transmission in the form:**       $ <data> # CSUM1 CSUM2**       <data> must be ASCII alphanumeric and cannot include characters*       '$' or '#'.  If <data> starts with two characters followed by*       ':', then the existing stubs interpret this as a sequence number.**       CSUM1 and CSUM2 are ascii hex representation of an 8-bit*       checksum of <data>, the most significant nibble is sent first.*       the hex digits 0-9,a-f are used.**  Receiver responds with:**       +    if CSUM is correct*       -    if CSUM is incorrect**  <data> is as follows.  All values are encoded in ascii hex digits.**       Request         Packet**       read registers  g*       reply           XX....X         Each byte of register data*                                       is described by two hex digits.*                                       Registers are in the internal order*                                       for GDB, and the bytes in a register*                                       are in the same order the machine uses.*                       or ENN          for an error.**       write regs      GXX..XX         Each byte of register data*                                       is described by two hex digits.*       reply           OK              for success*                       ENN             for an error**       write reg       Pn...=r...      Write register n... with value r....*       reply           OK              for success*                       ENN             for an error**       read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.*       reply           XX..XX          XX..XX is mem contents*                                       Can be fewer bytes than requested*                                       if able to read only part of the data.*                       or ENN          NN is errno**       write mem       MAA..AA,LLLL:XX..XX*                                       AA..AA is address,*                                       LLLL is number of bytes,*                                       XX..XX is data*       reply           OK              for success*                       ENN             for an error (this includes the case*                                       where only part of the data was*                                       written).**       cont            cAA..AA         AA..AA is address to resume*                                       If AA..AA is omitted,*                                       resume at same address.**       step            sAA..AA         AA..AA is address to resume*                                       If AA..AA is omitted,*                                       resume at same address.**       There is no immediate reply to step or cont.*       The reply comes when the machine stops.*       It is           SAA             AA is the "signal number"**       last signal     ?               Reply with the reason for stopping.*                                       This is the same reply as is generated*                                       for step or cont: SAA where AA is the*                                       signal number.**       detach          D               Host is detaching.  Reply OK and*                                       end remote debugging session.**       reserved        <other>         On other requests, the stub should*                                       ignore the request and send an empty*                                       response ($#<checksum>).  This way*                                       we can extend the protocol and GDB*                                       can tell whether the stub it is*                                       talking to uses the old or the new.**       Responses can be run-length encoded to save space.  A '*' means that*       the next character is an ASCII encoding giving a repeat count which*       stands for that many repetitions of the character preceding the '*'.*       The encoding is n+29, yielding a printable character when n >=3*       (which is where rle starts to win).  Don't use n > 99 since gdb*       masks each character is receives with 0x7f in order to strip off*       the parity bit.**       As an example, "0* " means the same thing as "0000".********************************************************************************/#include <string.h>#include <signal.h>#include "mips_opcode.h"/* #include "memlimits.h" */#include <rtems.h>#include "gdb_if.h"extern int printk(const char *fmt, ...);/* Change it to something meaningful when debugging */#undef ASSERT#define ASSERT(x) if(!(x)) printk("ASSERT: stub: %d\n", __LINE__)/***************//* Exception Codes */#define	EXC_INT		0		/* External interrupt */#define	EXC_MOD		1		/* TLB modification exception */#define	EXC_TLBL	2		/* TLB miss (Load or Ifetch) */#define	EXC_TLBS	3		/* TLB miss (Store) */#define	EXC_ADEL	4		/* Address error (Load or Ifetch) */#define	EXC_ADES	5		/* Address error (Store) */#define	EXC_IBE		6		/* Bus error (Ifetch) */#define	EXC_DBE		7		/* Bus error (data load or store) */#define	EXC_SYS		8		/* System call */#define	EXC_BP		9		/* Break point */#define	EXC_RI		10		/* Reserved instruction */#define	EXC_CPU		11		/* Coprocessor unusable */#define	EXC_OVF		12		/* Arithmetic overflow */#define	EXC_TRAP	13		/* Trap exception */#define	EXC_FPE		15		/* Floating Point Exception *//* FPU Control/Status register fields */#define	CSR_FS		0x01000000	/* Set to flush denormals to zero */#define	CSR_C		0x00800000	/* Condition bit (set by FP compare) */#define	CSR_CMASK	(0x3f<<12)#define	CSR_CE		0x00020000#define	CSR_CV		0x00010000#define	CSR_CZ		0x00008000#define	CSR_CO		0x00004000#define	CSR_CU		0x00002000#define	CSR_CI		0x00001000#define	CSR_EMASK	(0x1f<<7)#define	CSR_EV		0x00000800#define	CSR_EZ		0x00000400#define	CSR_EO		0x00000200#define	CSR_EU		0x00000100#define	CSR_EI		0x00000080#define	CSR_FMASK	(0x1f<<2)#define	CSR_FV		0x00000040#define	CSR_FZ		0x00000020#define	CSR_FO		0x00000010#define	CSR_FU		0x00000008#define	CSR_FI		0x00000004#define	CSR_RMODE_MASK	(0x3<<0)#define	CSR_RM		0x00000003#define	CSR_RP		0x00000002#define	CSR_RZ		0x00000001#define	CSR_RN		0x00000000/***************//* * Saved register information.  Must be prepared by the exception * preprocessor before handle_exception is invoked. */#if (__mips == 3)typedef long long mips_register_t;#define R_SZ 8#elif (__mips == 1)typedef unsigned int mips_register_t;#define R_SZ 4#else#error "unknown MIPS ISA"#endifstatic mips_register_t *registers;#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)static char do_threads;      /* != 0 means we are supporting threads */#endif/* * The following external functions provide character input and output. */extern char getDebugChar (void);extern void putDebugChar (char);/* * The following definitions are used for the gdb stub memory map */struct memseg{      unsigned begin, end, opts;};static int is_readable(unsigned,unsigned);static int is_writeable(unsigned,unsigned);static int is_steppable(unsigned);/* * BUFMAX defines the maximum number of characters in the inbound & outbound * packet buffers.  At least 4+(sizeof registers)*2 bytes will be needed for * register packets.  Memory dump packets can profitably use even more. */#define BUFMAX 1500static char inBuffer[BUFMAX];static char outBuffer[BUFMAX];/* Structure to keep info on a z-breaks */#define BREAKNUM 32struct z0break{  /* List support */  struct z0break *next;  struct z0break *prev;  /* Location, preserved data */  /* the address pointer, really, really must be a pointer to  ** a 32 bit quantity (likely 64 on the R4k), so the full instruction is read &  ** written.  Making it a char * as on the i386 will cause   ** the zbreaks to mess up the breakpoint instructions  */  unsigned *address;  unsigned instr;};static struct z0break z0break_arr[BREAKNUM];static struct z0break *z0break_avail = NULL;static struct z0break *z0break_list  = NULL;/* * Convert an int to hex. */const char gdb_hexchars[] = "0123456789abcdef";#define highhex(x) gdb_hexchars [(x >> 4) & 0xf]#define lowhex(x) gdb_hexchars [x & 0xf]/* * Convert length bytes of data starting at addr into hex, placing the * result in buf.  Return a pointer to the last (null) char in buf. */static char *mem2hex (void *_addr, int length, char *buf){  unsigned int addr = (unsigned int) _addr;  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */    {      long long *source = (long long *) (addr);      long long *limit  = (long long *) (addr + length);      while (source < limit)        {          int i;          long long k = *source++;          for (i = 15; i >= 0; i--)            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];        }    }  else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */    {      int *source = (int *) (addr);      int *limit  = (int *) (addr + length);      while (source < limit)        {          int i;          int k = *source++;          for (i = 7; i >= 0; i--)            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];        }    }  else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */    {      short *source = (short *) (addr);      short *limit  = (short *) (addr + length);      while (source < limit)        {          int i;          short k = *source++;          for (i = 3; i >= 0; i--)            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];        }    }  else                                                   /* byte aligned */    {      char *source = (char *) (addr);      char *limit  = (char *) (addr + length);      while (source < limit)        {          int i;          char k = *source++;          for (i = 1; i >= 0; i--)            *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];        }    }  *buf = '\0';  return (buf);}/* * Convert a hex character to an int. */static inthex (char ch){  if ((ch >= 'a') && (ch <= 'f'))    return (ch - 'a' + 10);  if ((ch >= '0') && (ch <= '9'))    return (ch - '0');  if ((ch >= 'A') && (ch <= 'F'))    return (ch - 'A' + 10);  return (-1);}/* * Convert a string from hex to int until a non-hex digit * is found.  Return the number of characters processed. */static inthexToInt (char **ptr, int *intValue){  int numChars = 0;  int hexValue;  *intValue = 0;  while (**ptr)    {      hexValue = hex (**ptr);      if (hexValue >= 0)        {          *intValue = (*intValue << 4) | hexValue;          numChars++;        }      else        break;      (*ptr)++;    }  return (numChars);}/* * Convert a string from hex to long long until a non-hex * digit is found.  Return the number of characters processed. */static inthexToLongLong (char **ptr, long long *intValue){  int numChars = 0;  int hexValue;  *intValue = 0;  while (**ptr)    {      hexValue = hex (**ptr);      if (hexValue >= 0)        {          *intValue = (*intValue << 4) | hexValue;          numChars++;        }      else        break;      (*ptr)++;    }  return (numChars);}/* * Convert the hex array buf into binary, placing the result at the * specified address.  If the conversion fails at any point (i.e., * if fewer bytes are written than indicated by the size parameter) * then return 0;  otherwise return 1. */static inthex2mem (char *buf, void *_addr, int length){  unsigned int addr = (unsigned int) _addr;  if (((addr & 0x7) == 0) && ((length & 0x7) == 0))      /* dword aligned */    {      long long *target = (long long *) (addr);      long long *limit  = (long long *) (addr + length);      while (target < limit)        {          int i, j;          long long k = 0;          for (i = 0; i < 16; i++)            if ((j = hex(*buf++)) < 0)              return 0;            else              k = (k << 4) + j;          *target++ = k;        }    }  else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */    {      int *target = (int *) (addr);      int *limit  = (int *) (addr + length);      while (target < limit)        {          int i, j;          int k = 0;          for (i = 0; i < 8; i++)            if ((j = hex(*buf++)) < 0)              return 0;            else              k = (k << 4) + j;          *target++ = k;        }    }  else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */    {      short *target = (short *) (addr);      short *limit  = (short *) (addr + length);      while (target < limit)        {          int i, j;          short k = 0;          for (i = 0; i < 4; i++)            if ((j = hex(*buf++)) < 0)              return 0;            else              k = (k << 4) + j;          *target++ = k;        }    }  else                                                   /* byte aligned */    {      char *target = (char *) (addr);      char *limit  = (char *) (addr + length);      while (target < limit)        {          int i, j;          char k = 0;          for (i = 0; i < 2; i++)            if ((j = hex(*buf++)) < 0)              return 0;            else              k = (k << 4) + j;          *target++ = k;        }    }  return 1;}/* Convert the binary stream in BUF to memory.   Gdb will escape $, #, and the escape char (0x7d).   COUNT is the total number of bytes to write into   memory. */static unsigned char *bin2mem (  unsigned char *buf,  unsigned char *mem,  int   count){  int i;  for (i = 0; i < count; i++) {      /* Check for any escaped characters. Be paranoid and         only unescape chars that should be escaped. */      if (*buf == 0x7d) {          switch (*(buf+1)) {            case 0x3:  /* # */            case 0x4:  /* $ */            case 0x5d: /* escape char */              buf++;              *buf |= 0x20;              break;            default:              /* nothing */              break;            }        }      *mem++ = *buf++;    }  return mem;}/* * Scan the input stream for a sequence for the form $<data>#<checksum>. */static voidgetpacket (char *buffer){  unsigned char checksum;  unsigned char xmitcsum;  int i;  int count;  char ch;  do

⌨️ 快捷键说明

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