* gdb.java/configure.in (AC_INIT): Use jmisc.exp.
[deliverable/binutils-gdb.git] / gdb / ppc-bdm.c
CommitLineData
c906108c
SS
1/* Remote target communications for the Macraigor Systems BDM Wiggler
2 talking to a Motorola PPC 8xx ADS board
3 Copyright 1996, 1997 Free Software Foundation, Inc.
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#include "defs.h"
23#include "gdbcore.h"
24#include "gdb_string.h"
25#include <fcntl.h>
26#include "frame.h"
27#include "inferior.h"
28#include "bfd.h"
29#include "symfile.h"
30#include "target.h"
03f2053f 31#include "gdb_wait.h"
c906108c
SS
32#include "gdbcmd.h"
33#include "objfiles.h"
34#include "gdb-stabs.h"
35#include <sys/types.h>
36#include <signal.h>
37#include "serial.h"
38#include "ocd.h"
39
a14ed312 40static void bdm_ppc_open (char *name, int from_tty);
c906108c 41
a14ed312 42static int bdm_ppc_wait (int pid, struct target_waitstatus *target_status);
c906108c 43
a14ed312 44static void bdm_ppc_fetch_registers (int regno);
c906108c 45
a14ed312 46static void bdm_ppc_store_registers (int regno);
c906108c
SS
47
48extern struct target_ops bdm_ppc_ops; /* Forward decl */
49\f
c5aa993b 50/*#define BDM_NUM_REGS 71 */
c906108c
SS
51#define BDM_NUM_REGS 24
52
53#define BDM_REGMAP \
54 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
55 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
56 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
57 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
58\
59 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
60 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
61 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
62 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
63\
64 26, /* pc (SRR0 (SPR 26)) */ \
65 2146, /* ps (MSR) */ \
66 2144, /* cnd (CR) */ \
67 8, /* lr (SPR 8) */ \
68 9, /* cnt (CTR (SPR 9)) */ \
69 1, /* xer (SPR 1) */ \
c5aa993b 70 0, /* mq (SPR 0) */
c906108c 71\f
c5aa993b
JM
72
73char nowatchdog[4] =
74{0xff, 0xff, 0xff, 0x88};
c906108c
SS
75
76/* Open a connection to a remote debugger.
77 NAME is the filename used for communication. */
78
79static void
80bdm_ppc_open (name, from_tty)
81 char *name;
82 int from_tty;
83{
84 CORE_ADDR watchdogaddr = 0xff000004;
85
86 ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
87
88 /* We want interrupts to drop us into debugging mode. */
89 /* Modify the DER register to accomplish this. */
90 ocd_write_bdm_register (149, 0x20024000);
91
92 /* Disable watchdog timer on the board */
93 ocd_write_bytes (watchdogaddr, nowatchdog, 4);
94}
95
96/* Wait until the remote machine stops, then return,
97 storing status in STATUS just as `wait' would.
98 Returns "pid" (though it's not clear what, if anything, that
99 means in the case of this target). */
100
101static int
102bdm_ppc_wait (pid, target_status)
103 int pid;
104 struct target_waitstatus *target_status;
105{
106 int stop_reason;
107
108 target_status->kind = TARGET_WAITKIND_STOPPED;
109
110 stop_reason = ocd_wait ();
111
112 if (stop_reason)
113 {
114 target_status->value.sig = TARGET_SIGNAL_INT;
115 return inferior_pid;
116 }
117
c5aa993b 118 target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
c906108c
SS
119
120#if 0
121 {
122 unsigned long ecr, der;
123
c5aa993b
JM
124 ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
125 der = ocd_read_bdm_register (149); /* Read the debug enables register */
c906108c
SS
126 fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
127 }
128#endif
129
130 return inferior_pid;
131}
132\f
c5aa993b
JM
133static int bdm_regmap[] =
134{BDM_REGMAP};
c906108c
SS
135
136/* Read the remote registers into regs.
137 Fetch register REGNO, or all registers if REGNO == -1
138
139 The Wiggler uses the following codes to access the registers:
140
c5aa993b
JM
141 0 -> 1023 SPR 0 -> 1023
142 0 - SPR 0 - MQ
143 1 - SPR 1 - XER
144 8 - SPR 8 - LR
145 9 - SPR 9 - CTR (known as cnt in GDB)
146 26 - SPR 26 - SRR0 - pc
147 1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
148 2048 -> 2079 R0 -> R31
149 2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
150 2144 CR (known as cnd in GDB)
151 2145 FPCSR
152 2146 MSR (known as ps in GDB)
c906108c
SS
153 */
154
155static void
156bdm_ppc_fetch_registers (regno)
157 int regno;
158{
159 int i;
160 unsigned char *regs, *beginregs, *endregs, *almostregs;
161 unsigned char midregs[32];
162 unsigned char mqreg[1];
163 int first_regno, last_regno;
164 int first_bdm_regno, last_bdm_regno;
165 int reglen, beginreglen, endreglen;
166
167#if 1
168 for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
169 {
170 midregs[i] = -1;
171 }
172 mqreg[0] = -1;
173#endif
174
175 if (regno == -1)
176 {
177 first_regno = 0;
178 last_regno = NUM_REGS - 1;
179
180 first_bdm_regno = 0;
181 last_bdm_regno = BDM_NUM_REGS - 1;
182 }
183 else
184 {
185 first_regno = regno;
186 last_regno = regno;
187
c5aa993b
JM
188 first_bdm_regno = bdm_regmap[regno];
189 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
190 }
191
192 if (first_bdm_regno == -1)
193 {
194 supply_register (first_regno, NULL);
195 return; /* Unsupported register */
196 }
197
198#if 1
199 /* Can't ask for floating point regs on ppc 8xx, also need to
200 avoid asking for the mq register. */
201 if (first_regno == last_regno) /* only want one reg */
202 {
203/* printf("Asking for register %d\n", first_regno); */
204
205 /* if asking for an invalid register */
206 if ((first_regno == MQ_REGNUM) ||
c5aa993b 207 ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
c906108c
SS
208 {
209/* printf("invalid reg request!\n"); */
c5aa993b
JM
210 supply_register (first_regno, NULL);
211 return; /* Unsupported register */
212 }
c906108c
SS
213 else
214 {
c5aa993b
JM
215 regs = ocd_read_bdm_registers (first_bdm_regno,
216 last_bdm_regno, &reglen);
217 }
c906108c 218 }
c5aa993b
JM
219 else
220 /* want all regs */
c906108c
SS
221 {
222/* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
223 beginregs = ocd_read_bdm_registers (first_bdm_regno,
c5aa993b
JM
224 FP0_REGNUM - 1, &beginreglen);
225 endregs = (strcat (midregs,
226 ocd_read_bdm_registers (FPLAST_REGNUM + 1,
227 last_bdm_regno - 1, &endreglen)));
c906108c
SS
228 almostregs = (strcat (beginregs, endregs));
229 regs = (strcat (almostregs, mqreg));
230 reglen = beginreglen + 32 + endreglen + 1;
231 }
232
233#endif
234#if 0
235 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
236#endif
237
238 for (i = first_regno; i <= last_regno; i++)
239 {
240 int bdm_regno, regoffset;
241
c5aa993b 242 bdm_regno = bdm_regmap[i];
c906108c
SS
243 if (bdm_regno != -1)
244 {
245 regoffset = bdm_regno - first_bdm_regno;
246
247 if (regoffset >= reglen / 4)
248 continue;
249
250 supply_register (i, regs + 4 * regoffset);
251 }
252 else
c5aa993b 253 supply_register (i, NULL); /* Unsupported register */
c906108c
SS
254 }
255}
256
257/* Store register REGNO, or all registers if REGNO == -1, from the contents
258 of REGISTERS. FIXME: ignores errors. */
259
260static void
261bdm_ppc_store_registers (regno)
262 int regno;
263{
264 int i;
265 int first_regno, last_regno;
266 int first_bdm_regno, last_bdm_regno;
267
268 if (regno == -1)
269 {
270 first_regno = 0;
271 last_regno = NUM_REGS - 1;
272
273 first_bdm_regno = 0;
274 last_bdm_regno = BDM_NUM_REGS - 1;
275 }
276 else
277 {
278 first_regno = regno;
279 last_regno = regno;
280
c5aa993b
JM
281 first_bdm_regno = bdm_regmap[regno];
282 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
283 }
284
285 if (first_bdm_regno == -1)
286 return; /* Unsupported register */
287
288 for (i = first_regno; i <= last_regno; i++)
289 {
290 int bdm_regno;
291
c5aa993b 292 bdm_regno = bdm_regmap[i];
c906108c
SS
293
294 /* only attempt to write if it's a valid ppc 8xx register */
295 /* (need to avoid FP regs and MQ reg) */
296 if ((i != MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
297 {
298/* printf("write valid reg %d\n", bdm_regno); */
c5aa993b
JM
299 ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
300 }
c906108c 301/*
c5aa993b
JM
302 else if (i == MQ_REGNUM)
303 printf("don't write invalid reg %d (MQ_REGNUM)\n", bdm_regno);
304 else
305 printf("don't write invalid reg %d\n", bdm_regno);
306 */
c906108c
SS
307 }
308}
309\f
310/* Define the target subroutine names */
311
c5aa993b 312struct target_ops bdm_ppc_ops;
c906108c 313
c5aa993b
JM
314static void
315init_bdm_ppc_ops (void)
c906108c 316{
c5aa993b
JM
317 bdm_ppc_ops.to_shortname = "ocd";
318 bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
319 bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
c906108c
SS
320specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
321a wiggler, specify wiggler and then the port it is connected to\n\
c5aa993b
JM
322(e.g. wiggler lpt1)."; /* to_doc */
323 bdm_ppc_ops.to_open = bdm_ppc_open;
324 bdm_ppc_ops.to_close = ocd_close;
325 bdm_ppc_ops.to_attach = NULL;
c906108c
SS
326 bdm_ppc_ops.to_post_attach = NULL;
327 bdm_ppc_ops.to_require_attach = NULL;
c5aa993b 328 bdm_ppc_ops.to_detach = ocd_detach;
c906108c 329 bdm_ppc_ops.to_require_detach = NULL;
c5aa993b
JM
330 bdm_ppc_ops.to_resume = ocd_resume;
331 bdm_ppc_ops.to_wait = bdm_ppc_wait;
c906108c 332 bdm_ppc_ops.to_post_wait = NULL;
c5aa993b
JM
333 bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
334 bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
335 bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
336 bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
337 bdm_ppc_ops.to_files_info = ocd_files_info;
338 bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
339 bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
340 bdm_ppc_ops.to_terminal_init = NULL;
341 bdm_ppc_ops.to_terminal_inferior = NULL;
342 bdm_ppc_ops.to_terminal_ours_for_output = NULL;
343 bdm_ppc_ops.to_terminal_ours = NULL;
344 bdm_ppc_ops.to_terminal_info = NULL;
345 bdm_ppc_ops.to_kill = ocd_kill;
346 bdm_ppc_ops.to_load = ocd_load;
347 bdm_ppc_ops.to_lookup_symbol = NULL;
348 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
c906108c
SS
349 bdm_ppc_ops.to_post_startup_inferior = NULL;
350 bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
c5aa993b
JM
351 bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
352 bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
c906108c
SS
353 bdm_ppc_ops.to_insert_fork_catchpoint = NULL;
354 bdm_ppc_ops.to_remove_fork_catchpoint = NULL;
355 bdm_ppc_ops.to_insert_vfork_catchpoint = NULL;
c5aa993b 356 bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
c906108c 357 bdm_ppc_ops.to_has_forked = NULL;
c5aa993b
JM
358 bdm_ppc_ops.to_has_vforked = NULL;
359 bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
c906108c
SS
360 bdm_ppc_ops.to_post_follow_vfork = NULL;
361 bdm_ppc_ops.to_insert_exec_catchpoint = NULL;
362 bdm_ppc_ops.to_remove_exec_catchpoint = NULL;
363 bdm_ppc_ops.to_has_execd = NULL;
364 bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL;
365 bdm_ppc_ops.to_has_exited = NULL;
c5aa993b
JM
366 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
367 bdm_ppc_ops.to_can_run = 0;
368 bdm_ppc_ops.to_notice_signals = 0;
369 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
370 bdm_ppc_ops.to_stop = ocd_stop;
c906108c 371 bdm_ppc_ops.to_pid_to_exec_file = NULL;
c5aa993b
JM
372 bdm_ppc_ops.to_core_file_to_sym_file = NULL;
373 bdm_ppc_ops.to_stratum = process_stratum;
374 bdm_ppc_ops.DONT_USE = NULL;
375 bdm_ppc_ops.to_has_all_memory = 1;
376 bdm_ppc_ops.to_has_memory = 1;
377 bdm_ppc_ops.to_has_stack = 1;
378 bdm_ppc_ops.to_has_registers = 1;
379 bdm_ppc_ops.to_has_execution = 1;
380 bdm_ppc_ops.to_sections = NULL;
381 bdm_ppc_ops.to_sections_end = NULL;
382 bdm_ppc_ops.to_magic = OPS_MAGIC;
383} /* init_bdm_ppc_ops */
c906108c
SS
384
385void
386_initialize_bdm_ppc ()
387{
c5aa993b 388 init_bdm_ppc_ops ();
c906108c
SS
389 add_target (&bdm_ppc_ops);
390}
This page took 0.079661 seconds and 4 git commands to generate.