SVR4 names don't have underscores, according to the ABI.
[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 237
ae0ea72e 238static CONST char *dev_name;
1f46923f 239
fa4b55a1
SC
240
241/* Descriptor for I/O to remote machine. Initialize it to -1 so that
242 hms_open knows that we don't have a file open when the program
243 starts. */
fa4b55a1 244
1f46923f 245
ae0ea72e
SC
246int is_open = 0;
247int check_open()
fa4b55a1 248{
ae0ea72e
SC
249 if (!is_open)
250 {
251 error("remote device not open");
fa4b55a1 252 }
fa4b55a1
SC
253}
254
ae0ea72e
SC
255#define ON 1
256#define OFF 0
1f46923f
SC
257
258/* Read a character from the remote system, doing all the fancy
259 timeout stuff. */
260static int
261readchar ()
fa4b55a1 262{
ae0ea72e
SC
263 int ok;
264 int buf;
265 buf = serial_timedreadchar(timeout, &ok);
1f46923f 266
ae0ea72e 267 if (!ok)
1f46923f
SC
268 error ("Timeout reading from remote system.");
269
270 if (!quiet)
271 printf("%c",buf);
272
273 return buf & 0x7f;
fa4b55a1
SC
274}
275
fa4b55a1 276static int
1f46923f 277readchar_nofail ()
fa4b55a1 278{
ae0ea72e
SC
279 int ok;
280 int buf;
281 buf = serial_timedreadchar(timeout, &ok);
282 if (!ok) buf = 0;
283 if (!quiet)
284 printf("%c",buf);
285
fa4b55a1 286 return buf & 0x7f;
ae0ea72e 287
fa4b55a1
SC
288}
289
290/* Keep discarding input from the remote system, until STRING is found.
291 Let the user break out immediately. */
292static void
293expect (string)
294 char *string;
295{
296 char *p = string;
297
298
299 immediate_quit = 1;
300 while (1)
301 {
302 if (readchar() == *p)
303 {
304 p++;
305 if (*p == '\0')
306 {
307 immediate_quit = 0;
308 return;
309 }
310 }
311 else
312 p = string;
313 }
314}
315
316/* Keep discarding input until we see the hms prompt.
317
318 The convention for dealing with the prompt is that you
319 o give your command
320 o *then* wait for the prompt.
321
322 Thus the last thing that a procedure does with the serial line
323 will be an expect_prompt(). Exception: hms_resume does not
324 wait for the prompt, because the terminal is being handed over
325 to the inferior. However, the next thing which happens after that
326 is a hms_wait which does wait for the prompt.
327 Note that this includes abnormal exit, e.g. error(). This is
328 necessary to prevent getting into states from which we can't
329 recover. */
330static void
331expect_prompt ()
332{
fa4b55a1
SC
333 expect ("HMS>");
334}
335
336/* Get a hex digit from the remote system & return its value.
337 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
338static int
339get_hex_digit (ignore_space)
340 int ignore_space;
341{
342 int ch;
343 while (1)
344 {
345 ch = readchar ();
346 if (ch >= '0' && ch <= '9')
347 return ch - '0';
348 else if (ch >= 'A' && ch <= 'F')
349 return ch - 'A' + 10;
350 else if (ch >= 'a' && ch <= 'f')
351 return ch - 'a' + 10;
352 else if (ch == ' ' && ignore_space)
353 ;
354 else
355 {
356 expect_prompt ();
357 error ("Invalid hex digit from remote system.");
358 }
359 }
360}
361
362/* Get a byte from hms_desc and put it in *BYT. Accept any number
363 leading spaces. */
364static void
365get_hex_byte (byt)
366 char *byt;
367{
368 int val;
369
370 val = get_hex_digit (1) << 4;
371 val |= get_hex_digit (0);
372 *byt = val;
373}
374
375/* Read a 32-bit hex word from the hms, preceded by a space */
376static long
377get_hex_word()
378{
379 long val;
380 int j;
381
382 val = 0;
383 for (j = 0; j < 8; j++)
384 val = (val << 4) + get_hex_digit (j == 0);
385 return val;
386}
387/* Called when SIGALRM signal sent due to alarm() timeout. */
fa4b55a1 388
fa4b55a1 389
fa4b55a1
SC
390
391/* Number of SIGTRAPs we need to simulate. That is, the next
392 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
393 SIGTRAP without actually waiting for anything. */
394
395static int need_artificial_trap = 0;
396
397void
398hms_kill(arg,from_tty)
399char *arg;
400int from_tty;
401{
fa4b55a1 402
fa4b55a1 403}
1f46923f 404
ae0ea72e 405
1f46923f 406
fa4b55a1
SC
407/*
408 * Download a file specified in 'args', to the hms.
409 */
410static void
411hms_load(args,fromtty)
412char *args;
413int fromtty;
414{
415 bfd *abfd;
416 asection *s;
417 int n;
418 char buffer[1024];
ae0ea72e
SC
419
420
fa4b55a1 421 DENTER("hms_load()");
1f46923f
SC
422 check_open();
423
424 dcache_flush();
425 inferior_pid = 0;
fa4b55a1
SC
426 abfd = bfd_openr(args,"coff-h8300");
427 if (!abfd)
428 {
1f46923f 429 printf_filtered("Unable to open file %s\n", args);
fa4b55a1
SC
430 return;
431 }
432
433 if (bfd_check_format(abfd, bfd_object) ==0)
434 {
435 printf_filtered("File is not an object file\n");
436 return ;
437 }
438
439 s = abfd->sections;
440 while (s != (asection *)NULL)
441 {
442 if (s->flags & SEC_LOAD)
443 {
96743d3c 444 int i;
fa4b55a1 445
96743d3c 446
ae0ea72e 447#define DELTA 1024
96743d3c 448 char *buffer = xmalloc(DELTA);
ae0ea72e 449 printf_filtered("%s\t: 0x%4x .. 0x%4x ",s->name, s->vma, s->vma + s->_raw_size);
96743d3c
SC
450 for (i = 0; i < s->_raw_size; i+= DELTA)
451 {
452 int delta = DELTA;
453 if (delta > s->_raw_size - i)
454 delta = s->_raw_size - i ;
455
456 bfd_get_section_contents(abfd, s, buffer, i, delta);
457 hms_write_inferior_memory(s->vma + i, buffer, delta);
458 printf_filtered("*");
459 fflush(stdout);
460 }
ae0ea72e 461 printf_filtered( "\n");
fa4b55a1
SC
462 free(buffer);
463 }
464 s = s->next;
465 }
ae0ea72e
SC
466 sprintf(buffer, "r PC=%x", abfd->start_address);
467 hms_write_cr(buffer);
468 expect_prompt();
fa4b55a1
SC
469
470 DEXIT("hms_load()");
471}
472
473/* This is called not only when we first attach, but also when the
474 user types "run" after having attached. */
475void
476hms_create_inferior (execfile, args, env)
477 char *execfile;
478 char *args;
479 char **env;
480{
481 int entry_pt;
ae0ea72e 482 char buffer[100];
fa4b55a1
SC
483 DENTER("hms_create_inferior()");
484
485 if (args && *args)
486 error ("Can't pass arguments to remote hms process.");
487
488 if (execfile == 0 || exec_bfd == 0)
489 error ("No exec file specified");
490
491 entry_pt = (int) bfd_get_start_address (exec_bfd);
1f46923f 492 check_open();
1f46923f 493
fa4b55a1 494
ae0ea72e
SC
495 hms_kill(NULL,NULL);
496 hms_clear_breakpoints();
497 init_wait_for_inferior ();
498 hms_write_cr("");
499 expect_prompt();
fa4b55a1 500
ae0ea72e
SC
501 insert_breakpoints (); /* Needed to get correct instruction in cache */
502 proceed(entry_pt, -1, 0);
fa4b55a1
SC
503
504
fa4b55a1
SC
505 DEXIT("hms_create_inferior()");
506}
507
fa4b55a1
SC
508
509/* Open a connection to a remote debugger.
510 NAME is the filename used for communication, then a space,
511 then the baud rate.
512 */
513
514static char *
515find_end_of_word(s)
516char *s;
517{
518 while (*s && !isspace(*s))
519 s++;
520 return s;
521}
522
523static char *get_word(p)
524char **p;
525{
526 char *s = *p;
527 char *word ;
528 char *copy;
529 size_t len;
530
531 while (isspace(*s))
532 s++;
533
534 word = s;
535
536 len = 0;
537
538 while (*s && !isspace(*s))
539 {
540 s++;
541 len++;
542
543 }
544 copy = xmalloc(len+1);
545 memcpy(copy, word, len);
546 copy[len] = 0;
547 *p = s;
548 return copy;
549}
550
551static int baudrate = 9600;
1f46923f
SC
552
553static int
554is_baudrate_right()
555{
ae0ea72e 556 int ok;
1f46923f 557 /* Put this port into NORMAL mode, send the 'normal' character */
ae0ea72e 558
1f46923f
SC
559 hms_write("\001", 1); /* Control A */
560 hms_write("\r", 1); /* Cr */
1f46923f 561
ae0ea72e
SC
562 while (1)
563 {
564 serial_timedreadchar(timeout, &ok);
565 if (!ok) break;
566 }
567
568 hms_write("r",1);
569
1f46923f
SC
570 if (readchar_nofail() == 'r')
571 return 1;
572
573 /* Not the right baudrate, or the board's not on */
574 return 0;
1f46923f
SC
575}
576static void
577set_rate()
578{
ae0ea72e
SC
579 if (!serial_setbaudrate(baudrate))
580 error("Can't set baudrate");
1f46923f
SC
581}
582
583static void
584get_baudrate_right()
585{
1f46923f
SC
586 while (!is_baudrate_right())
587 {
ae0ea72e
SC
588 baudrate = serial_nextbaudrate(baudrate);
589 if (baudrate == 0) {
590 printf_filtered("Board not yet in sync\n");
591 break;
1f46923f 592 }
1f46923f
SC
593 printf_filtered("Board not responding, trying %d baud\n",baudrate);
594 QUIT;
ae0ea72e 595 serial_setbaudrate(baudrate);
1f46923f
SC
596 }
597}
598
fa4b55a1
SC
599static void
600hms_open (name, from_tty)
601 char *name;
602 int from_tty;
603{
1f46923f 604
fa4b55a1
SC
605 unsigned int prl;
606 char *p;
607
608 DENTER("hms_open()");
609 if(name == 0)
610 {
611 name = "";
612
613 }
ae0ea72e
SC
614 if (is_open)
615 hms_close (0);
616 if (name && strlen(name))
617 dev_name = strdup(name);
618 if (!serial_open(dev_name))
619 perror_with_name ((char *)dev_name);
620 serial_raw();
621 is_open = 1;
fa4b55a1 622
1f46923f
SC
623
624 dcache_init();
fa4b55a1
SC
625
626
fa4b55a1
SC
627 /* start_remote (); /* Initialize gdb process mechanisms */
628
1f46923f 629 get_baudrate_right();
fa4b55a1
SC
630
631 /* Hello? Are you there? */
ae0ea72e 632 serial_write("\r",1);
fa4b55a1
SC
633 expect_prompt ();
634
635 /* Clear any break points */
636 hms_clear_breakpoints();
637
638
ae0ea72e 639 printf_filtered("Connected to remote H8/300 HMS system.\n");
fa4b55a1
SC
640
641 DEXIT("hms_open()");
642}
643
644/* Close out all files and local state before this target loses control. */
645
646static void
647hms_close (quitting)
648 int quitting;
649{
650
651 DENTER("hms_close()");
652
653 /* Clear any break points */
654 hms_clear_breakpoints();
655
656 /* Put this port back into REMOTE mode */
ae0ea72e
SC
657 sleep(1); /* Let any output make it all the way back */
658 serial_write("R\r", 2);
659 serial_close();
660 is_open = 0;
fa4b55a1
SC
661
662 DEXIT("hms_close()");
663}
664
665/* Attach to the target that is already loaded and possibly running */
666static void
667hms_attach (args, from_tty)
668 char *args;
669 int from_tty;
670{
671
672 DENTER("hms_attach()");
fa4b55a1
SC
673
674 /* push_target(&hms_ops); /* This done in hms_open() */
675
676 mark_breakpoints_out ();
677
678 /* Send the hms a kill. It is ok if it is not already running */
679#if 0
680 fprintf(hms_stream, "K\r");
681 expect_prompt(); /* Slurp the echo */
682#endif
683 /* We will get a task spawn event immediately. */
684 init_wait_for_inferior ();
685 clear_proceed_status ();
686 stop_soon_quietly = 1;
687 wait_for_inferior ();
688 stop_soon_quietly = 0;
689 normal_stop ();
690 DEXIT("hms_attach()");
691}
692
693
694/* Terminate the open connection to the remote debugger.
695 Use this when you want to detach and do something else
696 with your gdb. */
697void
698hms_detach (args,from_tty)
699 char *args;
700 int from_tty;
701{
702 DENTER("hms_detach()");
ae0ea72e
SC
703 if (is_open)
704 {
fa4b55a1 705 hms_clear_breakpoints();
fa4b55a1
SC
706 }
707
708 pop_target(); /* calls hms_close to do the real work */
709 if (from_tty)
710 printf_filtered ("Ending remote %s debugging\n", target_shortname);
711 DEXIT("hms_detach()");
712}
713
714/* Tell the remote machine to resume. */
715
716void
717hms_resume (step, sig)
718 int step, sig;
719{
720 DENTER("hms_resume()");
1f46923f
SC
721 dcache_flush();
722
fa4b55a1
SC
723 if (step)
724 {
725 hms_write_cr("s");
96743d3c
SC
726 expect("Step>");
727
fa4b55a1
SC
728 /* Force the next hms_wait to return a trap. Not doing anything
729 about I/O from the target means that the user has to type
730 "continue" to see any. FIXME, this should be fixed. */
731 need_artificial_trap = 1;
732 }
733 else
734 {
735 hms_write_cr("g");
96743d3c 736 expect("g");
fa4b55a1
SC
737 }
738 DEXIT("hms_resume()");
739}
740
741/* Wait until the remote machine stops, then return,
742 storing status in STATUS just as `wait' would. */
743
744int
745hms_wait (status)
746 WAITTYPE *status;
747{
748 /* Strings to look for. '?' means match any single character.
749 Note that with the algorithm we use, the initial character
750 of the string cannot recur in the string, or we will not
751 find some cases of the string in the input. */
752
96743d3c 753 static char bpt[] = "At breakpoint:";
fa4b55a1
SC
754 /* It would be tempting to look for "\n[__exit + 0x8]\n"
755 but that requires loading symbols with "yc i" and even if
756 we did do that we don't know that the file has symbols. */
757 static char exitmsg[] = "HMS>";
758 char *bp = bpt;
759 char *ep = exitmsg;
760
761 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
762 char swallowed[50];
763 /* Current position in swallowed. */
764 char *swallowed_p = swallowed;
765
766 int ch;
767 int ch_handled;
768 int old_timeout = timeout;
769 int old_immediate_quit = immediate_quit;
1f46923f
SC
770 int swallowed_cr = 0;
771
fa4b55a1
SC
772 DENTER("hms_wait()");
773
774 WSETEXIT ((*status), 0);
775
776 if (need_artificial_trap != 0)
1f46923f
SC
777 {
778 WSETSTOP ((*status), SIGTRAP);
779 need_artificial_trap--;
780 return 0;
781 }
fa4b55a1 782
ae0ea72e 783 timeout = 99999; /* Don't time out -- user program is running. */
1f46923f 784 immediate_quit = 1; /* Helps ability to QUIT */
96743d3c
SC
785 while (1)
786 {
787 QUIT; /* Let user quit and leave process running */
788 ch_handled = 0;
789 ch = readchar ();
790 if (ch == *bp)
791 {
792 bp++;
793 if (*bp == '\0')
794 break;
795 ch_handled = 1;
796
797 *swallowed_p++ = ch;
798 }
799 else
800 {
801 bp = bpt;
802 }
803 if (ch == *ep || *ep == '?')
804 {
805 ep++;
806 if (*ep == '\0')
807 break;
808
809 if (!ch_handled)
810 *swallowed_p++ = ch;
811 ch_handled = 1;
812 }
813 else
814 {
815 ep = exitmsg;
816 }
817
818 if (!ch_handled) {
819 char *p;
820 /* Print out any characters which have been swallowed. */
821 for (p = swallowed; p < swallowed_p; ++p)
822 putc (*p, stdout);
823 swallowed_p = swallowed;
fa4b55a1
SC
824
825
96743d3c
SC
826 if ((ch != '\r' && ch != '\n') || swallowed_cr>10)
827 {
828 putc (ch, stdout);
829 swallowed_cr = 10;
fa4b55a1 830 }
96743d3c
SC
831 swallowed_cr ++;
832
833 }
834 }
fa4b55a1
SC
835 if (*bp== '\0')
836 {
837 WSETSTOP ((*status), SIGTRAP);
838 expect_prompt();
839 }
840 else
841 {
842 WSETEXIT ((*status), 0);
843 }
844
845 timeout = old_timeout;
846 immediate_quit = old_immediate_quit;
fa4b55a1
SC
847 DEXIT("hms_wait()");
848 return 0;
849}
850
851/* Return the name of register number REGNO
852 in the form input and output by hms.
853
854 Returns a pointer to a static buffer containing the answer. */
855static char *
856get_reg_name (regno)
857 int regno;
858{
ae0ea72e 859 static char *rn[NUM_REGS]= REGISTER_NAMES;
fa4b55a1 860 return rn[regno];
fa4b55a1
SC
861}
862
863/* Read the remote registers. */
864static int gethex(length, start, ok)
865unsigned int length;
866char *start;
867int *ok;
868{
869 int result = 0;
870 while (length--)
871 {
872 result <<= 4 ;
873 if (*start >='a' && *start <= 'f')
874 {
875 result += *start - 'a' + 10;
876 }
877 else if (*start >='A' && *start <= 'F')
878 {
879 result += *start - 'A' + 10;
880 }
881 else if (*start >='0' && *start <= '9')
882 {
883 result += *start - '0' ;
884 }
885 else *ok = 0;
886 start++;
887
888 }
889 return result;
890}
891static int
892timed_read(buf, n, timeout)
893char *buf;
894
895{
896 int i;
897 char c;
898 i = 0;
899 while (i < n)
900 {
901 c = readchar();
902
903 if (c == 0) return i;
904 buf[i] = c;
905 i++;
906
907 }
908 return i;
909
910}
911hms_write(a,l)
912char *a;
913{
914 int i;
ae0ea72e
SC
915 serial_write(a, l);
916
96743d3c
SC
917 if (!quiet)
918 for (i = 0; i < l ; i++)
919 {
920 printf("%c", a[i]);
921 }
fa4b55a1
SC
922}
923
1f46923f
SC
924hms_write_cr(s)
925char *s;
fa4b55a1 926{
ae0ea72e
SC
927 hms_write( s, strlen(s));
928 hms_write("\r",1);
1f46923f
SC
929}
930
931static void
ae0ea72e
SC
932hms_fetch_register (dummy)
933int dummy;
fa4b55a1
SC
934{
935#define REGREPLY_SIZE 79
936 char linebuf[REGREPLY_SIZE+1];
937 int i;
938 int s ;
939 int gottok;
940
1f46923f
SC
941 REGISTER_TYPE reg[NUM_REGS];
942 int foo[8];
fa4b55a1
SC
943 check_open();
944
945 do
946 {
947
948 hms_write_cr("r");
949 s = timed_read(linebuf, REGREPLY_SIZE, 1);
950
951
952 linebuf[REGREPLY_SIZE] = 0;
953 gottok = 0;
954 if (linebuf[0] == 'r' &&
fa4b55a1
SC
955 linebuf[3] == 'P' &&
956 linebuf[4] == 'C' &&
957 linebuf[5] == '=' &&
958 linebuf[75] == 'H' &&
959 linebuf[76] == 'M' &&
960 linebuf[77] == 'S')
961 {
962 /*
963 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
964 5436789012345678901234567890123456789012345678901234567890123456789012
965 0 1 2 3 4 5 6
966 */
967 gottok = 1;
968
969 reg[PC_REGNUM] = gethex(4,linebuf+6, &gottok);
970 reg[CCR_REGNUM] = gethex(2,linebuf+15, &gottok);
971 for (i = 0; i < 8; i++)
972 {
973 reg[i] = gethex(4, linebuf+34+5*i, &gottok);
974 }
975 }
976 }
977 while (!gottok);
978 for (i = 0; i < NUM_REGS; i++)
979 {
ae0ea72e
SC
980 char swapped[2];
981 swapped[1] = reg[i];
982 swapped[0] = (reg[i])>> 8;
fa4b55a1 983
ae0ea72e
SC
984 supply_register (i, swapped);
985 }
fa4b55a1
SC
986}
987
fa4b55a1
SC
988
989/* Store register REGNO, or all if REGNO == -1.
990 Return errno value. */
ae0ea72e 991static void
fa4b55a1
SC
992hms_store_register (regno)
993 int regno;
994{
995
1f46923f 996 /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
ae0ea72e
SC
997 if (regno == -1)
998 {
999 for (regno = 0; regno < NUM_REGS; regno ++)
1000 {
1001 hms_store_register(regno);
1002 }
1003 }
fa4b55a1
SC
1004 else
1005 {
1006 char *name = get_reg_name (regno);
1007 char buffer[100];
1008 sprintf(buffer,"r %s=%x", name, read_register(regno));
1009 hms_write_cr(buffer);
1010 expect_prompt();
1011 }
1012
1013 DEXIT("hms_store_registers()");
ae0ea72e 1014
fa4b55a1
SC
1015}
1016
ae0ea72e
SC
1017
1018
fa4b55a1
SC
1019/* Get ready to modify the registers array. On machines which store
1020 individual registers, this doesn't need to do anything. On machines
1021 which store all the registers in one fell swoop, this makes sure
1022 that registers contains all the registers from the program being
1023 debugged. */
1024
1025void
1026hms_prepare_to_store ()
1027{
1028 /* Do nothing, since we can store individual regs */
1029}
1030
1031static CORE_ADDR
1032translate_addr(addr)
1033CORE_ADDR addr;
1034{
1035
1036 return(addr);
1037
1038}
1039
1040/* Read a word from remote address ADDR and return it.
1041 * This goes through the data cache.
1042 */
1043int
1044hms_fetch_word (addr)
1045 CORE_ADDR addr;
1046{
1047 return dcache_fetch (addr);
1048}
1049
1050/* Write a word WORD into remote address ADDR.
1051 This goes through the data cache. */
1052
1053void
1054hms_store_word (addr, word)
1055 CORE_ADDR addr;
1056 int word;
1057{
1058 dcache_poke (addr, word);
1059}
1060
1061int
1062hms_xfer_inferior_memory(memaddr, myaddr, len, write, target)
1063 CORE_ADDR memaddr;
1064 char *myaddr;
1065 int len;
1066 int write;
1067 struct target_ops *target; /* ignored */
1068{
1069 register int i;
1070 /* Round starting address down to longword boundary. */
1071 register CORE_ADDR addr;
1072 /* Round ending address up; get number of longwords that makes. */
1073 register int count;
1074 /* Allocate buffer of that many longwords. */
1075 register int *buffer ;
1076
1077 memaddr &= 0xffff;
1078 addr = memaddr & - sizeof (int);
1079 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1080
1f46923f 1081
fa4b55a1
SC
1082 buffer = (int *)alloca (count * sizeof (int));
1083 if (write)
1084 {
1085 /* Fill start and end extra bytes of buffer with existing memory data. */
1086
1087 if (addr != memaddr || len < (int)sizeof (int)) {
1088 /* Need part of initial word -- fetch it. */
1089 buffer[0] = hms_fetch_word (addr);
1090 }
1091
1092 if (count > 1) /* FIXME, avoid if even boundary */
1093 {
1094 buffer[count - 1]
1095 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1096 }
1097
1098 /* Copy data to be written over corresponding part of buffer */
1099
1100 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1101
1102 /* Write the entire buffer. */
1103
1104 for (i = 0; i < count; i++, addr += sizeof (int))
1105 {
1106 errno = 0;
1107 hms_store_word (addr, buffer[i]);
1108 if (errno)
1109 {
1110
1111 return 0;
1112 }
1113
1114 }
1115 }
1116 else
1117 {
1118 /* Read all the longwords */
1119 for (i = 0; i < count; i++, addr += sizeof (int))
1120 {
1121 errno = 0;
1122 buffer[i] = hms_fetch_word (addr);
1123 if (errno)
1124 {
1125 return 0;
1126 }
1127 QUIT;
1128 }
1129
1130 /* Copy appropriate bytes out of the buffer. */
1131 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1132 }
1133
1134
1135 return len;
1136}
1137
fa4b55a1
SC
1138int
1139hms_write_inferior_memory (memaddr, myaddr, len)
1140 CORE_ADDR memaddr;
ae0ea72e 1141 unsigned char *myaddr;
fa4b55a1
SC
1142 int len;
1143{
ae0ea72e
SC
1144 bfd_vma addr;
1145 int done;
1146 int todo ;
1147 done = 0;
1148 while(done < len)
1149 {
1150 char buffer[20];
1151 int thisgo;
1152 int idx;
1153 thisgo = len - done;
1154 if (thisgo > 20) thisgo = 20;
1155
1156 sprintf(buffer,"M.B %4x =", memaddr+done);
1157 hms_write(buffer,10);
1158 for (idx = 0; idx < thisgo; idx++)
1159 {
1160 char buf[20];
1161 sprintf(buf, "%2x ", myaddr[idx+done]);
1162 hms_write(buf, 3);
1163 }
1164 hms_write_cr("");
1165 expect_prompt();
1166 done += thisgo;
1167 }
1168
fa4b55a1 1169
fa4b55a1
SC
1170}
1171
1172void
1173hms_files_info ()
1174{
ae0ea72e
SC
1175char *file = "nothing";
1176if (exec_bfd)
1177 file = bfd_get_filename(exec_bfd);
1178
1179if (exec_bfd)
1180#ifdef __GO32__
1181 printf_filtered("\tAttached to DOS asynctsr and running program %s\n",file);
1182#else
1183 printf_filtered("\tAttached to %s at %d baud and running program %s\n",file);
1184#endif
fa4b55a1
SC
1185 printf_filtered("\ton an H8/300 processor.\n");
1186}
1187
1188/* Copy LEN bytes of data from debugger memory at MYADDR
1189 to inferior's memory at MEMADDR. Returns errno value.
1190 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1191 */
1192
1193
1194/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1195 at debugger address MYADDR. Returns errno value. */
1196int
1197hms_read_inferior_memory(memaddr, myaddr, len)
1198 CORE_ADDR memaddr;
1199 char *myaddr;
1200 int len;
1201{
1202 /* Align to nearest low 16 bits */
1203 int i;
1204
1205#if 0
1206 CORE_ADDR start = memaddr & ~0xf;
1207 CORE_ADDR end = ((memaddr + len +16) & ~0xf) -1;
1208#endif
1209 CORE_ADDR start = memaddr;
1210 CORE_ADDR end = memaddr + len -1;
1211
1212 int ok =1;
1213
1214 /*
1215 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1216 012345678901234567890123456789012345678901234567890123456789012345
1217 0 1 2 3 4 5 6
1218 */
1219 char buffer[66];
1220 if (memaddr & 0xf) abort();
1221 if (len != 16) abort();
1222
96743d3c 1223 sprintf(buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
fa4b55a1
SC
1224 hms_write_cr(buffer);
1225 /* drop the echo and newline*/
1226 for (i = 0; i < 13; i++)
1227 readchar();
1228
1229
1230
1231 /* Grab the lines as they come out and fill the area */
1232 /* Skip over cr */
1233 while(1)
1234 {
1235 int p;
1236 int i;
1237 int addr;
1238 size_t idx;
1239
1240 char byte[16];
1241 buffer[0] = readchar();
1242 if (buffer[0] == 'M')
1243 break;
1244 for (i = 1; i < 66; i++)
1245 buffer[i] = readchar();
1246
1247 /* Now parse the line */
1248
1249 addr = gethex(4, buffer, &ok);
1250 idx = 6;
1251 for (p = 0; p < 16; p+=2)
1252 {
1253 byte[p] = gethex(2, buffer + idx, &ok);
1254 byte[p+1] = gethex(2, buffer+ idx + 2, &ok);
1255 idx+=5;
1256
1257 }
1258
1259
1260 for (p = 0; p<16;p++)
1261 {
1262 if (addr + p >= memaddr &&
1263 addr + p < memaddr + len)
1264 {
1265 myaddr[ (addr + p)-memaddr] = byte[p];
1266
1267 }
1268
1269 }
1270 }
96743d3c 1271 hms_write_cr(" ");
fa4b55a1 1272 expect_prompt();
fa4b55a1 1273 return len;
fa4b55a1
SC
1274}
1275
1276/* This routine is run as a hook, just before the main command loop is
1277 entered. If gdb is configured for the H8, but has not had its
1278 target specified yet, this will loop prompting the user to do so.
1279*/
1280
1281hms_before_main_loop ()
1282{
1283 char ttyname[100];
1284 char *p, *p2;
1285 extern FILE *instream;
1286 extern jmp_buf to_top_level;
1287
1288 push_target (&hms_ops);
fa4b55a1
SC
1289}
1290
1291
1292#define MAX_BREAKS 16
1293static int num_brkpts=0;
1294static int
1295hms_insert_breakpoint(addr, save)
1296CORE_ADDR addr;
1297char *save; /* Throw away, let hms save instructions */
1298{
fa4b55a1
SC
1299 DENTER("hms_insert_breakpoint()");
1300 check_open();
1301
ae0ea72e
SC
1302 if (num_brkpts < MAX_BREAKS)
1303 {
1304 char buffer[100];
1305 num_brkpts++;
1306 sprintf(buffer,"b %x", addr & 0xffff);
1307 hms_write_cr(buffer);
1308 expect_prompt ();
1309 DEXIT("hms_insert_breakpoint() success");
1310 return(0);
1311 }
1312 else
1313 {
1314 fprintf_filtered(stderr,
1315 "Too many break points, break point not installed\n");
1316 DEXIT("hms_insert_breakpoint() failure");
1317 return(1);
1318 }
fa4b55a1
SC
1319
1320
1321}
1322static int
1323hms_remove_breakpoint(addr, save)
1324CORE_ADDR addr;
1325char *save; /* Throw away, let hms save instructions */
1326{
1327 DENTER("hms_remove_breakpoint()");
ae0ea72e
SC
1328 if (num_brkpts > 0)
1329 {
1330 char buffer[100];
fa4b55a1 1331
ae0ea72e
SC
1332 num_brkpts--;
1333 sprintf(buffer,"b - %x", addr & 0xffff);
1334 hms_write_cr(buffer);
1335 expect_prompt();
fa4b55a1 1336
ae0ea72e 1337 }
fa4b55a1
SC
1338 DEXIT("hms_remove_breakpoint()");
1339 return(0);
1340}
1341
1342/* Clear the hmss notion of what the break points are */
1343static int
1344hms_clear_breakpoints()
1345{
1346
1347 DENTER("hms_clear_breakpoint()");
ae0ea72e
SC
1348 if (is_open) {
1349 hms_write_cr("b -");
1350 expect_prompt ();
1351 }
fa4b55a1 1352 num_brkpts = 0;
fa4b55a1
SC
1353 DEXIT("hms_clear_breakpoint()");
1354}
1355static void
1356hms_mourn()
1357{
1358 DENTER("hms_mourn()");
1359 hms_clear_breakpoints();
fa4b55a1
SC
1360 generic_mourn_inferior ();
1361 DEXIT("hms_mourn()");
1362}
1363
fa4b55a1
SC
1364
1365
1366/* Put a command string, in args, out to the hms. The hms is assumed to
ae0ea72e 1367 be in raw mode, all writing/reading done through desc.
fa4b55a1
SC
1368 Ouput from the hms is placed on the users terminal until the
1369 prompt from the hms is seen.
1370 FIXME: Can't handle commands that take input. */
1371
1372void
1373hms_com (args, fromtty)
1374 char *args;
1375 int fromtty;
1376{
1377 check_open();
1378
1379 if (!args) return;
1380
1381 /* Clear all input so only command relative output is displayed */
1382
fa4b55a1
SC
1383 hms_write_cr(args);
1384 hms_write("\030",1);
1385 expect_prompt();
fa4b55a1
SC
1386}
1387
1388/* Define the target subroutine names */
1389
1390struct target_ops hms_ops = {
1391 "hms", "Remote HMS monitor",
1392"Use the H8 evaluation board running the HMS monitor connected\n\
1393by a serial line.",
1394
1395 hms_open, hms_close,
1396 hms_attach, hms_detach, hms_resume, hms_wait,
1397 hms_fetch_register, hms_store_register,
1398 hms_prepare_to_store, 0, 0, /* conv_to, conv_from */
1399 hms_xfer_inferior_memory,
1400 hms_files_info,
1401 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1402 0, 0, 0, 0, 0, /* Terminal handling */
1403 hms_kill, /* FIXME, kill */
1404 hms_load,
fa4b55a1
SC
1405 0, /* lookup_symbol */
1406 hms_create_inferior, /* create_inferior */
1407 hms_mourn, /* mourn_inferior FIXME */
1408 process_stratum, 0, /* next */
1409 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1410 0,0, /* Section pointers */
1411 OPS_MAGIC, /* Always the last thing */
1412};
1413
1414
1415hms_quiet()
1416{
ae0ea72e
SC
1417 quiet = ! quiet;
1418 if (quiet)
1419 printf_filtered("Snoop disabled\n");
1420 else
1421 printf_filtered("Snoop enabled\n");
1422
fa4b55a1
SC
1423}
1424
1425hms_device(s)
1426char *s;
1427{
ae0ea72e
SC
1428 if (s)
1429 {
1430 dev_name = get_word(&s);
1431 }
fa4b55a1
SC
1432}
1433
ae0ea72e 1434
96743d3c
SC
1435static
1436hms_speed(s)
fa4b55a1
SC
1437char *s;
1438{
ae0ea72e 1439 check_open();
96743d3c 1440
fa4b55a1
SC
1441 if (s)
1442 {
1443 char buffer[100];
1444 int newrate = atoi(s);
1445 int which = 0;
ae0ea72e 1446 if (!serial_setbaudrate(newrate))
fa4b55a1 1447 error("Can't use %d baud\n", newrate);
fa4b55a1 1448
fa4b55a1 1449 printf_filtered("Checking target is in sync\n");
fa4b55a1
SC
1450
1451 get_baudrate_right();
1452 baudrate = newrate;
1453 printf_filtered("Sending commands to set target to %d\n",
1454 baudrate);
1455
1456 sprintf(buffer, "tm %d. N 8 1", baudrate);
96743d3c 1457 hms_write_cr(buffer);
fa4b55a1
SC
1458 }
1459}
1460
1461/***********************************************************************/
1462
1463void
1464_initialize_remote_hms ()
1465{
1466 add_target (&hms_ops);
1467 add_com ("hms <command>", class_obscure, hms_com,
1468 "Send a command to the HMS monitor.");
1469 add_com ("snoop", class_obscure, hms_quiet,
1470 "Show what commands are going to the monitor");
ae0ea72e 1471
fa4b55a1
SC
1472 add_com ("device", class_obscure, hms_device,
1473 "Set the terminal line for HMS communications");
1474
1475 add_com ("speed", class_obscure, hms_speed,
1476 "Set the terminal line speed for HMS communications");
1477
ae0ea72e 1478 dev_name = serial_default_name();
fa4b55a1
SC
1479}
1480
1481
This page took 0.096841 seconds and 4 git commands to generate.