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