]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ppc-bdm.c
Copyright updates for 2007.
[thirdparty/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
6aba47ca 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2007
b6ba6518 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
197e01b6
EZ
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, 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"
383f0f5b 40#include "gdb_assert.h"
c906108c 41
a14ed312 42static void bdm_ppc_open (char *name, int from_tty);
c906108c 43
39f77062
KB
44static ptid_t bdm_ppc_wait (ptid_t ptid,
45 struct target_waitstatus *target_status);
c906108c 46
a14ed312 47static void bdm_ppc_fetch_registers (int regno);
c906108c 48
a14ed312 49static void bdm_ppc_store_registers (int regno);
c906108c
SS
50
51extern struct target_ops bdm_ppc_ops; /* Forward decl */
52\f
c5aa993b 53/*#define BDM_NUM_REGS 71 */
c906108c
SS
54#define BDM_NUM_REGS 24
55
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 */ \
61\
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 */ \
66\
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) */ \
c5aa993b 73 0, /* mq (SPR 0) */
c906108c 74\f
c5aa993b
JM
75
76char nowatchdog[4] =
77{0xff, 0xff, 0xff, 0x88};
c906108c
SS
78
79/* Open a connection to a remote debugger.
80 NAME is the filename used for communication. */
81
82static void
fba45db2 83bdm_ppc_open (char *name, int from_tty)
c906108c
SS
84{
85 CORE_ADDR watchdogaddr = 0xff000004;
86
87 ocd_open (name, from_tty, OCD_TARGET_MOTO_PPC, &bdm_ppc_ops);
88
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);
92
93 /* Disable watchdog timer on the board */
94 ocd_write_bytes (watchdogaddr, nowatchdog, 4);
95}
96
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). */
101
39f77062
KB
102static ptid_t
103bdm_ppc_wait (ptid_t ptid, struct target_waitstatus *target_status)
c906108c
SS
104{
105 int stop_reason;
106
107 target_status->kind = TARGET_WAITKIND_STOPPED;
108
109 stop_reason = ocd_wait ();
110
111 if (stop_reason)
112 {
113 target_status->value.sig = TARGET_SIGNAL_INT;
39f77062 114 return inferior_ptid;
c906108c
SS
115 }
116
c5aa993b 117 target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
c906108c
SS
118
119#if 0
120 {
121 unsigned long ecr, der;
122
c5aa993b
JM
123 ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
124 der = ocd_read_bdm_register (149); /* Read the debug enables register */
c906108c
SS
125 fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
126 }
127#endif
128
39f77062 129 return inferior_ptid;
c906108c
SS
130}
131\f
c5aa993b
JM
132static int bdm_regmap[] =
133{BDM_REGMAP};
c906108c
SS
134
135/* Read the remote registers into regs.
136 Fetch register REGNO, or all registers if REGNO == -1
137
138 The Wiggler uses the following codes to access the registers:
139
c5aa993b
JM
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)
c906108c
SS
152 */
153
154static void
fba45db2 155bdm_ppc_fetch_registers (int regno)
c906108c 156{
366f009f 157 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c906108c 158 int i;
d0b57c3a 159 unsigned char *regs;
c906108c
SS
160 int first_regno, last_regno;
161 int first_bdm_regno, last_bdm_regno;
d0b57c3a 162 int reglen;
c906108c
SS
163
164 if (regno == -1)
165 {
166 first_regno = 0;
167 last_regno = NUM_REGS - 1;
168
169 first_bdm_regno = 0;
170 last_bdm_regno = BDM_NUM_REGS - 1;
171 }
172 else
173 {
174 first_regno = regno;
175 last_regno = regno;
176
c5aa993b
JM
177 first_bdm_regno = bdm_regmap[regno];
178 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
179 }
180
181 if (first_bdm_regno == -1)
182 {
23a6d369 183 regcache_raw_supply (current_regcache, first_regno, NULL);
c906108c
SS
184 return; /* Unsupported register */
185 }
186
383f0f5b
JB
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));
192
c906108c
SS
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 */
197 {
198/* printf("Asking for register %d\n", first_regno); */
199
200 /* if asking for an invalid register */
2188cbdd 201 if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
cb06fa07 202 || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
366f009f
JB
203 || ((first_regno >= tdep->ppc_fp0_regnum)
204 && (first_regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
c906108c
SS
205 {
206/* printf("invalid reg request!\n"); */
23a6d369 207 regcache_raw_supply (current_regcache, first_regno, NULL);
c5aa993b
JM
208 return; /* Unsupported register */
209 }
c906108c
SS
210 else
211 {
c5aa993b
JM
212 regs = ocd_read_bdm_registers (first_bdm_regno,
213 last_bdm_regno, &reglen);
214 }
c906108c 215 }
c5aa993b 216 else
d0b57c3a 217 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
218 _("ppc_bdm_fetch_registers: "
219 "'all registers' case not implemented"));
c906108c
SS
220
221#endif
222#if 0
223 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
224#endif
225
226 for (i = first_regno; i <= last_regno; i++)
227 {
228 int bdm_regno, regoffset;
229
c5aa993b 230 bdm_regno = bdm_regmap[i];
c906108c
SS
231 if (bdm_regno != -1)
232 {
233 regoffset = bdm_regno - first_bdm_regno;
234
235 if (regoffset >= reglen / 4)
236 continue;
237
23a6d369 238 regcache_raw_supply (current_regcache, i, regs + 4 * regoffset);
c906108c
SS
239 }
240 else
23a6d369 241 regcache_raw_supply (current_regcache, i, NULL); /* Unsupported register */
c906108c
SS
242 }
243}
244
245/* Store register REGNO, or all registers if REGNO == -1, from the contents
246 of REGISTERS. FIXME: ignores errors. */
247
248static void
fba45db2 249bdm_ppc_store_registers (int regno)
c906108c 250{
366f009f 251 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c906108c
SS
252 int i;
253 int first_regno, last_regno;
254 int first_bdm_regno, last_bdm_regno;
255
256 if (regno == -1)
257 {
258 first_regno = 0;
259 last_regno = NUM_REGS - 1;
260
261 first_bdm_regno = 0;
262 last_bdm_regno = BDM_NUM_REGS - 1;
263 }
264 else
265 {
266 first_regno = regno;
267 last_regno = regno;
268
c5aa993b
JM
269 first_bdm_regno = bdm_regmap[regno];
270 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
271 }
272
273 if (first_bdm_regno == -1)
274 return; /* Unsupported register */
275
383f0f5b
JB
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));
281
c906108c
SS
282 for (i = first_regno; i <= last_regno; i++)
283 {
284 int bdm_regno;
285
c5aa993b 286 bdm_regno = bdm_regmap[i];
c906108c
SS
287
288 /* only attempt to write if it's a valid ppc 8xx register */
289 /* (need to avoid FP regs and MQ reg) */
e3f36dbd
KB
290 if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
291 && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
366f009f
JB
292 && ((i < tdep->ppc_fp0_regnum)
293 || (i >= tdep->ppc_fp0_regnum + ppc_num_fprs)))
c906108c
SS
294 {
295/* printf("write valid reg %d\n", bdm_regno); */
62700349 296 ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
c5aa993b 297 }
c906108c 298/*
2188cbdd 299 else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
9aa1e687 300 printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
c5aa993b
JM
301 else
302 printf("don't write invalid reg %d\n", bdm_regno);
303 */
c906108c
SS
304 }
305}
306\f
307/* Define the target subroutine names */
308
c5aa993b 309struct target_ops bdm_ppc_ops;
c906108c 310
c5aa993b
JM
311static void
312init_bdm_ppc_ops (void)
c906108c 313{
c5aa993b
JM
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\
c906108c
SS
317specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
318a wiggler, specify wiggler and then the port it is connected to\n\
c5aa993b
JM
319(e.g. wiggler lpt1)."; /* to_doc */
320 bdm_ppc_ops.to_open = bdm_ppc_open;
321 bdm_ppc_ops.to_close = ocd_close;
c5aa993b 322 bdm_ppc_ops.to_detach = ocd_detach;
c5aa993b
JM
323 bdm_ppc_ops.to_resume = ocd_resume;
324 bdm_ppc_ops.to_wait = bdm_ppc_wait;
c5aa993b
JM
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;
c8e73a31 328 bdm_ppc_ops.deprecated_xfer_memory = ocd_xfer_memory;
c5aa993b
JM
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;
c5aa993b
JM
332 bdm_ppc_ops.to_kill = ocd_kill;
333 bdm_ppc_ops.to_load = ocd_load;
c5aa993b 334 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
c5aa993b 335 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
c5aa993b
JM
336 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
337 bdm_ppc_ops.to_stop = ocd_stop;
c5aa993b 338 bdm_ppc_ops.to_stratum = process_stratum;
c5aa993b
JM
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;
c5aa993b
JM
344 bdm_ppc_ops.to_magic = OPS_MAGIC;
345} /* init_bdm_ppc_ops */
c906108c 346
a78f21af
AC
347extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */
348
c906108c 349void
fba45db2 350_initialize_bdm_ppc (void)
c906108c 351{
c5aa993b 352 init_bdm_ppc_ops ();
c906108c
SS
353 add_target (&bdm_ppc_ops);
354}