1 /****************************************************************************
3 THIS SOFTWARE IS NOT COPYRIGHTED
5 HP offers the following for use in the public domain. HP makes no
6 warranty with regard to the software or it's performance and the
7 user accepts the software "AS IS" with all faults.
9 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
10 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
11 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 ****************************************************************************/
15 /****************************************************************************
16 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
18 * Module name: remcom.c $
20 * Date: 91/03/09 12:29:49 $
21 * Contributor: Lake Stevens Instrument Division$
23 * Description: low level support for gdb debugger. $
25 * Considerations: only works on target hardware $
27 * Written by: Glenn Engel $
28 * ModuleState: Experimental $
32 * Modified for M32R by Michael Snyder, Cygnus Support.
34 * To enable debugger support, two things need to happen. One, a
35 * call to set_debug_traps() is necessary in order to allow any breakpoints
36 * or error conditions to be properly intercepted and reported to gdb.
37 * Two, a breakpoint needs to be generated to begin communication. This
38 * is most easily accomplished by a call to breakpoint(). Breakpoint()
39 * simulates a breakpoint by executing a trap #1.
41 * The external function exceptionHandler() is
42 * used to attach a specific handler to a specific M32R vector number.
43 * It should use the same privilege level it runs at. It should
44 * install it as an interrupt gate so that interrupts are masked
45 * while the handler runs.
47 * Because gdb will sometimes write to the stack area to execute function
48 * calls, this program cannot rely on using the supervisor stack so it
49 * uses it's own stack area reserved in the int array remcomStack.
53 * The following gdb commands are supported:
55 * command function Return value
57 * g return the value of the CPU registers hex data or ENN
58 * G set the value of the CPU registers OK or ENN
60 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
61 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
63 * c Resume at current address SNN ( signal NN)
64 * cAA..AA Continue at address AA..AA SNN
66 * s Step one instruction SNN
67 * sAA..AA Step one instruction from AA..AA SNN
71 * ? What was the last sigval ? SNN (signal NN)
73 * All commands and responses are sent with a packet which includes a
74 * checksum. A packet consists of
76 * $<packet info>#<checksum>.
79 * <packet info> :: <characters representing the command or response>
80 * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
82 * When a packet is received, it is first acknowledged with either '+' or '-'.
83 * '+' indicates a successful transfer. '-' indicates a failed transfer.
88 * $m0,10#2a +$00010203040506070809101112131415#42
90 ****************************************************************************/
93 /************************************************************************
95 * external low-level support routines
97 extern void putDebugChar(); /* write a single character */
98 extern int getDebugChar(); /* read and return a single char */
99 extern void exceptionHandler(); /* assign an exception handler */
101 /*****************************************************************************
102 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
103 * at least NUMREGBYTES*2 are needed for register packets
107 static char initialized; /* boolean flag. != 0 means we've been initialized */
110 /* debug > 0 prints ill-formed commands in valid packets & checksum errors */
112 static const char hexchars[]="0123456789abcdef";
116 /* Number of bytes of registers. */
117 #define NUMREGBYTES (NUMREGS * 4)
118 enum regnames { R0, R1, R2, R3, R4, R5, R6, R7,
119 R8, R9, R10, R11, R12, R13, R14, R15,
120 PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH };
147 static int registers[NUMREGS];
149 #define STACKSIZE 8096
150 static char remcomInBuffer[BUFMAX];
151 static char remcomOutBuffer[BUFMAX];
152 static int remcomStack[STACKSIZE/sizeof(int)];
153 static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
155 static unsigned int save_vectors[18]; /* previous exception vectors */
157 /* Indicate to caller of mem2hex or hex2mem that there has been an error. */
158 static volatile int mem_err = 0;
160 /* Store the vector number here (since GDB only gets the signal
161 number through the usual means, and that's not very specific). */
162 int gdb_m32r_vector = -1;
165 #include "syscall.h" /* for SYS_exit, SYS_write etc. */
168 /* Global entry points:
171 extern void handle_exception(int);
172 extern void set_debug_traps(void);
173 extern void breakpoint(void);
178 static int computeSignal(int);
179 static void putpacket(char *);
180 static void getpacket(char *);
181 static char *mem2hex(char *, char *, int, int);
182 static char *hex2mem(char *, char *, int, int);
183 static int hexToInt(char **, int *);
184 static void stash_registers(void);
185 static void restore_registers(void);
186 static int prepare_to_step(int);
187 static int finish_from_step(void);
189 static void gdb_error(char *, char *);
190 static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int);
192 static char *strcpy (char *, const char *);
193 static int strlen (const char *);
196 * This function does all command procesing for interfacing to gdb.
200 handle_exception(int exceptionVector)
207 if (!finish_from_step())
208 return; /* "false step": let the target continue */
210 gdb_m32r_vector = exceptionVector;
214 mem2hex((char *) &exceptionVector, buf, 4, 0);
215 gdb_error("Handle exception %s, ", buf);
216 mem2hex((char *) ®isters[PC], buf, 4, 0);
217 gdb_error("PC == 0x%s\n", buf);
220 /* reply to host that an exception has occurred */
221 sigval = computeSignal( exceptionVector );
223 ptr = remcomOutBuffer;
225 *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
226 *ptr++ = hexchars[sigval >> 4];
227 *ptr++ = hexchars[sigval & 0xf];
229 *ptr++ = hexchars[PC >> 4];
230 *ptr++ = hexchars[PC & 0xf];
232 ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); /* PC */
235 *ptr++ = hexchars[R13 >> 4];
236 *ptr++ = hexchars[R13 & 0xf];
238 ptr = mem2hex((char *)®isters[R13], ptr, 4, 0); /* FP */
241 *ptr++ = hexchars[R15 >> 4];
242 *ptr++ = hexchars[R15 & 0xf];
244 ptr = mem2hex((char *)®isters[R15], ptr, 4, 0); /* SP */
248 if (exceptionVector == 0) /* simulated SYS call stuff */
250 mem2hex((char *) ®isters[PC], buf, 4, 0);
251 switch (registers[R0]) {
253 gdb_error("Target program has exited at %s\n", buf);
254 ptr = remcomOutBuffer;
256 sigval = registers[R1] & 0xff;
257 *ptr++ = hexchars[sigval >> 4];
258 *ptr++ = hexchars[sigval & 0xf];
262 gdb_error("Target attempts SYS_open call at %s\n", buf);
265 gdb_error("Target attempts SYS_close call at %s\n", buf);
268 gdb_error("Target attempts SYS_read call at %s\n", buf);
271 if (registers[R1] == 1 || /* write to stdout */
272 registers[R1] == 2) /* write to stderr */
273 { /* (we can do that) */
274 registers[R0] = gdb_write((void *) registers[R2], registers[R3]);
278 gdb_error("Target attempts SYS_write call at %s\n", buf);
281 gdb_error("Target attempts SYS_lseek call at %s\n", buf);
284 gdb_error("Target attempts SYS_unlink call at %s\n", buf);
287 gdb_error("Target attempts SYS_getpid call at %s\n", buf);
290 gdb_error("Target attempts SYS_kill call at %s\n", buf);
293 gdb_error("Target attempts SYS_fstat call at %s\n", buf);
296 gdb_error("Target attempts unknown SYS call at %s\n", buf);
301 putpacket(remcomOutBuffer);
304 remcomOutBuffer[0] = 0;
305 getpacket(remcomInBuffer);
306 switch (remcomInBuffer[0]) {
307 default: /* Unknown code. Return an empty reply message. */
310 ptr = &remcomInBuffer[1];
311 if (hexToInt (&ptr, &addr))
312 registers[PC] = addr;
313 strcpy(remcomOutBuffer, "OK");
316 strcpy(remcomOutBuffer, "OK");
318 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
319 /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
320 ptr = &remcomInBuffer[1];
321 if (hexToInt(&ptr,&addr))
323 if (hexToInt(&ptr,&length))
327 hex2mem(ptr, (char*) addr, length, 1);
329 strcpy (remcomOutBuffer, "E03");
330 gdb_error ("memory fault", "");
332 strcpy(remcomOutBuffer,"OK");
338 strcpy(remcomOutBuffer,"E02");
339 gdb_error("malformed write memory command: %s",
343 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
344 /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
345 ptr = &remcomInBuffer[1];
346 if (hexToInt(&ptr,&addr))
348 if (hexToInt(&ptr,&length))
352 mem2hex((char*) addr, remcomOutBuffer, length, 1);
354 strcpy (remcomOutBuffer, "E03");
355 gdb_error ("memory fault", "");
360 strcpy(remcomOutBuffer,"E01");
361 gdb_error("malformed read memory command: %s",
366 remcomOutBuffer[0] = 'S';
367 remcomOutBuffer[1] = hexchars[sigval >> 4];
368 remcomOutBuffer[2] = hexchars[sigval % 16];
369 remcomOutBuffer[3] = 0;
372 remote_debug = !(remote_debug); /* toggle debug flag */
374 case 'g': /* return the value of the CPU registers */
375 mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES, 0);
377 case 'P': /* set the value of a single CPU register - return OK */
381 ptr = &remcomInBuffer[1];
382 if (hexToInt (&ptr, ®no) && *ptr++ == '=')
383 if (regno >= 0 && regno < NUMREGS)
387 hex2mem (ptr, (char *) ®isters[regno], 4, 0);
389 * Since we just changed a single CPU register, let's
390 * make sure to keep the several stack pointers consistant.
392 stackmode = registers[PSW] & 0x80;
393 if (regno == R15) /* stack pointer changed */
394 { /* need to change SPI or SPU */
396 registers[SPI] = registers[R15];
398 registers[SPU] = registers[R15];
400 else if (regno == SPU) /* "user" stack pointer changed */
402 if (stackmode != 0) /* stack in user mode: copy SP */
403 registers[R15] = registers[SPU];
405 else if (regno == SPI) /* "interrupt" stack pointer changed */
407 if (stackmode == 0) /* stack in interrupt mode: copy SP */
408 registers[R15] = registers[SPI];
410 else if (regno == PSW) /* stack mode may have changed! */
411 { /* force SP to either SPU or SPI */
412 if (stackmode == 0) /* stack in user mode */
413 registers[R15] = registers[SPI];
414 else /* stack in interrupt mode */
415 registers[R15] = registers[SPU];
417 strcpy (remcomOutBuffer, "OK");
420 strcpy (remcomOutBuffer, "P01");
423 case 'G': /* set the value of the CPU registers - return OK */
424 hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES, 0);
425 strcpy(remcomOutBuffer,"OK");
427 case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
428 case 'c': /* cAA..AA Continue from address AA..AA(optional) */
429 /* try to read optional parameter, pc unchanged if no parm */
430 ptr = &remcomInBuffer[1];
431 if (hexToInt(&ptr,&addr))
432 registers[ PC ] = addr;
434 if (remcomInBuffer[0] == 's') /* single-stepping */
436 if (!prepare_to_step(0)) /* set up for single-step */
438 /* prepare_to_step has already emulated the target insn:
439 Send SIGTRAP to gdb, don't resume the target at all. */
440 ptr = remcomOutBuffer;
441 *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
445 *ptr++ = hexchars[PC >> 4]; /* send PC */
446 *ptr++ = hexchars[PC & 0xf];
448 ptr = mem2hex((char *)®isters[PC], ptr, 4, 0);
451 *ptr++ = hexchars[R13 >> 4]; /* send FP */
452 *ptr++ = hexchars[R13 & 0xf];
454 ptr = mem2hex((char *)®isters[R13], ptr, 4, 0);
457 *ptr++ = hexchars[R15 >> 4]; /* send SP */
458 *ptr++ = hexchars[R15 & 0xf];
460 ptr = mem2hex((char *)®isters[R15], ptr, 4, 0);
467 else /* continuing, not single-stepping */
469 /* OK, about to do a "continue". First check to see if the
470 target pc is on an odd boundary (second instruction in the
471 word). If so, we must do a single-step first, because
472 ya can't jump or return back to an odd boundary! */
473 if ((registers[PC] & 2) != 0)
478 case 'D': /* Detach */
479 /* I am interpreting this to mean, release the board from control
480 by the remote stub. To do this, I am restoring the original
481 (or at least previous) exception vectors.
483 for (i = 0; i < 18; i++)
484 exceptionHandler (i, save_vectors[i]);
486 return; /* continue the inferior */
488 case 'k': /* kill the program */
492 /* reply to the request */
493 putpacket(remcomOutBuffer);
501 if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
502 if ((ch >= '0') && (ch <= '9')) return (ch-'0');
503 if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
507 /* scan for the sequence $<data>#<checksum> */
513 unsigned char checksum;
514 unsigned char xmitcsum;
520 /* wait around for the start character, ignore all other characters */
521 while ((ch = (getDebugChar() & 0x7f)) != '$');
527 /* now, read until a # or end of buffer is found */
528 while (count < BUFMAX) {
529 ch = getDebugChar() & 0x7f;
530 if (ch == '#') break;
531 checksum = checksum + ch;
538 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
539 xmitcsum += hex(getDebugChar() & 0x7f);
540 if (checksum != xmitcsum) {
544 mem2hex((char *) &checksum, buf, 4, 0);
545 gdb_error("Bad checksum: my count = %s, ", buf);
546 mem2hex((char *) &xmitcsum, buf, 4, 0);
547 gdb_error("sent count = %s\n", buf);
548 gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
551 putDebugChar('-'); /* failed checksum */
553 putDebugChar('+'); /* successful transfer */
554 /* if a sequence char is present, reply the sequence ID */
555 if (buffer[2] == ':') {
556 putDebugChar( buffer[0] );
557 putDebugChar( buffer[1] );
558 /* remove sequence chars from buffer */
559 count = strlen(buffer);
560 for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
564 } while (checksum != xmitcsum);
567 /* send the packet in buffer. */
573 unsigned char checksum;
577 /* $<packet info>#<checksum>. */
583 while (ch=buffer[count]) {
589 putDebugChar(hexchars[checksum >> 4]);
590 putDebugChar(hexchars[checksum % 16]);
591 } while ((getDebugChar() & 0x7f) != '+');
594 /* Address of a routine to RTE to if we get a memory fault. */
596 static void (*volatile mem_fault_routine)() = 0;
604 /* Check the address for safe access ranges. As currently defined,
605 this routine will reject the "expansion bus" address range(s).
606 To make those ranges useable, someone must implement code to detect
607 whether there's anything connected to the expansion bus. */
613 #define BAD_RANGE_ONE_START ((char *) 0x600000)
614 #define BAD_RANGE_ONE_END ((char *) 0xa00000)
615 #define BAD_RANGE_TWO_START ((char *) 0xff680000)
616 #define BAD_RANGE_TWO_END ((char *) 0xff800000)
618 if (addr < BAD_RANGE_ONE_START) return 1; /* safe */
619 if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */
620 if (addr < BAD_RANGE_TWO_START) return 1; /* safe */
621 if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */
624 /* These are separate functions so that they are so short and sweet
625 that the compiler won't save any registers (if there is a fault
626 to mem_fault, they won't get restored, so there better not be any
633 if (mem_fault_routine && !mem_safe(addr))
635 mem_fault_routine ();
648 if (mem_fault_routine && !mem_safe (addr))
650 mem_fault_routine ();
657 /* Convert the memory pointed to by mem into hex, placing result in buf.
658 Return a pointer to the last char put in buf (null).
659 If MAY_FAULT is non-zero, then we should set mem_err in response to
660 a fault; if zero treat a fault like any other fault in the stub. */
663 mem2hex(mem, buf, count, may_fault)
673 mem_fault_routine = set_mem_err;
674 for (i=0;i<count;i++) {
675 ch = get_char (mem++);
676 if (may_fault && mem_err)
678 *buf++ = hexchars[ch >> 4];
679 *buf++ = hexchars[ch % 16];
683 mem_fault_routine = 0;
687 /* Convert the hex array pointed to by buf into binary to be placed in mem.
688 Return a pointer to the character AFTER the last byte written. */
691 hex2mem(buf, mem, count, may_fault)
701 mem_fault_routine = set_mem_err;
702 for (i=0;i<count;i++) {
703 ch = hex(*buf++) << 4;
704 ch = ch + hex(*buf++);
705 set_char (mem++, ch);
706 if (may_fault && mem_err)
710 mem_fault_routine = 0;
714 /* this function takes the m32r exception vector and attempts to
715 translate this number into a unix compatible signal value */
718 computeSignal(exceptionVector)
722 switch (exceptionVector) {
723 case 0 : sigval = 23; break; /* I/O trap */
724 case 1 : sigval = 5; break; /* breakpoint */
725 case 2 : sigval = 5; break; /* breakpoint */
726 case 3 : sigval = 5; break; /* breakpoint */
727 case 4 : sigval = 5; break; /* breakpoint */
728 case 5 : sigval = 5; break; /* breakpoint */
729 case 6 : sigval = 5; break; /* breakpoint */
730 case 7 : sigval = 5; break; /* breakpoint */
731 case 8 : sigval = 5; break; /* breakpoint */
732 case 9 : sigval = 5; break; /* breakpoint */
733 case 10 : sigval = 5; break; /* breakpoint */
734 case 11 : sigval = 5; break; /* breakpoint */
735 case 12 : sigval = 5; break; /* breakpoint */
736 case 13 : sigval = 5; break; /* breakpoint */
737 case 14 : sigval = 5; break; /* breakpoint */
738 case 15 : sigval = 5; break; /* breakpoint */
739 case 16 : sigval = 10; break; /* BUS ERROR (alignment) */
740 case 17 : sigval = 2; break; /* INTerrupt */
741 default : sigval = 7; break; /* "software generated" */
746 /**********************************************/
747 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
748 /* RETURN NUMBER OF CHARS PROCESSED */
749 /**********************************************/
751 hexToInt(ptr, intValue)
761 hexValue = hex(**ptr);
764 *intValue = (*intValue <<4) | hexValue;
775 Table of branch instructions:
777 10B6 RTE return from trap or exception
779 1ECr JL jump and link
781 FFxxxxxx BRA branch (long)
782 B09rxxxx BNEZ branch not-equal-zero
783 Br1rxxxx BNE branch not-equal
784 7Dxx BNC branch not-condition
785 FDxxxxxx BNC branch not-condition (long)
786 B0Arxxxx BLTZ branch less-than-zero
787 B0Crxxxx BLEZ branch less-equal-zero
788 7Exx BL branch and link
789 FExxxxxx BL branch and link (long)
790 B0Drxxxx BGTZ branch greater-than-zero
791 B0Brxxxx BGEZ branch greater-equal-zero
792 B08rxxxx BEQZ branch equal-zero
793 Br0rxxxx BEQ branch equal
794 7Cxx BC branch condition
795 FCxxxxxx BC branch condition (long)
800 unsigned char *instr;
802 char instr0 = instr[0] & 0x7F; /* mask off high bit */
804 if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */
805 return 1; /* return from trap or exception */
807 if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */
808 if ((instr[1] & 0xF0) == 0xC0)
809 return 2; /* jump thru a register */
811 if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */
812 instr0 == 0x7E || instr0 == 0x7F)
813 return 3; /* eight bit PC offset */
820 unsigned char *instr;
822 if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */
823 instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */
825 if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */
827 if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
828 (instr[1] & 0xF0) == 0x10)
830 if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
831 if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
832 (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
833 (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
839 /* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,
840 then it's a 2-byte instruction, else it's a 4-byte instruction. */
842 #define INSTRUCTION_SIZE(addr) \
843 ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
847 unsigned char *instr;
849 if (INSTRUCTION_SIZE(instr) == 2)
850 return isShortBranch(instr);
852 return isLongBranch(instr);
856 willBranch(instr, branchCode)
857 unsigned char *instr;
861 case 0: return 0; /* not a branch */
862 case 1: return 1; /* RTE */
863 case 2: return 1; /* JL or JMP */
864 case 3: /* BC, BNC, BL, BRA (short) */
865 case 4: /* BC, BNC, BL, BRA (long) */
866 switch (instr[0] & 0x0F)
868 case 0xC: /* Branch if Condition Register */
869 return (registers[CBR] != 0);
870 case 0xD: /* Branch if NOT Condition Register */
871 return (registers[CBR] == 0);
872 case 0xE: /* Branch and Link */
873 case 0xF: /* Branch (unconditional) */
878 case 5: /* BNE, BEQ */
879 switch (instr[1] & 0xF0)
881 case 0x00: /* Branch if r1 equal to r2 */
882 return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
883 case 0x10: /* Branch if r1 NOT equal to r2 */
884 return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
888 case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
889 switch (instr[1] & 0xF0)
891 case 0x80: /* Branch if reg equal to zero */
892 return (registers[instr[1] & 0x0F] == 0);
893 case 0x90: /* Branch if reg NOT equal to zero */
894 return (registers[instr[1] & 0x0F] != 0);
895 case 0xA0: /* Branch if reg less than zero */
896 return (registers[instr[1] & 0x0F] < 0);
897 case 0xB0: /* Branch if reg greater or equal to zero */
898 return (registers[instr[1] & 0x0F] >= 0);
899 case 0xC0: /* Branch if reg less than or equal to zero */
900 return (registers[instr[1] & 0x0F] <= 0);
901 case 0xD0: /* Branch if reg greater than zero */
902 return (registers[instr[1] & 0x0F] > 0);
912 branchDestination(instr, branchCode)
913 unsigned char *instr;
915 switch (branchCode) {
917 case 0: /* not a branch */
920 return registers[BPC] & ~3; /* pop BPC into PC */
921 case 2: /* JL or JMP */
922 return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */
923 case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
924 return (((int) instr) & ~3) + ((char) instr[1] << 2);
925 case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
926 return ((int) instr +
927 ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
928 case 5: /* BNE, BEQ (16-bit relative offset) */
929 case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
930 return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
933 /* An explanatory note: in the last three return expressions, I have
934 cast the most-significant byte of the return offset to char.
935 What this accomplishes is sign extension. If the other
936 less-significant bytes were signed as well, they would get sign
937 extended too and, if negative, their leading bits would clobber
938 the bits of the more-significant bytes ahead of them. There are
939 other ways I could have done this, but sign extension from
940 odd-sized integers is always a pain. */
944 branchSideEffects(instr, branchCode)
951 return; /* I <THINK> this is already handled... */
952 case 2: /* JL (or JMP) */
953 case 3: /* BL (or BC, BNC, BRA) */
955 if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */
956 registers[R14] = (registers[PC] & ~3) + 4;
958 default: /* any other branch has no side effects */
963 static struct STEPPING_CONTEXT {
964 int stepping; /* true when we've started a single-step */
965 unsigned long target_addr; /* the instr we're trying to execute */
966 unsigned long target_size; /* the size of the target instr */
967 unsigned long noop_addr; /* where we've inserted a no-op, if any */
968 unsigned long trap1_addr; /* the trap following the target instr */
969 unsigned long trap2_addr; /* the trap at a branch destination, if any */
970 unsigned short noop_save; /* instruction overwritten by our no-op */
971 unsigned short trap1_save; /* instruction overwritten by trap1 */
972 unsigned short trap2_save; /* instruction overwritten by trap2 */
973 unsigned short continue_p; /* true if NOT returning to gdb after step */
976 /* Function: prepare_to_step
977 Called from handle_exception to prepare the user program to single-step.
978 Places a trap instruction after the target instruction, with special
979 extra handling for branch instructions and for instructions in the
980 second half-word of a word.
982 Returns: True if we should actually execute the instruction;
983 False if we are going to emulate executing the instruction,
984 in which case we simply report to GDB that the instruction
985 has already been executed. */
987 #define TRAP1 0x10f1; /* trap #1 instruction */
988 #define NOOP 0x7000; /* noop instruction */
990 static unsigned short trap1 = TRAP1;
991 static unsigned short noop = NOOP;
994 prepare_to_step(continue_p)
995 int continue_p; /* if this isn't REALLY a single-step (see below) */
997 unsigned long pc = registers[PC];
998 int branchCode = isBranch((char *) pc);
1001 /* zero out the stepping context
1002 (paranoia -- it should already be zeroed) */
1003 for (p = (char *) &stepping;
1004 p < ((char *) &stepping) + sizeof(stepping);
1008 if (branchCode != 0) /* next instruction is a branch */
1010 branchSideEffects((char *) pc, branchCode);
1011 if (willBranch((char *)pc, branchCode))
1012 registers[PC] = branchDestination((char *) pc, branchCode);
1014 registers[PC] = pc + INSTRUCTION_SIZE(pc);
1015 return 0; /* branch "executed" -- just notify GDB */
1017 else if (((int) pc & 2) != 0) /* "second-slot" instruction */
1019 /* insert no-op before pc */
1020 stepping.noop_addr = pc - 2;
1021 stepping.noop_save = *(unsigned short *) stepping.noop_addr;
1022 *(unsigned short *) stepping.noop_addr = noop;
1023 /* insert trap after pc */
1024 stepping.trap1_addr = pc + 2;
1025 stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1026 *(unsigned short *) stepping.trap1_addr = trap1;
1028 else /* "first-slot" instruction */
1030 /* insert trap after pc */
1031 stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc);
1032 stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1033 *(unsigned short *) stepping.trap1_addr = trap1;
1035 /* "continue_p" means that we are actually doing a continue, and not
1036 being requested to single-step by GDB. Sometimes we have to do
1037 one single-step before continuing, because the PC is on a half-word
1038 boundary. There's no way to simply resume at such an address. */
1039 stepping.continue_p = continue_p;
1040 stepping.stepping = 1; /* starting a single-step */
1044 /* Function: finish_from_step
1045 Called from handle_exception to finish up when the user program
1046 returns from a single-step. Replaces the instructions that had
1047 been overwritten by traps or no-ops,
1049 Returns: True if we should notify GDB that the target stopped.
1050 False if we only single-stepped because we had to before we
1051 could continue (ie. we were trying to continue at a
1052 half-word boundary). In that case don't notify GDB:
1053 just "continue continuing". */
1058 if (stepping.stepping) /* anything to do? */
1060 int continue_p = stepping.continue_p;
1063 if (stepping.noop_addr) /* replace instr "under" our no-op */
1064 *(unsigned short *) stepping.noop_addr = stepping.noop_save;
1065 if (stepping.trap1_addr) /* replace instr "under" our trap */
1066 *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
1067 if (stepping.trap2_addr) /* ditto our other trap, if any */
1068 *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
1070 for (p = (char *) &stepping; /* zero out the stepping context */
1071 p < ((char *) &stepping) + sizeof(stepping);
1075 return !(continue_p);
1077 else /* we didn't single-step, therefore this must be a legitimate stop */
1081 struct PSWreg { /* separate out the bit flags in the PSW register */
1093 /* Upon entry the value for LR to save has been pushed.
1094 We unpush that so that the value for the stack pointer saved is correct.
1095 Upon entry, all other registers are assumed to have not been modified
1096 since the interrupt/trap occured. */
1102 seth r1, #shigh(registers)
1103 add3 r1, r1, #low(registers)
1108 addi r1, #4 ; only add 4 as subsequent saves are `pre inc'
1123 st sp, @+r1 ; sp contains right value at this point
1125 st r0, @+r1 ; cr0 == PSW
1127 st r0, @+r1 ; cr1 == CBR
1129 st r0, @+r1 ; cr2 == SPI
1131 st r0, @+r1 ; cr3 == SPU
1133 st r0, @+r1 ; cr6 == BPC
1134 st r0, @+r1 ; PC == BPC
1141 /* C routine to clean up what stash_registers did.
1142 It is called after calling stash_registers.
1143 This is separate from stash_registers as we want to do this in C
1144 but doing stash_registers in C isn't straightforward. */
1149 psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */
1150 psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */
1153 registers[CBR] = psw->bc; /* fix up pre-trap "C" register */
1155 #if 0 /* FIXME: Was in previous version. Necessary?
1156 (Remember that we use the "rte" insn to return from the
1157 trap/interrupt so the values of bsm, bie, bc are important. */
1158 psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */
1161 /* FIXME: Copied from previous version. This can probably be deleted
1162 since methinks stash_registers has already done this. */
1163 registers[PC] = registers[BPC]; /* pre-trap PC */
1165 /* FIXME: Copied from previous version. Necessary? */
1166 if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */
1167 registers[SPU] = registers[R15];
1169 registers[SPI] = registers[R15];
1174 seth r0, #shigh(registers+8)
1175 add3 r0, r0, #low(registers+8)
1176 ld r2, @r0+ ; restore r2
1177 ld r3, @r0+ ; restore r3
1178 ld r4, @r0+ ; restore r4
1179 ld r5, @r0+ ; restore r5
1180 ld r6, @r0+ ; restore r6
1181 ld r7, @r0+ ; restore r7
1182 ld r8, @r0+ ; restore r8
1183 ld r9, @r0+ ; restore r9
1184 ld r10, @r0+ ; restore r10
1185 ld r11, @r0+ ; restore r11
1186 ld r12, @r0+ ; restore r12
1187 ld r13, @r0+ ; restore r13
1188 ld r14, @r0+ ; restore r14
1189 ld r15, @r0+ ; restore r15
1190 ld r1, @r0+ ; restore cr0 == PSW
1192 ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only)
1194 ld r1, @r0+ ; restore cr2 == SPI
1196 ld r1, @r0+ ; restore cr3 == SPU
1198 addi r0, #4 ; skip BPC
1199 ld r1, @r0+ ; restore cr6 (BPC) == PC
1201 ld r1, @r0+ ; restore ACCL
1203 ld r1, @r0+ ; restore ACCH
1205 seth r0, #shigh(registers)
1206 add3 r0, r0, #low(registers)
1207 ld r1, @(4,r0) ; restore r1
1208 ld r0, @r0 ; restore r0
1211 /* General trap handler, called after the registers have been stashed.
1212 NUM is the trap/exception number. */
1215 process_exception (num)
1220 seth r1, #shigh(stackPtr)
1221 add3 r1, r1, #low(stackPtr)
1222 ld r15, @r1 ; setup local stack (protect user stack)
1225 bl restore_and_return"
1226 : : "r" (num) : "r0", "r1");
1229 void _catchException0 ();
1235 ; Note that at this point the pushed value of `lr' has been popped
1237 bl process_exception");
1239 void _catchException1 ();
1245 ; Note that at this point the pushed value of `lr' has been popped
1247 seth r1, #shigh(stackPtr)
1248 add3 r1, r1, #low(stackPtr)
1249 ld r15, @r1 ; setup local stack (protect user stack)
1250 seth r1, #shigh(registers + 21*4) ; PC
1251 add3 r1, r1, #low(registers + 21*4)
1253 addi r0, #-4 ; back up PC for breakpoint trap.
1254 st r0, @r1 ; FIXME: what about bp in right slot?
1257 bl restore_and_return");
1259 void _catchException2 ();
1265 ; Note that at this point the pushed value of `lr' has been popped
1267 bl process_exception");
1269 void _catchException3 ();
1275 ; Note that at this point the pushed value of `lr' has been popped
1277 bl process_exception");
1279 void _catchException4 ();
1285 ; Note that at this point the pushed value of `lr' has been popped
1287 bl process_exception");
1289 void _catchException5 ();
1295 ; Note that at this point the pushed value of `lr' has been popped
1297 bl process_exception");
1299 void _catchException6 ();
1305 ; Note that at this point the pushed value of `lr' has been popped
1307 bl process_exception");
1309 void _catchException7 ();
1315 ; Note that at this point the pushed value of `lr' has been popped
1317 bl process_exception");
1319 void _catchException8 ();
1325 ; Note that at this point the pushed value of `lr' has been popped
1327 bl process_exception");
1329 void _catchException9 ();
1335 ; Note that at this point the pushed value of `lr' has been popped
1337 bl process_exception");
1339 void _catchException10 ();
1345 ; Note that at this point the pushed value of `lr' has been popped
1347 bl process_exception");
1349 void _catchException11 ();
1355 ; Note that at this point the pushed value of `lr' has been popped
1357 bl process_exception");
1359 void _catchException12 ();
1365 ; Note that at this point the pushed value of `lr' has been popped
1367 bl process_exception");
1369 void _catchException13 ();
1375 ; Note that at this point the pushed value of `lr' has been popped
1377 bl process_exception");
1379 void _catchException14 ();
1385 ; Note that at this point the pushed value of `lr' has been popped
1387 bl process_exception");
1389 void _catchException15 ();
1395 ; Note that at this point the pushed value of `lr' has been popped
1397 bl process_exception");
1399 void _catchException16 ();
1405 ; Note that at this point the pushed value of `lr' has been popped
1407 bl process_exception");
1409 void _catchException17 ();
1415 ; Note that at this point the pushed value of `lr' has been popped
1417 bl process_exception");
1420 /* this function is used to set up exception handlers for tracing and
1425 /* extern void remcomHandler(); */
1428 for (i = 0; i < 18; i++) /* keep a copy of old vectors */
1429 if (save_vectors[i] == 0) /* only copy them the first time */
1430 save_vectors[i] = getExceptionHandler (i);
1432 stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
1434 exceptionHandler (0, _catchException0);
1435 exceptionHandler (1, _catchException1);
1436 exceptionHandler (2, _catchException2);
1437 exceptionHandler (3, _catchException3);
1438 exceptionHandler (4, _catchException4);
1439 exceptionHandler (5, _catchException5);
1440 exceptionHandler (6, _catchException6);
1441 exceptionHandler (7, _catchException7);
1442 exceptionHandler (8, _catchException8);
1443 exceptionHandler (9, _catchException9);
1444 exceptionHandler (10, _catchException10);
1445 exceptionHandler (11, _catchException11);
1446 exceptionHandler (12, _catchException12);
1447 exceptionHandler (13, _catchException13);
1448 exceptionHandler (14, _catchException14);
1449 exceptionHandler (15, _catchException15);
1450 exceptionHandler (16, _catchException16);
1451 /* exceptionHandler (17, _catchException17); */
1453 /* In case GDB is started before us, ack any packets (presumably
1454 "$?#xx") sitting there. */
1460 /* This function will generate a breakpoint exception. It is used at the
1461 beginning of a program to sync up with a debugger and can be used
1462 otherwise as a quick means to stop program execution and "break" into
1465 #define BREAKPOINT() asm volatile (" trap #2");
1475 Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
1476 Functions: gdb_putchar(char ch)
1478 gdb_write(char *str, int len)
1479 gdb_error(char *format, char *parm)
1482 /* Function: gdb_putchar(int)
1483 Make gdb write a char to stdout.
1484 Returns: the char */
1493 buf[1] = hexchars[ch >> 4];
1494 buf[2] = hexchars[ch & 0x0F];
1500 /* Function: gdb_write(char *, int)
1501 Make gdb write n bytes to stdout (not assumed to be null-terminated).
1502 Returns: number of bytes written */
1505 gdb_write(data, len)
1512 buf = remcomOutBuffer;
1518 i < len && cpy < buf + sizeof(remcomOutBuffer) - 3;
1521 *cpy++ = hexchars[data[i] >> 4];
1522 *cpy++ = hexchars[data[i] & 0x0F];
1530 /* Function: gdb_puts(char *)
1531 Make gdb write a null-terminated string to stdout.
1532 Returns: the length of the string */
1538 return gdb_write(str, strlen(str));
1541 /* Function: gdb_error(char *, char *)
1542 Send an error message to gdb's stdout.
1543 First string may have 1 (one) optional "%s" in it, which
1544 will cause the optional second string to be inserted. */
1547 gdb_error(format, parm)
1551 char buf[400], *cpy;
1556 if (format && *format)
1557 len = strlen(format);
1559 return; /* empty input */
1562 len += strlen(parm);
1564 for (cpy = buf; *format; )
1566 if (format[0] == '%' && format[1] == 's') /* include second string */
1568 format += 2; /* advance two chars instead of just one */
1569 while (parm && *parm)
1581 strcpy (char *dest, const char *src)
1595 strlen (const char *src)
1599 for (ret = 0; *src; src++)
1612 int atexit (void *p)