* Sanitization fixes to retain new files.
[binutils-gdb.git] / gdb / sparclet-rom.c
blob24484cd80504f6654a89cb7f53fbc96fb44e8c1a
1 /* Remote target glue for the SPARC Sparclet ROM monitor.
2 Copyright 1995, 1996 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "defs.h"
22 #include "gdbcore.h"
23 #include "target.h"
24 #include "monitor.h"
25 #include "serial.h"
26 #include "srec.h"
27 #include "symtab.h"
28 #include "symfile.h" /* for generic_load */
29 #include <time.h>
31 extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t));
33 static struct target_ops sparclet_ops;
35 static void sparclet_open PARAMS ((char *args, int from_tty));
37 /* This array of registers need to match the indexes used by GDB.
38 This exists because the various ROM monitors use different strings
39 than does GDB, and don't necessarily support all the registers
40 either. So, typing "info reg sp" becomes a "r30". */
42 /*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM
43 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2
44 0000010
45 INS LOCALS OUTS GLOBALS
46 0 0x00000000 0x00000000 0x00000000 0x00000000
47 1 0x00000000 0x00000000 0x00000000 0x00000000
48 2 0x00000000 0x00000000 0x00000000 0x00000000
49 3 0x00000000 0x00000000 0x00000000 0x00000000
50 4 0x00000000 0x00000000 0x00000000 0x00000000
51 5 0x00000000 0x00001000 0x00000000 0x00000000
52 6 0x00000000 0x00000000 0x123f0000 0x00000000
53 7 0x00000000 0x00000000 0x00000000 0x00000000
54 pc: 0x12010000 0x00000000 unimp
55 npc: 0x12010004 0x00001000 unimp 0x1000
56 tbr: 0x00000000
57 y: 0x00000000
59 /* these correspond to the offsets from tm-* files from config directories */
61 /* is wim part of psr?? */
62 /* monitor wants lower case */
63 static char *sparclet_regnames[NUM_REGS] = REGISTER_NAMES;
66 /* Function: sparclet_supply_register
67 Just returns with no action.
68 This function is required, because parse_register_dump (monitor.c)
69 expects to be able to call it. If we don't supply something, it will
70 call a null pointer and core-dump. Since this function does not
71 actually do anything, GDB will request the registers individually. */
73 static void
74 sparclet_supply_register (regname, regnamelen, val, vallen)
75 char *regname;
76 int regnamelen;
77 char *val;
78 int vallen;
80 return;
83 static void
84 sparclet_load (desc, file, hashmark)
85 serial_t desc;
86 char *file;
87 int hashmark;
89 bfd *abfd;
90 asection *s;
91 int i;
92 CORE_ADDR load_offset;
93 time_t start_time, end_time;
94 unsigned long data_count = 0;
96 /* enable user to specify address for downloading as 2nd arg to load */
98 i = sscanf(file, "%*s 0x%lx", &load_offset);
99 if (i >= 1 )
101 char *p;
103 for (p = file; *p != '\000' && !isspace (*p); p++);
105 *p = '\000';
107 else
108 load_offset = 0;
110 abfd = bfd_openr (file, 0);
111 if (!abfd)
113 printf_filtered ("Unable to open file %s\n", file);
114 return;
117 if (bfd_check_format (abfd, bfd_object) == 0)
119 printf_filtered ("File is not an object file\n");
120 return;
123 start_time = time (NULL);
125 for (s = abfd->sections; s; s = s->next)
126 if (s->flags & SEC_LOAD)
128 bfd_size_type section_size;
129 bfd_vma vma;
131 vma = bfd_get_section_vma (abfd, s) + load_offset;
132 section_size = bfd_section_size (abfd, s);
134 data_count += section_size;
136 printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
137 bfd_get_section_name (abfd, s), vma,
138 vma + section_size);
139 gdb_flush (gdb_stdout);
141 monitor_printf ("load c r %x %x\r", vma, section_size);
143 monitor_expect ("load: loading ", NULL, 0);
144 monitor_expect ("\r", NULL, 0);
146 for (i = 0; i < section_size; i += 2048)
148 int numbytes;
149 char buf[2048];
151 numbytes = min (sizeof buf, section_size - i);
153 bfd_get_section_contents (abfd, s, buf, i, numbytes);
155 SERIAL_WRITE (desc, buf, numbytes);
157 if (hashmark)
159 putchar_unfiltered ('#');
160 gdb_flush (gdb_stdout);
162 } /* Per-packet (or S-record) loop */
164 monitor_expect_prompt (NULL, 0);
166 putchar_unfiltered ('\n');
167 } /* Loadable sections */
169 monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd));
170 monitor_expect_prompt (NULL, 0);
171 monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4);
172 monitor_expect_prompt (NULL, 0);
174 monitor_printf ("run\r");
176 end_time = time (NULL);
178 if (hashmark)
179 putchar_unfiltered ('\n');
181 report_transfer_performance (data_count, start_time, end_time);
183 pop_target ();
184 push_remote_target (monitor_get_dev_name (), 1);
186 return_to_top_level (RETURN_QUIT);
189 /* Define the monitor command strings. Since these are passed directly
190 through to a printf style function, we may include formatting
191 strings. We also need a CR or LF on the end. */
193 /* need to pause the monitor for timing reasons, so slow it down */
195 static char *sparclet_inits[] = {"\n\r\r\n", NULL};
197 static struct monitor_ops sparclet_cmds ;
198 static void init_sparclet_cmds(void)
200 sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR |
201 MO_HEX_PREFIX |
202 MO_NO_ECHO_ON_OPEN |
203 MO_NO_ECHO_ON_SETMEM |
204 MO_RUN_FIRST_TIME |
205 MO_GETMEM_READ_SINGLE ; /* flags */
206 sparclet_cmds.init = sparclet_inits; /* Init strings */
207 sparclet_cmds.cont = "cont\r"; /* continue command */
208 sparclet_cmds.step = "step\r"; /* single step */
209 sparclet_cmds.stop = "\r"; /* break interrupts the program */
210 sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */
211 sparclet_cmds.clr_break = "-bp %x\r" ; /* can't use "br" because only 2 hw bps are supported */
212 sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */
213 "-bp\r" ; /* clear all breakpoints */
214 sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */
215 /* can't use "fi" because it takes words, not bytes */
216 /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */
217 sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */
218 sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */
219 sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */
220 sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
221 sparclet_cmds.setmem.resp_delim = NULL; /*": " */ /* setmem.resp_delim */
222 sparclet_cmds.setmem.term = NULL; /*"? " */ /* setmem.term */
223 sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" */ /* setmem.term_cmd */
224 /* since the parsing of multiple bytes is difficult due to
225 interspersed addresses, we'll only read 1 value at a time,
226 even tho these can handle a count */
227 /* we can use -n to set count to read, but may have to parse? */
228 sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */
229 sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */
230 sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */
231 sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */
232 sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
233 sparclet_cmds.getmem.term = NULL; /* getmem.term */
234 sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
235 sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */
236 sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
237 sparclet_cmds.setreg.term = NULL; /* setreg.term */
238 sparclet_cmds.setreg.term_cmd = NULL ; /* setreg.term_cmd */
239 sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */
240 sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */
241 sparclet_cmds.getreg.term = NULL; /* getreg.term */
242 sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
243 sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */
244 sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
245 sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */
246 sparclet_cmds.load_routine = sparclet_load; /* load_routine */
247 sparclet_cmds.load = NULL; /* download command (srecs on console) */
248 sparclet_cmds.loadresp = NULL; /* load response */
249 sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */
250 /* yikes! gdb core dumps without this delimitor!! */
251 sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */
252 sparclet_cmds.cmd_end = NULL; /* optional command terminator */
253 sparclet_cmds.target = &sparclet_ops; /* target operations */
254 sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
255 sparclet_cmds.regnames = sparclet_regnames; /* registers names */
256 sparclet_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */
259 static void
260 sparclet_open (args, from_tty)
261 char *args;
262 int from_tty;
264 monitor_open (args, &sparclet_cmds, from_tty);
267 void
268 _initialize_sparclet ()
270 int i;
271 init_sparclet_cmds() ;
273 for (i = 0; i < NUM_REGS; i++)
274 if (sparclet_regnames[i][0] == 'c' ||
275 sparclet_regnames[i][0] == 'a')
276 sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */
278 sparclet_regnames[0] = 0; /* mon won't report %G0 */
280 init_monitor_ops (&sparclet_ops);
281 sparclet_ops.to_shortname = "sparclet"; /* for the target command */
282 sparclet_ops.to_longname = "SPARC Sparclet monitor";
283 /* use SW breaks; target only supports 2 HW breakpoints */
284 sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
285 sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
287 sparclet_ops.to_doc =
288 "Use a board running the Sparclet debug monitor.\n\
289 Specify the serial device it is connected to (e.g. /dev/ttya).";
291 sparclet_ops.to_open = sparclet_open;
292 add_target (&sparclet_ops);