1 /****************************************************************************
2 
3 		THIS SOFTWARE IS NOT COPYRIGHTED
4 
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.
8 
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.
12 
13 ****************************************************************************/
14 
15 /****************************************************************************
16  *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
17  *
18  *  Module name: remcom.c $
19  *  Revision: 1.34 $
20  *  Date: 91/03/09 12:29:49 $
21  *  Contributor:     Lake Stevens Instrument Division$
22  *
23  *  Description:     low level support for gdb debugger. $
24  *
25  *  Considerations:  only works on target hardware $
26  *
27  *  Written by:      Glenn Engel $
28  *  ModuleState:     Experimental $
29  *
30  *  NOTES:           See Below $
31  *
32  *  Heavily modified for XStormy16 by Mark Salter, Red Hat.
33  *  Optimisations and 'X' support by Geoff Keating, Red Hat.
34  *
35  *  To enable debugger support, two things need to happen.  One, a
36  *  call to set_debug_traps() is necessary in order to allow any breakpoints
37  *  or error conditions to be properly intercepted and reported to gdb.
38  *  Two, a breakpoint needs to be generated to begin communication.  This
39  *  is most easily accomplished by a call to breakpoint().  Breakpoint()
40  *  simulates a breakpoint by executing a trap #1.
41  *
42  *  Because gdb will sometimes write to the stack area to execute function
43  *  calls, this program cannot rely on using the inferior stack so it uses
44  *  it's own stack area.
45  *
46  *************
47  *
48  *    The following gdb commands are supported:
49  *
50  * command          function                               Return value
51  *
52  *    g             return the value of the CPU registers  hex data or ENN
53  *    G             set the value of the CPU registers     OK or ENN
54  *
55  *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
56  *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
57  *    XAA..AA,LLLL: Write LLLL binary bytes at address     OK or ENN
58  *                  AA..AA
59  *
60  *    c             Resume at current address              SNN   ( signal NN)
61  *    cAA..AA       Continue at address AA..AA             SNN
62  *
63  *    s             Step one instruction                   SNN
64  *    sAA..AA       Step one instruction from AA..AA       SNN
65  *
66  *    k             kill
67  *
68  *    ?             What was the last sigval ?             SNN   (signal NN)
69  *
70  * All commands and responses are sent with a packet which includes a
71  * checksum.  A packet consists of
72  *
73  * $<packet info>#<checksum>.
74  *
75  * where
76  * <packet info> :: <characters representing the command or response>
77  * <checksum>    :: <two hex digits computed as modulo 256 sum of <packetinfo>>
78  *
79  * When a packet is received, it is first acknowledged with either '+' or '-'.
80  * '+' indicates a successful transfer.  '-' indicates a failed transfer.
81  *
82  * Example:
83  *
84  * Host:                  Reply:
85  * $m0,10#2a               +$00010203040506070809101112131415#42
86  *
87  ****************************************************************************/
88 
89 /* Local functions:
90  */
91 static void putDebugChar(unsigned ch);
92 static unsigned char getDebugChar(void);
93 static void putPacket(unsigned char *);
94 static void putHex (char c, unsigned long mem_arg, int count);
95 static unsigned char *getpacket(void);
96 static void hex2mem(unsigned char *, unsigned long, int);
97 static int valid_addr_range (unsigned long mem, int count);
98 static int  hexToInt(unsigned char **, long *);
99 static void prepare_to_step(void);
100 static void finish_from_step(void);
101 
102 /* breakpoint opcode */
103 #define BREAKPOINT_OPCODE 0x0006
104 
105 /* Error Detection Register */
106 #define ERR_DETECT_REG  (*(volatile unsigned *)0x7f08)
107 #define UNDEF_INSN_ENA   0x01
108 #define UNDEF_INSN_FLAG  0x02
109 #define ODD_ADDR_ENA     0x04
110 #define ODD_ADDR_FLAG    0x08
111 #define BAD_ADDR_ENA     0x10
112 #define BAD_ADDR_FLAG    0x20
113 #define SER0_IRQ_ENA     0x1000
114 #define SER0_IRQ_FLAG    0x2000
115 
116 /*****************************************************************************
117  * BUFMAX defines the maximum number of characters in inbound/outbound buffers
118  * at least NUMREGBYTES*2 are needed for register packets
119  */
120 #define BUFMAX 80
121 
122 static const unsigned char hexchars[]="0123456789abcdef";
123 
124 #define NUMREGS 17
125 
126 /* Number of bytes of registers (extra 2 bytes is for 4 byte PC).  */
127 #define NUMREGBYTES ((NUMREGS * 2) + 2)
128 enum regnames { R0,  R1,  R2,  R3,  R4,  R5,  R6,   R7,
129 		R8,  R9,  R10, R11, R12, R13, R14,  R15,
130 		PC };
131 
132 #define FP  R13
133 #define PSW R14
134 #define SP  R15
135 
136 struct regs {
137     int  r[16];
138     long pc;
139 } registers;
140 
141 static struct regs orig_registers;
142 
143 static unsigned char remcomBuffer[BUFMAX];
144 
145 /* Indicate whether inferior is running. Used to decide whether or not to
146    send T packet when stub is entered. */
147 static char is_running;
148 
149 static inline unsigned char
get_char(unsigned long addr)150 get_char(unsigned long addr)
151 {
152   unsigned int msw, lsw;
153   unsigned char ret;
154 
155   msw = addr >> 16;
156   lsw = addr & 0xffff;
157 
158   asm("movf.b %0,(%2)\n"
159       : "=e"(ret) : "d"(msw), "r"(lsw) : "memory");
160 
161   return ret;
162 }
163 
164 static inline void
set_char(unsigned long addr,unsigned int val)165 set_char(unsigned long addr, unsigned int val)
166 {
167   unsigned int msw, lsw;
168 
169   msw = addr >> 16;
170   lsw = addr & 0xffff;
171 
172   asm("movf.b (%1),%2\n"
173       : /* none */ : "d"(msw), "r"(lsw), "e"(val) : "memory" );
174 }
175 
176 static inline unsigned int
get_word(unsigned long addr)177 get_word(unsigned long addr)
178 {
179   unsigned int ret, msw, lsw;
180 
181   msw = addr >> 16;
182   lsw = addr & 0xffff;
183 
184   asm("movf.w %0,(%2)\n"
185       : "=e"(ret) : "d"(msw), "r"(lsw) : "memory" );
186 
187   return ret;
188 }
189 
190 static inline void
set_word(unsigned long addr,unsigned int val)191 set_word(unsigned long addr, unsigned int val)
192 {
193   unsigned int msw, lsw;
194 
195   msw = addr >> 16;
196   lsw = addr & 0xffff;
197 
198   asm("movf.w (%1),%2\n"
199       : /* none */ : "d"(msw), "r"(lsw), "e"(val) : "memory" );
200 }
201 
202 static void
assign_regs(struct regs * dest,const struct regs * src)203 assign_regs (struct regs *dest, const struct regs *src)
204 {
205   int i;
206   char *d = (char *)dest, *s = (char *)src;
207   for (i = 0; i < sizeof (struct regs); i++)
208     *d++ = *s++;
209 }
210 
211 /* Write out a register for a 'T' packet.  */
212 
213 static unsigned char *
putreg(unsigned char * buf,int regnum,void * mem_p,int count)214 putreg (unsigned char *buf, int regnum, void *mem_p, int count)
215 {
216   int i;
217   unsigned char ch;
218   char *mem = (char *)mem_p;
219 
220   *buf++ = hexchars[regnum >> 4];
221   *buf++ = hexchars[regnum % 16];
222   *buf++ = ':';
223 
224   for (i=0;i<count;i++)
225     {
226       ch = *mem++;
227       *buf++ = hexchars[ch >> 4];
228       *buf++ = hexchars[ch % 16];
229     }
230   *buf++ = ';';
231   return(buf);
232 }
233 
234 /*
235  * This function does all command procesing for interfacing to gdb.
236  */
237 void
handle_exception(void)238 handle_exception(void)
239 {
240   char sigval;
241   unsigned char *ptr;
242   long addr, length;
243 
244   /* reply to host that an exception has occurred */
245   sigval = 5; /* SIGTRAP is default */
246   if (ERR_DETECT_REG & UNDEF_INSN_FLAG)
247     {
248       ERR_DETECT_REG &= ~UNDEF_INSN_FLAG;
249       registers.pc -= 2;
250       if (get_word(registers.pc) != BREAKPOINT_OPCODE)
251 	sigval = 4; /* SIGILL */
252     }
253   if (ERR_DETECT_REG & BAD_ADDR_FLAG)
254     {
255       ERR_DETECT_REG &= ~BAD_ADDR_FLAG;
256       sigval = 11; /* SIGSEGV */
257     }
258   if (ERR_DETECT_REG & SER0_IRQ_FLAG)
259     {
260       unsigned char ch;
261 
262       ch = getDebugChar();
263       ERR_DETECT_REG &= ~SER0_IRQ_FLAG;
264       if (ch != 0x03)
265 	return;
266       sigval = 2; /* SIGINT */
267     }
268 
269   finish_from_step();
270 
271   /* save original context so it can be restored as a result of
272      a kill packet. */
273   if (orig_registers.pc == 0L)
274     assign_regs (&orig_registers, &registers);
275 
276   if (is_running)
277     {
278       ptr = remcomBuffer;
279 
280       *ptr++ = 'T';         /* notify gdb with signo, PC, FP and SP */
281       *ptr++ = hexchars[sigval >> 4];
282       *ptr++ = hexchars[sigval & 0xf];
283 
284       ptr = putreg (ptr, PC, &registers.pc, 4);
285       ptr = putreg (ptr, FP, &registers.r[FP], 2);
286       ptr = putreg (ptr, SP, &registers.r[SP], 2);
287 
288       *ptr++ = 0;
289 
290       putPacket(remcomBuffer);
291     }
292 
293   while (1) {
294     char kind;
295 
296     ptr = getpacket();
297     kind = *ptr++;
298     if (kind == 'M' || kind == 'X')
299       {
300 	/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
301         /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
302 	if (hexToInt(&ptr,&addr)
303 	    && *(ptr++) == ','
304 	    && hexToInt(&ptr,&length)
305 	    && *(ptr++) == ':')
306 	  {
307 	    if (valid_addr_range (addr, length))
308 	      {
309 		if (kind == 'M')
310 		  hex2mem(ptr, addr, length);
311 		else
312 		  {
313 		    int i;
314 		    for (i = 0; i < length; i++)
315 		      if (*ptr++ == 0x7d)
316 			set_char (addr++, *ptr++ ^ 0x20);
317 		      else
318 			set_char (addr++, ptr[-1]);
319 
320 		  }
321 		putPacket ("OK");
322 	      }
323 	    else
324 	      putPacket ("E03");
325 	  }
326 	else
327 	  putPacket ("E02");
328       }
329     else if (kind == 'm')
330       {
331 	/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
332 	/* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
333         if (hexToInt(&ptr,&addr)
334 	    && *(ptr++) == ','
335 	    && hexToInt (&ptr,&length))
336 	  {
337 	    if (valid_addr_range (addr, length))
338 	      putHex (0, addr, length);
339 	    else
340 	      putPacket ("E03");
341 	  }
342 	else
343 	  putPacket ("E02");
344       }
345     else if (kind == 'R')
346       {
347 	if (hexToInt (&ptr, &addr))
348 	  registers.pc = addr;
349 	putPacket ("OK");
350       }
351     else if (kind == '!')
352       putPacket ("OK");
353     else if (kind == '?')
354       putHex ('S', (unsigned long)(unsigned int)&sigval, 1);
355     else if (kind == 'g')
356       putHex (0, (unsigned long)(unsigned int)&registers, NUMREGBYTES);
357     else if (kind == 'P')
358       {
359 	/* set the value of a single CPU register - return OK */
360 	unsigned long regno;
361 
362 	if (hexToInt (&ptr, &regno)
363 	    && *ptr++ == '='
364 	    && regno < NUMREGS)
365 	  {
366 	    hex2mem (ptr, (unsigned long)(unsigned int)(registers.r + regno),
367 		     regno == PC ? 4 : 2);
368 	    putPacket ("OK");
369 	  }
370 	else
371 	  putPacket ("E01");
372       }
373     else if (kind == 'G')
374       {
375 	/* set the value of the CPU registers - return OK */
376 	hex2mem(ptr, (unsigned long)(unsigned int)&registers, NUMREGBYTES);
377 	putPacket ("OK");
378       }
379     else if (kind == 's' || kind == 'c')
380       {
381 	/* sAA..AA	Step one instruction from AA..AA(optional) */
382 	/* cAA..AA	Continue from address AA..AA(optional) */
383 	/* try to read optional parameter, pc unchanged if no parm */
384 
385 	is_running = 1;
386 
387 	if (hexToInt(&ptr,&addr))
388 	  registers.pc = addr;
389 
390 	if (kind == 's')	/* single-stepping */
391 	  prepare_to_step();
392 	return;
393       }
394     else if (kind == 'k')
395       {
396 	/* kill the program */
397 	assign_regs (&registers, &orig_registers);
398 	is_running = 0;
399 	putPacket ("");
400       }
401     else
402       /* Unknown code.  Return an empty reply message. */
403       putPacket ("");
404   }
405 }
406 
407 static int
hex(int ch)408 hex (int ch)
409 {
410   if ((ch >= '0') && (ch <= '9')) return (ch-'0');
411   if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
412   if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
413   return (-1);
414 }
415 
416 /* scan for the sequence $<data>#<checksum>     */
417 
418 static unsigned char *
getpacket(void)419 getpacket (void)
420 {
421   unsigned char *buffer = &remcomBuffer[0];
422   unsigned checksum;
423   int count;
424   char ch;
425 
426   while (1)
427     {
428       /* wait around for the start character, ignore all other characters */
429       while (getDebugChar () != '$')
430 	;
431 
432       checksum = 0;
433       count = 0;
434       while ((ch = getDebugChar ()) == '$')
435 	;
436 
437       /* now, read until a # or end of buffer is found */
438       while (ch != '#' && count < BUFMAX - 1)
439 	{
440 	  checksum = checksum + ch;
441 	  buffer[count] = ch;
442 	  count = count + 1;
443 	  ch = getDebugChar ();
444 	}
445       buffer[count] = 0;
446 
447       if (ch == '#')
448 	{
449 	  unsigned xmitcsum;
450 	  ch = getDebugChar ();
451 	  xmitcsum = hex (ch) << 4;
452 	  ch = getDebugChar ();
453 	  xmitcsum += hex (ch);
454 
455 	  /* If one of the above 'hex' calls returns -1, xmitcsum will
456 	     have high bits set, and so the test below will fail.  */
457 
458 	  if ((checksum & 0xFF) != xmitcsum)
459 	    putDebugChar ('-');	/* failed checksum */
460 	  else
461 	    {
462 	      putDebugChar ('+');	/* successful transfer */
463 	      return &buffer[0];
464 	    }
465 	}
466     }
467 }
468 
469 /* send the packet in buffer.  */
470 
471 static void
putPacket(unsigned char * buffer_p)472 putPacket (unsigned char *buffer_p)
473 {
474   /*  $<packet info>#<checksum>. */
475   do {
476     unsigned checksum;
477     unsigned char *buffer = buffer_p;
478 
479     putDebugChar('$');
480     checksum = 0;
481 
482     while (*buffer) {
483       putDebugChar(*buffer);
484       checksum += *buffer;
485       buffer++;
486     }
487     putDebugChar('#');
488     putDebugChar(hexchars[(checksum >> 4) % 16]);
489     putDebugChar(hexchars[checksum % 16]);
490   } while (getDebugChar() != '+');
491 }
492 
493 /* Convert the memory pointed to by mem into hex, and return it as a packet. */
494 
495 static void
putHex(char c,unsigned long mem_arg,int count)496 putHex (char c, unsigned long mem_arg, int count)
497 {
498   do {
499     unsigned long mem = mem_arg;
500     int i;
501     unsigned checksum;
502 
503     putDebugChar('$');
504     checksum = 0;
505 
506     if (c)
507       {
508 	checksum = c;
509 	putDebugChar(c);
510       }
511 
512     for (i = 0; i < count; i++)
513       {
514 	unsigned char c = get_char (mem);
515 	char ch = hexchars[c >> 4];
516 	putDebugChar(ch);
517 	checksum += ch;
518 	ch = hexchars[c % 16];
519 	putDebugChar(ch);
520 	checksum += ch;
521 	mem++;
522       }
523     putDebugChar('#');
524     putDebugChar(hexchars[(checksum >> 4) % 16]);
525     putDebugChar(hexchars[checksum % 16]);
526   } while (getDebugChar() != '+');
527 }
528 
529 /* Function: gdb_write(char *, int)
530    Make gdb write n bytes to stdout (not assumed to be null-terminated). */
531 
532 void
gdb_write(char * data,int len)533 gdb_write (char *data, int len)
534 {
535   ERR_DETECT_REG &= ~SER0_IRQ_ENA;
536   putHex ('O', (unsigned long)(unsigned int)data, len);
537   ERR_DETECT_REG |= SER0_IRQ_ENA;
538 }
539 
540 int
gdb_read(char * buf,int nbytes)541 gdb_read (char *buf, int nbytes)
542 {
543   int i = 0;
544 
545   ERR_DETECT_REG &= ~SER0_IRQ_ENA;
546   for (i = 0; i < nbytes; i++)
547     {
548       *(buf + i) = getDebugChar();
549       if ((*(buf + i) == '\n') || (*(buf + i) == '\r'))
550         {
551           (*(buf + i + 1)) = 0;
552           break;
553         }
554     }
555   ERR_DETECT_REG |= SER0_IRQ_ENA;
556   return (i);
557 }
558 
559 static int
valid_addr_range(unsigned long mem,int count)560 valid_addr_range (unsigned long mem, int count)
561 {
562   unsigned long last = mem + count - 1;
563 
564   if (last < 0x800L)
565     return 1;
566 
567   if (mem < 0x7f00L)
568     return 0;
569 
570   if (last > 0x7ffffL)
571     return 0;
572 
573   return 1;
574 }
575 
576 /* Convert the hex array pointed to by buf into binary to be placed in mem.
577    Return a pointer to the character AFTER the last byte written. */
578 
579 static void
hex2mem(unsigned char * buf,unsigned long mem,int count)580 hex2mem (unsigned char *buf, unsigned long mem, int count)
581 {
582   int i;
583   unsigned char ch;
584 
585   for (i=0;i<count;i++)
586     {
587       ch = hex(*buf++) << 4;
588       ch = ch + hex(*buf++);
589       set_char (mem++, ch);
590     }
591 }
592 
593 /**********************************************/
594 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
595 /* RETURN NUMBER OF CHARS PROCESSED           */
596 /**********************************************/
597 static int
hexToInt(unsigned char ** ptr,long * intValue)598 hexToInt (unsigned char **ptr, long *intValue)
599 {
600   int numChars = 0;
601   int hexValue;
602 
603   *intValue = 0;
604   while (**ptr)
605     {
606       hexValue = hex(**ptr);
607       if (hexValue >=0)
608         {
609 	  *intValue = (*intValue <<4) | (unsigned) hexValue;
610 	  numChars ++;
611         }
612       else
613 	break;
614       (*ptr)++;
615     }
616   return (numChars);
617 }
618 
619 
620 /* Function: opcode_size
621    Determine number of bytes in full opcode by examining first word.
622 */
623 static int
opcode_size(unsigned int opcode)624 opcode_size(unsigned int opcode)
625 {
626   if ((opcode & 0xff00) == 0)
627     return 2;
628 
629   if ((opcode & 0xf800) == 0)
630     return 4;
631 
632   if ((opcode & 0xf800) == 0x7800)
633     return 4;
634 
635   if ((opcode & 0xf000) == 0xc000)
636     return 4;
637 
638   if ((opcode & 0xf100) == 0x2000)
639     return 4;
640 
641   if ((opcode & 0xfff0) == 0x30e0)
642     return 4;
643 
644   if ((opcode & 0xf008) == 0x6008)
645     return 4;
646 
647   if ((opcode & 0xf808) == 0x7008)
648     return 4;
649 
650   opcode >>= 8;
651   if (opcode == 0x0c || opcode == 0x0d || opcode == 0x31)
652     return 4;
653 
654   return 2;
655 }
656 
657 static struct {
658   unsigned long  addr;
659   unsigned long  addr2;
660   unsigned int   opcode;
661   unsigned int   opcode2;
662 } stepinfo;
663 
664 /* Function: prepare_to_step
665    Called from handle_exception to prepare the user program to single-step.
666    Places a trap instruction after the target instruction, with special
667    extra handling for branch instructions.
668 */
669 
670 static void
prepare_to_step(void)671 prepare_to_step(void)
672 {
673   unsigned long pc = registers.pc;
674   unsigned long next_pc, next_pc2;
675   unsigned int  op, op2, sp;
676   unsigned char op_msb, op_lsb;
677   int  r12;
678   char r8;
679 
680   op = get_word(pc);
681   op_msb = (op >> 8) & 0xff;
682   op_lsb = op & 0xff;
683   op2 = get_word(pc + 2);
684   next_pc = pc + opcode_size(op);
685   next_pc2 = 0;
686 
687   if (op_msb == 0)
688     {
689       if (op_lsb == 2)
690 	{
691 	  /* IRET */
692 	  sp = registers.r[SP];
693 	  next_pc = *(unsigned *)(sp - 4);
694 	  next_pc = (next_pc << 16) | *(unsigned *)(sp - 6);
695 	}
696       else if (op_lsb == 3)
697 	{
698 	  /* RET */
699 	  sp = registers.r[SP];
700 	  next_pc = *(unsigned *)(sp - 2);
701 	  next_pc = (next_pc << 16) | *(unsigned *)(sp - 4);
702 	}
703       else
704 	{
705 	  op2 = op_lsb & 0xf0;
706 	  if (op2 && op2 < 0x40)
707 	    {
708 	      /* {CALLR,BR,ICALLR} Rs */
709 	      next_pc = (pc + 2) + (int)registers.r[op_lsb & 0xf];
710 	    }
711 	  else if (op2 < 0x80 || op2 == 0xa0 || op2 == 0xb0)
712 	    {
713 	      /* {JMP,ICALL,CALL} Rb,Rs */
714 	      next_pc = registers.r[(op_lsb & 0x10) ? 9 : 8];
715 	      next_pc = (next_pc << 16) | (unsigned int)registers.r[op_lsb & 0xf];
716 	    }
717 	}
718     }
719   else if (op_msb < 4)
720     {
721       /* {CALLF,JMPF,ICALLF} a24 */
722       next_pc = ((unsigned long)op2) << 8;
723       next_pc |= op_lsb;
724     }
725   else if (op_msb < 8)
726     {
727       if ((op2 & 0xf000) == 0)
728 	{
729 	    /* Bx Rd,#imm4,r12 */
730 	    /* Bx Rd,Rs,r12    */
731 	    r12 = op2 << 4;
732 	    r12 >>= 4;
733 	    next_pc2 = (pc + 4) + r12;
734 	}
735     }
736   else if (op_msb == 0x0c || op_msb == 0x0d || (op_msb & 0xf1) == 0x20 ||
737 	   ((op_msb >= 0x7c && op_msb <= 0x7f) && (op2 & 0x8000) == 0))
738     {
739       /* Bxx Rd,Rs,r12    */
740       /* Bxx Rd,#imm8,r12 */
741       /* Bx  m8,#imm3,r12 */
742       /* Bx s8,#imm3,r12  */
743       r12 = op2 << 4;
744       r12 >>= 4;
745       next_pc2 = (pc + 4) + r12;
746     }
747   else if ((op_msb & 0xf0) == 0x10)
748     {
749       /* {BR,CALLR} r12 */
750       r12 = (op & 0xffe) << 4;
751       r12 >>= 4;
752       next_pc = (pc + 2) + r12;
753     }
754   else if ((op_msb & 0xe0) == 0xc0)
755     {
756       /* Bxx Rx,#imm16,r8 */
757       /* TBxx r8 */
758       r8 = op_lsb;
759       next_pc2 = next_pc + r8;
760     }
761 
762   stepinfo.addr = next_pc;
763   stepinfo.opcode = get_word(next_pc);
764   set_word(next_pc, BREAKPOINT_OPCODE);
765 
766   if (next_pc2)
767     {
768       stepinfo.addr2 = next_pc2;
769       stepinfo.opcode2 = get_word(next_pc2);
770       set_word(next_pc2, BREAKPOINT_OPCODE);
771     }
772 }
773 
774 /* Function: finish_from_step
775    Called from handle_exception to finish up when the user program
776    returns from a single-step.  Replaces the instructions that had
777    been overwritten by breakpoint. */
778 
779 static void
finish_from_step(void)780 finish_from_step (void)
781 {
782   if (stepinfo.addr)	/* anything to do? */
783     {
784       set_word(stepinfo.addr, stepinfo.opcode);
785       stepinfo.addr = 0;
786       if (stepinfo.addr2)
787 	{
788 	  set_word(stepinfo.addr2, stepinfo.opcode2);
789           stepinfo.addr2 = 0;
790 	}
791     }
792 }
793 
794 
795 /*
796  * UART support
797  */
798 #define UART0_BASE 0x7f38
799 #define UART1_BASE 0x7f48
800 
801 #define UART_CR(base)  (*(volatile unsigned char *)(base))
802 #define UART_RXD(base) (*(volatile unsigned int *)((base) + 2))
803 #define UART_TXD(base) (*(volatile unsigned int *)((base) + 4))
804 
805 #define UART_CR_RUN       0x80
806 #define UART_CR_ERR       0x40
807 #define UART_CR_BAUD_115k 0x20
808 #define UART_CR_PARITY    0x10
809 #define UART_CR_TXEMPTY   0x08
810 #define UART_CR_TXIEN     0x04
811 #define UART_CR_RXRDY     0x02
812 #define UART_CR_RXIEN     0x01
813 
814 #define DBG_UART UART0_BASE
815 
816 static void
putDebugChar(unsigned ch)817 putDebugChar(unsigned ch)
818 {
819   while ((UART_CR(DBG_UART) & UART_CR_TXEMPTY) == 0) ;
820 
821   UART_TXD(DBG_UART) = ch;
822 }
823 
824 static unsigned char
getDebugChar(void)825 getDebugChar(void)
826 {
827   while ((UART_CR(DBG_UART) & UART_CR_RXRDY) == 0) ;
828 
829   return UART_RXD(DBG_UART);
830 }
831 
832 void
uart_init(void)833 uart_init(void)
834 {
835   UART_CR(DBG_UART) |= (UART_CR_RUN | UART_CR_RXIEN);
836 }
837 
838