* remote-est.c: New file supports EST-300 CPU32 background
[deliverable/binutils-gdb.git] / gdb / remote-est.c
1 /* Remote debugging interface for EST-300 ICE, for GDB
2 Copyright 1994 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 Written by Steve Chamberlain for Cygnus Support.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23
24 #include "defs.h"
25 #include "command.h"
26 #include "gdbcore.h"
27 #include "target.h"
28 #include "wait.h"
29 #include <varargs.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include "serial.h"
34 #include "remote-utils.h"
35
36
37 static void expect_char PARAMS ((int));
38
39
40 static void
41 write_and_expect (x)
42 char *x;
43 {
44 sr_write_cr (x);
45 sr_expect (x);
46 }
47
48 static void
49 expect_char (want)
50 int want;
51 {
52 int c = sr_readchar ();
53 while (c != want)
54 c = sr_readchar ();
55 }
56
57
58 static void
59 expect_prompt ()
60 {
61 expect_char ('>');
62 }
63
64 static int
65 get_hex_digit (ch)
66 int ch;
67 {
68 if (ch >= '0' && ch <= '9')
69 return ch - '0';
70 else if (ch >= 'A' && ch <= 'F')
71 return ch - 'A' + 10;
72 else if (ch >= 'a' && ch <= 'f')
73 return ch - 'a' + 10;
74 return -1;
75 }
76
77 static int
78 get_hex (start)
79 int *start;
80 {
81 int value = get_hex_digit (*start);
82 int try;
83
84 *start = sr_readchar ();
85 while ((try = get_hex_digit (*start)) >= 0)
86 {
87 value <<= 4;
88 value += try;
89 *start = sr_readchar ();
90 }
91 return value;
92 }
93
94 /* Tell the remote machine to resume. */
95
96 static void
97 est_resume (pid, step, sig)
98 int pid, step, sig;
99 {
100 write_and_expect (step ? ".SI" : ".GO");
101 }
102
103 /* A reg dump looks like
104 D0 = 00000000 D1 = 00000000 D2 = 00000000 D3 = 00000000
105 D4 = 00000000 D5 = 00000000 D6 = 00000000 D7 = 00000000
106 A0 = 00000000 A1 = 00000000 A2 = 00000000 A3 = 00000000
107 A4 = 00000000 A5 = 00000000 A6 = 00000000 A7 = 001104FE
108 USP = 00110400 SSP*= 001104FE PC = 00229BBC SR = 2000
109 VBR = 00110000 SFC = 0005 DFC = 0005
110
111 or
112
113 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001234 00000000 001104FE 00110400 001104FE 00229BBC 2000 00110000 0005 0005
114 */
115
116 static int
117 target_to_gdb_rn (rn)
118 int rn;
119 {
120 if (rn < 16)
121 return rn;
122 if (rn == 18)
123 return PC_REGNUM;
124 if (rn == 19)
125 return PS_REGNUM;
126 return -1;
127 }
128
129
130 static void est_fetch_register ();
131 static void
132 est_fetch_registers ()
133 {
134 int regno;
135 unsigned long val;
136 int c;
137 int target_rn;
138 char buf[4];
139 write_and_expect (".DR");
140 buf[0] = 0;
141 buf[1] = 0;
142 buf[2] = 0;
143 buf[3] = 0;
144 for (regno = 0; regno < NUM_REGS; regno++)
145 supply_register (regno, buf);
146
147 c = sr_readchar ();
148 for (target_rn = 0; target_rn < 23; target_rn++)
149 {
150 unsigned long val;
151 while (!isdigit (c) && !isalpha (c))
152 c = sr_readchar ();
153
154 while (isdigit (c) || (c >= 'A' && c <= 'F'))
155 {
156 val <<= 4;
157 if (isdigit (c))
158 val = val + c - '0';
159 else
160 val = val + c - 'A' + 10;
161 c = sr_readchar ();
162 }
163
164 regno = target_to_gdb_rn (target_rn);
165 if (regno >= 0)
166 {
167 buf[0] = val >> 24;
168 buf[1] = val >> 16;
169 buf[2] = val >> 8;
170 buf[3] = val >> 0;
171 supply_register (regno, buf);
172 }
173 }
174 expect_prompt();
175 }
176
177 /* Fetch register REGNO, or all registers if REGNO is -1.
178 Returns errno value. */
179
180 static
181 void
182 est_fetch_register (regno)
183 int regno;
184 {
185 est_fetch_registers ();
186 }
187
188 /* Store the remote registers from the contents of the block REGS. */
189
190 static void est_store_register ();
191 static void
192 est_store_registers ()
193 {
194 int regno;
195
196 for (regno = 0; regno < 18; regno++)
197 est_store_register (regno);
198 registers_changed ();
199 }
200
201 /* Store register REGNO, or all if REGNO == 0.
202 Return errno value. */
203 static void
204 est_store_register (regno)
205 int regno;
206 {
207 char buf[20];
208 if (regno == -1)
209 {
210 est_store_registers ();
211 return;
212 }
213
214 if (regno < 8)
215 sprintf (buf, ".SR D%d %x", regno, read_register (regno));
216 else if (regno < 16)
217 sprintf (buf, ".SR A%d %x", regno - 8, read_register (regno));
218 else if (regno == PC_REGNUM)
219 sprintf (buf, ".SR PC %x", read_register (regno));
220 else if (regno == PS_REGNUM)
221 sprintf (buf, ".SR SR %x", read_register (regno));
222 else
223 return;
224 write_and_expect (buf);
225 expect_prompt ();
226 }
227
228 /* Get ready to modify the registers array. On machines which store
229 individual registers, this doesn't need to do anything. On machines
230 which store all the registers in one fell swoop, this makes sure
231 that registers contains all the registers from the program being
232 debugged. */
233
234
235 static
236 int
237 stickbyte (where, what)
238 char *where;
239 unsigned int what;
240 {
241 static CONST char digs[] = "0123456789ABCDEF";
242 where[0] = digs[(what >> 4) & 0xf];
243 where[1] = digs[(what & 0xf) & 0xf];
244 return what;
245 }
246
247 /* Copy LEN bytes of data from debugger memory at MYADDR
248 to inferior's memory at MEMADDR. Returns length moved. */
249
250 static int
251 est_write_memory (memaddr, myaddr, len)
252 CORE_ADDR memaddr;
253 unsigned char *myaddr;
254 int len;
255 {
256 int i;
257 #define maxstride 128
258 int stride;
259
260 write_and_expect (".DL");
261 expect_char ('+');
262 for (i = 0; i < len; i += stride)
263 {
264 char compose[maxstride * 2 + 50];
265 int address = i + memaddr;
266 int j;
267 int check_sum;
268 int where = 0;
269 int alen;
270 stride = len - i;
271 if (stride > maxstride)
272 stride = maxstride;
273
274 compose[where++] = 'S';
275 check_sum = 0;
276 if (address >= 0xffffff)
277 {
278 alen = 4;
279 }
280 else if (address >= 0xffff)
281 {
282 alen = 3;
283 }
284 else
285 alen = 2;
286 compose[where++] = alen - 1 + '0'; /* insert type */
287 check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
288 where += 2;
289 while (alen > 0)
290 {
291 alen--;
292 check_sum += stickbyte (compose + where, address >> (8 * (alen)));
293 where += 2;
294 }
295
296 for (j = 0; j < stride; j++)
297 {
298 check_sum += stickbyte (compose + where, myaddr[i + j]);
299 where += 2;
300 }
301
302 stickbyte (compose + where, ~check_sum);
303
304 where += 2;
305 compose[where++] = 0;
306
307 sr_write_cr (compose);
308 while (sr_readchar () != '+')
309 sr_write_cr (compose);
310 }
311
312 /* Send the trailer record */
313 sr_write_cr ("S70500000000FA");
314 expect_prompt ();
315 return len;
316 }
317
318
319
320 /*
321
322 The dump memory command generates output which looks like:
323
324
325 .dmb 0 100
326 4E 56 FF FC 4E 71 42 AE FF FC 72 09 B2 AE FF FC NV..NqB...r.....
327 6C 02 60 12 2F 2E FF FC 4E B9 00 00 00 2A 58 4F l.`./...N....*XO
328 52 AE FF FC 60 E4 4E 5E 4E 75 4E 56 00 00 20 2E R...`.N^NuNV.. .
329 00 08 D1 B9 00 00 00 00 4E 5E 4E 75 06 46 40 54 ........N^Nu.F@T
330 04 45 44 4C 54 45 40 56 42 F4 04 64 24 45 05 05 .EDLTE@VB..d$E..
331 00 6D 04 46 00 45 4C 05 04 46 04 4C 44 CD 00 65 .m.F.EL..F.LD..e
332 40 45 44 55 45 45 45 46 04 44 44 40 05 4D 00 44 @EDUEEEF.DD@.M.D
333
334 */
335
336 static int
337 est_read_memory (memaddr, myaddr, len)
338 CORE_ADDR memaddr;
339 unsigned char *myaddr;
340 int len;
341 {
342 int count;
343 int c;
344 char buf[20];
345 /* Starting address of this pass. */
346
347 if (((memaddr - 1) + len) < memaddr)
348 {
349 errno = EIO;
350 return 0;
351 }
352
353 sprintf (buf, ".dmb %x %x", memaddr, len);
354 write_and_expect (buf);
355 count = 0;
356
357 c = sr_readchar ();
358
359 while (count < len)
360 {
361 while (!isdigit (c) && !isalpha (c)) {
362 if (c == '!')
363 {
364 expect_prompt();
365 errno =EIO;
366 return 0;
367
368 }
369 c = sr_readchar ();
370 }
371 myaddr[count++] = get_hex (&c);
372 c = sr_readchar ();
373 if (c == ' ')
374 {
375 c = sr_readchar ();
376 if (c == ' ')
377 while (c != '\r')
378 c = sr_readchar ();
379 }
380 }
381
382 expect_prompt ();
383
384
385 return len;
386 }
387
388 static int
389 est_xfer_inferior_memory (memaddr, myaddr, len, write, target)
390 CORE_ADDR memaddr;
391 unsigned char *myaddr;
392 int len;
393 int write;
394 struct target_ops *target; /* ignored */
395 {
396 if (write)
397 {
398 return est_write_memory (memaddr, myaddr, len);
399 }
400 else
401 {
402 return est_read_memory (memaddr, myaddr, len);
403 }
404 }
405
406
407 #define MAX_DEBUG_BREAKPOINTS 100
408
409 extern int memory_breakpoint_size;
410 static CORE_ADDR breakaddr[MAX_DEBUG_BREAKPOINTS] =
411 {0};
412
413 int
414 est_clear_all_breakpoints ()
415 {
416 int i;
417 for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
418 {
419 breakaddr[i] = 0;
420 }
421
422 if (sr_is_open ())
423 {
424 write_and_expect (".RB");
425 expect_prompt ();
426 }
427 return 0;
428 }
429
430 static int
431 est_insert_breakpoint (addr, shadow)
432 CORE_ADDR addr;
433 unsigned char *shadow;
434 {
435 int i;
436
437 for (i = 0; i <= MAX_DEBUG_BREAKPOINTS; i++)
438 if (breakaddr[i] == 0)
439 {
440 char buf[20];
441 breakaddr[i] = addr;
442 sprintf (buf, ".SB %x", addr);
443 write_and_expect (buf);
444 expect_prompt ();
445 return 0;
446 }
447 error ("Too many breakpoints ( > %d) for the est\n", MAX_DEBUG_BREAKPOINTS);
448 return 1;
449 }
450
451 static int
452 est_remove_breakpoint (addr, shadow)
453 CORE_ADDR addr;
454 unsigned char *shadow;
455 {
456 int i;
457
458 for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
459 if (breakaddr[i] == addr)
460 {
461 char buf[20];
462 breakaddr[i] = 0;
463 sprintf (buf, ".RB %x", addr);
464 write_and_expect (buf);
465 expect_prompt ();
466 return 0;
467 }
468
469 error ("Can't find breakpoint associated with 0x%x\n", addr);
470 return 1;
471 }
472
473
474 /* Wait until the remote machine stops, then return,
475 storing status in STATUS just as `wait' would. */
476
477 static int
478 est_wait (pid, status)
479 int pid;
480 struct target_waitstatus *status;
481 {
482 int c = sr_readchar ();
483 while (c != '!')
484 c = sr_readchar ();
485 /* What sort of stop */
486 c = sr_readchar ();
487 status->kind = TARGET_WAITKIND_STOPPED;
488 switch (c)
489 {
490 case 'E':
491 status->value.sig = TARGET_SIGNAL_BUS;
492 break;
493 /* Address error */
494 case 'A':
495 status->value.sig = TARGET_SIGNAL_BUS;
496 break;
497 /* Break */
498 case 'B':
499 status->value.sig = TARGET_SIGNAL_TRAP;
500 break;
501 }
502 expect_prompt ();
503 return 0;
504 }
505
506 void
507 est_checkin ()
508 {
509 write_and_expect (".in");
510 gr_expect_prompt ();
511 }
512
513 extern struct gr_settings est_settings;
514
515 static void
516 est_open (args, from_tty)
517 char *args;
518 int from_tty;
519 {
520 gr_open (args, from_tty, &est_settings);
521 }
522
523 /* Define the target subroutine names */
524
525 struct target_ops est_ops =
526 {
527 "est",
528 "Remote EST-300 target",
529 "Use a remote EST-300 ICE connected by a serial line,\n\
530 or a network connection.\n\
531 Arguments are the name of the device for the serial line,\n\
532 the speed to connect at in bits per second.\n\
533 eg\n\
534 target est /dev/ttya 9600\n\
535 target est foobar",
536 est_open,
537 gr_close,
538 0,
539 gr_detach,
540 est_resume,
541 est_wait,
542 est_fetch_register,
543 est_store_register,
544 gr_prepare_to_store,
545 est_xfer_inferior_memory,
546 gr_files_info,
547 est_insert_breakpoint,
548 est_remove_breakpoint, /* Breakpoints */
549 0,
550 0,
551 0,
552 0,
553 0, /* Terminal handling */
554 gr_kill,
555 gr_load_image, /* load */
556 0, /* lookup_symbol */
557 gr_create_inferior,
558 gr_mourn,
559 0, /* can_run */
560 0, /* notice_signals */
561 0, /* to_stop */
562 process_stratum,
563 0, /* next */
564 1,
565 1,
566 1,
567 1,
568 1, /* all mem, mem, stack, regs, exec */
569 0,
570 0, /* Section pointers */
571 OPS_MAGIC, /* Always the last thing */
572 };
573
574 static struct gr_settings est_settings =
575 {
576 NULL, /* dcache */
577 ">", /* prompt */
578 &est_ops, /* ops */
579 est_clear_all_breakpoints,
580 est_read_memory, /* readfunc */
581 est_write_memory, /* writefunc */
582 est_checkin, /* checkin */
583 };
584
585 void
586 _initialize_remote_est ()
587 {
588 add_target (&est_ops);
589 }
This page took 0.042786 seconds and 5 git commands to generate.