OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [ppc-bdm.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Remote target communications for the Macraigor Systems BDM Wiggler
2
   talking to a Motorola PPC 8xx ADS board
3
   Copyright 1996, 1997 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "gdbcore.h"
24
#include "gdb_string.h"
25
#include <fcntl.h>
26
#include "frame.h"
27
#include "inferior.h"
28
#include "bfd.h"
29
#include "symfile.h"
30
#include "target.h"
31
#include "gdb_wait.h"
32
#include "gdbcmd.h"
33
#include "objfiles.h"
34
#include "gdb-stabs.h"
35
#include <sys/types.h>
36
#include <signal.h>
37
#include "serial.h"
38
#include "ocd.h"
39
 
40
static void bdm_ppc_open PARAMS ((char *name, int from_tty));
41
 
42
static int bdm_ppc_wait PARAMS ((int pid,
43
                                 struct target_waitstatus * target_status));
44
 
45
static void bdm_ppc_fetch_registers PARAMS ((int regno));
46
 
47
static void bdm_ppc_store_registers PARAMS ((int regno));
48
 
49
extern struct target_ops bdm_ppc_ops;   /* Forward decl */
50
 
51
/*#define BDM_NUM_REGS 71 */
52
#define BDM_NUM_REGS 24
53
 
54
#define BDM_REGMAP \
55
        2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, /* r0-r7 */ \
56
        2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, /* r8-r15 */ \
57
        2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, /* r16-r23 */ \
58
        2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, /* r24-r31 */ \
59
\
60
        2080, 2082, 2084, 2086, 2088, 2090, 2092, 2094, /* fp0->fp8 */ \
61
        2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, /* fp0->fp8 */ \
62
        2112, 2114, 2116, 2118, 2120, 2122, 2124, 2126, /* fp0->fp8 */ \
63
        2128, 2130, 2132, 2134, 2136, 2138, 2140, 2142, /* fp0->fp8 */ \
64
\
65
        26,        /* pc (SRR0 (SPR 26)) */ \
66
        2146,      /* ps (MSR) */ \
67
        2144,      /* cnd (CR) */ \
68
        8,         /* lr (SPR 8) */ \
69
        9,         /* cnt (CTR (SPR 9)) */ \
70
        1,         /* xer (SPR 1) */ \
71
        0,                       /* mq (SPR 0) */
72
 
73
 
74
char nowatchdog[4] =
75
{0xff, 0xff, 0xff, 0x88};
76
 
77
/* Open a connection to a remote debugger.
78
   NAME is the filename used for communication.  */
79
 
80
static void
81
bdm_ppc_open (name, from_tty)
82
     char *name;
83
     int from_tty;
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
 
102
static int
103
bdm_ppc_wait (pid, target_status)
104
     int pid;
105
     struct target_waitstatus *target_status;
106
{
107
  int stop_reason;
108
 
109
  target_status->kind = TARGET_WAITKIND_STOPPED;
110
 
111
  stop_reason = ocd_wait ();
112
 
113
  if (stop_reason)
114
    {
115
      target_status->value.sig = TARGET_SIGNAL_INT;
116
      return inferior_pid;
117
    }
118
 
119
  target_status->value.sig = TARGET_SIGNAL_TRAP;        /* XXX for now */
120
 
121
#if 0
122
  {
123
    unsigned long ecr, der;
124
 
125
    ecr = ocd_read_bdm_register (148);  /* Read the exception cause register */
126
    der = ocd_read_bdm_register (149);  /* Read the debug enables register */
127
    fprintf_unfiltered (gdb_stdout, "ecr = 0x%x, der = 0x%x\n", ecr, der);
128
  }
129
#endif
130
 
131
  return inferior_pid;
132
}
133
 
134
static int bdm_regmap[] =
135
{BDM_REGMAP};
136
 
137
/* Read the remote registers into regs.
138
   Fetch register REGNO, or all registers if REGNO == -1
139
 
140
   The Wiggler uses the following codes to access the registers:
141
 
142
 
143
 
144
   1 - SPR 1 - XER
145
   8 - SPR 8 - LR
146
   9 - SPR 9 - CTR (known as cnt in GDB)
147
   26 - SPR 26 - SRR0 - pc
148
   1024 -> 2047         DCR 0 -> DCR 1023 (IBM PPC 4xx only)
149
   2048 -> 2079         R0 -> R31
150
   2080 -> 2143         FP0 -> FP31 (64 bit regs) (IBM PPC 5xx only)
151
   2144                 CR (known as cnd in GDB)
152
   2145                 FPCSR
153
   2146                 MSR (known as ps in GDB)
154
 */
155
 
156
static void
157
bdm_ppc_fetch_registers (regno)
158
     int regno;
159
{
160
  int i;
161
  unsigned char *regs, *beginregs, *endregs, *almostregs;
162
  unsigned char midregs[32];
163
  unsigned char mqreg[1];
164
  int first_regno, last_regno;
165
  int first_bdm_regno, last_bdm_regno;
166
  int reglen, beginreglen, endreglen;
167
 
168
#if 1
169
  for (i = 0; i < (FPLAST_REGNUM - FP0_REGNUM + 1); i++)
170
    {
171
      midregs[i] = -1;
172
    }
173
  mqreg[0] = -1;
174
#endif
175
 
176
  if (regno == -1)
177
    {
178
      first_regno = 0;
179
      last_regno = NUM_REGS - 1;
180
 
181
      first_bdm_regno = 0;
182
      last_bdm_regno = BDM_NUM_REGS - 1;
183
    }
184
  else
185
    {
186
      first_regno = regno;
187
      last_regno = regno;
188
 
189
      first_bdm_regno = bdm_regmap[regno];
190
      last_bdm_regno = bdm_regmap[regno];
191
    }
192
 
193
  if (first_bdm_regno == -1)
194
    {
195
      supply_register (first_regno, NULL);
196
      return;                   /* Unsupported register */
197
    }
198
 
199
#if 1
200
  /* Can't ask for floating point regs on ppc 8xx, also need to
201
     avoid asking for the mq register. */
202
  if (first_regno == last_regno)        /* only want one reg */
203
    {
204
/*      printf("Asking for register %d\n", first_regno); */
205
 
206
      /* if asking for an invalid register */
207
      if ((first_regno == MQ_REGNUM) ||
208
          ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
209
        {
210
/*          printf("invalid reg request!\n"); */
211
          supply_register (first_regno, NULL);
212
          return;               /* Unsupported register */
213
        }
214
      else
215
        {
216
          regs = ocd_read_bdm_registers (first_bdm_regno,
217
                                         last_bdm_regno, &reglen);
218
        }
219
    }
220
  else
221
    /* want all regs */
222
    {
223
/*      printf("Asking for registers %d to %d\n", first_regno, last_regno); */
224
      beginregs = ocd_read_bdm_registers (first_bdm_regno,
225
                                          FP0_REGNUM - 1, &beginreglen);
226
      endregs = (strcat (midregs,
227
                         ocd_read_bdm_registers (FPLAST_REGNUM + 1,
228
                                          last_bdm_regno - 1, &endreglen)));
229
      almostregs = (strcat (beginregs, endregs));
230
      regs = (strcat (almostregs, mqreg));
231
      reglen = beginreglen + 32 + endreglen + 1;
232
    }
233
 
234
#endif
235
#if 0
236
  regs = ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, &reglen);
237
#endif
238
 
239
  for (i = first_regno; i <= last_regno; i++)
240
    {
241
      int bdm_regno, regoffset;
242
 
243
      bdm_regno = bdm_regmap[i];
244
      if (bdm_regno != -1)
245
        {
246
          regoffset = bdm_regno - first_bdm_regno;
247
 
248
          if (regoffset >= reglen / 4)
249
            continue;
250
 
251
          supply_register (i, regs + 4 * regoffset);
252
        }
253
      else
254
        supply_register (i, NULL);      /* Unsupported register */
255
    }
256
}
257
 
258
/* Store register REGNO, or all registers if REGNO == -1, from the contents
259
   of REGISTERS.  FIXME: ignores errors.  */
260
 
261
static void
262
bdm_ppc_store_registers (regno)
263
     int regno;
264
{
265
  int i;
266
  int first_regno, last_regno;
267
  int first_bdm_regno, last_bdm_regno;
268
 
269
  if (regno == -1)
270
    {
271
      first_regno = 0;
272
      last_regno = NUM_REGS - 1;
273
 
274
      first_bdm_regno = 0;
275
      last_bdm_regno = BDM_NUM_REGS - 1;
276
    }
277
  else
278
    {
279
      first_regno = regno;
280
      last_regno = regno;
281
 
282
      first_bdm_regno = bdm_regmap[regno];
283
      last_bdm_regno = bdm_regmap[regno];
284
    }
285
 
286
  if (first_bdm_regno == -1)
287
    return;                     /* Unsupported register */
288
 
289
  for (i = first_regno; i <= last_regno; i++)
290
    {
291
      int bdm_regno;
292
 
293
      bdm_regno = bdm_regmap[i];
294
 
295
      /* only attempt to write if it's a valid ppc 8xx register */
296
      /* (need to avoid FP regs and MQ reg) */
297
      if ((i != MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
298
        {
299
/*          printf("write valid reg %d\n", bdm_regno); */
300
          ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
301
        }
302
/*
303
   else if (i == MQ_REGNUM)
304
   printf("don't write invalid reg %d (MQ_REGNUM)\n", bdm_regno);
305
   else
306
   printf("don't write invalid reg %d\n", bdm_regno);
307
 */
308
    }
309
}
310
 
311
/* Define the target subroutine names */
312
 
313
struct target_ops bdm_ppc_ops;
314
 
315
static void
316
init_bdm_ppc_ops (void)
317
{
318
  bdm_ppc_ops.to_shortname = "ocd";
319
  bdm_ppc_ops.to_longname = "Remote target with On-Chip Debugging";
320
  bdm_ppc_ops.to_doc = "Use a remote target with On-Chip Debugging.  To use a target box;\n\
321
specify the serial device it is connected to (e.g. /dev/ttya).  To use\n\
322
a wiggler, specify wiggler and then the port it is connected to\n\
323
(e.g. wiggler lpt1).";          /* to_doc */
324
  bdm_ppc_ops.to_open = bdm_ppc_open;
325
  bdm_ppc_ops.to_close = ocd_close;
326
  bdm_ppc_ops.to_attach = NULL;
327
  bdm_ppc_ops.to_post_attach = NULL;
328
  bdm_ppc_ops.to_require_attach = NULL;
329
  bdm_ppc_ops.to_detach = ocd_detach;
330
  bdm_ppc_ops.to_require_detach = NULL;
331
  bdm_ppc_ops.to_resume = ocd_resume;
332
  bdm_ppc_ops.to_wait = bdm_ppc_wait;
333
  bdm_ppc_ops.to_post_wait = NULL;
334
  bdm_ppc_ops.to_fetch_registers = bdm_ppc_fetch_registers;
335
  bdm_ppc_ops.to_store_registers = bdm_ppc_store_registers;
336
  bdm_ppc_ops.to_prepare_to_store = ocd_prepare_to_store;
337
  bdm_ppc_ops.to_xfer_memory = ocd_xfer_memory;
338
  bdm_ppc_ops.to_files_info = ocd_files_info;
339
  bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
340
  bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
341
  bdm_ppc_ops.to_terminal_init = NULL;
342
  bdm_ppc_ops.to_terminal_inferior = NULL;
343
  bdm_ppc_ops.to_terminal_ours_for_output = NULL;
344
  bdm_ppc_ops.to_terminal_ours = NULL;
345
  bdm_ppc_ops.to_terminal_info = NULL;
346
  bdm_ppc_ops.to_kill = ocd_kill;
347
  bdm_ppc_ops.to_load = ocd_load;
348
  bdm_ppc_ops.to_lookup_symbol = NULL;
349
  bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
350
  bdm_ppc_ops.to_post_startup_inferior = NULL;
351
  bdm_ppc_ops.to_acknowledge_created_inferior = NULL;
352
  bdm_ppc_ops.to_clone_and_follow_inferior = NULL;
353
  bdm_ppc_ops.to_post_follow_inferior_by_clone = NULL;
354
  bdm_ppc_ops.to_insert_fork_catchpoint = NULL;
355
  bdm_ppc_ops.to_remove_fork_catchpoint = NULL;
356
  bdm_ppc_ops.to_insert_vfork_catchpoint = NULL;
357
  bdm_ppc_ops.to_remove_vfork_catchpoint = NULL;
358
  bdm_ppc_ops.to_has_forked = NULL;
359
  bdm_ppc_ops.to_has_vforked = NULL;
360
  bdm_ppc_ops.to_can_follow_vfork_prior_to_exec = NULL;
361
  bdm_ppc_ops.to_post_follow_vfork = NULL;
362
  bdm_ppc_ops.to_insert_exec_catchpoint = NULL;
363
  bdm_ppc_ops.to_remove_exec_catchpoint = NULL;
364
  bdm_ppc_ops.to_has_execd = NULL;
365
  bdm_ppc_ops.to_reported_exec_events_per_exec_call = NULL;
366
  bdm_ppc_ops.to_has_exited = NULL;
367
  bdm_ppc_ops.to_mourn_inferior = ocd_mourn;
368
  bdm_ppc_ops.to_can_run = 0;
369
  bdm_ppc_ops.to_notice_signals = 0;
370
  bdm_ppc_ops.to_thread_alive = ocd_thread_alive;
371
  bdm_ppc_ops.to_stop = ocd_stop;
372
  bdm_ppc_ops.to_pid_to_exec_file = NULL;
373
  bdm_ppc_ops.to_core_file_to_sym_file = NULL;
374
  bdm_ppc_ops.to_stratum = process_stratum;
375
  bdm_ppc_ops.DONT_USE = NULL;
376
  bdm_ppc_ops.to_has_all_memory = 1;
377
  bdm_ppc_ops.to_has_memory = 1;
378
  bdm_ppc_ops.to_has_stack = 1;
379
  bdm_ppc_ops.to_has_registers = 1;
380
  bdm_ppc_ops.to_has_execution = 1;
381
  bdm_ppc_ops.to_sections = NULL;
382
  bdm_ppc_ops.to_sections_end = NULL;
383
  bdm_ppc_ops.to_magic = OPS_MAGIC;
384
}                               /* init_bdm_ppc_ops */
385
 
386
void
387
_initialize_bdm_ppc ()
388
{
389
  init_bdm_ppc_ops ();
390
  add_target (&bdm_ppc_ops);
391
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.