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