Phase 1 of the ptid_t changes.
[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 */
9aa1e687 203 if ((first_regno == PPC_MQ_REGNUM) ||
c5aa993b 204 ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
c906108c
SS
205 {
206/* printf("invalid reg request!\n"); */
c5aa993b
JM
207 supply_register (first_regno, NULL);
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
JM
216 else
217 /* want all regs */
c906108c
SS
218 {
219/* printf("Asking for registers %d to %d\n", first_regno, last_regno); */
220 beginregs = ocd_read_bdm_registers (first_bdm_regno,
c5aa993b
JM
221 FP0_REGNUM - 1, &beginreglen);
222 endregs = (strcat (midregs,
223 ocd_read_bdm_registers (FPLAST_REGNUM + 1,
224 last_bdm_regno - 1, &endreglen)));
c906108c
SS
225 almostregs = (strcat (beginregs, endregs));
226 regs = (strcat (almostregs, mqreg));
227 reglen = beginreglen + 32 + endreglen + 1;
228 }
229
230#endif
231#if 0
232 regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
233#endif
234
235 for (i = first_regno; i <= last_regno; i++)
236 {
237 int bdm_regno, regoffset;
238
c5aa993b 239 bdm_regno = bdm_regmap[i];
c906108c
SS
240 if (bdm_regno != -1)
241 {
242 regoffset = bdm_regno - first_bdm_regno;
243
244 if (regoffset >= reglen / 4)
245 continue;
246
247 supply_register (i, regs + 4 * regoffset);
248 }
249 else
c5aa993b 250 supply_register (i, NULL); /* Unsupported register */
c906108c
SS
251 }
252}
253
254/* Store register REGNO, or all registers if REGNO == -1, from the contents
255 of REGISTERS. FIXME: ignores errors. */
256
257static void
fba45db2 258bdm_ppc_store_registers (int regno)
c906108c
SS
259{
260 int i;
261 int first_regno, last_regno;
262 int first_bdm_regno, last_bdm_regno;
263
264 if (regno == -1)
265 {
266 first_regno = 0;
267 last_regno = NUM_REGS - 1;
268
269 first_bdm_regno = 0;
270 last_bdm_regno = BDM_NUM_REGS - 1;
271 }
272 else
273 {
274 first_regno = regno;
275 last_regno = regno;
276
c5aa993b
JM
277 first_bdm_regno = bdm_regmap[regno];
278 last_bdm_regno = bdm_regmap[regno];
c906108c
SS
279 }
280
281 if (first_bdm_regno == -1)
282 return; /* Unsupported register */
283
284 for (i = first_regno; i <= last_regno; i++)
285 {
286 int bdm_regno;
287
c5aa993b 288 bdm_regno = bdm_regmap[i];
c906108c
SS
289
290 /* only attempt to write if it's a valid ppc 8xx register */
291 /* (need to avoid FP regs and MQ reg) */
9aa1e687 292 if ((i != PPC_MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
c906108c
SS
293 {
294/* printf("write valid reg %d\n", bdm_regno); */
c5aa993b
JM
295 ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
296 }
c906108c 297/*
9aa1e687
KB
298 else if (i == PPC_MQ_REGNUM)
299 printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
c5aa993b
JM
300 else
301 printf("don't write invalid reg %d\n", bdm_regno);
302 */
c906108c
SS
303 }
304}
305\f
306/* Define the target subroutine names */
307
c5aa993b 308struct target_ops bdm_ppc_ops;
c906108c 309
c5aa993b
JM
310static void
311init_bdm_ppc_ops (void)
c906108c 312{
c5aa993b
JM
313 bdm_ppc_ops.to_shortname = "ocd";
314 bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
315 bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging. To use a target box;\n\
c906108c
SS
316specify the serial device it is connected to (e.g. /dev/ttya). To use\n\
317a wiggler, specify wiggler and then the port it is connected to\n\
c5aa993b
JM
318(e.g. wiggler lpt1)."; /* to_doc */
319 bdm_ppc_ops.to_open = bdm_ppc_open;
320 bdm_ppc_ops.to_close = ocd_close;
321 bdm_ppc_ops.to_attach = NULL;
c906108c
SS
322 bdm_ppc_ops.to_post_attach = NULL;
323 bdm_ppc_ops.to_require_attach = NULL;
c5aa993b 324 bdm_ppc_ops.to_detach = ocd_detach;
c906108c 325 bdm_ppc_ops.to_require_detach = NULL;
c5aa993b
JM
326 bdm_ppc_ops.to_resume = ocd_resume;
327 bdm_ppc_ops.to_wait = bdm_ppc_wait;
c906108c 328 bdm_ppc_ops.to_post_wait = NULL;
c5aa993b
JM
329 bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
330 bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
331 bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
332 bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
333 bdm_ppc_ops.to_files_info = ocd_files_info;
334 bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
335 bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
336 bdm_ppc_ops.to_terminal_init = NULL;
337 bdm_ppc_ops.to_terminal_inferior = NULL;
338 bdm_ppc_ops.to_terminal_ours_for_output = NULL;
339 bdm_ppc_ops.to_terminal_ours = NULL;
340 bdm_ppc_ops.to_terminal_info = NULL;
341 bdm_ppc_ops.to_kill = ocd_kill;
342 bdm_ppc_ops.to_load = ocd_load;
343 bdm_ppc_ops.to_lookup_symbol = NULL;
344 bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
c906108c
SS
345 bdm_ppc_ops.to_post_startup_inferior = NULL;
346 bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
c5aa993b
JM
347 bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
348 bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
c906108c
SS
349 bdm_ppc_ops.to_insert_fork_catchpoint = NULL;
350 bdm_ppc_ops.to_remove_fork_catchpoint = NULL;
351 bdm_ppc_ops.to_insert_vfork_catchpoint = NULL;
c5aa993b 352 bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
c906108c 353 bdm_ppc_ops.to_has_forked = NULL;
c5aa993b
JM
354 bdm_ppc_ops.to_has_vforked = NULL;
355 bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
c906108c
SS
356 bdm_ppc_ops.to_post_follow_vfork = NULL;
357 bdm_ppc_ops.to_insert_exec_catchpoint = NULL;
358 bdm_ppc_ops.to_remove_exec_catchpoint = NULL;
359 bdm_ppc_ops.to_has_execd = NULL;
360 bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL;
361 bdm_ppc_ops.to_has_exited = NULL;
c5aa993b
JM
362 bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
363 bdm_ppc_ops.to_can_run = 0;
364 bdm_ppc_ops.to_notice_signals = 0;
365 bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
366 bdm_ppc_ops.to_stop = ocd_stop;
c906108c 367 bdm_ppc_ops.to_pid_to_exec_file = NULL;
c5aa993b
JM
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.119346 seconds and 4 git commands to generate.