2003-09-17 Andrew Cagney <cagney@redhat.com>
[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
SS
155{
156 int i;
157 unsigned char *regs, *beginregs, *endregs, *almostregs;
158 unsigned char midregs[32];
159 unsigned char mqreg[1];
160 int first_regno, last_regno;
161 int first_bdm_regno, last_bdm_regno;
162 int reglen, beginreglen, endreglen;
163
164#if 1
165 for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
166 {
167 midregs[i] = -1;
168 }
169 mqreg[0] = -1;
170#endif
171
172 if (regno == -1)
173 {
174 first_regno = 0;
175 last_regno = NUM_REGS - 1;
176
177 first_bdm_regno = 0;
178 last_bdm_regno = BDM_NUM_REGS - 1;
179 }
180 else
181 {
182 first_regno = regno;
183 last_regno = regno;
184
c5aa993b
JM
185 first_bdm_regno = bdm_regmap[regno];
186 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
187 }
188
189 if (first_bdm_regno == -1)
190 {
191 supply_register (first_regno, NULL);
192 return; /* Unsupported register */
193 }
194
195#if 1
196 /* Can't ask for floating point regs on ppc 8xx, also need to
197 avoid asking for the mq register. */
198 if (first_regno == last_regno) /* only want one reg */
199 {
200/* printf("Asking for register %d\n", first_regno); */
201
202 /* if asking for an invalid register */
2188cbdd 203 if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
cb06fa07 204 || (first_regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
2188cbdd 205 || ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
c906108c
SS
206 {
207/* printf("invalid reg request!\n"); */
c5aa993b
JM
208 supply_register (first_regno, NULL);
209 return; /* Unsupported register */
210 }
c906108c
SS
211 else
212 {
c5aa993b
JM
213 regs = ocd_read_bdm_registers (first_bdm_regno,
214 last_bdm_regno, &reglen);
215 }
c906108c 216 }
c5aa993b
JM
217 else
218 /* want all regs */
c906108c
SS
219 {
220/* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
221 beginregs = ocd_read_bdm_registers (first_bdm_regno,
c5aa993b
JM
222 FP0_REGNUM - 1, &beginreglen);
223 endregs = (strcat (midregs,
224 ocd_read_bdm_registers (FPLAST_REGNUM + 1,
225 last_bdm_regno - 1, &endreglen)));
c906108c
SS
226 almostregs = (strcat (beginregs, endregs));
227 regs = (strcat (almostregs, mqreg));
228 reglen = beginreglen + 32 + endreglen + 1;
229 }
230
231#endif
232#if 0
233 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
234#endif
235
236 for (i = first_regno; i <= last_regno; i++)
237 {
238 int bdm_regno, regoffset;
239
c5aa993b 240 bdm_regno = bdm_regmap[i];
c906108c
SS
241 if (bdm_regno != -1)
242 {
243 regoffset = bdm_regno - first_bdm_regno;
244
245 if (regoffset >= reglen / 4)
246 continue;
247
248 supply_register (i, regs + 4 * regoffset);
249 }
250 else
c5aa993b 251 supply_register (i, NULL); /* Unsupported register */
c906108c
SS
252 }
253}
254
255/* Store register REGNO, or all registers if REGNO == -1, from the contents
256 of REGISTERS. FIXME: ignores errors. */
257
258static void
fba45db2 259bdm_ppc_store_registers (int regno)
c906108c
SS
260{
261 int i;
262 int first_regno, last_regno;
263 int first_bdm_regno, last_bdm_regno;
264
265 if (regno == -1)
266 {
267 first_regno = 0;
268 last_regno = NUM_REGS - 1;
269
270 first_bdm_regno = 0;
271 last_bdm_regno = BDM_NUM_REGS - 1;
272 }
273 else
274 {
275 first_regno = regno;
276 last_regno = regno;
277
c5aa993b
JM
278 first_bdm_regno = bdm_regmap[regno];
279 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
280 }
281
282 if (first_bdm_regno == -1)
283 return; /* Unsupported register */
284
285 for (i = first_regno; i <= last_regno; i++)
286 {
287 int bdm_regno;
288
c5aa993b 289 bdm_regno = bdm_regmap[i];
c906108c
SS
290
291 /* only attempt to write if it's a valid ppc 8xx register */
292 /* (need to avoid FP regs and MQ reg) */
e3f36dbd
KB
293 if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
294 && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum)
295 && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
c906108c
SS
296 {
297/* printf("write valid reg %d\n", bdm_regno); */
62700349 298 ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
c5aa993b 299 }
c906108c 300/*
2188cbdd 301 else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
9aa1e687 302 printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
c5aa993b
JM
303 else
304 printf("don't write invalid reg %d\n", bdm_regno);
305 */
c906108c
SS
306 }
307}
308\f
309/* Define the target subroutine names */
310
c5aa993b 311struct target_ops bdm_ppc_ops;
c906108c 312
c5aa993b
JM
313static void
314init_bdm_ppc_ops (void)
c906108c 315{
c5aa993b
JM
316 bdm_ppc_ops.to_shortname = "ocd";
317 bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
318 bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
c906108c
SS
319specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
320a wiggler, specify wiggler and then the port it is connected to\n\
c5aa993b
JM
321(e.g. wiggler lpt1)."; /* to_doc */
322 bdm_ppc_ops.to_open = bdm_ppc_open;
323 bdm_ppc_ops.to_close = ocd_close;
c5aa993b 324 bdm_ppc_ops.to_detach = ocd_detach;
c5aa993b
JM
325 bdm_ppc_ops.to_resume = ocd_resume;
326 bdm_ppc_ops.to_wait = bdm_ppc_wait;
c5aa993b
JM
327 bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
328 bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
329 bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
330 bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
331 bdm_ppc_ops.to_files_info = ocd_files_info;
332 bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
333 bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
c5aa993b
JM
334 bdm_ppc_ops.to_kill = ocd_kill;
335 bdm_ppc_ops.to_load = ocd_load;
c5aa993b 336 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
c5aa993b 337 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
c5aa993b
JM
338 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
339 bdm_ppc_ops.to_stop = ocd_stop;
c5aa993b 340 bdm_ppc_ops.to_stratum = process_stratum;
c5aa993b
JM
341 bdm_ppc_ops.to_has_all_memory = 1;
342 bdm_ppc_ops.to_has_memory = 1;
343 bdm_ppc_ops.to_has_stack = 1;
344 bdm_ppc_ops.to_has_registers = 1;
345 bdm_ppc_ops.to_has_execution = 1;
c5aa993b
JM
346 bdm_ppc_ops.to_magic = OPS_MAGIC;
347} /* init_bdm_ppc_ops */
c906108c 348
a78f21af
AC
349extern initialize_file_ftype _initialize_bdm_ppc; /* -Wmissing-prototypes */
350
c906108c 351void
fba45db2 352_initialize_bdm_ppc (void)
c906108c 353{
c5aa993b 354 init_bdm_ppc_ops ();
c906108c
SS
355 add_target (&bdm_ppc_ops);
356}
This page took 0.416984 seconds and 4 git commands to generate.