Fix up mix of man(7)/mdoc(7).
[netbsd-mini2440.git] / gnu / dist / gdb6 / gdb / ppc-bdm.c
blob96ea612c974ea5f12de7c0f1f50d26765fda6895
1 /* Remote target communications for the Macraigor Systems BDM Wiggler
2 talking to a Motorola PPC 8xx ADS board
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
4 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
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"
32 #include "gdbcmd.h"
33 #include "objfiles.h"
34 #include "gdb-stabs.h"
35 #include <sys/types.h>
36 #include "serial.h"
37 #include "ocd.h"
38 #include "ppc-tdep.h"
39 #include "regcache.h"
40 #include "gdb_assert.h"
42 static void bdm_ppc_open (char *name, int from_tty);
44 static ptid_t bdm_ppc_wait (ptid_t ptid,
45 struct target_waitstatus *target_status);
47 static void bdm_ppc_fetch_registers (int regno);
49 static void bdm_ppc_store_registers (int regno);
51 extern struct target_ops bdm_ppc_ops; /* Forward decl */
53 /*#define BDM_NUM_REGS 71 */
54 #define BDM_NUM_REGS 24
56 #define BDM_REGMAP \
57 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
58 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
59 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
60 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
62 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
63 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
64 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
65 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
67 26, /* pc (SRR0 (SPR 26)) */ \
68 2146, /* ps (MSR) */ \
69 2144, /* cnd (CR) */ \
70 8, /* lr (SPR 8) */ \
71 9, /* cnt (CTR (SPR 9)) */ \
72 1, /* xer (SPR 1) */ \
73 0, /* mq (SPR 0) */
76 char nowatchdog[4] =
77 {0xff, 0xff, 0xff, 0x88};
79 /* Open a connection to a remote debugger.
80 NAME is the filename used for communication. */
82 static void
83 bdm_ppc_open (char *name, int from_tty)
85 CORE_ADDR watchdogaddr = 0xff000004;
87 ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
89 /* We want interrupts to drop us into debugging mode. */
90 /* Modify the DER register to accomplish this. */
91 ocd_write_bdm_register (149, 0x20024000);
93 /* Disable watchdog timer on the board */
94 ocd_write_bytes (watchdogaddr, nowatchdog, 4);
97 /* Wait until the remote machine stops, then return,
98 storing status in STATUS just as `wait' would.
99 Returns "pid" (though it's not clear what, if anything, that
100 means in the case of this target). */
102 static ptid_t
103 bdm_ppc_wait (ptid_t ptid, struct target_waitstatus *target_status)
105 int stop_reason;
107 target_status->kind = TARGET_WAITKIND_STOPPED;
109 stop_reason = ocd_wait ();
111 if (stop_reason)
113 target_status->value.sig = TARGET_SIGNAL_INT;
114 return inferior_ptid;
117 target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
119 #if 0
121 unsigned long ecr, der;
123 ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
124 der = ocd_read_bdm_register (149); /* Read the debug enables register */
125 fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
127 #endif
129 return inferior_ptid;
132 static int bdm_regmap[] =
133 {BDM_REGMAP};
135 /* Read the remote registers into regs.
136 Fetch register REGNO, or all registers if REGNO == -1
138 The Wiggler uses the following codes to access the registers:
140 0 -> 1023 SPR 0 -> 1023
141 0 - SPR 0 - MQ
142 1 - SPR 1 - XER
143 8 - SPR 8 - LR
144 9 - SPR 9 - CTR (known as cnt in GDB)
145 26 - SPR 26 - SRR0 - pc
146 1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
147 2048 -> 2079 R0 -> R31
148 2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
149 2144 CR (known as cnd in GDB)
150 2145 FPCSR
151 2146 MSR (known as ps in GDB)
154 static void
155 bdm_ppc_fetch_registers (int regno)
157 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
158 int i;
159 unsigned char *regs;
160 int first_regno, last_regno;
161 int first_bdm_regno, last_bdm_regno;
162 int reglen;
164 if (regno == -1)
166 first_regno = 0;
167 last_regno = NUM_REGS - 1;
169 first_bdm_regno = 0;
170 last_bdm_regno = BDM_NUM_REGS - 1;
172 else
174 first_regno = regno;
175 last_regno = regno;
177 first_bdm_regno = bdm_regmap[regno];
178 last_bdm_regno = bdm_regmap[regno];
181 if (first_bdm_regno == -1)
183 regcache_raw_supply (current_regcache, first_regno, NULL);
184 return; /* Unsupported register */
187 /* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to
188 processors that lack floating point registers, and I don't have
189 have the equipment to test it. So we'll leave that case for the
190 next person who encounters it. */
191 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
193 #if 1
194 /* Can't ask for floating point regs on ppc 8xx, also need to
195 avoid asking for the mq register. */
196 if (first_regno == last_regno) /* only want one reg */
198 /* printf("Asking for register %d\n", first_regno); */
200 /* if asking for an invalid register */
201 if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
202 || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
203 || ((first_regno >= tdep->ppc_fp0_regnum)
204 && (first_regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
206 /* printf("invalid reg request!\n"); */
207 regcache_raw_supply (current_regcache, first_regno, NULL);
208 return; /* Unsupported register */
210 else
212 regs = ocd_read_bdm_registers (first_bdm_regno,
213 last_bdm_regno, &reglen);
216 else
217 internal_error (__FILE__, __LINE__,
218 _("ppc_bdm_fetch_registers: "
219 "'all registers' case not implemented"));
221 #endif
222 #if 0
223 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
224 #endif
226 for (i = first_regno; i <= last_regno; i++)
228 int bdm_regno, regoffset;
230 bdm_regno = bdm_regmap[i];
231 if (bdm_regno != -1)
233 regoffset = bdm_regno - first_bdm_regno;
235 if (regoffset >= reglen / 4)
236 continue;
238 regcache_raw_supply (current_regcache, i, regs + 4 * regoffset);
240 else
241 regcache_raw_supply (current_regcache, i, NULL); /* Unsupported register */
245 /* Store register REGNO, or all registers if REGNO == -1, from the contents
246 of REGISTERS. FIXME: ignores errors. */
248 static void
249 bdm_ppc_store_registers (int regno)
251 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
252 int i;
253 int first_regno, last_regno;
254 int first_bdm_regno, last_bdm_regno;
256 if (regno == -1)
258 first_regno = 0;
259 last_regno = NUM_REGS - 1;
261 first_bdm_regno = 0;
262 last_bdm_regno = BDM_NUM_REGS - 1;
264 else
266 first_regno = regno;
267 last_regno = regno;
269 first_bdm_regno = bdm_regmap[regno];
270 last_bdm_regno = bdm_regmap[regno];
273 if (first_bdm_regno == -1)
274 return; /* Unsupported register */
276 /* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to
277 processors that lack floating point registers, and I don't have
278 have the equipment to test it. So we'll leave that case for the
279 next person who encounters it. */
280 gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
282 for (i = first_regno; i <= last_regno; i++)
284 int bdm_regno;
286 bdm_regno = bdm_regmap[i];
288 /* only attempt to write if it's a valid ppc 8xx register */
289 /* (need to avoid FP regs and MQ reg) */
290 if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
291 && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
292 && ((i < tdep->ppc_fp0_regnum)
293 || (i >= tdep->ppc_fp0_regnum + ppc_num_fprs)))
295 /* printf("write valid reg %d\n", bdm_regno); */
296 ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
299 else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
300 printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
301 else
302 printf("don't write invalid reg %d\n", bdm_regno);
307 /* Define the target subroutine names */
309 struct target_ops bdm_ppc_ops;
311 static void
312 init_bdm_ppc_ops (void)
314 bdm_ppc_ops.to_shortname = "ocd";
315 bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
316 bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
317 specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
318 a wiggler, specify wiggler and then the port it is connected to\n\
319 (e.g. wiggler lpt1)."; /* to_doc */
320 bdm_ppc_ops.to_open = bdm_ppc_open;
321 bdm_ppc_ops.to_close = ocd_close;
322 bdm_ppc_ops.to_detach = ocd_detach;
323 bdm_ppc_ops.to_resume = ocd_resume;
324 bdm_ppc_ops.to_wait = bdm_ppc_wait;
325 bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
326 bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
327 bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
328 bdm_ppc_ops.deprecated_xfer_memory = ocd_xfer_memory;
329 bdm_ppc_ops.to_files_info = ocd_files_info;
330 bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
331 bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
332 bdm_ppc_ops.to_kill = ocd_kill;
333 bdm_ppc_ops.to_load = ocd_load;
334 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
335 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
336 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
337 bdm_ppc_ops.to_stop = ocd_stop;
338 bdm_ppc_ops.to_stratum = process_stratum;
339 bdm_ppc_ops.to_has_all_memory = 1;
340 bdm_ppc_ops.to_has_memory = 1;
341 bdm_ppc_ops.to_has_stack = 1;
342 bdm_ppc_ops.to_has_registers = 1;
343 bdm_ppc_ops.to_has_execution = 1;
344 bdm_ppc_ops.to_magic = OPS_MAGIC;
345 } /* init_bdm_ppc_ops */
347 extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */
349 void
350 _initialize_bdm_ppc (void)
352 init_bdm_ppc_ops ();
353 add_target (&bdm_ppc_ops);