Back out change. The NetBSD changes need Jason Thorpe's approval, but
[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
39f77062
KB
43static ptid_t bdm_ppc_wait (ptid_t ptid,
44 struct target_waitstatus *target_status);
c906108c 45
a14ed312 46static void bdm_ppc_fetch_registers (int regno);
c906108c 47
a14ed312 48static void bdm_ppc_store_registers (int regno);
c906108c
SS
49
50extern struct target_ops bdm_ppc_ops; /* Forward decl */
51\f
c5aa993b 52/*#define BDM_NUM_REGS 71 */
c906108c
SS
53#define BDM_NUM_REGS 24
54
55#define BDM_REGMAP \
56 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
57 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
58 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
59 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
60\
61 2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
62 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
63 2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
64 2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
65\
66 26, /* pc (SRR0 (SPR 26)) */ \
67 2146, /* ps (MSR) */ \
68 2144, /* cnd (CR) */ \
69 8, /* lr (SPR 8) */ \
70 9, /* cnt (CTR (SPR 9)) */ \
71 1, /* xer (SPR 1) */ \
c5aa993b 72 0, /* mq (SPR 0) */
c906108c 73\f
c5aa993b
JM
74
75char nowatchdog[4] =
76{0xff, 0xff, 0xff, 0x88};
c906108c
SS
77
78/* Open a connection to a remote debugger.
79 NAME is the filename used for communication. */
80
81static void
fba45db2 82bdm_ppc_open (char *name, int from_tty)
c906108c
SS
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
39f77062
KB
101static ptid_t
102bdm_ppc_wait (ptid_t ptid, struct target_waitstatus *target_status)
c906108c
SS
103{
104 int stop_reason;
105
106 target_status->kind = TARGET_WAITKIND_STOPPED;
107
108 stop_reason = ocd_wait ();
109
110 if (stop_reason)
111 {
112 target_status->value.sig = TARGET_SIGNAL_INT;
39f77062 113 return inferior_ptid;
c906108c
SS
114 }
115
c5aa993b 116 target_status->value.sig = TARGET_SIGNAL_TRAP; /* XXX for now */
c906108c
SS
117
118#if 0
119 {
120 unsigned long ecr, der;
121
c5aa993b
JM
122 ecr = ocd_read_bdm_register (148); /* Read the exception cause register */
123 der = ocd_read_bdm_register (149); /* Read the debug enables register */
c906108c
SS
124 fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
125 }
126#endif
127
39f77062 128 return inferior_ptid;
c906108c
SS
129}
130\f
c5aa993b
JM
131static int bdm_regmap[] =
132{BDM_REGMAP};
c906108c
SS
133
134/* Read the remote registers into regs.
135 Fetch register REGNO, or all registers if REGNO == -1
136
137 The Wiggler uses the following codes to access the registers:
138
c5aa993b
JM
139 0 -> 1023 SPR 0 -> 1023
140 0 - SPR 0 - MQ
141 1 - SPR 1 - XER
142 8 - SPR 8 - LR
143 9 - SPR 9 - CTR (known as cnt in GDB)
144 26 - SPR 26 - SRR0 - pc
145 1024 -> 2047 DCR 0 -> DCR 1023 (IBM PPC 4xx only)
146 2048 -> 2079 R0 -> R31
147 2080 -> 2143 FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
148 2144 CR (known as cnd in GDB)
149 2145 FPCSR
150 2146 MSR (known as ps in GDB)
c906108c
SS
151 */
152
153static void
fba45db2 154bdm_ppc_fetch_registers (int regno)
c906108c 155{
366f009f 156 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c906108c
SS
157 int i;
158 unsigned char *regs, *beginregs, *endregs, *almostregs;
159 unsigned char midregs[32];
160 unsigned char mqreg[1];
161 int first_regno, last_regno;
162 int first_bdm_regno, last_bdm_regno;
163 int reglen, beginreglen, endreglen;
164
165#if 1
b967e06f 166 for (i = 0; i < ppc_num_fprs; i++)
c906108c
SS
167 {
168 midregs[i] = -1;
169 }
170 mqreg[0] = -1;
171#endif
172
173 if (regno == -1)
174 {
175 first_regno = 0;
176 last_regno = NUM_REGS - 1;
177
178 first_bdm_regno = 0;
179 last_bdm_regno = BDM_NUM_REGS - 1;
180 }
181 else
182 {
183 first_regno = regno;
184 last_regno = regno;
185
c5aa993b
JM
186 first_bdm_regno = bdm_regmap[regno];
187 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
188 }
189
190 if (first_bdm_regno == -1)
191 {
192 supply_register (first_regno, NULL);
193 return; /* Unsupported register */
194 }
195
196#if 1
197 /* Can't ask for floating point regs on ppc 8xx, also need to
198 avoid asking for the mq register. */
199 if (first_regno == last_regno) /* only want one reg */
200 {
201/* printf("Asking for register %d\n", first_regno); */
202
203 /* if asking for an invalid register */
2188cbdd 204 if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
cb06fa07 205 || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
366f009f
JB
206 || ((first_regno >= tdep->ppc_fp0_regnum)
207 && (first_regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
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,
366f009f
JB
224 tdep->ppc_fp0_regnum - 1,
225 &beginreglen);
226 endregs
227 = (strcat (midregs,
228 ocd_read_bdm_registers (tdep->ppc_fp0_regnum + ppc_num_fprs,
229 last_bdm_regno - 1, &endreglen)));
c906108c
SS
230 almostregs = (strcat (beginregs, endregs));
231 regs = (strcat (almostregs, mqreg));
232 reglen = beginreglen + 32 + endreglen + 1;
233 }
234
235#endif
236#if 0
237 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
238#endif
239
240 for (i = first_regno; i <= last_regno; i++)
241 {
242 int bdm_regno, regoffset;
243
c5aa993b 244 bdm_regno = bdm_regmap[i];
c906108c
SS
245 if (bdm_regno != -1)
246 {
247 regoffset = bdm_regno - first_bdm_regno;
248
249 if (regoffset >= reglen / 4)
250 continue;
251
252 supply_register (i, regs + 4 * regoffset);
253 }
254 else
c5aa993b 255 supply_register (i, NULL); /* Unsupported register */
c906108c
SS
256 }
257}
258
259/* Store register REGNO, or all registers if REGNO == -1, from the contents
260 of REGISTERS. FIXME: ignores errors. */
261
262static void
fba45db2 263bdm_ppc_store_registers (int regno)
c906108c 264{
366f009f 265 struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
c906108c
SS
266 int i;
267 int first_regno, last_regno;
268 int first_bdm_regno, last_bdm_regno;
269
270 if (regno == -1)
271 {
272 first_regno = 0;
273 last_regno = NUM_REGS - 1;
274
275 first_bdm_regno = 0;
276 last_bdm_regno = BDM_NUM_REGS - 1;
277 }
278 else
279 {
280 first_regno = regno;
281 last_regno = regno;
282
c5aa993b
JM
283 first_bdm_regno = bdm_regmap[regno];
284 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
285 }
286
287 if (first_bdm_regno == -1)
288 return; /* Unsupported register */
289
290 for (i = first_regno; i <= last_regno; i++)
291 {
292 int bdm_regno;
293
c5aa993b 294 bdm_regno = bdm_regmap[i];
c906108c
SS
295
296 /* only attempt to write if it's a valid ppc 8xx register */
297 /* (need to avoid FP regs and MQ reg) */
e3f36dbd
KB
298 if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
299 && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
366f009f
JB
300 && ((i < tdep->ppc_fp0_regnum)
301 || (i >= tdep->ppc_fp0_regnum + ppc_num_fprs)))
c906108c
SS
302 {
303/* printf("write valid reg %d\n", bdm_regno); */
62700349 304 ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
c5aa993b 305 }
c906108c 306/*
2188cbdd 307 else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
9aa1e687 308 printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
c5aa993b
JM
309 else
310 printf("don't write invalid reg %d\n", bdm_regno);
311 */
c906108c
SS
312 }
313}
314\f
315/* Define the target subroutine names */
316
c5aa993b 317struct target_ops bdm_ppc_ops;
c906108c 318
c5aa993b
JM
319static void
320init_bdm_ppc_ops (void)
c906108c 321{
c5aa993b
JM
322 bdm_ppc_ops.to_shortname = "ocd";
323 bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
324 bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
c906108c
SS
325specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
326a wiggler, specify wiggler and then the port it is connected to\n\
c5aa993b
JM
327(e.g. wiggler lpt1)."; /* to_doc */
328 bdm_ppc_ops.to_open = bdm_ppc_open;
329 bdm_ppc_ops.to_close = ocd_close;
c5aa993b 330 bdm_ppc_ops.to_detach = ocd_detach;
c5aa993b
JM
331 bdm_ppc_ops.to_resume = ocd_resume;
332 bdm_ppc_ops.to_wait = bdm_ppc_wait;
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;
c5aa993b
JM
340 bdm_ppc_ops.to_kill = ocd_kill;
341 bdm_ppc_ops.to_load = ocd_load;
c5aa993b 342 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
c5aa993b 343 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
c5aa993b
JM
344 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
345 bdm_ppc_ops.to_stop = ocd_stop;
c5aa993b 346 bdm_ppc_ops.to_stratum = process_stratum;
c5aa993b
JM
347 bdm_ppc_ops.to_has_all_memory = 1;
348 bdm_ppc_ops.to_has_memory = 1;
349 bdm_ppc_ops.to_has_stack = 1;
350 bdm_ppc_ops.to_has_registers = 1;
351 bdm_ppc_ops.to_has_execution = 1;
c5aa993b
JM
352 bdm_ppc_ops.to_magic = OPS_MAGIC;
353} /* init_bdm_ppc_ops */
c906108c 354
a78f21af
AC
355extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */
356
c906108c 357void
fba45db2 358_initialize_bdm_ppc (void)
c906108c 359{
c5aa993b 360 init_bdm_ppc_ops ();
c906108c
SS
361 add_target (&bdm_ppc_ops);
362}
This page took 0.587088 seconds and 4 git commands to generate.