* testsuite/regress-demangle (failed test): Show result and
[binutils-gdb.git] / gdb / ppc-bdm.c
blobe10ebace770c1a7d0e7caa6e4879360a74814496
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.
5 This file is part of GDB.
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.
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.
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. */
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"
31 #include "gdb_wait.h"
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"
40 static void bdm_ppc_open (char *name, int from_tty);
42 static int bdm_ppc_wait (int pid, struct target_waitstatus *target_status);
44 static void bdm_ppc_fetch_registers (int regno);
46 static void bdm_ppc_store_registers (int regno);
48 extern struct target_ops bdm_ppc_ops; /* Forward decl */
50 /*#define BDM_NUM_REGS 71 */
51 #define BDM_NUM_REGS 24
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 */ \
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 */ \
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) */ \
70 0, /* mq (SPR 0) */
73 char nowatchdog[4] =
74 {0xff, 0xff, 0xff, 0x88};
76 /* Open a connection to a remote debugger.
77 NAME is the filename used for communication. */
79 static void
80 bdm_ppc_open (name, from_tty)
81 char *name;
82 int from_tty;
84 CORE_ADDR watchdogaddr = 0xff000004;
86 ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
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);
92 /* Disable watchdog timer on the board */
93 ocd_write_bytes (watchdogaddr, nowatchdog, 4);
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). */
101 static int
102 bdm_ppc_wait (pid, target_status)
103 int pid;
104 struct target_waitstatus *target_status;
106 int stop_reason;
108 target_status->kind = TARGET_WAITKIND_STOPPED;
110 stop_reason = ocd_wait ();
112 if (stop_reason)
114 target_status->value.sig = TARGET_SIGNAL_INT;
115 return inferior_pid;
118 target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
120 #if 0
122 unsigned long ecr, der;
124 ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
125 der = ocd_read_bdm_register (149); /* Read the debug enables register */
126 fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
128 #endif
130 return inferior_pid;
133 static int bdm_regmap[] =
134 {BDM_REGMAP};
136 /* Read the remote registers into regs.
137 Fetch register REGNO, or all registers if REGNO == -1
139 The Wiggler uses the following codes to access the registers:
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)
155 static void
156 bdm_ppc_fetch_registers (regno)
157 int regno;
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;
167 #if 1
168 for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
170 midregs[i] = -1;
172 mqreg[0] = -1;
173 #endif
175 if (regno == -1)
177 first_regno = 0;
178 last_regno = NUM_REGS - 1;
180 first_bdm_regno = 0;
181 last_bdm_regno = BDM_NUM_REGS - 1;
183 else
185 first_regno = regno;
186 last_regno = regno;
188 first_bdm_regno = bdm_regmap[regno];
189 last_bdm_regno = bdm_regmap[regno];
192 if (first_bdm_regno == -1)
194 supply_register (first_regno, NULL);
195 return; /* Unsupported register */
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 */
203 /* printf("Asking for register %d\n", first_regno); */
205 /* if asking for an invalid register */
206 if ((first_regno == MQ_REGNUM) ||
207 ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
209 /* printf("invalid reg request!\n"); */
210 supply_register (first_regno, NULL);
211 return; /* Unsupported register */
213 else
215 regs = ocd_read_bdm_registers (first_bdm_regno,
216 last_bdm_regno, &reglen);
219 else
220 /* want all regs */
222 /* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
223 beginregs = ocd_read_bdm_registers (first_bdm_regno,
224 FP0_REGNUM - 1, &beginreglen);
225 endregs = (strcat (midregs,
226 ocd_read_bdm_registers (FPLAST_REGNUM + 1,
227 last_bdm_regno - 1, &endreglen)));
228 almostregs = (strcat (beginregs, endregs));
229 regs = (strcat (almostregs, mqreg));
230 reglen = beginreglen + 32 + endreglen + 1;
233 #endif
234 #if 0
235 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
236 #endif
238 for (i = first_regno; i <= last_regno; i++)
240 int bdm_regno, regoffset;
242 bdm_regno = bdm_regmap[i];
243 if (bdm_regno != -1)
245 regoffset = bdm_regno - first_bdm_regno;
247 if (regoffset >= reglen / 4)
248 continue;
250 supply_register (i, regs + 4 * regoffset);
252 else
253 supply_register (i, NULL); /* Unsupported register */
257 /* Store register REGNO, or all registers if REGNO == -1, from the contents
258 of REGISTERS. FIXME: ignores errors. */
260 static void
261 bdm_ppc_store_registers (regno)
262 int regno;
264 int i;
265 int first_regno, last_regno;
266 int first_bdm_regno, last_bdm_regno;
268 if (regno == -1)
270 first_regno = 0;
271 last_regno = NUM_REGS - 1;
273 first_bdm_regno = 0;
274 last_bdm_regno = BDM_NUM_REGS - 1;
276 else
278 first_regno = regno;
279 last_regno = regno;
281 first_bdm_regno = bdm_regmap[regno];
282 last_bdm_regno = bdm_regmap[regno];
285 if (first_bdm_regno == -1)
286 return; /* Unsupported register */
288 for (i = first_regno; i <= last_regno; i++)
290 int bdm_regno;
292 bdm_regno = bdm_regmap[i];
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)))
298 /* printf("write valid reg %d\n", bdm_regno); */
299 ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
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);
310 /* Define the target subroutine names */
312 struct target_ops bdm_ppc_ops;
314 static void
315 init_bdm_ppc_ops (void)
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\
320 specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
321 a wiggler, specify wiggler and then the port it is connected to\n\
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;
326 bdm_ppc_ops.to_post_attach = NULL;
327 bdm_ppc_ops.to_require_attach = NULL;
328 bdm_ppc_ops.to_detach = ocd_detach;
329 bdm_ppc_ops.to_require_detach = NULL;
330 bdm_ppc_ops.to_resume = ocd_resume;
331 bdm_ppc_ops.to_wait = bdm_ppc_wait;
332 bdm_ppc_ops.to_post_wait = NULL;
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;
349 bdm_ppc_ops.to_post_startup_inferior = NULL;
350 bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
351 bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
352 bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
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;
356 bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
357 bdm_ppc_ops.to_has_forked = NULL;
358 bdm_ppc_ops.to_has_vforked = NULL;
359 bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
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;
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;
371 bdm_ppc_ops.to_pid_to_exec_file = NULL;
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 */
385 void
386 _initialize_bdm_ppc ()
388 init_bdm_ppc_ops ();
389 add_target (&bdm_ppc_ops);