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

📄 m68k-stub.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
_catchException:");DISABLE_INTERRUPTS();asm("\        moveml %d0-%d7/%a0-%a6,registers  /* save registers               */ \n\	movel	lastFrame,%a0	/* last frame pointer */ \n\");SAVE_FP_REGS();        asm(" \n\        lea     registers,%a5   /* get address of registers     */ \n\        movel   (%sp)+,%d2         /* pop return address           */ \n\	addl 	#1530,%d2        /* convert return addr to 	*/ \n\	divs 	#6,%d2   	/*  exception number		*/ \n\	extl    %d2    \n\ \n\        moveql  #3,%d3           /* assume a three word frame     */ \n\ \n\        cmpiw   #3,%d2           /* bus error or address error ? */ \n\        bgt     normal          /* if >3 then normal error      */ \n\        movel   (%sp)+,-(%a0)       /* copy error info to frame buff*/ \n\        movel   (%sp)+,-(%a0)       /* these are never used         */ \n\        moveql  #7,%d3           /* this is a 7 word frame       */ \n\      \n\normal:    \n\	movew   (%sp)+,%d1         /* pop status register          */ \n\        movel   (%sp)+,%a4         /* pop program counter          */ \n\        movew   %d1,66(%a5)      /* save sr		 	*/	 \n\        movel   %a4,68(%a5)      /* save pc in _regisers[]      	*/ \n\        movel   %a4,-(%a0)         /* copy pc to frame buffer      */ \n\	movew   %d1,-(%a0)         /* copy sr to frame buffer      */ \n\ \n\        movel   %sp,superStack  /* save supervisor sp          */ \n\ \n\        andiw   #0x2000,%d1      /* were we in supervisor mode ? */ \n\        beq     userMode        \n\        movel   %a7,60(%a5)      /* save a7                  */ \n\        bra     saveDone              \n\userMode: \n\        movel   %usp,%a1    	/* save user stack pointer 	*/ \n\        movel   %a1,60(%a5)      /* save user stack pointer	*/ \n\saveDone: \n\ \n\        movew   %d3,-(%a0)         /* push frame size in words     */ \n\        movel   %d2,-(%a0)         /* push vector number           */ \n\        movel   %a4,-(%a0)         /* push exception pc            */ \n\ \n\# \n\# save old frame link and set the new value \n\	movel	_lastFrame,%a1	/* last frame pointer */ \n\	movel   %a1,-(%a0)		/* save pointer to prev frame	*/ \n\        movel   %a0,lastFrame \n\ \n\        movel   %d2,-(%sp)		/* push exception num           */ \n\	movel   exceptionHook,%a0  /* get address of handler */ \n\        jbsr    (%a0)             /* and call it */ \n\        clrl    (%sp)             /* replace exception num parm with frame ptr */ \n\        jbsr     _returnFromException   /* jbsr, but never returns */ \n\");#endif/* * remcomHandler is a front end for handle_exception.  It moves the * stack pointer into an area reserved for debugger use in case the * breakpoint happened in supervisor mode. */asm("remcomHandler:");asm("           add.l    #4,%sp");        /* pop off return address     */asm("           move.l   (%sp)+,%d0");      /* get the exception number   */asm("		move.l   stackPtr,%sp"); /* move to remcom stack area  */asm("		move.l   %d0,-(%sp)");	/* push exception onto stack  */asm("		jbsr    handle_exception");    /* this never returns */asm("           rts");                  /* return */} /* end of stub_dummy_asm_wrapper function */void _returnFromException( Frame *frame ){    /* if no passed in frame, use the last one */    if (! frame)    {        frame = lastFrame;	frame->frameSize = 4;        frame->format = 0;        frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/    }#if !M68K_HAS_VBR    /* a 68000 cannot use the internal info pushed onto a bus error     * or address error frame when doing an RTE so don't put this info     * onto the stack or the stack will creep every time this happens.     */    frame->frameSize=3;#endif    /* throw away any frames in the list after this frame */    lastFrame = frame;    frame->sr = registers[(int) PS];    frame->pc = registers[(int) PC];    if (registers[(int) PS] & 0x2000)    {         /* return to supervisor mode... */        return_to_super();    }    else    { /* return to user mode */        return_to_user();    }}int hex(ch)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);}/* scan for the sequence $<data>#<checksum>     */void getpacket(buffer)char * buffer;{  unsigned char checksum;  unsigned char xmitcsum;  int  i;  int  count;  char ch;    do {    /* wait around for the start character, ignore all other characters */    while ((ch = getDebugChar()) != '$');     checksum = 0;    xmitcsum = -1;        count = 0;        /* now, read until a # or end of buffer is found */    while (count < BUFMAX) {      ch = getDebugChar();      if (ch == '#') break;      checksum = checksum + ch;      buffer[count] = ch;      count = count + 1;      }    buffer[count] = 0;    if (ch == '#') {      xmitcsum = hex(getDebugChar()) << 4;      xmitcsum += hex(getDebugChar());      if ((remote_debug ) && (checksum != xmitcsum)) {        fprintf (stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",						     checksum,xmitcsum,buffer);      }            if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */       else {	 putDebugChar('+');  /* successful transfer */	 /* if a sequence char is present, reply the sequence ID */	 if (buffer[2] == ':') {	    putDebugChar( buffer[0] );	    putDebugChar( buffer[1] );	    /* remove sequence chars from buffer */	    count = strlen(buffer);	    for (i=3; i <= count; i++) buffer[i-3] = buffer[i];	 }       }     }   } while (checksum != xmitcsum);  }/* send the packet in buffer.  The host get's one chance to read it.     This routine does not wait for a positive acknowledge.  *//* * Send the packet in buffer and wait for a positive acknowledgement. */static voidputpacket (char *buffer){  int checksum;  /* $<packet info>#<checksum> */  do    {      char *src = buffer;      putDebugChar ('$');      checksum = 0;      while (*src != '\0')        {          int runlen = 0;          /* Do run length encoding */          while ((src[runlen] == src[0]) && (runlen < 99))            runlen++;          if (runlen > 3)            {              int encode;              /* Got a useful amount */              putDebugChar (*src);              checksum += *src;              putDebugChar ('*');              checksum += '*';              checksum += (encode = (runlen - 4) + ' ');              putDebugChar (encode);              src += runlen;            }          else            {              putDebugChar (*src);              checksum += *src;              src++;             }        }      putDebugChar ('#');      putDebugChar (highhex (checksum));      putDebugChar (lowhex (checksum));    }  while  (getDebugChar () != '+');}char  remcomInBuffer[BUFMAX];char  remcomOutBuffer[BUFMAX];static short error;void debug_error(  char * format,  char * parm){  if (remote_debug) fprintf (stderr,format,parm);}/* convert the memory pointed to by mem into hex, placing result in buf *//* return a pointer to the last char put in buf (null) */char* mem2hex(mem, buf, count)char* mem;char* buf;int   count;{      int i;      unsigned char ch;      for (i=0;i<count;i++) {          ch = *mem++;          *buf++ = gdb_hexchars[ch >> 4];          *buf++ = gdb_hexchars[ch % 16];      }      *buf = 0;       return(buf);}/* convert the hex array pointed to by buf into binary to be placed in mem *//* return a pointer to the character AFTER the last byte written */char* hex2mem(buf, mem, count)char* buf;char* mem;int   count;{      int i;      unsigned char ch;      for (i=0;i<count;i++) {          ch = hex(*buf++) << 4;          ch = ch + hex(*buf++);          *mem++ = ch;      }      return(mem);}/* 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;}/* a bus error has occurred, perform a longjmp   to return execution and allow handling of the error */void handle_buserror(){  longjmp(remcomEnv,1);}/* this function takes the 68000 exception number and attempts to    translate this number into a unix compatible signal value */int computeSignal( exceptionVector )int exceptionVector;{  int sigval;  switch (exceptionVector) {    case 2 : sigval = 10; break; /* bus error           */    case 3 : sigval = 10; break; /* address error       */    case 4 : sigval = 4;  break; /* illegal instruction */    case 5 : sigval = 8;  break; /* zero divide         */    case 6 : sigval = 8; break; /* chk instruction     */    case 7 : sigval = 8; break; /* trapv instruction   */    case 8 : sigval = 11; break; /* privilege violation */    case 9 : sigval = 5;  break; /* trace trap          */    case 10: sigval = 4;  break; /* line 1010 emulator  */    case 11: sigval = 4;  break; /* line 1111 emulator  */      /* Coprocessor protocol violation.  Using a standard MMU or FPU	 this cannot be triggered by software.  Call it a SIGBUS.  */    case 13: sigval = 10;  break;    case 31: sigval = 2;  break; /* interrupt           */    case 33: sigval = 5;  break; /* GDB breakpoint      */    case 34: sigval = 5;  break; /* coded breakpoint    */      /* This is a trap #8 instruction.  Apparently it is someone's software	 convention for some sort of SIGFPE condition.  Whose?  How many	 people are being screwed by having this code the way it is?	 Is there a clean solution?  */    case 40: sigval = 8;  break; /* floating point err  */    case 48: sigval = 8;  break; /* floating point err  */    case 49: sigval = 8;  break; /* floating point err  */    case 50: sigval = 8;  break; /* zero divide         */    case 51: sigval = 8;  break; /* underflow           */    case 52: sigval = 8;  break; /* operand error       */    case 53: sigval = 8;  break; /* overflow            */    case 54: sigval = 8;  break; /* NAN                 */    default:       sigval = 7;         /* "software generated"*/  }  return (sigval);}/**********************************************//* WHILE WE FIND NICE HEX CHARS, BUILD AN INT *//* RETURN NUMBER OF CHARS PROCESSED           *//**********************************************/int hexToInt(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);}/* *  This support function prepares and sends the message containing the *  basic information about this exception. */void gdb_stub_report_exception_info(  int vector,  int *regs,  int thread){   char *optr;   int sigval;   optr = remcomOutBuffer;   *optr++ = 'T';   sigval = computeSignal (vector);   *optr++ = highhex (sigval);   *optr++ = lowhex (sigval);   *optr++ = highhex(A7);   *optr++ = lowhex(A7);   *optr++ = ':';   optr    = mem2hstr(optr, 		      (unsigned char *)&(regs[A7]), 		      sizeof(regs[A7]));   *optr++ = ';';     *optr++ = highhex(PC);   *optr++ = lowhex(PC);   *optr++ = ':';   optr    = mem2hstr(optr, 		      (unsigned char *)&(regs[PC]), 		      sizeof(regs[PC]) );   *optr++ = ';';#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)   if (do_threads)    {      *optr++ = 't';      *optr++ = 'h';      *optr++ = 'r';      *optr++ = 'e';      *optr++ = 'a';

⌨️ 快捷键说明

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