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