Add swapin() function, and SWAPIN macro that calls it, to do byte swapping
[deliverable/binutils-gdb.git] / gdb / remote-hms.c
CommitLineData
1f46923f 1/* Remote debugging interface for Hitachi HMS Monitor Version 1.0
fa4b55a1 2 Copyright 1992 Free Software Foundation, Inc.
e17960fb
JG
3 Contributed by Cygnus Support. Written by Steve Chamberlain
4 (sac@cygnus.com).
fa4b55a1
SC
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
fa4b55a1
SC
22#include "defs.h"
23#include "inferior.h"
24#include "wait.h"
25#include "value.h"
e17960fb 26#include <string.h>
fa4b55a1
SC
27#include <ctype.h>
28#include <fcntl.h>
29#include <signal.h>
30#include <setjmp.h>
31#include <errno.h>
32#include "terminal.h"
33#include "target.h"
34#include "gdbcore.h"
35
36/* External data declarations */
37extern int stop_soon_quietly; /* for wait_for_inferior */
38
fa4b55a1
SC
39/* Forward data declarations */
40extern struct target_ops hms_ops; /* Forward declaration */
41
42/* Forward function declarations */
43static void hms_fetch_registers ();
44static int hms_store_registers ();
45static void hms_close ();
46static int hms_clear_breakpoints();
47
48extern struct target_ops hms_ops;
49
1f46923f
SC
50static int quiet = 1;
51
fa4b55a1 52#ifdef DEBUG
1f46923f
SC
53# define DENTER(NAME) if (!quiet) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
54# define DEXIT(NAME) if (!quiet) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
fa4b55a1
SC
55#else
56# define DENTER(NAME)
57# define DEXIT(NAME)
58#endif
59
60
1f46923f
SC
61/***********************************************************************/
62/* Caching stuff stolen from remote-nindy.c */
63
64/* The data cache records all the data read from the remote machine
65 since the last time it stopped.
66
67 Each cache block holds LINE_SIZE bytes of data
68 starting at a multiple-of-LINE_SIZE address. */
69
70
71#define LINE_SIZE_POWER 4
72#define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
73#define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
74#define DCACHE_SIZE 64 /* Number of cache blocks */
75#define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
76struct dcache_block {
77 struct dcache_block *next, *last;
78 unsigned int addr; /* Address for which data is recorded. */
79 int data[LINE_SIZE/sizeof(int)];
80};
81
82struct dcache_block dcache_free, dcache_valid;
83
84/* Free all the data cache blocks, thus discarding all cached data. */
85static
86void
87dcache_flush ()
88{
89 register struct dcache_block *db;
90
91 while ((db = dcache_valid.next) != &dcache_valid)
92 {
93 remque (db);
94 insque (db, &dcache_free);
95 }
96}
97
98/*
99 * If addr is present in the dcache, return the address of the block
100 * containing it.
101 */
102static
103struct dcache_block *
104dcache_hit (addr)
105 unsigned int addr;
106{
107 register struct dcache_block *db;
108
109 if (addr & 3)
110 abort ();
111
112 /* Search all cache blocks for one that is at this address. */
113 db = dcache_valid.next;
114 while (db != &dcache_valid)
115 {
116 if ((addr & ~LINE_SIZE_MASK)== db->addr)
117 return db;
118 db = db->next;
119 }
120 return NULL;
121}
122
123/* Return the int data at address ADDR in dcache block DC. */
124static
125int
126dcache_value (db, addr)
127 struct dcache_block *db;
128 unsigned int addr;
129{
130 if (addr & 3)
131 abort ();
132 return (db->data[XFORM(addr)]);
133}
134
135/* Get a free cache block, put or keep it on the valid list,
136 and return its address. The caller should store into the block
137 the address and data that it describes, then remque it from the
138 free list and insert it into the valid list. This procedure
139 prevents errors from creeping in if a ninMemGet is interrupted
140 (which used to put garbage blocks in the valid list...). */
141static
142struct dcache_block *
143dcache_alloc ()
144{
145 register struct dcache_block *db;
146
147 if ((db = dcache_free.next) == &dcache_free)
148 {
149 /* If we can't get one from the free list, take last valid and put
150 it on the free list. */
151 db = dcache_valid.last;
152 remque (db);
153 insque (db, &dcache_free);
154 }
155
156 remque (db);
157 insque (db, &dcache_valid);
158 return (db);
159}
160
161/* Return the contents of the word at address ADDR in the remote machine,
162 using the data cache. */
163static
164int
165dcache_fetch (addr)
166 CORE_ADDR addr;
167{
168 register struct dcache_block *db;
169
170 db = dcache_hit (addr);
171 if (db == 0)
172 {
173 db = dcache_alloc ();
174 immediate_quit++;
175 hms_read_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
176 immediate_quit--;
177 db->addr = addr & ~LINE_SIZE_MASK;
178 remque (db); /* Off the free list */
179 insque (db, &dcache_valid); /* On the valid list */
180 }
181 return (dcache_value (db, addr));
182}
183
184/* Write the word at ADDR both in the data cache and in the remote machine. */
185static void
186dcache_poke (addr, data)
187 CORE_ADDR addr;
188 int data;
189{
190 register struct dcache_block *db;
191
192 /* First make sure the word is IN the cache. DB is its cache block. */
193 db = dcache_hit (addr);
194 if (db == 0)
195 {
196 db = dcache_alloc ();
197 immediate_quit++;
198 hms_write_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
199 immediate_quit--;
200 db->addr = addr & ~LINE_SIZE_MASK;
201 remque (db); /* Off the free list */
202 insque (db, &dcache_valid); /* On the valid list */
203 }
204
205 /* Modify the word in the cache. */
206 db->data[XFORM(addr)] = data;
207
208 /* Send the changed word. */
209 immediate_quit++;
210 hms_write_inferior_memory(addr, (unsigned char *)&data, 4);
211 immediate_quit--;
212}
213
214/* The cache itself. */
215struct dcache_block the_cache[DCACHE_SIZE];
216
217/* Initialize the data cache. */
218static void
219dcache_init ()
220{
221 register i;
222 register struct dcache_block *db;
223
224 db = the_cache;
225 dcache_free.next = dcache_free.last = &dcache_free;
226 dcache_valid.next = dcache_valid.last = &dcache_valid;
227 for (i=0;i<DCACHE_SIZE;i++,db++)
228 insque (db, &dcache_free);
229}
fa4b55a1 230
1f46923f
SC
231
232/***********************************************************************
233 * I/O stuff stolen from remote-eb.c
234 ***********************************************************************/
235
236static int timeout = 2;
fa4b55a1
SC
237static char *dev_name = "/dev/ttya";
238
239
1f46923f 240
fa4b55a1
SC
241
242/* Descriptor for I/O to remote machine. Initialize it to -1 so that
243 hms_open knows that we don't have a file open when the program
244 starts. */
245int hms_desc = -1;
246#define OPEN(x) ((x) >= 0)
247
248
1f46923f
SC
249void hms_open();
250
fa4b55a1
SC
251#define ON 1
252#define OFF 0
253static void
254rawmode(desc, turnon)
255int desc;
256int turnon;
257{
258 TERMINAL sg;
259
260 if (desc < 0)
261 return;
262
263 ioctl (desc, TIOCGETP, &sg);
264
265 if (turnon) {
266#ifdef HAVE_TERMIO
267 sg.c_lflag &= ~(ICANON);
268#else
269 sg.sg_flags |= RAW;
270#endif
271 } else {
272#ifdef HAVE_TERMIO
273 sg.c_lflag |= ICANON;
274#else
275 sg.sg_flags &= ~(RAW);
276#endif
277 }
278 ioctl (desc, TIOCSETP, &sg);
279}
280
1f46923f
SC
281
282/* Read a character from the remote system, doing all the fancy
283 timeout stuff. */
284static int
285readchar ()
fa4b55a1 286{
1f46923f 287 char buf;
fa4b55a1 288
1f46923f 289 buf = '\0';
fa4b55a1
SC
290#ifdef HAVE_TERMIO
291 /* termio does the timeout for us. */
1f46923f 292 read (hms_desc, &buf, 1);
fa4b55a1
SC
293#else
294 alarm (timeout);
1f46923f
SC
295 if (read (hms_desc, &buf, 1) < 0)
296 {
297 if (errno == EINTR)
298 error ("Timeout reading from remote system.");
299 else
300 perror_with_name ("remote");
301 }
fa4b55a1
SC
302 alarm (0);
303#endif
1f46923f
SC
304
305 if (buf == '\0')
306 error ("Timeout reading from remote system.");
307
308 if (!quiet)
309 printf("%c",buf);
310
311 return buf & 0x7f;
fa4b55a1
SC
312}
313
fa4b55a1 314static int
1f46923f 315readchar_nofail ()
fa4b55a1
SC
316{
317 char buf;
318
319 buf = '\0';
320#ifdef HAVE_TERMIO
321 /* termio does the timeout for us. */
322 read (hms_desc, &buf, 1);
323#else
324 alarm (timeout);
325 if (read (hms_desc, &buf, 1) < 0)
1f46923f
SC
326 {
327 return 0;
328 }
fa4b55a1
SC
329 alarm (0);
330#endif
331
1f46923f
SC
332 if (buf == '\0')
333 {
334 return 0;
335 }
fa4b55a1
SC
336 return buf & 0x7f;
337}
338
339/* Keep discarding input from the remote system, until STRING is found.
340 Let the user break out immediately. */
341static void
342expect (string)
343 char *string;
344{
345 char *p = string;
346
347
348 immediate_quit = 1;
349 while (1)
350 {
351 if (readchar() == *p)
352 {
353 p++;
354 if (*p == '\0')
355 {
356 immediate_quit = 0;
357 return;
358 }
359 }
360 else
361 p = string;
362 }
363}
364
365/* Keep discarding input until we see the hms prompt.
366
367 The convention for dealing with the prompt is that you
368 o give your command
369 o *then* wait for the prompt.
370
371 Thus the last thing that a procedure does with the serial line
372 will be an expect_prompt(). Exception: hms_resume does not
373 wait for the prompt, because the terminal is being handed over
374 to the inferior. However, the next thing which happens after that
375 is a hms_wait which does wait for the prompt.
376 Note that this includes abnormal exit, e.g. error(). This is
377 necessary to prevent getting into states from which we can't
378 recover. */
379static void
380expect_prompt ()
381{
382
383 expect ("HMS>");
384}
385
386/* Get a hex digit from the remote system & return its value.
387 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
388static int
389get_hex_digit (ignore_space)
390 int ignore_space;
391{
392 int ch;
393 while (1)
394 {
395 ch = readchar ();
396 if (ch >= '0' && ch <= '9')
397 return ch - '0';
398 else if (ch >= 'A' && ch <= 'F')
399 return ch - 'A' + 10;
400 else if (ch >= 'a' && ch <= 'f')
401 return ch - 'a' + 10;
402 else if (ch == ' ' && ignore_space)
403 ;
404 else
405 {
406 expect_prompt ();
407 error ("Invalid hex digit from remote system.");
408 }
409 }
410}
411
412/* Get a byte from hms_desc and put it in *BYT. Accept any number
413 leading spaces. */
414static void
415get_hex_byte (byt)
416 char *byt;
417{
418 int val;
419
420 val = get_hex_digit (1) << 4;
421 val |= get_hex_digit (0);
422 *byt = val;
423}
424
425/* Read a 32-bit hex word from the hms, preceded by a space */
426static long
427get_hex_word()
428{
429 long val;
430 int j;
431
432 val = 0;
433 for (j = 0; j < 8; j++)
434 val = (val << 4) + get_hex_digit (j == 0);
435 return val;
436}
437/* Called when SIGALRM signal sent due to alarm() timeout. */
438#ifndef HAVE_TERMIO
439
440#ifndef __STDC__
441# ifndef volatile
442# define volatile /**/
443# endif
444#endif
445volatile int n_alarms;
446
447void
448hms_timer ()
449{
fa4b55a1
SC
450 n_alarms++;
451}
452#endif
453
fa4b55a1
SC
454
455/* Number of SIGTRAPs we need to simulate. That is, the next
456 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
457 SIGTRAP without actually waiting for anything. */
458
459static int need_artificial_trap = 0;
460
461void
462hms_kill(arg,from_tty)
463char *arg;
464int from_tty;
465{
fa4b55a1 466
fa4b55a1 467}
1f46923f
SC
468
469static check_open()
470{
471 if (!OPEN(hms_desc)) {
472 hms_open("",0);
473 }
474}
475
fa4b55a1
SC
476/*
477 * Download a file specified in 'args', to the hms.
478 */
479static void
480hms_load(args,fromtty)
481char *args;
482int fromtty;
483{
484 bfd *abfd;
485 asection *s;
486 int n;
487 char buffer[1024];
488
489 DENTER("hms_load()");
1f46923f
SC
490 check_open();
491
492 dcache_flush();
493 inferior_pid = 0;
fa4b55a1
SC
494 abfd = bfd_openr(args,"coff-h8300");
495 if (!abfd)
496 {
1f46923f 497 printf_filtered("Unable to open file %s\n", args);
fa4b55a1
SC
498 return;
499 }
500
501 if (bfd_check_format(abfd, bfd_object) ==0)
502 {
503 printf_filtered("File is not an object file\n");
504 return ;
505 }
506
507 s = abfd->sections;
508 while (s != (asection *)NULL)
509 {
510 if (s->flags & SEC_LOAD)
511 {
96743d3c 512 int i;
fa4b55a1 513
96743d3c
SC
514
515#define DELTA 2048
516 char *buffer = xmalloc(DELTA);
517 printf_filtered("%s: %4x .. %4x ",s->name, s->vma, s->vma + s->_raw_size);
518 for (i = 0; i < s->_raw_size; i+= DELTA)
519 {
520 int delta = DELTA;
521 if (delta > s->_raw_size - i)
522 delta = s->_raw_size - i ;
523
524 bfd_get_section_contents(abfd, s, buffer, i, delta);
525 hms_write_inferior_memory(s->vma + i, buffer, delta);
526 printf_filtered("*");
527 fflush(stdout);
528 }
529 printf_filtered( "\n");
fa4b55a1
SC
530 free(buffer);
531 }
532 s = s->next;
533 }
96743d3c 534
fa4b55a1
SC
535
536 DEXIT("hms_load()");
537}
538
539/* This is called not only when we first attach, but also when the
540 user types "run" after having attached. */
541void
542hms_create_inferior (execfile, args, env)
543 char *execfile;
544 char *args;
545 char **env;
546{
547 int entry_pt;
548
549 DENTER("hms_create_inferior()");
550
551 if (args && *args)
552 error ("Can't pass arguments to remote hms process.");
553
554 if (execfile == 0 || exec_bfd == 0)
555 error ("No exec file specified");
556
557 entry_pt = (int) bfd_get_start_address (exec_bfd);
1f46923f
SC
558 check_open();
559
fa4b55a1
SC
560 if (OPEN(hms_desc))
561 {
96743d3c 562char buffer[100];
fa4b55a1
SC
563 hms_kill(NULL,NULL);
564 hms_clear_breakpoints();
565 init_wait_for_inferior ();
566 /* Clear the input because what the hms sends back is different
567 * depending on whether it was running or not.
568 */
96743d3c
SC
569/*sprintf(buffer,"g %x", entry_pt);
570
571 hms_write_cr(buffer);
572 */
573hms_write_cr("");
1f46923f 574
fa4b55a1 575 expect_prompt();
fa4b55a1
SC
576
577
578 insert_breakpoints (); /* Needed to get correct instruction in cache */
579 proceed(entry_pt, -1, 0);
580
581
1f46923f 582 }
fa4b55a1
SC
583 DEXIT("hms_create_inferior()");
584}
585
586/* Translate baud rates from integers to damn B_codes. Unix should
587 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
588
589#ifndef B19200
590#define B19200 EXTA
591#endif
592#ifndef B38400
593#define B38400 EXTB
594#endif
595
596static struct {int rate, damn_b;} baudtab[] = {
1f46923f
SC
597 {9600, B9600},
598 {19200, B19200},
fa4b55a1 599 {300, B300},
fa4b55a1 600 {1200, B1200},
fa4b55a1
SC
601 {2400, B2400},
602 {4800, B4800},
fa4b55a1
SC
603 {-1, -1},
604};
605
606static int damn_b (rate)
607 int rate;
608{
609 int i;
610
611 for (i = 0; baudtab[i].rate != -1; i++)
612 if (rate == baudtab[i].rate) return baudtab[i].damn_b;
1f46923f 613 return B19200;
fa4b55a1
SC
614}
615
616
617/* Open a connection to a remote debugger.
618 NAME is the filename used for communication, then a space,
619 then the baud rate.
620 */
621
622static char *
623find_end_of_word(s)
624char *s;
625{
626 while (*s && !isspace(*s))
627 s++;
628 return s;
629}
630
631static char *get_word(p)
632char **p;
633{
634 char *s = *p;
635 char *word ;
636 char *copy;
637 size_t len;
638
639 while (isspace(*s))
640 s++;
641
642 word = s;
643
644 len = 0;
645
646 while (*s && !isspace(*s))
647 {
648 s++;
649 len++;
650
651 }
652 copy = xmalloc(len+1);
653 memcpy(copy, word, len);
654 copy[len] = 0;
655 *p = s;
656 return copy;
657}
658
659static int baudrate = 9600;
1f46923f
SC
660
661static int
662is_baudrate_right()
663{
664
665
666 /* Put this port into NORMAL mode, send the 'normal' character */
667 hms_write("\001", 1); /* Control A */
668 hms_write("\r", 1); /* Cr */
669
670 while ( readchar_nofail()) /* Skip noise we put there */
671 ;
672
673 hms_write("r");
674 if (readchar_nofail() == 'r')
675 return 1;
676
677 /* Not the right baudrate, or the board's not on */
678 return 0;
679
680
681}
682static void
683set_rate()
684{
685 TERMINAL sg;
686 ioctl (hms_desc, TIOCGETP, &sg);
687#ifdef HAVE_TERMIO
688 sg.c_cc[VMIN] = 0; /* read with timeout. */
689 sg.c_cc[VTIME] = timeout * 10;
690 sg.c_lflag &= ~(ICANON | ECHO);
691 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
692#else
693 sg.sg_ispeed = damn_b (baudrate);
694 sg.sg_ospeed = damn_b (baudrate);
695 sg.sg_flags |= RAW | ANYP;
696 sg.sg_flags &= ~ECHO;
697#endif
698
699 ioctl (hms_desc, TIOCSETP, &sg);
96743d3c 700
1f46923f
SC
701}
702
703static void
704get_baudrate_right()
705{
706
707 int which_rate = 0;
708
709 while (!is_baudrate_right())
710 {
96743d3c
SC
711 which_rate++;
712
1f46923f
SC
713 if (baudtab[which_rate].rate == -1)
714 {
715 which_rate = 0;
716 }
96743d3c 717
1f46923f
SC
718
719 baudrate = baudtab[which_rate].rate;
720 printf_filtered("Board not responding, trying %d baud\n",baudrate);
721 QUIT;
722 set_rate();
723 }
724}
725
fa4b55a1
SC
726static void
727hms_open (name, from_tty)
728 char *name;
729 int from_tty;
730{
1f46923f 731
fa4b55a1
SC
732 unsigned int prl;
733 char *p;
734
735 DENTER("hms_open()");
736 if(name == 0)
737 {
738 name = "";
739
740 }
741
fa4b55a1
SC
742 hms_close (0);
743
744 hms_desc = open (dev_name, O_RDWR);
745 if (hms_desc < 0)
746 perror_with_name (dev_name);
fa4b55a1 747
1f46923f
SC
748 set_rate();
749
750 dcache_init();
fa4b55a1
SC
751
752
fa4b55a1
SC
753 /* start_remote (); /* Initialize gdb process mechanisms */
754
755
756#ifndef HAVE_TERMIO
757#ifndef NO_SIGINTERRUPT
758 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
759 the read. */
760 if (siginterrupt (SIGALRM, 1) != 0)
761 perror ("hms_open: error in siginterrupt");
762#endif
763
764 /* Set up read timeout timer. */
765 if ((void (*)) signal (SIGALRM, hms_timer) == (void (*)) -1)
766 perror ("hms_open: error in signal");
767#endif
768
1f46923f 769 get_baudrate_right();
fa4b55a1
SC
770
771 /* Hello? Are you there? */
772 write (hms_desc, "\r", 1);
773
774 expect_prompt ();
775
776 /* Clear any break points */
777 hms_clear_breakpoints();
778
779
1f46923f 780 printf_filtered("Remote debugging on an H8/300 HMS via %s.\n",dev_name);
fa4b55a1
SC
781
782 DEXIT("hms_open()");
783}
784
785/* Close out all files and local state before this target loses control. */
786
787static void
788hms_close (quitting)
789 int quitting;
790{
791
792 DENTER("hms_close()");
793
794 /* Clear any break points */
795 hms_clear_breakpoints();
796
797 /* Put this port back into REMOTE mode */
798 if (OPEN(hms_desc)) {
799
800 sleep(1); /* Let any output make it all the way back */
801 write(hms_desc, "R\r", 2);
802 }
803
804 /* Due to a bug in Unix, fclose closes not only the stdio stream,
805 but also the file descriptor. So we don't actually close
806 hms_desc. */
807 if (OPEN(hms_desc))
808 close (hms_desc);
809
810 /* Do not try to close hms_desc again, later in the program. */
811
812 hms_desc = -1;
813
814 DEXIT("hms_close()");
815}
816
817/* Attach to the target that is already loaded and possibly running */
818static void
819hms_attach (args, from_tty)
820 char *args;
821 int from_tty;
822{
823
824 DENTER("hms_attach()");
fa4b55a1
SC
825
826 /* push_target(&hms_ops); /* This done in hms_open() */
827
828 mark_breakpoints_out ();
829
830 /* Send the hms a kill. It is ok if it is not already running */
831#if 0
832 fprintf(hms_stream, "K\r");
833 expect_prompt(); /* Slurp the echo */
834#endif
835 /* We will get a task spawn event immediately. */
836 init_wait_for_inferior ();
837 clear_proceed_status ();
838 stop_soon_quietly = 1;
839 wait_for_inferior ();
840 stop_soon_quietly = 0;
841 normal_stop ();
842 DEXIT("hms_attach()");
843}
844
845
846/* Terminate the open connection to the remote debugger.
847 Use this when you want to detach and do something else
848 with your gdb. */
849void
850hms_detach (args,from_tty)
851 char *args;
852 int from_tty;
853{
854 DENTER("hms_detach()");
855 if (OPEN(hms_desc)) { /* Send it on its way (tell it to continue) */
856 hms_clear_breakpoints();
857#if 0
858 fprintf(hms_stream,"G\r");
859#endif
860 }
861
862 pop_target(); /* calls hms_close to do the real work */
863 if (from_tty)
864 printf_filtered ("Ending remote %s debugging\n", target_shortname);
865 DEXIT("hms_detach()");
866}
867
868/* Tell the remote machine to resume. */
869
870void
871hms_resume (step, sig)
872 int step, sig;
873{
874 DENTER("hms_resume()");
1f46923f
SC
875 dcache_flush();
876
fa4b55a1
SC
877 if (step)
878 {
879 hms_write_cr("s");
96743d3c
SC
880 expect("Step>");
881
fa4b55a1
SC
882 /* Force the next hms_wait to return a trap. Not doing anything
883 about I/O from the target means that the user has to type
884 "continue" to see any. FIXME, this should be fixed. */
885 need_artificial_trap = 1;
886 }
887 else
888 {
889 hms_write_cr("g");
96743d3c 890 expect("g");
fa4b55a1
SC
891 }
892 DEXIT("hms_resume()");
893}
894
895/* Wait until the remote machine stops, then return,
896 storing status in STATUS just as `wait' would. */
897
898int
899hms_wait (status)
900 WAITTYPE *status;
901{
902 /* Strings to look for. '?' means match any single character.
903 Note that with the algorithm we use, the initial character
904 of the string cannot recur in the string, or we will not
905 find some cases of the string in the input. */
906
96743d3c 907 static char bpt[] = "At breakpoint:";
fa4b55a1
SC
908 /* It would be tempting to look for "\n[__exit + 0x8]\n"
909 but that requires loading symbols with "yc i" and even if
910 we did do that we don't know that the file has symbols. */
911 static char exitmsg[] = "HMS>";
912 char *bp = bpt;
913 char *ep = exitmsg;
914
915 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
916 char swallowed[50];
917 /* Current position in swallowed. */
918 char *swallowed_p = swallowed;
919
920 int ch;
921 int ch_handled;
922 int old_timeout = timeout;
923 int old_immediate_quit = immediate_quit;
1f46923f
SC
924 int swallowed_cr = 0;
925
fa4b55a1
SC
926 DENTER("hms_wait()");
927
928 WSETEXIT ((*status), 0);
929
930 if (need_artificial_trap != 0)
1f46923f
SC
931 {
932 WSETSTOP ((*status), SIGTRAP);
933 need_artificial_trap--;
934 return 0;
935 }
fa4b55a1 936
1f46923f
SC
937 timeout = 0; /* Don't time out -- user program is running. */
938 immediate_quit = 1; /* Helps ability to QUIT */
96743d3c
SC
939 while (1)
940 {
941 QUIT; /* Let user quit and leave process running */
942 ch_handled = 0;
943 ch = readchar ();
944 if (ch == *bp)
945 {
946 bp++;
947 if (*bp == '\0')
948 break;
949 ch_handled = 1;
950
951 *swallowed_p++ = ch;
952 }
953 else
954 {
955 bp = bpt;
956 }
957 if (ch == *ep || *ep == '?')
958 {
959 ep++;
960 if (*ep == '\0')
961 break;
962
963 if (!ch_handled)
964 *swallowed_p++ = ch;
965 ch_handled = 1;
966 }
967 else
968 {
969 ep = exitmsg;
970 }
971
972 if (!ch_handled) {
973 char *p;
974 /* Print out any characters which have been swallowed. */
975 for (p = swallowed; p < swallowed_p; ++p)
976 putc (*p, stdout);
977 swallowed_p = swallowed;
fa4b55a1
SC
978
979
96743d3c
SC
980 if ((ch != '\r' && ch != '\n') || swallowed_cr>10)
981 {
982 putc (ch, stdout);
983 swallowed_cr = 10;
fa4b55a1 984 }
96743d3c
SC
985 swallowed_cr ++;
986
987 }
988 }
fa4b55a1
SC
989 if (*bp== '\0')
990 {
991 WSETSTOP ((*status), SIGTRAP);
992 expect_prompt();
993 }
994 else
995 {
996 WSETEXIT ((*status), 0);
997 }
998
999 timeout = old_timeout;
1000 immediate_quit = old_immediate_quit;
fa4b55a1
SC
1001 DEXIT("hms_wait()");
1002 return 0;
1003}
1004
1005/* Return the name of register number REGNO
1006 in the form input and output by hms.
1007
1008 Returns a pointer to a static buffer containing the answer. */
1009static char *
1010get_reg_name (regno)
1011 int regno;
1012{
1013static char *rn[NUM_REGS]= REGISTER_NAMES;
1014
1015
1016 return rn[regno];
1017
1018}
1019
1020/* Read the remote registers. */
1021static int gethex(length, start, ok)
1022unsigned int length;
1023char *start;
1024int *ok;
1025{
1026 int result = 0;
1027 while (length--)
1028 {
1029 result <<= 4 ;
1030 if (*start >='a' && *start <= 'f')
1031 {
1032 result += *start - 'a' + 10;
1033 }
1034 else if (*start >='A' && *start <= 'F')
1035 {
1036 result += *start - 'A' + 10;
1037 }
1038 else if (*start >='0' && *start <= '9')
1039 {
1040 result += *start - '0' ;
1041 }
1042 else *ok = 0;
1043 start++;
1044
1045 }
1046 return result;
1047}
1048static int
1049timed_read(buf, n, timeout)
1050char *buf;
1051
1052{
1053 int i;
1054 char c;
1055 i = 0;
1056 while (i < n)
1057 {
1058 c = readchar();
1059
1060 if (c == 0) return i;
1061 buf[i] = c;
1062 i++;
1063
1064 }
1065 return i;
1066
1067}
1068hms_write(a,l)
1069char *a;
1070{
1071 int i;
1072 write(hms_desc,a,l);
96743d3c
SC
1073 if (!quiet)
1074 for (i = 0; i < l ; i++)
1075 {
1076 printf("%c", a[i]);
1077 }
fa4b55a1
SC
1078}
1079
1f46923f
SC
1080hms_write_cr(s)
1081char *s;
fa4b55a1
SC
1082{
1083hms_write( s, strlen(s));
1f46923f
SC
1084hms_write("\r",1);
1085}
1086
1087static void
1088hms_fetch_registers ()
fa4b55a1
SC
1089{
1090#define REGREPLY_SIZE 79
1091 char linebuf[REGREPLY_SIZE+1];
1092 int i;
1093 int s ;
1094 int gottok;
1095
1f46923f
SC
1096 REGISTER_TYPE reg[NUM_REGS];
1097 int foo[8];
fa4b55a1
SC
1098 check_open();
1099
1100 do
1101 {
1102
1103 hms_write_cr("r");
1104 s = timed_read(linebuf, REGREPLY_SIZE, 1);
1105
1106
1107 linebuf[REGREPLY_SIZE] = 0;
1108 gottok = 0;
1109 if (linebuf[0] == 'r' &&
fa4b55a1
SC
1110 linebuf[3] == 'P' &&
1111 linebuf[4] == 'C' &&
1112 linebuf[5] == '=' &&
1113 linebuf[75] == 'H' &&
1114 linebuf[76] == 'M' &&
1115 linebuf[77] == 'S')
1116 {
1117 /*
1118 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
1119 5436789012345678901234567890123456789012345678901234567890123456789012
1120 0 1 2 3 4 5 6
1121 */
1122 gottok = 1;
1123
1124 reg[PC_REGNUM] = gethex(4,linebuf+6, &gottok);
1125 reg[CCR_REGNUM] = gethex(2,linebuf+15, &gottok);
1126 for (i = 0; i < 8; i++)
1127 {
1128 reg[i] = gethex(4, linebuf+34+5*i, &gottok);
1129 }
1130 }
1131 }
1132 while (!gottok);
1133 for (i = 0; i < NUM_REGS; i++)
1134 {
1135 supply_register (i, reg+i);
1136 }
1137}
1138
1139/* Fetch register REGNO, or all registers if REGNO is -1.
1140 */
1141static void
1142hms_fetch_register (regno)
1143 int regno;
1144{
1145
1146 hms_fetch_registers ();
1147
1148}
1149
1150/* Store the remote registers from the contents of the block REGS. */
1151
1152static int
1153hms_store_registers ()
1154{
1155 int i;
1156 for (i = 0; i < NUM_REGS; i++)
1157 hms_store_register(i);
1158 return 0;
1159
1160}
1161
1162/* Store register REGNO, or all if REGNO == -1.
1163 Return errno value. */
1164int
1165hms_store_register (regno)
1166 int regno;
1167{
1168
1f46923f 1169 /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
fa4b55a1
SC
1170 if (regno == -1)
1171 hms_store_registers ();
1172 else
1173 {
1174 char *name = get_reg_name (regno);
1175 char buffer[100];
1176 sprintf(buffer,"r %s=%x", name, read_register(regno));
1177 hms_write_cr(buffer);
1178 expect_prompt();
1179 }
1180
1181 DEXIT("hms_store_registers()");
1182 return 0;
1183}
1184
1185/* Get ready to modify the registers array. On machines which store
1186 individual registers, this doesn't need to do anything. On machines
1187 which store all the registers in one fell swoop, this makes sure
1188 that registers contains all the registers from the program being
1189 debugged. */
1190
1191void
1192hms_prepare_to_store ()
1193{
1194 /* Do nothing, since we can store individual regs */
1195}
1196
1197static CORE_ADDR
1198translate_addr(addr)
1199CORE_ADDR addr;
1200{
1201
1202 return(addr);
1203
1204}
1205
1206/* Read a word from remote address ADDR and return it.
1207 * This goes through the data cache.
1208 */
1209int
1210hms_fetch_word (addr)
1211 CORE_ADDR addr;
1212{
1213 return dcache_fetch (addr);
1214}
1215
1216/* Write a word WORD into remote address ADDR.
1217 This goes through the data cache. */
1218
1219void
1220hms_store_word (addr, word)
1221 CORE_ADDR addr;
1222 int word;
1223{
1224 dcache_poke (addr, word);
1225}
1226
1227int
1228hms_xfer_inferior_memory(memaddr, myaddr, len, write, target)
1229 CORE_ADDR memaddr;
1230 char *myaddr;
1231 int len;
1232 int write;
1233 struct target_ops *target; /* ignored */
1234{
1235 register int i;
1236 /* Round starting address down to longword boundary. */
1237 register CORE_ADDR addr;
1238 /* Round ending address up; get number of longwords that makes. */
1239 register int count;
1240 /* Allocate buffer of that many longwords. */
1241 register int *buffer ;
1242
1243 memaddr &= 0xffff;
1244 addr = memaddr & - sizeof (int);
1245 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1246
1f46923f 1247
fa4b55a1
SC
1248 buffer = (int *)alloca (count * sizeof (int));
1249 if (write)
1250 {
1251 /* Fill start and end extra bytes of buffer with existing memory data. */
1252
1253 if (addr != memaddr || len < (int)sizeof (int)) {
1254 /* Need part of initial word -- fetch it. */
1255 buffer[0] = hms_fetch_word (addr);
1256 }
1257
1258 if (count > 1) /* FIXME, avoid if even boundary */
1259 {
1260 buffer[count - 1]
1261 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1262 }
1263
1264 /* Copy data to be written over corresponding part of buffer */
1265
1266 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1267
1268 /* Write the entire buffer. */
1269
1270 for (i = 0; i < count; i++, addr += sizeof (int))
1271 {
1272 errno = 0;
1273 hms_store_word (addr, buffer[i]);
1274 if (errno)
1275 {
1276
1277 return 0;
1278 }
1279
1280 }
1281 }
1282 else
1283 {
1284 /* Read all the longwords */
1285 for (i = 0; i < count; i++, addr += sizeof (int))
1286 {
1287 errno = 0;
1288 buffer[i] = hms_fetch_word (addr);
1289 if (errno)
1290 {
1291 return 0;
1292 }
1293 QUIT;
1294 }
1295
1296 /* Copy appropriate bytes out of the buffer. */
1297 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1298 }
1299
1300
1301 return len;
1302}
1303
1304#if 0
1305int
1306hms_xfer_inferior_memory (memaddr, myaddr, len, write)
1307 CORE_ADDR memaddr;
1308 char *myaddr;
1309 int len;
1310 int write;
1311{
1312 memaddr &= 0xffff;
1313 if (write)
1314 return hms_write_inferior_memory (memaddr, myaddr, len);
1315 else
1316 return hms_read_inferior_memory (memaddr, myaddr, len);
1317
1318}
1319#endif
1320
1321int
1322hms_write_inferior_memory (memaddr, myaddr, len)
1323 CORE_ADDR memaddr;
1324 char *myaddr;
1325 int len;
1326{
1327
1328 bfd *abfd = bfd_openw(dev_name, "srec");
1329 asection *a;
1330
1331 bfd_set_format(abfd, bfd_object);
1332 a = bfd_make_section(abfd, ".text");
1333 a->vma = memaddr;
1334 a->_raw_size = len;
1335 a->flags = SEC_LOAD | SEC_HAS_CONTENTS;
1336 hms_write_cr("tl"); /* tell hms here comes the recs */
1337 bfd_set_section_contents(abfd, a, myaddr, 0, len);
1338 bfd_close(abfd);
1339
1340 expect_prompt();
1341}
1342
1343void
1344hms_files_info ()
1345{
1346 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1347 dev_name, baudrate, bfd_get_filename(exec_bfd));
1348 printf_filtered("\ton an H8/300 processor.\n");
1349}
1350
1351/* Copy LEN bytes of data from debugger memory at MYADDR
1352 to inferior's memory at MEMADDR. Returns errno value.
1353 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1354 */
1355
1356
1357/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1358 at debugger address MYADDR. Returns errno value. */
1359int
1360hms_read_inferior_memory(memaddr, myaddr, len)
1361 CORE_ADDR memaddr;
1362 char *myaddr;
1363 int len;
1364{
1365 /* Align to nearest low 16 bits */
1366 int i;
1367
1368#if 0
1369 CORE_ADDR start = memaddr & ~0xf;
1370 CORE_ADDR end = ((memaddr + len +16) & ~0xf) -1;
1371#endif
1372 CORE_ADDR start = memaddr;
1373 CORE_ADDR end = memaddr + len -1;
1374
1375 int ok =1;
1376
1377 /*
1378 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1379 012345678901234567890123456789012345678901234567890123456789012345
1380 0 1 2 3 4 5 6
1381 */
1382 char buffer[66];
1383 if (memaddr & 0xf) abort();
1384 if (len != 16) abort();
1385
96743d3c 1386 sprintf(buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
fa4b55a1
SC
1387 hms_write_cr(buffer);
1388 /* drop the echo and newline*/
1389 for (i = 0; i < 13; i++)
1390 readchar();
1391
1392
1393
1394 /* Grab the lines as they come out and fill the area */
1395 /* Skip over cr */
1396 while(1)
1397 {
1398 int p;
1399 int i;
1400 int addr;
1401 size_t idx;
1402
1403 char byte[16];
1404 buffer[0] = readchar();
1405 if (buffer[0] == 'M')
1406 break;
1407 for (i = 1; i < 66; i++)
1408 buffer[i] = readchar();
1409
1410 /* Now parse the line */
1411
1412 addr = gethex(4, buffer, &ok);
1413 idx = 6;
1414 for (p = 0; p < 16; p+=2)
1415 {
1416 byte[p] = gethex(2, buffer + idx, &ok);
1417 byte[p+1] = gethex(2, buffer+ idx + 2, &ok);
1418 idx+=5;
1419
1420 }
1421
1422
1423 for (p = 0; p<16;p++)
1424 {
1425 if (addr + p >= memaddr &&
1426 addr + p < memaddr + len)
1427 {
1428 myaddr[ (addr + p)-memaddr] = byte[p];
1429
1430 }
1431
1432 }
1433 }
1434
1435
1436
96743d3c 1437 hms_write_cr(" ");
fa4b55a1
SC
1438 expect_prompt();
1439
1440
1441
1442
1443 return len;
1444
1445}
1446
1447/* This routine is run as a hook, just before the main command loop is
1448 entered. If gdb is configured for the H8, but has not had its
1449 target specified yet, this will loop prompting the user to do so.
1450*/
1451
1452hms_before_main_loop ()
1453{
1454 char ttyname[100];
1455 char *p, *p2;
1456 extern FILE *instream;
1457 extern jmp_buf to_top_level;
1458
1459 push_target (&hms_ops);
1460#if 0
1461
1462 while (current_target != &hms_ops) {
1463 /* remote tty not specified yet */
1464 if ( instream == stdin ){
1465 printf("\nEnter device and filename, or \"quit\" to quit: ");
1466 fflush( stdout );
1467 }
1468 fgets( ttyname, sizeof(ttyname)-1, stdin );
1469
1470 if ( !strcmp("quit", ttyname) ){
1471 exit(1);
1472 }
1473
1474 hms_open( ttyname, 1 );
1475
1476 /* Now that we have a tty open for talking to the remote machine,
1477 download the executable file if one was specified. */
1478 if ( !setjmp(to_top_level) && exec_bfd ) {
1479 target_load (bfd_get_filename (exec_bfd), 1);
1480 }
1481 }
1482#endif
1483}
1484
1485
1486#define MAX_BREAKS 16
1487static int num_brkpts=0;
1488static int
1489hms_insert_breakpoint(addr, save)
1490CORE_ADDR addr;
1491char *save; /* Throw away, let hms save instructions */
1492{
1493
1494 DENTER("hms_insert_breakpoint()");
1495 check_open();
1496
1497 if (num_brkpts < MAX_BREAKS) {
1498 char buffer[100];
1499 num_brkpts++;
1500 sprintf(buffer,"b %x", addr & 0xffff);
1501 hms_write_cr(buffer);
1502 expect_prompt ();
1503 DEXIT("hms_insert_breakpoint() success");
1504 return(0); /* Success */
1505 } else {
1506 fprintf_filtered(stderr,
1507 "Too many break points, break point not installed\n");
1508 DEXIT("hms_insert_breakpoint() failure");
1509 return(1); /* Failure */
1510 }
1511
1512
1513}
1514static int
1515hms_remove_breakpoint(addr, save)
1516CORE_ADDR addr;
1517char *save; /* Throw away, let hms save instructions */
1518{
1519 DENTER("hms_remove_breakpoint()");
1520 if (num_brkpts > 0) {
1521 char buffer[100];
1522
1523 num_brkpts--;
1524 sprintf(buffer,"b - %x", addr & 0xffff);
1525 hms_write_cr(buffer);
1526 expect_prompt();
1527
1528 }
1529 DEXIT("hms_remove_breakpoint()");
1530 return(0);
1531}
1532
1533/* Clear the hmss notion of what the break points are */
1534static int
1535hms_clear_breakpoints()
1536{
1537
1538 DENTER("hms_clear_breakpoint()");
1539 if (OPEN(hms_desc)) {
1540 hms_write_cr("b -");
1541 expect_prompt ();
1542 }
1543 num_brkpts = 0;
1544
1545 DEXIT("hms_clear_breakpoint()");
1546}
1547static void
1548hms_mourn()
1549{
1550 DENTER("hms_mourn()");
1551 hms_clear_breakpoints();
1552/* pop_target (); /* Pop back to no-child state */
1553 generic_mourn_inferior ();
1554 DEXIT("hms_mourn()");
1555}
1556
1557/* Display everthing we read in from the hms until we match/see the
1558 * specified string
1559 */
1560static int
1561display_until(str)
1562char *str;
1563{
1564 int i=0,j,c;
1565
1566 while (c=readchar()) {
1567 if (c==str[i]) {
1568 i++;
1569 if (i == strlen(str)) return;
1570 } else {
1571 if (i) {
1572 for (j=0 ; j<i ; j++) /* Put everthing we matched */
1573 putchar(str[j]);
1574 i=0;
1575 }
1576 putchar(c);
1577 }
1578 }
1579
1580}
1581
1582
1583/* Put a command string, in args, out to the hms. The hms is assumed to
1584 be in raw mode, all writing/reading done through hms_desc.
1585 Ouput from the hms is placed on the users terminal until the
1586 prompt from the hms is seen.
1587 FIXME: Can't handle commands that take input. */
1588
1589void
1590hms_com (args, fromtty)
1591 char *args;
1592 int fromtty;
1593{
1594 check_open();
1595
1596 if (!args) return;
1597
1598 /* Clear all input so only command relative output is displayed */
1599
1600
1601 hms_write_cr(args);
1602 hms_write("\030",1);
1603 expect_prompt();
1604
1605}
1606
1607/* Define the target subroutine names */
1608
1609struct target_ops hms_ops = {
1610 "hms", "Remote HMS monitor",
1611"Use the H8 evaluation board running the HMS monitor connected\n\
1612by a serial line.",
1613
1614 hms_open, hms_close,
1615 hms_attach, hms_detach, hms_resume, hms_wait,
1616 hms_fetch_register, hms_store_register,
1617 hms_prepare_to_store, 0, 0, /* conv_to, conv_from */
1618 hms_xfer_inferior_memory,
1619 hms_files_info,
1620 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1621 0, 0, 0, 0, 0, /* Terminal handling */
1622 hms_kill, /* FIXME, kill */
1623 hms_load,
fa4b55a1
SC
1624 0, /* lookup_symbol */
1625 hms_create_inferior, /* create_inferior */
1626 hms_mourn, /* mourn_inferior FIXME */
1627 process_stratum, 0, /* next */
1628 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1629 0,0, /* Section pointers */
1630 OPS_MAGIC, /* Always the last thing */
1631};
1632
1633
1634hms_quiet()
1635{
1636 quiet = ! quiet;
1637}
1638
1639hms_device(s)
1640char *s;
1641{
1642 if (s) {
1643 dev_name = get_word(&s);
1644 }
1645}
1646
96743d3c
SC
1647static
1648hms_speed(s)
fa4b55a1
SC
1649char *s;
1650{
96743d3c
SC
1651check_open();
1652
1653
fa4b55a1
SC
1654 if (s)
1655 {
1656 char buffer[100];
1657 int newrate = atoi(s);
1658 int which = 0;
1659 while (baudtab[which].rate != newrate)
1660 {
1661 if (baudtab[which].rate == -1)
1662 {
1663 error("Can't use %d baud\n", newrate);
1664 }
1665 which++;
1666 }
1667
fa4b55a1 1668 printf_filtered("Checking target is in sync\n");
fa4b55a1
SC
1669
1670 get_baudrate_right();
1671 baudrate = newrate;
1672 printf_filtered("Sending commands to set target to %d\n",
1673 baudrate);
1674
1675 sprintf(buffer, "tm %d. N 8 1", baudrate);
96743d3c 1676 hms_write_cr(buffer);
fa4b55a1
SC
1677 }
1678}
1679
1680/***********************************************************************/
1681
1682void
1683_initialize_remote_hms ()
1684{
1685 add_target (&hms_ops);
1686 add_com ("hms <command>", class_obscure, hms_com,
1687 "Send a command to the HMS monitor.");
1688 add_com ("snoop", class_obscure, hms_quiet,
1689 "Show what commands are going to the monitor");
1690 add_com ("device", class_obscure, hms_device,
1691 "Set the terminal line for HMS communications");
1692
1693 add_com ("speed", class_obscure, hms_speed,
1694 "Set the terminal line speed for HMS communications");
1695
1696}
1697
1698
This page took 0.109327 seconds and 4 git commands to generate.