xref: /openbsd/gnu/usr.bin/binutils/gdb/remote-rdp.c (revision 63addd46)
1 /* Remote debugging for the ARM RDP interface.
2 
3    Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 Free
4    Software Foundation, Inc.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.
22 
23 
24  */
25 
26 
27 /*
28    Much of this file (in particular the SWI stuff) is based on code by
29    David Taylor (djt1000@uk.ac.cam.hermes).
30 
31    I hacked on and simplified it by removing a lot of sexy features he
32    had added, and some of the (unix specific) workarounds he'd done
33    for other GDB problems - which if they still exist should be fixed
34    in GDB, not in a remote-foo thing .  I also made it conform more to
35    the doc I have; which may be wrong.
36 
37    Steve Chamberlain (sac@cygnus.com).
38  */
39 
40 
41 #include "defs.h"
42 #include "inferior.h"
43 #include "value.h"
44 #include "gdb/callback.h"
45 #include "command.h"
46 #include <ctype.h>
47 #include <fcntl.h>
48 #include "symfile.h"
49 #include "remote-utils.h"
50 #include "gdb_string.h"
51 #include "gdbcore.h"
52 #include "regcache.h"
53 #include "serial.h"
54 
55 #include "arm-tdep.h"
56 
57 #ifdef HAVE_TIME_H
58 #include <time.h>
59 #endif
60 
61 extern struct target_ops remote_rdp_ops;
62 static struct serial *io;
63 static host_callback *callback = &default_callback;
64 
65 struct
66   {
67     int step_info;
68     int break_info;
69     int model_info;
70     int target_info;
71     int can_step;
72     char command_line[10];
73     int rdi_level;
74     int rdi_stopped_status;
75   }
76 ds;
77 
78 
79 
80 /* Definitions for the RDP protocol. */
81 
82 #define RDP_MOUTHFULL   		(1<<6)
83 #define FPU_COPRO_NUMBER 		1
84 
85 #define RDP_OPEN 	 		0
86 #define RDP_OPEN_TYPE_COLD 		0
87 #define RDP_OPEN_TYPE_WARM 		1
88 #define RDP_OPEN_TYPE_BAUDRATE          2
89 
90 #define RDP_OPEN_BAUDRATE_9600       	1
91 #define RDP_OPEN_BAUDRATE_19200        	2
92 #define RDP_OPEN_BAUDRATE_38400        	3
93 
94 #define RDP_OPEN_TYPE_RETURN_SEX	(1<<3)
95 
96 #define RDP_CLOSE 			1
97 
98 #define RDP_MEM_READ 			2
99 
100 #define RDP_MEM_WRITE 			3
101 
102 #define RDP_CPU_READ 			4
103 #define RDP_CPU_WRITE 			5
104 #define RDP_CPU_READWRITE_MODE_CURRENT 255
105 #define RDP_CPU_READWRITE_MASK_PC 	(1<<16)
106 #define RDP_CPU_READWRITE_MASK_CPSR 	(1<<17)
107 #define RDP_CPU_READWRITE_MASK_SPSR 	(1<<18)
108 
109 #define RDP_COPRO_READ   		6
110 #define RDP_COPRO_WRITE 		7
111 #define RDP_FPU_READWRITE_MASK_FPS 	(1<<8)
112 
113 #define RDP_SET_BREAK			0xa
114 #define RDP_SET_BREAK_TYPE_PC_EQUAL     0
115 #define RDP_SET_BREAK_TYPE_GET_HANDLE   (0x10)
116 
117 #define RDP_CLEAR_BREAK 		0xb
118 
119 #define RDP_EXEC 			0x10
120 #define RDP_EXEC_TYPE_SYNC 		0
121 
122 #define RDP_STEP 			0x11
123 
124 #define RDP_INFO  			0x12
125 #define RDP_INFO_ABOUT_STEP 		2
126 #define RDP_INFO_ABOUT_STEP_GT_1	1
127 #define RDP_INFO_ABOUT_STEP_TO_JMP 	2
128 #define RDP_INFO_ABOUT_STEP_1		4
129 #define RDP_INFO_ABOUT_TARGET 		0
130 #define RDP_INFO_ABOUT_BREAK 		1
131 #define RDP_INFO_ABOUT_BREAK_COMP	1
132 #define RDP_INFO_ABOUT_BREAK_RANGE 	2
133 #define RDP_INFO_ABOUT_BREAK_BYTE_READ 	4
134 #define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8
135 #define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4)
136 #define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5)
137 #define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6)
138 #define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7)
139 #define RDP_INFO_ABOUT_BREAK_MASK 	(1<<8)
140 #define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
141 #define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
142 #define RDP_INFO_ABOUT_BREAK_COND 	(1<<11)
143 #define RDP_INFO_VECTOR_CATCH		(0x180)
144 #define RDP_INFO_ICEBREAKER		(7)
145 #define RDP_INFO_SET_CMDLINE            (0x300)
146 
147 #define RDP_SELECT_CONFIG		(0x16)
148 #define RDI_ConfigCPU			0
149 #define RDI_ConfigSystem		1
150 #define RDI_MatchAny			0
151 #define RDI_MatchExactly		1
152 #define RDI_MatchNoEarlier		2
153 
154 #define RDP_RESET 			0x7f
155 
156 /* Returns from RDP */
157 #define RDP_RES_STOPPED 		0x20
158 #define RDP_RES_SWI 			0x21
159 #define RDP_RES_FATAL 			0x5e
160 #define RDP_RES_VALUE 			0x5f
161 #define RDP_RES_VALUE_LITTLE_ENDIAN     240
162 #define RDP_RES_VALUE_BIG_ENDIAN 	241
163 #define RDP_RES_RESET			0x7f
164 #define RDP_RES_AT_BREAKPOINT    	143
165 #define RDP_RES_IDUNNO			0xe6
166 #define RDP_OSOpReply           	0x13
167 #define RDP_OSOpWord            	2
168 #define RDP_OSOpNothing         	0
169 
170 static int timeout = 2;
171 
172 static char *commandline = NULL;
173 
174 static int
175 remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
176 				 int write,
177 				 struct mem_attrib *attrib,
178 				 struct target_ops *target);
179 
180 
181 /* Stuff for talking to the serial layer. */
182 
183 static unsigned char
get_byte(void)184 get_byte (void)
185 {
186   int c = serial_readchar (io, timeout);
187 
188   if (remote_debug)
189     fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c);
190 
191   if (c == SERIAL_TIMEOUT)
192     {
193       if (timeout == 0)
194 	return (unsigned char) c;
195 
196       error ("Timeout reading from remote_system");
197     }
198 
199   return c;
200 }
201 
202 /* Note that the target always speaks little-endian to us,
203    even if it's a big endian machine. */
204 static unsigned int
get_word(void)205 get_word (void)
206 {
207   unsigned int val = 0;
208   unsigned int c;
209   int n;
210   for (n = 0; n < 4; n++)
211     {
212       c = get_byte ();
213       val |= c << (n * 8);
214     }
215   return val;
216 }
217 
218 static void
put_byte(char val)219 put_byte (char val)
220 {
221   if (remote_debug)
222     fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val);
223   serial_write (io, &val, 1);
224 }
225 
226 static void
put_word(int val)227 put_word (int val)
228 {
229   /* We always send in little endian */
230   unsigned char b[4];
231   b[0] = val;
232   b[1] = val >> 8;
233   b[2] = val >> 16;
234   b[3] = val >> 24;
235 
236   if (remote_debug)
237     fprintf_unfiltered (gdb_stdlog, "(%04x)", val);
238 
239   serial_write (io, b, 4);
240 }
241 
242 
243 
244 /* Stuff for talking to the RDP layer. */
245 
246 /* This is a bit more fancy that need be so that it syncs even in nasty cases.
247 
248    I'be been unable to make it reliably sync up with the change
249    baudrate open command.  It likes to sit and say it's been reset,
250    with no more action.  So I took all that code out.  I'd rather sync
251    reliably at 9600 than wait forever for a possible 19200 connection.
252 
253  */
254 static void
rdp_init(int cold,int tty)255 rdp_init (int cold, int tty)
256 {
257   int sync = 0;
258   int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM;
259   int baudtry = 9600;
260 
261   time_t now = time (0);
262   time_t stop_time = now + 10;	/* Try and sync for 10 seconds, then give up */
263 
264 
265   while (time (0) < stop_time && !sync)
266     {
267       int restype;
268       QUIT;
269 
270       serial_flush_input (io);
271       serial_flush_output (io);
272 
273       if (tty)
274 	printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
275 
276       /*
277          ** It seems necessary to reset an EmbeddedICE to get it going.
278          ** This has the side benefit of displaying the startup banner.
279        */
280       if (cold)
281 	{
282 	  put_byte (RDP_RESET);
283 	  while ((restype = serial_readchar (io, 1)) > 0)
284 	    {
285 	      switch (restype)
286 		{
287 		case SERIAL_TIMEOUT:
288 		  break;
289 		case RDP_RESET:
290 		  /* Sent at start of reset process: ignore */
291 		  break;
292 		default:
293 		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
294 		  break;
295 		}
296 	    }
297 
298 	  if (restype == 0)
299 	    {
300 	      /* Got end-of-banner mark */
301 	      printf_filtered ("\n");
302 	    }
303 	}
304 
305       put_byte (RDP_OPEN);
306 
307       put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
308       put_word (0);
309 
310       while (!sync && (restype = serial_readchar (io, 1)) > 0)
311 	{
312 	  if (remote_debug)
313 	    fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype);
314 
315 	  switch (restype)
316 	    {
317 	    case SERIAL_TIMEOUT:
318 	      break;
319 
320 	    case RDP_RESET:
321 	      while ((restype = serial_readchar (io, 1)) == RDP_RESET)
322 		;
323 	      do
324 		{
325 		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
326 		}
327 	      while ((restype = serial_readchar (io, 1)) > 0);
328 
329 	      if (tty)
330 		{
331 		  printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
332 		  printf_unfiltered ("Waiting for it to settle down...\n");
333 		}
334 	      sleep (3);
335 	      if (tty)
336 		printf_unfiltered ("\nTrying again.\n");
337 	      cold = 0;
338 	      break;
339 
340 	    default:
341 	      break;
342 
343 	    case RDP_RES_VALUE:
344 	      {
345 		int resval = serial_readchar (io, 1);
346 
347 		if (remote_debug)
348 		  fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval);
349 
350 		switch (resval)
351 		  {
352 		  case SERIAL_TIMEOUT:
353 		    break;
354 		  case RDP_RES_VALUE_LITTLE_ENDIAN:
355 #if 0
356 		    /* FIXME: cagney/2003-11-22: Ever since the ARM
357                        was multi-arched (in 2002-02-08), this
358                        assignment has had no effect.  There needs to
359                        be some sort of check/decision based on the
360                        current architecture's byte-order vs the remote
361                        target's byte order.  For the moment disable
362                        the assignment to keep things building.  */
363 		    target_byte_order = BFD_ENDIAN_LITTLE;
364 #endif
365 		    sync = 1;
366 		    break;
367 		  case RDP_RES_VALUE_BIG_ENDIAN:
368 #if 0
369 		    /* FIXME: cagney/2003-11-22: Ever since the ARM
370                        was multi-arched (in 2002-02-08), this
371                        assignment has had no effect.  There needs to
372                        be some sort of check/decision based on the
373                        current architecture's byte-order vs the remote
374                        target's byte order.  For the moment disable
375                        the assignment to keep things building.  */
376 		    target_byte_order = BFD_ENDIAN_BIG;
377 #endif
378 		    sync = 1;
379 		    break;
380 		  default:
381 		    break;
382 		  }
383 	      }
384 	    }
385 	}
386     }
387 
388   if (!sync)
389     {
390       error ("Couldn't reset the board, try pressing the reset button");
391     }
392 }
393 
394 
395 static void
send_rdp(char * template,...)396 send_rdp (char *template,...)
397 {
398   char buf[200];
399   char *dst = buf;
400   va_list alist;
401   va_start (alist, template);
402 
403   while (*template)
404     {
405       unsigned int val;
406       int *pi;
407       int *pstat;
408       char *pc;
409       int i;
410       switch (*template++)
411 	{
412 	case 'b':
413 	  val = va_arg (alist, int);
414 	  *dst++ = val;
415 	  break;
416 	case 'w':
417 	  val = va_arg (alist, int);
418 	  *dst++ = val;
419 	  *dst++ = val >> 8;
420 	  *dst++ = val >> 16;
421 	  *dst++ = val >> 24;
422 	  break;
423 	case 'S':
424 	  val = get_byte ();
425 	  if (val != RDP_RES_VALUE)
426 	    {
427 	      printf_unfiltered ("got bad res value of %d, %x\n", val, val);
428 	    }
429 	  break;
430 	case 'V':
431 	  pstat = va_arg (alist, int *);
432 	  pi = va_arg (alist, int *);
433 
434 	  *pstat = get_byte ();
435 	  /* Check the result was zero, if not read the syndrome */
436 	  if (*pstat)
437 	    {
438 	      *pi = get_word ();
439 	    }
440 	  break;
441 	case 'Z':
442 	  /* Check the result code */
443 	  switch (get_byte ())
444 	    {
445 	    case 0:
446 	      /* Success */
447 	      break;
448 	    case 253:
449 	      /* Target can't do it; never mind */
450 	      printf_unfiltered ("RDP: Insufficient privilege\n");
451 	      return;
452 	    case 254:
453 	      /* Target can't do it; never mind */
454 	      printf_unfiltered ("RDP: Unimplemented message\n");
455 	      return;
456 	    case 255:
457 	      error ("Command garbled");
458 	      break;
459 	    default:
460 	      error ("Corrupt reply from target");
461 	      break;
462 	    }
463 	  break;
464 	case 'W':
465 	  /* Read a word from the target */
466 	  pi = va_arg (alist, int *);
467 	  *pi = get_word ();
468 	  break;
469 	case 'P':
470 	  /* Read in some bytes from the target. */
471 	  pc = va_arg (alist, char *);
472 	  val = va_arg (alist, int);
473 	  for (i = 0; i < val; i++)
474 	    {
475 	      pc[i] = get_byte ();
476 	    }
477 	  break;
478 	case 'p':
479 	  /* send what's being pointed at */
480 	  pc = va_arg (alist, char *);
481 	  val = va_arg (alist, int);
482 	  dst = buf;
483 	  serial_write (io, pc, val);
484 	  break;
485 	case '-':
486 	  /* Send whats in the queue */
487 	  if (dst != buf)
488 	    {
489 	      serial_write (io, buf, dst - buf);
490 	      dst = buf;
491 	    }
492 	  break;
493 	case 'B':
494 	  pi = va_arg (alist, int *);
495 	  *pi = get_byte ();
496 	  break;
497 	default:
498 	  internal_error (__FILE__, __LINE__, "failed internal consistency check");
499 	}
500     }
501   va_end (alist);
502 
503   if (dst != buf)
504     internal_error (__FILE__, __LINE__, "failed internal consistency check");
505 }
506 
507 
508 static int
rdp_write(CORE_ADDR memaddr,char * buf,int len)509 rdp_write (CORE_ADDR memaddr, char *buf, int len)
510 {
511   int res;
512   int val;
513 
514   send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val);
515 
516   if (res)
517     {
518       return val;
519     }
520   return len;
521 }
522 
523 
524 static int
rdp_read(CORE_ADDR memaddr,char * buf,int len)525 rdp_read (CORE_ADDR memaddr, char *buf, int len)
526 {
527   int res;
528   int val;
529   send_rdp ("bww-S-P-V",
530 	    RDP_MEM_READ, memaddr, len,
531 	    buf, len,
532 	    &res, &val);
533   if (res)
534     {
535       return val;
536     }
537   return len;
538 }
539 
540 static void
rdp_fetch_one_register(int mask,char * buf)541 rdp_fetch_one_register (int mask, char *buf)
542 {
543   int val;
544   send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val);
545   store_signed_integer (buf, 4, val);
546 }
547 
548 static void
rdp_fetch_one_fpu_register(int mask,char * buf)549 rdp_fetch_one_fpu_register (int mask, char *buf)
550 {
551 #if 0
552   /* !!! Since the PIE board doesn't work as documented,
553      and it doesn't have FPU hardware anyway and since it
554      slows everything down, I've disabled this. */
555   int val;
556   if (mask == RDP_FPU_READWRITE_MASK_FPS)
557     {
558       /* this guy is only a word */
559       send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val);
560       store_signed_integer (buf, 4, val);
561     }
562   else
563     {
564       /* There are 12 bytes long
565          !! fixme about endianness
566        */
567       int dummy;		/* I've seen these come back as four words !! */
568       send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy);
569     }
570 #endif
571   memset (buf, 0, MAX_REGISTER_SIZE);
572 }
573 
574 
575 static void
rdp_store_one_register(int mask,char * buf)576 rdp_store_one_register (int mask, char *buf)
577 {
578   int val = extract_unsigned_integer (buf, 4);
579 
580   send_rdp ("bbww-SZ",
581 	    RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val);
582 }
583 
584 
585 static void
rdp_store_one_fpu_register(int mask,char * buf)586 rdp_store_one_fpu_register (int mask, char *buf)
587 {
588 #if 0
589   /* See comment in fetch_one_fpu_register */
590   if (mask == RDP_FPU_READWRITE_MASK_FPS)
591     {
592       int val = extract_unsigned_integer (buf, 4);
593       /* this guy is only a word */
594       send_rdp ("bbww-SZ", RDP_COPRO_WRITE,
595 		FPU_COPRO_NUMBER,
596 		mask, val);
597     }
598   else
599     {
600       /* There are 12 bytes long
601          !! fixme about endianness
602        */
603       int dummy = 0;
604       /* I've seen these come as four words, not the three advertized !! */
605       printf ("Sending mask %x\n", mask);
606       send_rdp ("bbwwwww-SZ",
607 		RDP_COPRO_WRITE,
608 		FPU_COPRO_NUMBER,
609 		mask,
610 		*(int *) (buf + 0),
611 		*(int *) (buf + 4),
612 		*(int *) (buf + 8),
613 		0);
614 
615       printf ("done mask %x\n", mask);
616     }
617 #endif
618 }
619 
620 
621 /* Convert between GDB requests and the RDP layer. */
622 
623 static void
remote_rdp_fetch_register(int regno)624 remote_rdp_fetch_register (int regno)
625 {
626   if (regno == -1)
627     {
628       for (regno = 0; regno < NUM_REGS; regno++)
629 	remote_rdp_fetch_register (regno);
630     }
631   else
632     {
633       char buf[MAX_REGISTER_SIZE];
634       if (regno < 15)
635 	rdp_fetch_one_register (1 << regno, buf);
636       else if (regno == ARM_PC_REGNUM)
637 	rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf);
638       else if (regno == ARM_PS_REGNUM)
639 	rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf);
640       else if (regno == ARM_FPS_REGNUM)
641 	rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf);
642       else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
643 	rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf);
644       else
645 	{
646 	  printf ("Help me with fetch reg %d\n", regno);
647 	}
648       regcache_raw_supply (current_regcache, regno, buf);
649     }
650 }
651 
652 
653 static void
remote_rdp_store_register(int regno)654 remote_rdp_store_register (int regno)
655 {
656   if (regno == -1)
657     {
658       for (regno = 0; regno < NUM_REGS; regno++)
659 	remote_rdp_store_register (regno);
660     }
661   else
662     {
663       char tmp[MAX_REGISTER_SIZE];
664       deprecated_read_register_gen (regno, tmp);
665       if (regno < 15)
666 	rdp_store_one_register (1 << regno, tmp);
667       else if (regno == ARM_PC_REGNUM)
668 	rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp);
669       else if (regno == ARM_PS_REGNUM)
670 	rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp);
671       else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
672 	rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp);
673       else
674 	{
675 	  printf ("Help me with reg %d\n", regno);
676 	}
677     }
678 }
679 
680 static void
remote_rdp_kill(void)681 remote_rdp_kill (void)
682 {
683   callback->shutdown (callback);
684 }
685 
686 
687 static void
rdp_info(void)688 rdp_info (void)
689 {
690   send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP,
691 	    &ds.step_info);
692   send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK,
693 	    &ds.break_info);
694   send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET,
695 	    &ds.target_info,
696 	    &ds.model_info);
697 
698   ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1;
699 
700   ds.rdi_level = (ds.target_info >> 5) & 3;
701 }
702 
703 
704 static void
rdp_execute_start(void)705 rdp_execute_start (void)
706 {
707   /* Start it off, but don't wait for it */
708   send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC);
709 }
710 
711 
712 static void
rdp_set_command_line(char * command,char * args)713 rdp_set_command_line (char *command, char *args)
714 {
715   /*
716      ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
717      ** don't implement that, and get all confused at the unexpected text.
718      ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
719    */
720 
721   if (commandline != NULL)
722     xfree (commandline);
723 
724   commandline = xstrprintf ("%s %s", command, args);
725 }
726 
727 static void
rdp_catch_vectors(void)728 rdp_catch_vectors (void)
729 {
730   /*
731      ** We want the target monitor to intercept the abort vectors
732      ** i.e. stop the program if any of these are used.
733    */
734   send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
735   /*
736      ** Specify a bitmask including
737      **  the reset vector
738      **  the undefined instruction vector
739      **  the prefetch abort vector
740      **  the data abort vector
741      **  the address exception vector
742    */
743 	    (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5)
744     );
745 }
746 
747 
748 
749 #define a_byte 1
750 #define a_word 2
751 #define a_string 3
752 
753 
754 typedef struct
755 {
756   CORE_ADDR n;
757   const char *s;
758 }
759 argsin;
760 
761 #define ABYTE 1
762 #define AWORD 2
763 #define ASTRING 3
764 #define ADDRLEN 4
765 
766 #define SWI_WriteC                      0x0
767 #define SWI_Write0                      0x2
768 #define SWI_ReadC                       0x4
769 #define SWI_CLI                         0x5
770 #define SWI_GetEnv                      0x10
771 #define SWI_Exit                        0x11
772 #define SWI_EnterOS                     0x16
773 
774 #define SWI_GetErrno                    0x60
775 #define SWI_Clock                       0x61
776 
777 #define SWI_Time                        0x63
778 #define SWI_Remove                      0x64
779 #define SWI_Rename                      0x65
780 #define SWI_Open                        0x66
781 
782 #define SWI_Close                       0x68
783 #define SWI_Write                       0x69
784 #define SWI_Read                        0x6a
785 #define SWI_Seek                        0x6b
786 #define SWI_Flen                        0x6c
787 
788 #define SWI_IsTTY                       0x6e
789 #define SWI_TmpNam                      0x6f
790 #define SWI_InstallHandler              0x70
791 #define SWI_GenerateError               0x71
792 
793 
794 #ifndef O_BINARY
795 #define O_BINARY 0
796 #endif
797 
798 static int translate_open_mode[] =
799 {
800   O_RDONLY,			/* "r"   */
801   O_RDONLY + O_BINARY,		/* "rb"  */
802   O_RDWR,			/* "r+"  */
803   O_RDWR + O_BINARY,		/* "r+b" */
804   O_WRONLY + O_CREAT + O_TRUNC,	/* "w"   */
805   O_WRONLY + O_BINARY + O_CREAT + O_TRUNC,	/* "wb"  */
806   O_RDWR + O_CREAT + O_TRUNC,	/* "w+"  */
807   O_RDWR + O_BINARY + O_CREAT + O_TRUNC,	/* "w+b" */
808   O_WRONLY + O_APPEND + O_CREAT,	/* "a"   */
809   O_WRONLY + O_BINARY + O_APPEND + O_CREAT,	/* "ab"  */
810   O_RDWR + O_APPEND + O_CREAT,	/* "a+"  */
811   O_RDWR + O_BINARY + O_APPEND + O_CREAT	/* "a+b" */
812 };
813 
814 static int
exec_swi(int swi,argsin * args)815 exec_swi (int swi, argsin *args)
816 {
817   int i;
818   char c;
819   switch (swi)
820     {
821     case SWI_WriteC:
822       callback->write_stdout (callback, &c, 1);
823       return 0;
824     case SWI_Write0:
825       for (i = 0; i < args->n; i++)
826 	callback->write_stdout (callback, args->s, strlen (args->s));
827       return 0;
828     case SWI_ReadC:
829       callback->read_stdin (callback, &c, 1);
830       args->n = c;
831       return 1;
832     case SWI_CLI:
833       args->n = callback->system (callback, args->s);
834       return 1;
835     case SWI_GetErrno:
836       args->n = callback->get_errno (callback);
837       return 1;
838     case SWI_Time:
839       args->n = callback->time (callback, NULL);
840       return 1;
841 
842     case SWI_Clock:
843       /* return number of centi-seconds... */
844       args->n =
845 #ifdef CLOCKS_PER_SEC
846 	(CLOCKS_PER_SEC >= 100)
847 	? (clock () / (CLOCKS_PER_SEC / 100))
848 	: ((clock () * 100) / CLOCKS_PER_SEC);
849 #else
850       /* presume unix... clock() returns microseconds */
851 	clock () / 10000;
852 #endif
853       return 1;
854 
855     case SWI_Remove:
856       args->n = callback->unlink (callback, args->s);
857       return 1;
858     case SWI_Rename:
859       args->n = callback->rename (callback, args[0].s, args[1].s);
860       return 1;
861 
862     case SWI_Open:
863       /* Now we need to decode the Demon open mode */
864       i = translate_open_mode[args[1].n];
865 
866       /* Filename ":tt" is special: it denotes stdin/out */
867       if (strcmp (args->s, ":tt") == 0)
868 	{
869 	  if (i == O_RDONLY)	/* opening tty "r" */
870 	    args->n = 0 /* stdin */ ;
871 	  else
872 	    args->n = 1 /* stdout */ ;
873 	}
874       else
875 	args->n = callback->open (callback, args->s, i);
876       return 1;
877 
878     case SWI_Close:
879       args->n = callback->close (callback, args->n);
880       return 1;
881 
882     case SWI_Write:
883       /* Return the number of bytes *not* written */
884       args->n = args[1].n -
885 	callback->write (callback, args[0].n, args[1].s, args[1].n);
886       return 1;
887 
888     case SWI_Read:
889       {
890 	char *copy = alloca (args[2].n);
891 	int done = callback->read (callback, args[0].n, copy, args[2].n);
892 	if (done > 0)
893 	  remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
894 	args->n = args[2].n - done;
895 	return 1;
896       }
897 
898     case SWI_Seek:
899       /* Return non-zero on failure */
900       args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0;
901       return 1;
902 
903     case SWI_Flen:
904       {
905 	long old = callback->lseek (callback, args->n, 0, SEEK_CUR);
906 	args->n = callback->lseek (callback, args->n, 0, SEEK_END);
907 	callback->lseek (callback, args->n, old, 0);
908 	return 1;
909       }
910 
911     case SWI_IsTTY:
912       args->n = callback->isatty (callback, args->n);
913       return 1;
914 
915     case SWI_GetEnv:
916       if (commandline != NULL)
917 	{
918 	  int len = strlen (commandline);
919 	  if (len > 255)
920 	    {
921 	      len = 255;
922 	      commandline[255] = '\0';
923 	    }
924 	  remote_rdp_xfer_inferior_memory (args[0].n,
925 					   commandline, len + 1, 1, 0, 0);
926 	}
927       else
928 	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
929       return 1;
930 
931     default:
932       return 0;
933     }
934 }
935 
936 
937 static void
handle_swi(void)938 handle_swi (void)
939 {
940   argsin args[3];
941   char *buf;
942   int len;
943   int count = 0;
944 
945   int swino = get_word ();
946   int type = get_byte ();
947   while (type != 0)
948     {
949       switch (type & 0x3)
950 	{
951 	case ABYTE:
952 	  args[count].n = get_byte ();
953 	  break;
954 
955 	case AWORD:
956 	  args[count].n = get_word ();
957 	  break;
958 
959 	case ASTRING:
960 	  /* If the word is under 32 bytes it will be sent otherwise
961 	     an address to it is passed. Also: Special case of 255 */
962 
963 	  len = get_byte ();
964 	  if (len > 32)
965 	    {
966 	      if (len == 255)
967 		{
968 		  len = get_word ();
969 		}
970 	      buf = alloca (len);
971 	      remote_rdp_xfer_inferior_memory (get_word (),
972 					       buf,
973 					       len,
974 					       0,
975 					       0,
976 					       0);
977 	    }
978 	  else
979 	    {
980 	      int i;
981 	      buf = alloca (len + 1);
982 	      for (i = 0; i < len; i++)
983 		buf[i] = get_byte ();
984 	      buf[i] = 0;
985 	    }
986 	  args[count].n = len;
987 	  args[count].s = buf;
988 	  break;
989 
990 	default:
991 	  error ("Unimplemented SWI argument");
992 	}
993 
994       type = type >> 2;
995       count++;
996     }
997 
998   if (exec_swi (swino, args))
999     {
1000       /* We have two options here reply with either a byte or a word
1001          which is stored in args[0].n. There is no harm in replying with
1002          a word all the time, so thats what I do! */
1003       send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n);
1004     }
1005   else
1006     {
1007       send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing);
1008     }
1009 }
1010 
1011 static void
rdp_execute_finish(void)1012 rdp_execute_finish (void)
1013 {
1014   int running = 1;
1015 
1016   while (running)
1017     {
1018       int res;
1019       res = serial_readchar (io, 1);
1020       while (res == SERIAL_TIMEOUT)
1021 	{
1022 	  QUIT;
1023 	  printf_filtered ("Waiting for target..\n");
1024 	  res = serial_readchar (io, 1);
1025 	}
1026 
1027       switch (res)
1028 	{
1029 	case RDP_RES_SWI:
1030 	  handle_swi ();
1031 	  break;
1032 	case RDP_RES_VALUE:
1033 	  send_rdp ("B", &ds.rdi_stopped_status);
1034 	  running = 0;
1035 	  break;
1036 	case RDP_RESET:
1037 	  printf_filtered ("Target reset\n");
1038 	  running = 0;
1039 	  break;
1040 	default:
1041 	  printf_filtered ("Ignoring %x\n", res);
1042 	  break;
1043 	}
1044     }
1045 }
1046 
1047 
1048 static void
rdp_execute(void)1049 rdp_execute (void)
1050 {
1051   rdp_execute_start ();
1052   rdp_execute_finish ();
1053 }
1054 
1055 static int
remote_rdp_insert_breakpoint(CORE_ADDR addr,char * save)1056 remote_rdp_insert_breakpoint (CORE_ADDR addr, char *save)
1057 {
1058   int res;
1059   if (ds.rdi_level > 0)
1060     {
1061       send_rdp ("bwb-SWB",
1062 		RDP_SET_BREAK,
1063 		addr,
1064 		RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE,
1065 		save,
1066 		&res);
1067     }
1068   else
1069     {
1070       send_rdp ("bwb-SB",
1071 		RDP_SET_BREAK,
1072 		addr,
1073 		RDP_SET_BREAK_TYPE_PC_EQUAL,
1074 		&res);
1075     }
1076   return res;
1077 }
1078 
1079 static int
remote_rdp_remove_breakpoint(CORE_ADDR addr,char * save)1080 remote_rdp_remove_breakpoint (CORE_ADDR addr, char *save)
1081 {
1082   int res;
1083   if (ds.rdi_level > 0)
1084     {
1085       send_rdp ("b-p-S-B",
1086 		RDP_CLEAR_BREAK,
1087 		save, 4,
1088 		&res);
1089     }
1090   else
1091     {
1092       send_rdp ("bw-S-B",
1093 		RDP_CLEAR_BREAK,
1094 		addr,
1095 		&res);
1096     }
1097   return res;
1098 }
1099 
1100 static void
rdp_step(void)1101 rdp_step (void)
1102 {
1103   if (ds.can_step && 0)
1104     {
1105       /* The pie board can't do steps so I can't test this, and
1106          the other code will always work. */
1107       int status;
1108       send_rdp ("bbw-S-B",
1109 		RDP_STEP, 0, 1,
1110 		&status);
1111     }
1112   else
1113     {
1114       char handle[4];
1115       CORE_ADDR pc = read_register (ARM_PC_REGNUM);
1116       pc = arm_get_next_pc (pc);
1117       remote_rdp_insert_breakpoint (pc, handle);
1118       rdp_execute ();
1119       remote_rdp_remove_breakpoint (pc, handle);
1120     }
1121 }
1122 
1123 static void
remote_rdp_open(char * args,int from_tty)1124 remote_rdp_open (char *args, int from_tty)
1125 {
1126   int not_icebreaker;
1127 
1128   if (!args)
1129     error_no_arg ("serial port device name");
1130 
1131   baud_rate = 9600;
1132 
1133   target_preopen (from_tty);
1134 
1135   io = serial_open (args);
1136 
1137   if (!io)
1138     perror_with_name (args);
1139 
1140   serial_raw (io);
1141 
1142   rdp_init (1, from_tty);
1143 
1144 
1145   if (from_tty)
1146     {
1147       printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate);
1148     }
1149 
1150   rdp_info ();
1151 
1152   /* Need to set up the vector interception state */
1153   rdp_catch_vectors ();
1154 
1155   /*
1156      ** If it's an EmbeddedICE, we need to set the processor config.
1157      ** Assume we can always have ARM7TDI...
1158    */
1159   send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, &not_icebreaker);
1160   if (!not_icebreaker)
1161     {
1162       const char *CPU = "ARM7TDI";
1163       int ICEversion;
1164       int len = strlen (CPU);
1165 
1166       send_rdp ("bbbbw-p-SWZ",
1167 		RDP_SELECT_CONFIG,
1168 		RDI_ConfigCPU,	/* Aspect: set the CPU */
1169 		len,		/* The number of bytes in the name */
1170 		RDI_MatchAny,	/* We'll take whatever we get */
1171 		0,		/* We'll take whatever version's there */
1172 		CPU, len,
1173 		&ICEversion);
1174     }
1175 
1176   /* command line initialised on 'run' */
1177 
1178   push_target (&remote_rdp_ops);
1179 
1180   callback->init (callback);
1181   flush_cached_frames ();
1182   registers_changed ();
1183   stop_pc = read_pc ();
1184   print_stack_frame (get_selected_frame (), 0, SRC_AND_LOC);
1185 }
1186 
1187 
1188 
1189 /* Close out all files and local state before this target loses control. */
1190 
1191 static void
remote_rdp_close(int quitting)1192 remote_rdp_close (int quitting)
1193 {
1194   callback->shutdown (callback);
1195   if (io)
1196     serial_close (io);
1197   io = 0;
1198 }
1199 
1200 
1201 /* Resume execution of the target process.  STEP says whether to single-step
1202    or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
1203    to the target, or zero for no signal.  */
1204 
1205 static void
remote_rdp_resume(ptid_t ptid,int step,enum target_signal siggnal)1206 remote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal)
1207 {
1208   if (step)
1209     rdp_step ();
1210   else
1211     rdp_execute ();
1212 }
1213 
1214 /* Wait for inferior process to do something.  Return pid of child,
1215    or -1 in case of error; store status through argument pointer STATUS,
1216    just as `wait' would.  */
1217 
1218 static ptid_t
remote_rdp_wait(ptid_t ptid,struct target_waitstatus * status)1219 remote_rdp_wait (ptid_t ptid, struct target_waitstatus *status)
1220 {
1221   switch (ds.rdi_stopped_status)
1222     {
1223     default:
1224     case RDP_RES_RESET:
1225     case RDP_RES_SWI:
1226       status->kind = TARGET_WAITKIND_EXITED;
1227       status->value.integer = read_register (0);
1228       break;
1229     case RDP_RES_AT_BREAKPOINT:
1230       status->kind = TARGET_WAITKIND_STOPPED;
1231       /* The signal in sigrc is a host signal.  That probably
1232          should be fixed.  */
1233       status->value.sig = TARGET_SIGNAL_TRAP;
1234       break;
1235 #if 0
1236     case rdp_signalled:
1237       status->kind = TARGET_WAITKIND_SIGNALLED;
1238       /* The signal in sigrc is a host signal.  That probably
1239          should be fixed.  */
1240       status->value.sig = target_signal_from_host (sigrc);
1241       break;
1242 #endif
1243     }
1244 
1245   return inferior_ptid;
1246 }
1247 
1248 /* Get ready to modify the registers array.  On machines which store
1249    individual registers, this doesn't need to do anything.  On machines
1250    which store all the registers in one fell swoop, this makes sure
1251    that registers contains all the registers from the program being
1252    debugged.  */
1253 
1254 static void
remote_rdp_prepare_to_store(void)1255 remote_rdp_prepare_to_store (void)
1256 {
1257   /* Do nothing, since we can store individual regs */
1258 }
1259 
1260 /* Transfer LEN bytes between GDB address MYADDR and target address
1261    MEMADDR.  If WRITE is non-zero, transfer them to the target,
1262    otherwise transfer them from the target.  TARGET is unused.
1263 
1264    Returns the number of bytes transferred. */
1265 
1266 static int
remote_rdp_xfer_inferior_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)1267 remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
1268 				 int write, struct mem_attrib *attrib,
1269 				 struct target_ops *target)
1270 {
1271   /* I infer from D Taylor's code that there's a limit on the amount
1272      we can transfer in one chunk.. */
1273   int done = 0;
1274   while (done < len)
1275     {
1276       int justdone;
1277       int thisbite = len - done;
1278       if (thisbite > RDP_MOUTHFULL)
1279 	thisbite = RDP_MOUTHFULL;
1280 
1281       QUIT;
1282 
1283       if (write)
1284 	{
1285 	  justdone = rdp_write (memaddr + done, myaddr + done, thisbite);
1286 	}
1287       else
1288 	{
1289 	  justdone = rdp_read (memaddr + done, myaddr + done, thisbite);
1290 	}
1291 
1292       done += justdone;
1293 
1294       if (justdone != thisbite)
1295 	break;
1296     }
1297   return done;
1298 }
1299 
1300 
1301 
1302 struct yn
1303 {
1304   const char *name;
1305   int bit;
1306 };
1307 static struct yn stepinfo[] =
1308 {
1309   {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1},
1310   {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP},
1311   {"Step one instruction", RDP_INFO_ABOUT_STEP_1},
1312   {0}
1313 };
1314 
1315 static struct yn breakinfo[] =
1316 {
1317   {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP},
1318   {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE},
1319   {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ},
1320   {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ},
1321   {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ},
1322   {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE},
1323   {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE},
1324   {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE},
1325   {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK},
1326 {"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK},
1327 {"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH},
1328   {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND},
1329   {0}
1330 };
1331 
1332 
1333 static void
dump_bits(struct yn * t,int info)1334 dump_bits (struct yn *t, int info)
1335 {
1336   while (t->name)
1337     {
1338       printf_unfiltered ("  %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No");
1339       t++;
1340     }
1341 }
1342 
1343 static void
remote_rdp_files_info(struct target_ops * target)1344 remote_rdp_files_info (struct target_ops *target)
1345 {
1346   printf_filtered ("Target capabilities:\n");
1347   dump_bits (stepinfo, ds.step_info);
1348   dump_bits (breakinfo, ds.break_info);
1349   printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3);
1350 }
1351 
1352 
1353 static void
remote_rdp_create_inferior(char * exec_file,char * allargs,char ** env,int from_tty)1354 remote_rdp_create_inferior (char *exec_file, char *allargs, char **env,
1355 			    int from_tty)
1356 {
1357   CORE_ADDR entry_point;
1358 
1359   if (exec_file == 0 || exec_bfd == 0)
1360     error ("No executable file specified.");
1361 
1362   entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
1363 
1364   remote_rdp_kill ();
1365   remove_breakpoints ();
1366   init_wait_for_inferior ();
1367 
1368   /* This gives us a chance to set up the command line */
1369   rdp_set_command_line (exec_file, allargs);
1370 
1371   inferior_ptid = pid_to_ptid (42);
1372   insert_breakpoints ();	/* Needed to get correct instruction in cache */
1373 
1374   /*
1375      ** RDP targets don't provide any facility to set the top of memory,
1376      ** so we don't bother to look for MEMSIZE in the environment.
1377    */
1378 
1379   /* Let's go! */
1380   proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
1381 }
1382 
1383 /* Attach doesn't need to do anything */
1384 static void
remote_rdp_attach(char * args,int from_tty)1385 remote_rdp_attach (char *args, int from_tty)
1386 {
1387   return;
1388 }
1389 
1390 /* Define the target subroutine names */
1391 
1392 struct target_ops remote_rdp_ops;
1393 
1394 static void
init_remote_rdp_ops(void)1395 init_remote_rdp_ops (void)
1396 {
1397   remote_rdp_ops.to_shortname = "rdp";
1398   remote_rdp_ops.to_longname = "Remote Target using the RDProtocol";
1399   remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol";
1400   remote_rdp_ops.to_open = remote_rdp_open;
1401   remote_rdp_ops.to_close = remote_rdp_close;
1402   remote_rdp_ops.to_attach = remote_rdp_attach;
1403   remote_rdp_ops.to_resume = remote_rdp_resume;
1404   remote_rdp_ops.to_wait = remote_rdp_wait;
1405   remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register;
1406   remote_rdp_ops.to_store_registers = remote_rdp_store_register;
1407   remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store;
1408   remote_rdp_ops.deprecated_xfer_memory = remote_rdp_xfer_inferior_memory;
1409   remote_rdp_ops.to_files_info = remote_rdp_files_info;
1410   remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
1411   remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
1412   remote_rdp_ops.to_kill = remote_rdp_kill;
1413   remote_rdp_ops.to_load = generic_load;
1414   remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
1415   remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior;
1416   remote_rdp_ops.to_stratum = process_stratum;
1417   remote_rdp_ops.to_has_all_memory = 1;
1418   remote_rdp_ops.to_has_memory = 1;
1419   remote_rdp_ops.to_has_stack = 1;
1420   remote_rdp_ops.to_has_registers = 1;
1421   remote_rdp_ops.to_has_execution = 1;
1422   remote_rdp_ops.to_magic = OPS_MAGIC;
1423 }
1424 
1425 extern initialize_file_ftype _initialize_remote_rdp; /* -Wmissing-prototypes */
1426 
1427 void
_initialize_remote_rdp(void)1428 _initialize_remote_rdp (void)
1429 {
1430   init_remote_rdp_ops ();
1431   add_target (&remote_rdp_ops);
1432 }
1433