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