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