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
62 * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN
65 * c Resume at current address SNN ( signal NN)
66 * cAA..AA Continue at address AA..AA SNN
68 * s Step one instruction SNN
69 * sAA..AA Step one instruction from AA..AA SNN
73 * ? What was the last sigval ? SNN (signal NN)
75 * All commands and responses are sent with a packet which includes a
76 * checksum. A packet consists of
78 * $<packet info>#<checksum>.
81 * <packet info> :: <characters representing the command or response>
82 * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
84 * When a packet is received, it is first acknowledged with either '+' or '-'.
85 * '+' indicates a successful transfer. '-' indicates a failed transfer.
90 * $m0,10#2a +$00010203040506070809101112131415#42
92 ****************************************************************************/
95 /************************************************************************
97 * external low-level support routines
99 extern void putDebugChar(); /* write a single character */
100 extern int getDebugChar(); /* read and return a single char */
101 extern void exceptionHandler(); /* assign an exception handler */
103 /*****************************************************************************
104 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
105 * at least NUMREGBYTES*2 are needed for register packets
109 static char initialized; /* boolean flag. != 0 means we've been initialized */
112 /* debug > 0 prints ill-formed commands in valid packets & checksum errors */
114 static const unsigned char hexchars[]="0123456789abcdef";
118 /* Number of bytes of registers. */
119 #define NUMREGBYTES (NUMREGS * 4)
120 enum regnames { R0, R1, R2, R3, R4, R5, R6, R7,
121 R8, R9, R10, R11, R12, R13, R14, R15,
122 PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH };
149 static int registers[NUMREGS];
151 #define STACKSIZE 8096
152 static unsigned char remcomInBuffer[BUFMAX];
153 static unsigned char remcomOutBuffer[BUFMAX];
154 static int remcomStack[STACKSIZE/sizeof(int)];
155 static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
157 static unsigned int save_vectors[18]; /* previous exception vectors */
159 /* Indicate to caller of mem2hex or hex2mem that there has been an error. */
160 static volatile int mem_err = 0;
162 /* Store the vector number here (since GDB only gets the signal
163 number through the usual means, and that's not very specific). */
164 int gdb_m32r_vector = -1;
167 #include "syscall.h" /* for SYS_exit, SYS_write etc. */
170 /* Global entry points:
173 extern void handle_exception(int);
174 extern void set_debug_traps(void);
175 extern void breakpoint(void);
180 static int computeSignal(int);
181 static void putpacket(unsigned char *);
182 static void getpacket(unsigned char *);
184 static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int);
185 static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int);
186 static int hexToInt(unsigned char **, int *);
187 static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int);
188 static void stash_registers(void);
189 static void restore_registers(void);
190 static int prepare_to_step(int);
191 static int finish_from_step(void);
193 static void gdb_error(char *, char *);
194 static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int);
196 static unsigned char *strcpy (unsigned char *, const unsigned char *);
197 static int strlen (const unsigned char *);
200 * This function does all command procesing for interfacing to gdb.
204 handle_exception(int exceptionVector)
209 unsigned char buf[16];
212 if (!finish_from_step())
213 return; /* "false step": let the target continue */
215 gdb_m32r_vector = exceptionVector;
219 mem2hex((unsigned char *) &exceptionVector, buf, 4, 0);
220 gdb_error("Handle exception %s, ", buf);
221 mem2hex((unsigned char *) ®isters[PC], buf, 4, 0);
222 gdb_error("PC == 0x%s\n", buf);
225 /* reply to host that an exception has occurred */
226 sigval = computeSignal( exceptionVector );
228 ptr = remcomOutBuffer;
230 *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */
231 *ptr++ = hexchars[sigval >> 4];
232 *ptr++ = hexchars[sigval & 0xf];
234 *ptr++ = hexchars[PC >> 4];
235 *ptr++ = hexchars[PC & 0xf];
237 ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); /* PC */
240 *ptr++ = hexchars[R13 >> 4];
241 *ptr++ = hexchars[R13 & 0xf];
243 ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); /* FP */
246 *ptr++ = hexchars[R15 >> 4];
247 *ptr++ = hexchars[R15 & 0xf];
249 ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); /* SP */
253 if (exceptionVector == 0) /* simulated SYS call stuff */
255 mem2hex((unsigned char *) ®isters[PC], buf, 4, 0);
256 switch (registers[R0]) {
258 gdb_error("Target program has exited at %s\n", buf);
259 ptr = remcomOutBuffer;
261 sigval = registers[R1] & 0xff;
262 *ptr++ = hexchars[sigval >> 4];
263 *ptr++ = hexchars[sigval & 0xf];
267 gdb_error("Target attempts SYS_open call at %s\n", buf);
270 gdb_error("Target attempts SYS_close call at %s\n", buf);
273 gdb_error("Target attempts SYS_read call at %s\n", buf);
276 if (registers[R1] == 1 || /* write to stdout */
277 registers[R1] == 2) /* write to stderr */
278 { /* (we can do that) */
279 registers[R0] = gdb_write((void *) registers[R2], registers[R3]);
283 gdb_error("Target attempts SYS_write call at %s\n", buf);
286 gdb_error("Target attempts SYS_lseek call at %s\n", buf);
289 gdb_error("Target attempts SYS_unlink call at %s\n", buf);
292 gdb_error("Target attempts SYS_getpid call at %s\n", buf);
295 gdb_error("Target attempts SYS_kill call at %s\n", buf);
298 gdb_error("Target attempts SYS_fstat call at %s\n", buf);
301 gdb_error("Target attempts unknown SYS call at %s\n", buf);
306 putpacket(remcomOutBuffer);
309 remcomOutBuffer[0] = 0;
310 getpacket(remcomInBuffer);
312 switch (remcomInBuffer[0]) {
313 default: /* Unknown code. Return an empty reply message. */
316 ptr = &remcomInBuffer[1];
317 if (hexToInt (&ptr, &addr))
318 registers[PC] = addr;
319 strcpy(remcomOutBuffer, "OK");
322 strcpy(remcomOutBuffer, "OK");
324 case 'X': /* XAA..AA,LLLL:<binary data>#cs */
326 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
327 /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
329 ptr = &remcomInBuffer[1];
330 if (hexToInt(&ptr,&addr))
332 if (hexToInt(&ptr,&length))
337 bin2mem (ptr, (unsigned char *) addr, length, 1);
339 hex2mem(ptr, (unsigned char*) addr, length, 1);
341 strcpy (remcomOutBuffer, "E03");
342 gdb_error ("memory fault", "");
344 strcpy(remcomOutBuffer,"OK");
350 strcpy(remcomOutBuffer,"E02");
351 gdb_error("malformed write memory command: %s",
356 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
357 /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
358 ptr = &remcomInBuffer[1];
359 if (hexToInt(&ptr,&addr))
361 if (hexToInt(&ptr,&length))
365 mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1);
367 strcpy (remcomOutBuffer, "E03");
368 gdb_error ("memory fault", "");
373 strcpy(remcomOutBuffer,"E01");
374 gdb_error("malformed read memory command: %s",
379 remcomOutBuffer[0] = 'S';
380 remcomOutBuffer[1] = hexchars[sigval >> 4];
381 remcomOutBuffer[2] = hexchars[sigval % 16];
382 remcomOutBuffer[3] = 0;
385 remote_debug = !(remote_debug); /* toggle debug flag */
387 case 'g': /* return the value of the CPU registers */
388 mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0);
390 case 'P': /* set the value of a single CPU register - return OK */
394 ptr = &remcomInBuffer[1];
395 if (hexToInt (&ptr, ®no) && *ptr++ == '=')
396 if (regno >= 0 && regno < NUMREGS)
400 hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0);
402 * Since we just changed a single CPU register, let's
403 * make sure to keep the several stack pointers consistant.
405 stackmode = registers[PSW] & 0x80;
406 if (regno == R15) /* stack pointer changed */
407 { /* need to change SPI or SPU */
409 registers[SPI] = registers[R15];
411 registers[SPU] = registers[R15];
413 else if (regno == SPU) /* "user" stack pointer changed */
415 if (stackmode != 0) /* stack in user mode: copy SP */
416 registers[R15] = registers[SPU];
418 else if (regno == SPI) /* "interrupt" stack pointer changed */
420 if (stackmode == 0) /* stack in interrupt mode: copy SP */
421 registers[R15] = registers[SPI];
423 else if (regno == PSW) /* stack mode may have changed! */
424 { /* force SP to either SPU or SPI */
425 if (stackmode == 0) /* stack in user mode */
426 registers[R15] = registers[SPI];
427 else /* stack in interrupt mode */
428 registers[R15] = registers[SPU];
430 strcpy (remcomOutBuffer, "OK");
433 strcpy (remcomOutBuffer, "P01");
436 case 'G': /* set the value of the CPU registers - return OK */
437 hex2mem(&remcomInBuffer[1], (unsigned char*) registers, NUMREGBYTES, 0);
438 strcpy(remcomOutBuffer,"OK");
440 case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
441 case 'c': /* cAA..AA Continue from address AA..AA(optional) */
442 /* try to read optional parameter, pc unchanged if no parm */
443 ptr = &remcomInBuffer[1];
444 if (hexToInt(&ptr,&addr))
445 registers[ PC ] = addr;
447 if (remcomInBuffer[0] == 's') /* single-stepping */
449 if (!prepare_to_step(0)) /* set up for single-step */
451 /* prepare_to_step has already emulated the target insn:
452 Send SIGTRAP to gdb, don't resume the target at all. */
453 ptr = remcomOutBuffer;
454 *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
458 *ptr++ = hexchars[PC >> 4]; /* send PC */
459 *ptr++ = hexchars[PC & 0xf];
461 ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0);
464 *ptr++ = hexchars[R13 >> 4]; /* send FP */
465 *ptr++ = hexchars[R13 & 0xf];
467 ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0);
470 *ptr++ = hexchars[R15 >> 4]; /* send SP */
471 *ptr++ = hexchars[R15 & 0xf];
473 ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0);
480 else /* continuing, not single-stepping */
482 /* OK, about to do a "continue". First check to see if the
483 target pc is on an odd boundary (second instruction in the
484 word). If so, we must do a single-step first, because
485 ya can't jump or return back to an odd boundary! */
486 if ((registers[PC] & 2) != 0)
491 case 'D': /* Detach */
492 /* I am interpreting this to mean, release the board from control
493 by the remote stub. To do this, I am restoring the original
494 (or at least previous) exception vectors.
496 for (i = 0; i < 18; i++)
497 exceptionHandler (i, save_vectors[i]);
499 return; /* continue the inferior */
501 case 'k': /* kill the program */
505 /* reply to the request */
506 putpacket(remcomOutBuffer);
514 if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
515 if ((ch >= '0') && (ch <= '9')) return (ch-'0');
516 if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
520 /* scan for the sequence $<data>#<checksum> */
524 unsigned char * buffer;
526 unsigned char checksum;
527 unsigned char xmitcsum;
533 /* wait around for the start character, ignore all other characters */
534 while ((ch = getDebugChar()) != '$');
540 /* now, read until a # or end of buffer is found */
541 while (count < BUFMAX) {
544 if (ch == '#' && (count == 0 || buffer[count-1] != 0x7d))
547 checksum = checksum + ch;
554 xmitcsum = hex(getDebugChar()) << 4;
555 xmitcsum += hex(getDebugChar());
556 if (checksum != xmitcsum) {
558 unsigned char buf[16];
560 mem2hex((unsigned char *) &checksum, buf, 4, 0);
561 gdb_error("Bad checksum: my count = %s, ", buf);
562 mem2hex((unsigned char *) &xmitcsum, buf, 4, 0);
563 gdb_error("sent count = %s\n", buf);
564 gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
567 putDebugChar('-'); /* failed checksum */
569 putDebugChar('+'); /* successful transfer */
570 /* if a sequence char is present, reply the sequence ID */
571 if (buffer[2] == ':') {
572 putDebugChar( buffer[0] );
573 putDebugChar( buffer[1] );
574 /* remove sequence chars from buffer */
575 count = strlen(buffer);
576 for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
580 } while (checksum != xmitcsum);
583 /* send the packet in buffer. */
587 unsigned char *buffer;
589 unsigned char checksum;
593 /* $<packet info>#<checksum>. */
599 while (ch=buffer[count]) {
605 putDebugChar(hexchars[checksum >> 4]);
606 putDebugChar(hexchars[checksum % 16]);
607 } while (getDebugChar() != '+');
610 /* Address of a routine to RTE to if we get a memory fault. */
612 static void (*volatile mem_fault_routine)() = 0;
620 /* Check the address for safe access ranges. As currently defined,
621 this routine will reject the "expansion bus" address range(s).
622 To make those ranges useable, someone must implement code to detect
623 whether there's anything connected to the expansion bus. */
629 #define BAD_RANGE_ONE_START ((unsigned char *) 0x600000)
630 #define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000)
631 #define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000)
632 #define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000)
634 if (addr < BAD_RANGE_ONE_START) return 1; /* safe */
635 if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */
636 if (addr < BAD_RANGE_TWO_START) return 1; /* safe */
637 if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */
640 /* These are separate functions so that they are so short and sweet
641 that the compiler won't save any registers (if there is a fault
642 to mem_fault, they won't get restored, so there better not be any
649 if (mem_fault_routine && !mem_safe(addr))
651 mem_fault_routine ();
664 if (mem_fault_routine && !mem_safe (addr))
666 mem_fault_routine ();
673 /* Convert the memory pointed to by mem into hex, placing result in buf.
674 Return a pointer to the last char put in buf (null).
675 If MAY_FAULT is non-zero, then we should set mem_err in response to
676 a fault; if zero treat a fault like any other fault in the stub. */
678 static unsigned char *
679 mem2hex(mem, buf, count, may_fault)
689 mem_fault_routine = set_mem_err;
690 for (i=0;i<count;i++) {
691 ch = get_char (mem++);
692 if (may_fault && mem_err)
694 *buf++ = hexchars[ch >> 4];
695 *buf++ = hexchars[ch % 16];
699 mem_fault_routine = 0;
703 /* Convert the hex array pointed to by buf into binary to be placed in mem.
704 Return a pointer to the character AFTER the last byte written. */
706 static unsigned char*
707 hex2mem(buf, mem, count, may_fault)
717 mem_fault_routine = set_mem_err;
718 for (i=0;i<count;i++) {
719 ch = hex(*buf++) << 4;
720 ch = ch + hex(*buf++);
721 set_char (mem++, ch);
722 if (may_fault && mem_err)
726 mem_fault_routine = 0;
730 /* Convert the binary stream in BUF to memory.
732 Gdb will escape $, #, and the escape char (0x7d).
733 COUNT is the total number of bytes to write into
735 static unsigned char *
736 bin2mem (buf, mem, count, may_fault)
746 mem_fault_routine = set_mem_err;
747 for (i = 0; i < count; i++)
749 /* Check for any escaped characters. Be paranoid and
750 only unescape chars that should be escaped. */
757 case 0x5d: /* escape char */
767 set_char (mem++, *buf++);
769 if (may_fault && mem_err)
774 mem_fault_routine = 0;
778 /* this function takes the m32r exception vector and attempts to
779 translate this number into a unix compatible signal value */
782 computeSignal(exceptionVector)
786 switch (exceptionVector) {
787 case 0 : sigval = 23; break; /* I/O trap */
788 case 1 : sigval = 5; break; /* breakpoint */
789 case 2 : sigval = 5; break; /* breakpoint */
790 case 3 : sigval = 5; break; /* breakpoint */
791 case 4 : sigval = 5; break; /* breakpoint */
792 case 5 : sigval = 5; break; /* breakpoint */
793 case 6 : sigval = 5; break; /* breakpoint */
794 case 7 : sigval = 5; break; /* breakpoint */
795 case 8 : sigval = 5; break; /* breakpoint */
796 case 9 : sigval = 5; break; /* breakpoint */
797 case 10 : sigval = 5; break; /* breakpoint */
798 case 11 : sigval = 5; break; /* breakpoint */
799 case 12 : sigval = 5; break; /* breakpoint */
800 case 13 : sigval = 5; break; /* breakpoint */
801 case 14 : sigval = 5; break; /* breakpoint */
802 case 15 : sigval = 5; break; /* breakpoint */
803 case 16 : sigval = 10; break; /* BUS ERROR (alignment) */
804 case 17 : sigval = 2; break; /* INTerrupt */
805 default : sigval = 7; break; /* "software generated" */
810 /**********************************************/
811 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
812 /* RETURN NUMBER OF CHARS PROCESSED */
813 /**********************************************/
815 hexToInt(ptr, intValue)
825 hexValue = hex(**ptr);
828 *intValue = (*intValue <<4) | hexValue;
839 Table of branch instructions:
841 10B6 RTE return from trap or exception
843 1ECr JL jump and link
845 FFxxxxxx BRA branch (long)
846 B09rxxxx BNEZ branch not-equal-zero
847 Br1rxxxx BNE branch not-equal
848 7Dxx BNC branch not-condition
849 FDxxxxxx BNC branch not-condition (long)
850 B0Arxxxx BLTZ branch less-than-zero
851 B0Crxxxx BLEZ branch less-equal-zero
852 7Exx BL branch and link
853 FExxxxxx BL branch and link (long)
854 B0Drxxxx BGTZ branch greater-than-zero
855 B0Brxxxx BGEZ branch greater-equal-zero
856 B08rxxxx BEQZ branch equal-zero
857 Br0rxxxx BEQ branch equal
858 7Cxx BC branch condition
859 FCxxxxxx BC branch condition (long)
864 unsigned char *instr;
866 unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */
868 if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */
869 return 1; /* return from trap or exception */
871 if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */
872 if ((instr[1] & 0xF0) == 0xC0)
873 return 2; /* jump thru a register */
875 if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */
876 instr0 == 0x7E || instr0 == 0x7F)
877 return 3; /* eight bit PC offset */
884 unsigned char *instr;
886 if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */
887 instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */
889 if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */
891 if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
892 (instr[1] & 0xF0) == 0x10)
894 if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
895 if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
896 (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
897 (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
903 /* if address is NOT on a 4-byte boundary, or high-bit of instr is zero,
904 then it's a 2-byte instruction, else it's a 4-byte instruction. */
906 #define INSTRUCTION_SIZE(addr) \
907 ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
911 unsigned char *instr;
913 if (INSTRUCTION_SIZE(instr) == 2)
914 return isShortBranch(instr);
916 return isLongBranch(instr);
920 willBranch(instr, branchCode)
921 unsigned char *instr;
925 case 0: return 0; /* not a branch */
926 case 1: return 1; /* RTE */
927 case 2: return 1; /* JL or JMP */
928 case 3: /* BC, BNC, BL, BRA (short) */
929 case 4: /* BC, BNC, BL, BRA (long) */
930 switch (instr[0] & 0x0F)
932 case 0xC: /* Branch if Condition Register */
933 return (registers[CBR] != 0);
934 case 0xD: /* Branch if NOT Condition Register */
935 return (registers[CBR] == 0);
936 case 0xE: /* Branch and Link */
937 case 0xF: /* Branch (unconditional) */
942 case 5: /* BNE, BEQ */
943 switch (instr[1] & 0xF0)
945 case 0x00: /* Branch if r1 equal to r2 */
946 return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
947 case 0x10: /* Branch if r1 NOT equal to r2 */
948 return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
952 case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
953 switch (instr[1] & 0xF0)
955 case 0x80: /* Branch if reg equal to zero */
956 return (registers[instr[1] & 0x0F] == 0);
957 case 0x90: /* Branch if reg NOT equal to zero */
958 return (registers[instr[1] & 0x0F] != 0);
959 case 0xA0: /* Branch if reg less than zero */
960 return (registers[instr[1] & 0x0F] < 0);
961 case 0xB0: /* Branch if reg greater or equal to zero */
962 return (registers[instr[1] & 0x0F] >= 0);
963 case 0xC0: /* Branch if reg less than or equal to zero */
964 return (registers[instr[1] & 0x0F] <= 0);
965 case 0xD0: /* Branch if reg greater than zero */
966 return (registers[instr[1] & 0x0F] > 0);
976 branchDestination(instr, branchCode)
977 unsigned char *instr;
979 switch (branchCode) {
981 case 0: /* not a branch */
984 return registers[BPC] & ~3; /* pop BPC into PC */
985 case 2: /* JL or JMP */
986 return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */
987 case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
988 return (((int) instr) & ~3) + ((unsigned char) instr[1] << 2);
989 case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
990 return ((int) instr +
991 ((((unsigned char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
992 case 5: /* BNE, BEQ (16-bit relative offset) */
993 case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
994 return ((int) instr + ((((unsigned char) instr[2] << 8) | (instr[3])) << 2));
997 /* An explanatory note: in the last three return expressions, I have
998 cast the most-significant byte of the return offset to char.
999 What this accomplishes is sign extension. If the other
1000 less-significant bytes were signed as well, they would get sign
1001 extended too and, if negative, their leading bits would clobber
1002 the bits of the more-significant bytes ahead of them. There are
1003 other ways I could have done this, but sign extension from
1004 odd-sized integers is always a pain. */
1008 branchSideEffects(instr, branchCode)
1009 unsigned char *instr;
1015 return; /* I <THINK> this is already handled... */
1016 case 2: /* JL (or JMP) */
1017 case 3: /* BL (or BC, BNC, BRA) */
1019 if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */
1020 registers[R14] = (registers[PC] & ~3) + 4;
1022 default: /* any other branch has no side effects */
1027 static struct STEPPING_CONTEXT {
1028 int stepping; /* true when we've started a single-step */
1029 unsigned long target_addr; /* the instr we're trying to execute */
1030 unsigned long target_size; /* the size of the target instr */
1031 unsigned long noop_addr; /* where we've inserted a no-op, if any */
1032 unsigned long trap1_addr; /* the trap following the target instr */
1033 unsigned long trap2_addr; /* the trap at a branch destination, if any */
1034 unsigned short noop_save; /* instruction overwritten by our no-op */
1035 unsigned short trap1_save; /* instruction overwritten by trap1 */
1036 unsigned short trap2_save; /* instruction overwritten by trap2 */
1037 unsigned short continue_p; /* true if NOT returning to gdb after step */
1040 /* Function: prepare_to_step
1041 Called from handle_exception to prepare the user program to single-step.
1042 Places a trap instruction after the target instruction, with special
1043 extra handling for branch instructions and for instructions in the
1044 second half-word of a word.
1046 Returns: True if we should actually execute the instruction;
1047 False if we are going to emulate executing the instruction,
1048 in which case we simply report to GDB that the instruction
1049 has already been executed. */
1051 #define TRAP1 0x10f1; /* trap #1 instruction */
1052 #define NOOP 0x7000; /* noop instruction */
1054 static unsigned short trap1 = TRAP1;
1055 static unsigned short noop = NOOP;
1058 prepare_to_step(continue_p)
1059 int continue_p; /* if this isn't REALLY a single-step (see below) */
1061 unsigned long pc = registers[PC];
1062 int branchCode = isBranch((unsigned char *) pc);
1065 /* zero out the stepping context
1066 (paranoia -- it should already be zeroed) */
1067 for (p = (unsigned char *) &stepping;
1068 p < ((unsigned char *) &stepping) + sizeof(stepping);
1072 if (branchCode != 0) /* next instruction is a branch */
1074 branchSideEffects((unsigned char *) pc, branchCode);
1075 if (willBranch((unsigned char *)pc, branchCode))
1076 registers[PC] = branchDestination((unsigned char *) pc, branchCode);
1078 registers[PC] = pc + INSTRUCTION_SIZE(pc);
1079 return 0; /* branch "executed" -- just notify GDB */
1081 else if (((int) pc & 2) != 0) /* "second-slot" instruction */
1083 /* insert no-op before pc */
1084 stepping.noop_addr = pc - 2;
1085 stepping.noop_save = *(unsigned short *) stepping.noop_addr;
1086 *(unsigned short *) stepping.noop_addr = noop;
1087 /* insert trap after pc */
1088 stepping.trap1_addr = pc + 2;
1089 stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1090 *(unsigned short *) stepping.trap1_addr = trap1;
1092 else /* "first-slot" instruction */
1094 /* insert trap after pc */
1095 stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc);
1096 stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
1097 *(unsigned short *) stepping.trap1_addr = trap1;
1099 /* "continue_p" means that we are actually doing a continue, and not
1100 being requested to single-step by GDB. Sometimes we have to do
1101 one single-step before continuing, because the PC is on a half-word
1102 boundary. There's no way to simply resume at such an address. */
1103 stepping.continue_p = continue_p;
1104 stepping.stepping = 1; /* starting a single-step */
1108 /* Function: finish_from_step
1109 Called from handle_exception to finish up when the user program
1110 returns from a single-step. Replaces the instructions that had
1111 been overwritten by traps or no-ops,
1113 Returns: True if we should notify GDB that the target stopped.
1114 False if we only single-stepped because we had to before we
1115 could continue (ie. we were trying to continue at a
1116 half-word boundary). In that case don't notify GDB:
1117 just "continue continuing". */
1122 if (stepping.stepping) /* anything to do? */
1124 int continue_p = stepping.continue_p;
1127 if (stepping.noop_addr) /* replace instr "under" our no-op */
1128 *(unsigned short *) stepping.noop_addr = stepping.noop_save;
1129 if (stepping.trap1_addr) /* replace instr "under" our trap */
1130 *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
1131 if (stepping.trap2_addr) /* ditto our other trap, if any */
1132 *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
1134 for (p = (unsigned char *) &stepping; /* zero out the stepping context */
1135 p < ((unsigned char *) &stepping) + sizeof(stepping);
1139 return !(continue_p);
1141 else /* we didn't single-step, therefore this must be a legitimate stop */
1145 struct PSWreg { /* separate out the bit flags in the PSW register */
1157 /* Upon entry the value for LR to save has been pushed.
1158 We unpush that so that the value for the stack pointer saved is correct.
1159 Upon entry, all other registers are assumed to have not been modified
1160 since the interrupt/trap occured. */
1166 seth r1, #shigh(registers)
1167 add3 r1, r1, #low(registers)
1172 addi r1, #4 ; only add 4 as subsequent saves are `pre inc'
1187 st sp, @+r1 ; sp contains right value at this point
1189 st r0, @+r1 ; cr0 == PSW
1191 st r0, @+r1 ; cr1 == CBR
1193 st r0, @+r1 ; cr2 == SPI
1195 st r0, @+r1 ; cr3 == SPU
1197 st r0, @+r1 ; cr6 == BPC
1198 st r0, @+r1 ; PC == BPC
1205 /* C routine to clean up what stash_registers did.
1206 It is called after calling stash_registers.
1207 This is separate from stash_registers as we want to do this in C
1208 but doing stash_registers in C isn't straightforward. */
1213 psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */
1214 psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */
1217 registers[CBR] = psw->bc; /* fix up pre-trap "C" register */
1219 #if 0 /* FIXME: Was in previous version. Necessary?
1220 (Remember that we use the "rte" insn to return from the
1221 trap/interrupt so the values of bsm, bie, bc are important. */
1222 psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */
1225 /* FIXME: Copied from previous version. This can probably be deleted
1226 since methinks stash_registers has already done this. */
1227 registers[PC] = registers[BPC]; /* pre-trap PC */
1229 /* FIXME: Copied from previous version. Necessary? */
1230 if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */
1231 registers[SPU] = registers[R15];
1233 registers[SPI] = registers[R15];
1238 seth r0, #shigh(registers+8)
1239 add3 r0, r0, #low(registers+8)
1240 ld r2, @r0+ ; restore r2
1241 ld r3, @r0+ ; restore r3
1242 ld r4, @r0+ ; restore r4
1243 ld r5, @r0+ ; restore r5
1244 ld r6, @r0+ ; restore r6
1245 ld r7, @r0+ ; restore r7
1246 ld r8, @r0+ ; restore r8
1247 ld r9, @r0+ ; restore r9
1248 ld r10, @r0+ ; restore r10
1249 ld r11, @r0+ ; restore r11
1250 ld r12, @r0+ ; restore r12
1251 ld r13, @r0+ ; restore r13
1252 ld r14, @r0+ ; restore r14
1253 ld r15, @r0+ ; restore r15
1254 ld r1, @r0+ ; restore cr0 == PSW
1256 ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only)
1258 ld r1, @r0+ ; restore cr2 == SPI
1260 ld r1, @r0+ ; restore cr3 == SPU
1262 addi r0, #4 ; skip BPC
1263 ld r1, @r0+ ; restore cr6 (BPC) == PC
1265 ld r1, @r0+ ; restore ACCL
1267 ld r1, @r0+ ; restore ACCH
1269 seth r0, #shigh(registers)
1270 add3 r0, r0, #low(registers)
1271 ld r1, @(4,r0) ; restore r1
1272 ld r0, @r0 ; restore r0
1275 /* General trap handler, called after the registers have been stashed.
1276 NUM is the trap/exception number. */
1279 process_exception (num)
1284 seth r1, #shigh(stackPtr)
1285 add3 r1, r1, #low(stackPtr)
1286 ld r15, @r1 ; setup local stack (protect user stack)
1289 bl restore_and_return"
1290 : : "r" (num) : "r0", "r1");
1293 void _catchException0 ();
1299 ; Note that at this point the pushed value of `lr' has been popped
1301 bl process_exception");
1303 void _catchException1 ();
1309 ; Note that at this point the pushed value of `lr' has been popped
1311 seth r1, #shigh(stackPtr)
1312 add3 r1, r1, #low(stackPtr)
1313 ld r15, @r1 ; setup local stack (protect user stack)
1314 seth r1, #shigh(registers + 21*4) ; PC
1315 add3 r1, r1, #low(registers + 21*4)
1317 addi r0, #-4 ; back up PC for breakpoint trap.
1318 st r0, @r1 ; FIXME: what about bp in right slot?
1321 bl restore_and_return");
1323 void _catchException2 ();
1329 ; Note that at this point the pushed value of `lr' has been popped
1331 bl process_exception");
1333 void _catchException3 ();
1339 ; Note that at this point the pushed value of `lr' has been popped
1341 bl process_exception");
1343 void _catchException4 ();
1349 ; Note that at this point the pushed value of `lr' has been popped
1351 bl process_exception");
1353 void _catchException5 ();
1359 ; Note that at this point the pushed value of `lr' has been popped
1361 bl process_exception");
1363 void _catchException6 ();
1369 ; Note that at this point the pushed value of `lr' has been popped
1371 bl process_exception");
1373 void _catchException7 ();
1379 ; Note that at this point the pushed value of `lr' has been popped
1381 bl process_exception");
1383 void _catchException8 ();
1389 ; Note that at this point the pushed value of `lr' has been popped
1391 bl process_exception");
1393 void _catchException9 ();
1399 ; Note that at this point the pushed value of `lr' has been popped
1401 bl process_exception");
1403 void _catchException10 ();
1409 ; Note that at this point the pushed value of `lr' has been popped
1411 bl process_exception");
1413 void _catchException11 ();
1419 ; Note that at this point the pushed value of `lr' has been popped
1421 bl process_exception");
1423 void _catchException12 ();
1429 ; Note that at this point the pushed value of `lr' has been popped
1431 bl process_exception");
1433 void _catchException13 ();
1439 ; Note that at this point the pushed value of `lr' has been popped
1441 bl process_exception");
1443 void _catchException14 ();
1449 ; Note that at this point the pushed value of `lr' has been popped
1451 bl process_exception");
1453 void _catchException15 ();
1459 ; Note that at this point the pushed value of `lr' has been popped
1461 bl process_exception");
1463 void _catchException16 ();
1469 ; Note that at this point the pushed value of `lr' has been popped
1471 bl process_exception");
1473 void _catchException17 ();
1479 ; Note that at this point the pushed value of `lr' has been popped
1481 bl process_exception");
1484 /* this function is used to set up exception handlers for tracing and
1489 /* extern void remcomHandler(); */
1492 for (i = 0; i < 18; i++) /* keep a copy of old vectors */
1493 if (save_vectors[i] == 0) /* only copy them the first time */
1494 save_vectors[i] = getExceptionHandler (i);
1496 stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
1498 exceptionHandler (0, _catchException0);
1499 exceptionHandler (1, _catchException1);
1500 exceptionHandler (2, _catchException2);
1501 exceptionHandler (3, _catchException3);
1502 exceptionHandler (4, _catchException4);
1503 exceptionHandler (5, _catchException5);
1504 exceptionHandler (6, _catchException6);
1505 exceptionHandler (7, _catchException7);
1506 exceptionHandler (8, _catchException8);
1507 exceptionHandler (9, _catchException9);
1508 exceptionHandler (10, _catchException10);
1509 exceptionHandler (11, _catchException11);
1510 exceptionHandler (12, _catchException12);
1511 exceptionHandler (13, _catchException13);
1512 exceptionHandler (14, _catchException14);
1513 exceptionHandler (15, _catchException15);
1514 exceptionHandler (16, _catchException16);
1515 /* exceptionHandler (17, _catchException17); */
1517 /* In case GDB is started before us, ack any packets (presumably
1518 "$?#xx") sitting there. */
1524 /* This function will generate a breakpoint exception. It is used at the
1525 beginning of a program to sync up with a debugger and can be used
1526 otherwise as a quick means to stop program execution and "break" into
1529 #define BREAKPOINT() asm volatile (" trap #2");
1539 Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
1540 Functions: gdb_putchar(char ch)
1542 gdb_write(char *str, int len)
1543 gdb_error(char *format, char *parm)
1546 /* Function: gdb_putchar(int)
1547 Make gdb write a char to stdout.
1548 Returns: the char */
1557 buf[1] = hexchars[ch >> 4];
1558 buf[2] = hexchars[ch & 0x0F];
1564 /* Function: gdb_write(char *, int)
1565 Make gdb write n bytes to stdout (not assumed to be null-terminated).
1566 Returns: number of bytes written */
1569 gdb_write(data, len)
1576 buf = remcomOutBuffer;
1582 i < len && cpy < buf + sizeof(remcomOutBuffer) - 3;
1585 *cpy++ = hexchars[data[i] >> 4];
1586 *cpy++ = hexchars[data[i] & 0x0F];
1594 /* Function: gdb_puts(char *)
1595 Make gdb write a null-terminated string to stdout.
1596 Returns: the length of the string */
1602 return gdb_write(str, strlen(str));
1605 /* Function: gdb_error(char *, char *)
1606 Send an error message to gdb's stdout.
1607 First string may have 1 (one) optional "%s" in it, which
1608 will cause the optional second string to be inserted. */
1611 gdb_error(format, parm)
1615 char buf[400], *cpy;
1620 if (format && *format)
1621 len = strlen(format);
1623 return; /* empty input */
1626 len += strlen(parm);
1628 for (cpy = buf; *format; )
1630 if (format[0] == '%' && format[1] == 's') /* include second string */
1632 format += 2; /* advance two chars instead of just one */
1633 while (parm && *parm)
1644 static unsigned char *
1645 strcpy (unsigned char *dest, const unsigned char *src)
1647 unsigned char *ret = dest;
1659 strlen (const unsigned char *src)
1663 for (ret = 0; *src; src++)
1676 int atexit (void *p)