Obsolete harris 88k target.
[deliverable/binutils-gdb.git] / gdb / sparclet-rom.c
CommitLineData
c906108c 1/* Remote target glue for the SPARC Sparclet ROM monitor.
b6ba6518
KB
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22
23#include "defs.h"
24#include "gdbcore.h"
25#include "target.h"
26#include "monitor.h"
27#include "serial.h"
28#include "srec.h"
29#include "symtab.h"
c5aa993b 30#include "symfile.h" /* for generic_load */
4e052eda 31#include "regcache.h"
c906108c
SS
32#include <time.h>
33
a14ed312 34extern void report_transfer_performance (unsigned long, time_t, time_t);
c906108c
SS
35
36static struct target_ops sparclet_ops;
37
a14ed312 38static void sparclet_open (char *args, int from_tty);
c906108c
SS
39
40/* This array of registers need to match the indexes used by GDB.
41 This exists because the various ROM monitors use different strings
42 than does GDB, and don't necessarily support all the registers
43 either. So, typing "info reg sp" becomes a "r30". */
44
45/*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM
c5aa993b
JM
46 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2
47 0000010
48 INS LOCALS OUTS GLOBALS
49 0 0x00000000 0x00000000 0x00000000 0x00000000
50 1 0x00000000 0x00000000 0x00000000 0x00000000
51 2 0x00000000 0x00000000 0x00000000 0x00000000
52 3 0x00000000 0x00000000 0x00000000 0x00000000
53 4 0x00000000 0x00000000 0x00000000 0x00000000
54 5 0x00000000 0x00001000 0x00000000 0x00000000
55 6 0x00000000 0x00000000 0x123f0000 0x00000000
56 7 0x00000000 0x00000000 0x00000000 0x00000000
57 pc: 0x12010000 0x00000000 unimp
58 npc: 0x12010004 0x00001000 unimp 0x1000
59 tbr: 0x00000000
60 y: 0x00000000
61 */
c906108c
SS
62/* these correspond to the offsets from tm-* files from config directories */
63
64/* is wim part of psr?? */
65/* monitor wants lower case */
5af923b0
MS
66static char *sparclet_regnames[] = {
67 "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
68 "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
69 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
70 "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
71
72 "", "", "", "", "", "", "", "", /* no FPU regs */
73 "", "", "", "", "", "", "", "",
74 "", "", "", "", "", "", "", "",
75 "", "", "", "", "", "", "", "",
76 /* no CPSR, FPSR */
77 "y", "psr", "wim", "tbr", "pc", "npc", "", "",
78
79 "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "",
80
81 /* ASR15 ASR19 (don't display them) */
82 "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22",
83/*
84 "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7",
85 "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15",
86 "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23",
87 "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31",
88 "apsr",
89 */
90};
91
c906108c
SS
92
93
94/* Function: sparclet_supply_register
95 Just returns with no action.
96 This function is required, because parse_register_dump (monitor.c)
97 expects to be able to call it. If we don't supply something, it will
98 call a null pointer and core-dump. Since this function does not
99 actually do anything, GDB will request the registers individually. */
100
101static void
fba45db2 102sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen)
c906108c
SS
103{
104 return;
105}
106
107static void
fba45db2 108sparclet_load (serial_t desc, char *file, int hashmark)
c906108c
SS
109{
110 bfd *abfd;
111 asection *s;
112 int i;
113 CORE_ADDR load_offset;
114 time_t start_time, end_time;
115 unsigned long data_count = 0;
116
117 /* enable user to specify address for downloading as 2nd arg to load */
118
c5aa993b
JM
119 i = sscanf (file, "%*s 0x%lx", &load_offset);
120 if (i >= 1)
c906108c
SS
121 {
122 char *p;
123
124 for (p = file; *p != '\000' && !isspace (*p); p++);
125
126 *p = '\000';
127 }
128 else
129 load_offset = 0;
130
131 abfd = bfd_openr (file, 0);
132 if (!abfd)
133 {
134 printf_filtered ("Unable to open file %s\n", file);
135 return;
136 }
137
138 if (bfd_check_format (abfd, bfd_object) == 0)
139 {
140 printf_filtered ("File is not an object file\n");
141 return;
142 }
c5aa993b 143
c906108c
SS
144 start_time = time (NULL);
145
146 for (s = abfd->sections; s; s = s->next)
147 if (s->flags & SEC_LOAD)
148 {
149 bfd_size_type section_size;
150 bfd_vma vma;
151
152 vma = bfd_get_section_vma (abfd, s) + load_offset;
153 section_size = bfd_section_size (abfd, s);
154
155 data_count += section_size;
156
157 printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
158 bfd_get_section_name (abfd, s), vma,
159 vma + section_size);
160 gdb_flush (gdb_stdout);
161
162 monitor_printf ("load c r %x %x\r", vma, section_size);
163
164 monitor_expect ("load: loading ", NULL, 0);
165 monitor_expect ("\r", NULL, 0);
166
167 for (i = 0; i < section_size; i += 2048)
168 {
169 int numbytes;
170 char buf[2048];
171
172 numbytes = min (sizeof buf, section_size - i);
173
174 bfd_get_section_contents (abfd, s, buf, i, numbytes);
175
176 SERIAL_WRITE (desc, buf, numbytes);
177
178 if (hashmark)
179 {
180 putchar_unfiltered ('#');
181 gdb_flush (gdb_stdout);
182 }
183 } /* Per-packet (or S-record) loop */
184
185 monitor_expect_prompt (NULL, 0);
186
187 putchar_unfiltered ('\n');
188 } /* Loadable sections */
189
190 monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd));
191 monitor_expect_prompt (NULL, 0);
192 monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4);
193 monitor_expect_prompt (NULL, 0);
194
195 monitor_printf ("run\r");
196
197 end_time = time (NULL);
198
c5aa993b 199 if (hashmark)
c906108c
SS
200 putchar_unfiltered ('\n');
201
202 report_transfer_performance (data_count, start_time, end_time);
203
204 pop_target ();
205 push_remote_target (monitor_get_dev_name (), 1);
206
207 return_to_top_level (RETURN_QUIT);
208}
209
210/* Define the monitor command strings. Since these are passed directly
211 through to a printf style function, we may include formatting
212 strings. We also need a CR or LF on the end. */
213
214/* need to pause the monitor for timing reasons, so slow it down */
215
c5aa993b
JM
216static char *sparclet_inits[] =
217{"\n\r\r\n", NULL};
c906108c 218
c5aa993b 219static struct monitor_ops sparclet_cmds;
c906108c 220
c5aa993b
JM
221static void
222init_sparclet_cmds (void)
c906108c 223{
c5aa993b
JM
224 sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR |
225 MO_HEX_PREFIX |
226 MO_NO_ECHO_ON_OPEN |
227 MO_NO_ECHO_ON_SETMEM |
228 MO_RUN_FIRST_TIME |
229 MO_GETMEM_READ_SINGLE; /* flags */
230 sparclet_cmds.init = sparclet_inits; /* Init strings */
231 sparclet_cmds.cont = "cont\r"; /* continue command */
232 sparclet_cmds.step = "step\r"; /* single step */
233 sparclet_cmds.stop = "\r"; /* break interrupts the program */
234 sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */
235 sparclet_cmds.clr_break = "-bp %x\r"; /* can't use "br" because only 2 hw bps are supported */
236 sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */
237 "-bp\r"; /* clear all breakpoints */
238 sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */
c906108c
SS
239 /* can't use "fi" because it takes words, not bytes */
240 /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */
c5aa993b
JM
241 sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */
242 sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */
243 sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */
244 sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
245 sparclet_cmds.setmem.resp_delim = NULL; /*": " *//* setmem.resp_delim */
246 sparclet_cmds.setmem.term = NULL; /*"? " *//* setmem.term */
247 sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" *//* setmem.term_cmd */
c906108c
SS
248 /* since the parsing of multiple bytes is difficult due to
249 interspersed addresses, we'll only read 1 value at a time,
250 even tho these can handle a count */
251 /* we can use -n to set count to read, but may have to parse? */
c5aa993b
JM
252 sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */
253 sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */
254 sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */
255 sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */
256 sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
257 sparclet_cmds.getmem.term = NULL; /* getmem.term */
258 sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
259 sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */
260 sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
261 sparclet_cmds.setreg.term = NULL; /* setreg.term */
262 sparclet_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
263 sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */
264 sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */
265 sparclet_cmds.getreg.term = NULL; /* getreg.term */
266 sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
267 sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */
268 sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
269 sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */
270 sparclet_cmds.load_routine = sparclet_load; /* load_routine */
271 sparclet_cmds.load = NULL; /* download command (srecs on console) */
272 sparclet_cmds.loadresp = NULL; /* load response */
273 sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */
c906108c 274 /* yikes! gdb core dumps without this delimitor!! */
c5aa993b
JM
275 sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */
276 sparclet_cmds.cmd_end = NULL; /* optional command terminator */
277 sparclet_cmds.target = &sparclet_ops; /* target operations */
278 sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
279 sparclet_cmds.regnames = sparclet_regnames; /* registers names */
280 sparclet_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
c906108c
SS
281};
282
283static void
fba45db2 284sparclet_open (char *args, int from_tty)
c906108c
SS
285{
286 monitor_open (args, &sparclet_cmds, from_tty);
287}
288
289void
fba45db2 290_initialize_sparclet (void)
c906108c
SS
291{
292 int i;
c5aa993b 293 init_sparclet_cmds ();
c906108c
SS
294
295 for (i = 0; i < NUM_REGS; i++)
296 if (sparclet_regnames[i][0] == 'c' ||
297 sparclet_regnames[i][0] == 'a')
c5aa993b 298 sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */
c906108c 299
c5aa993b 300 sparclet_regnames[0] = 0; /* mon won't report %G0 */
c906108c
SS
301
302 init_monitor_ops (&sparclet_ops);
c5aa993b 303 sparclet_ops.to_shortname = "sparclet"; /* for the target command */
c906108c
SS
304 sparclet_ops.to_longname = "SPARC Sparclet monitor";
305 /* use SW breaks; target only supports 2 HW breakpoints */
c5aa993b
JM
306 sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
307 sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
c906108c 308
c5aa993b 309 sparclet_ops.to_doc =
c906108c
SS
310 "Use a board running the Sparclet debug monitor.\n\
311Specify the serial device it is connected to (e.g. /dev/ttya).";
312
313 sparclet_ops.to_open = sparclet_open;
314 add_target (&sparclet_ops);
315}
This page took 0.110922 seconds and 4 git commands to generate.