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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [linux-ppc-low.c] - Blame information for rev 816

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

Line No. Rev Author Line
1 330 jeremybenn
/* GNU/Linux/PowerPC specific low level interface, for the remote server for
2
   GDB.
3
   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008,
4
   2009, 2010 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
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 3 of the License, or
11
   (at your option) any later version.
12
 
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.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "server.h"
22
#include "linux-low.h"
23
 
24
#include <elf.h>
25
#include <asm/ptrace.h>
26
 
27
/* These are in <asm/cputable.h> in current kernels.  */
28
#define PPC_FEATURE_HAS_VSX             0x00000080
29
#define PPC_FEATURE_HAS_ALTIVEC         0x10000000
30
#define PPC_FEATURE_HAS_SPE             0x00800000
31
#define PPC_FEATURE_CELL                0x00010000
32
#define PPC_FEATURE_HAS_DFP             0x00000400
33
 
34
static unsigned long ppc_hwcap;
35
 
36
 
37
/* Defined in auto-generated file powerpc-32l.c.  */
38
void init_registers_powerpc_32l (void);
39
/* Defined in auto-generated file powerpc-altivec32l.c.  */
40
void init_registers_powerpc_altivec32l (void);
41
/* Defined in auto-generated file powerpc-cell32l.c.  */
42
void init_registers_powerpc_cell32l (void);
43
/* Defined in auto-generated file powerpc-vsx32l.c.  */
44
void init_registers_powerpc_vsx32l (void);
45
/* Defined in auto-generated file powerpc-isa205-32l.c.  */
46
void init_registers_powerpc_isa205_32l (void);
47
/* Defined in auto-generated file powerpc-isa205-altivec32l.c.  */
48
void init_registers_powerpc_isa205_altivec32l (void);
49
/* Defined in auto-generated file powerpc-isa205-vsx32l.c.  */
50
void init_registers_powerpc_isa205_vsx32l (void);
51
/* Defined in auto-generated file powerpc-e500l.c.  */
52
void init_registers_powerpc_e500l (void);
53
/* Defined in auto-generated file powerpc-64l.c.  */
54
void init_registers_powerpc_64l (void);
55
/* Defined in auto-generated file powerpc-altivec64l.c.  */
56
void init_registers_powerpc_altivec64l (void);
57
/* Defined in auto-generated file powerpc-cell64l.c.  */
58
void init_registers_powerpc_cell64l (void);
59
/* Defined in auto-generated file powerpc-vsx64l.c.  */
60
void init_registers_powerpc_vsx64l (void);
61
/* Defined in auto-generated file powerpc-isa205-64l.c.  */
62
void init_registers_powerpc_isa205_64l (void);
63
/* Defined in auto-generated file powerpc-isa205-altivec64l.c.  */
64
void init_registers_powerpc_isa205_altivec64l (void);
65
/* Defined in auto-generated file powerpc-isa205-vsx64l.c.  */
66
void init_registers_powerpc_isa205_vsx64l (void);
67
 
68
#define ppc_num_regs 73
69
 
70
/* This sometimes isn't defined.  */
71
#ifndef PT_ORIG_R3
72
#define PT_ORIG_R3 34
73
#endif
74
#ifndef PT_TRAP
75
#define PT_TRAP 40
76
#endif
77
 
78
#ifdef __powerpc64__
79
/* We use a constant for FPSCR instead of PT_FPSCR, because
80
   many shipped PPC64 kernels had the wrong value in ptrace.h.  */
81
static int ppc_regmap[] =
82
 {PT_R0 * 8,     PT_R1 * 8,     PT_R2 * 8,     PT_R3 * 8,
83
  PT_R4 * 8,     PT_R5 * 8,     PT_R6 * 8,     PT_R7 * 8,
84
  PT_R8 * 8,     PT_R9 * 8,     PT_R10 * 8,    PT_R11 * 8,
85
  PT_R12 * 8,    PT_R13 * 8,    PT_R14 * 8,    PT_R15 * 8,
86
  PT_R16 * 8,    PT_R17 * 8,    PT_R18 * 8,    PT_R19 * 8,
87
  PT_R20 * 8,    PT_R21 * 8,    PT_R22 * 8,    PT_R23 * 8,
88
  PT_R24 * 8,    PT_R25 * 8,    PT_R26 * 8,    PT_R27 * 8,
89
  PT_R28 * 8,    PT_R29 * 8,    PT_R30 * 8,    PT_R31 * 8,
90
  PT_FPR0*8,     PT_FPR0*8 + 8, PT_FPR0*8+16,  PT_FPR0*8+24,
91
  PT_FPR0*8+32,  PT_FPR0*8+40,  PT_FPR0*8+48,  PT_FPR0*8+56,
92
  PT_FPR0*8+64,  PT_FPR0*8+72,  PT_FPR0*8+80,  PT_FPR0*8+88,
93
  PT_FPR0*8+96,  PT_FPR0*8+104,  PT_FPR0*8+112,  PT_FPR0*8+120,
94
  PT_FPR0*8+128, PT_FPR0*8+136,  PT_FPR0*8+144,  PT_FPR0*8+152,
95
  PT_FPR0*8+160,  PT_FPR0*8+168,  PT_FPR0*8+176,  PT_FPR0*8+184,
96
  PT_FPR0*8+192,  PT_FPR0*8+200,  PT_FPR0*8+208,  PT_FPR0*8+216,
97
  PT_FPR0*8+224,  PT_FPR0*8+232,  PT_FPR0*8+240,  PT_FPR0*8+248,
98
  PT_NIP * 8,    PT_MSR * 8,    PT_CCR * 8,    PT_LNK * 8,
99
  PT_CTR * 8,    PT_XER * 8,    PT_FPR0*8 + 256,
100
  PT_ORIG_R3 * 8, PT_TRAP * 8 };
101
#else
102
/* Currently, don't check/send MQ.  */
103
static int ppc_regmap[] =
104
 {PT_R0 * 4,     PT_R1 * 4,     PT_R2 * 4,     PT_R3 * 4,
105
  PT_R4 * 4,     PT_R5 * 4,     PT_R6 * 4,     PT_R7 * 4,
106
  PT_R8 * 4,     PT_R9 * 4,     PT_R10 * 4,    PT_R11 * 4,
107
  PT_R12 * 4,    PT_R13 * 4,    PT_R14 * 4,    PT_R15 * 4,
108
  PT_R16 * 4,    PT_R17 * 4,    PT_R18 * 4,    PT_R19 * 4,
109
  PT_R20 * 4,    PT_R21 * 4,    PT_R22 * 4,    PT_R23 * 4,
110
  PT_R24 * 4,    PT_R25 * 4,    PT_R26 * 4,    PT_R27 * 4,
111
  PT_R28 * 4,    PT_R29 * 4,    PT_R30 * 4,    PT_R31 * 4,
112
  PT_FPR0*4,     PT_FPR0*4 + 8, PT_FPR0*4+16,  PT_FPR0*4+24,
113
  PT_FPR0*4+32,  PT_FPR0*4+40,  PT_FPR0*4+48,  PT_FPR0*4+56,
114
  PT_FPR0*4+64,  PT_FPR0*4+72,  PT_FPR0*4+80,  PT_FPR0*4+88,
115
  PT_FPR0*4+96,  PT_FPR0*4+104,  PT_FPR0*4+112,  PT_FPR0*4+120,
116
  PT_FPR0*4+128, PT_FPR0*4+136,  PT_FPR0*4+144,  PT_FPR0*4+152,
117
  PT_FPR0*4+160,  PT_FPR0*4+168,  PT_FPR0*4+176,  PT_FPR0*4+184,
118
  PT_FPR0*4+192,  PT_FPR0*4+200,  PT_FPR0*4+208,  PT_FPR0*4+216,
119
  PT_FPR0*4+224,  PT_FPR0*4+232,  PT_FPR0*4+240,  PT_FPR0*4+248,
120
  PT_NIP * 4,    PT_MSR * 4,    PT_CCR * 4,    PT_LNK * 4,
121
  PT_CTR * 4,    PT_XER * 4,    PT_FPSCR * 4,
122
  PT_ORIG_R3 * 4, PT_TRAP * 4
123
 };
124
 
125
static int ppc_regmap_e500[] =
126
 {PT_R0 * 4,     PT_R1 * 4,     PT_R2 * 4,     PT_R3 * 4,
127
  PT_R4 * 4,     PT_R5 * 4,     PT_R6 * 4,     PT_R7 * 4,
128
  PT_R8 * 4,     PT_R9 * 4,     PT_R10 * 4,    PT_R11 * 4,
129
  PT_R12 * 4,    PT_R13 * 4,    PT_R14 * 4,    PT_R15 * 4,
130
  PT_R16 * 4,    PT_R17 * 4,    PT_R18 * 4,    PT_R19 * 4,
131
  PT_R20 * 4,    PT_R21 * 4,    PT_R22 * 4,    PT_R23 * 4,
132
  PT_R24 * 4,    PT_R25 * 4,    PT_R26 * 4,    PT_R27 * 4,
133
  PT_R28 * 4,    PT_R29 * 4,    PT_R30 * 4,    PT_R31 * 4,
134
  -1,            -1,            -1,            -1,
135
  -1,            -1,            -1,            -1,
136
  -1,            -1,            -1,            -1,
137
  -1,            -1,            -1,            -1,
138
  -1,            -1,            -1,            -1,
139
  -1,            -1,            -1,            -1,
140
  -1,            -1,            -1,            -1,
141
  -1,            -1,            -1,            -1,
142
  PT_NIP * 4,    PT_MSR * 4,    PT_CCR * 4,    PT_LNK * 4,
143
  PT_CTR * 4,    PT_XER * 4,    -1,
144
  PT_ORIG_R3 * 4, PT_TRAP * 4
145
 };
146
#endif
147
 
148
static int
149
ppc_cannot_store_register (int regno)
150
{
151
#ifndef __powerpc64__
152
  /* Some kernels do not allow us to store fpscr.  */
153
  if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE) && regno == find_regno ("fpscr"))
154
    return 2;
155
#endif
156
 
157
  /* Some kernels do not allow us to store orig_r3 or trap.  */
158
  if (regno == find_regno ("orig_r3")
159
      || regno == find_regno ("trap"))
160
    return 2;
161
 
162
  return 0;
163
}
164
 
165
static int
166
ppc_cannot_fetch_register (int regno)
167
{
168
  return 0;
169
}
170
 
171
static void
172
ppc_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
173
{
174
  int size = register_size (regno);
175
 
176
  memset (buf, 0, sizeof (long));
177
 
178
  if (size < sizeof (long))
179
    collect_register (regcache, regno, buf + sizeof (long) - size);
180
  else
181
    collect_register (regcache, regno, buf);
182
}
183
 
184
static void
185
ppc_supply_ptrace_register (struct regcache *regcache,
186
                            int regno, const char *buf)
187
{
188
  int size = register_size (regno);
189
  if (size < sizeof (long))
190
    supply_register (regcache, regno, buf + sizeof (long) - size);
191
  else
192
    supply_register (regcache, regno, buf);
193
}
194
 
195
 
196
#define INSTR_SC        0x44000002
197
#define NR_spu_run      0x0116
198
 
199
/* If the PPU thread is currently stopped on a spu_run system call,
200
   return to FD and ADDR the file handle and NPC parameter address
201
   used with the system call.  Return non-zero if successful.  */
202
static int
203
parse_spufs_run (struct regcache *regcache, int *fd, CORE_ADDR *addr)
204
{
205
  CORE_ADDR curr_pc;
206
  int curr_insn;
207
  int curr_r0;
208
 
209
  if (register_size (0) == 4)
210
    {
211
      unsigned int pc, r0, r3, r4;
212
      collect_register_by_name (regcache, "pc", &pc);
213
      collect_register_by_name (regcache, "r0", &r0);
214
      collect_register_by_name (regcache, "orig_r3", &r3);
215
      collect_register_by_name (regcache, "r4", &r4);
216
      curr_pc = (CORE_ADDR) pc;
217
      curr_r0 = (int) r0;
218
      *fd = (int) r3;
219
      *addr = (CORE_ADDR) r4;
220
    }
221
  else
222
    {
223
      unsigned long pc, r0, r3, r4;
224
      collect_register_by_name (regcache, "pc", &pc);
225
      collect_register_by_name (regcache, "r0", &r0);
226
      collect_register_by_name (regcache, "orig_r3", &r3);
227
      collect_register_by_name (regcache, "r4", &r4);
228
      curr_pc = (CORE_ADDR) pc;
229
      curr_r0 = (int) r0;
230
      *fd = (int) r3;
231
      *addr = (CORE_ADDR) r4;
232
    }
233
 
234
  /* Fetch instruction preceding current NIP.  */
235
  if ((*the_target->read_memory) (curr_pc - 4,
236
                                  (unsigned char *) &curr_insn, 4) != 0)
237
    return 0;
238
  /* It should be a "sc" instruction.  */
239
  if (curr_insn != INSTR_SC)
240
    return 0;
241
  /* System call number should be NR_spu_run.  */
242
  if (curr_r0 != NR_spu_run)
243
    return 0;
244
 
245
  return 1;
246
}
247
 
248
static CORE_ADDR
249
ppc_get_pc (struct regcache *regcache)
250
{
251
  CORE_ADDR addr;
252
  int fd;
253
 
254
  if (parse_spufs_run (regcache, &fd, &addr))
255
    {
256
      unsigned int pc;
257
      (*the_target->read_memory) (addr, (unsigned char *) &pc, 4);
258
      return ((CORE_ADDR)1 << 63) | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4);
259
    }
260
  else if (register_size (0) == 4)
261
    {
262
      unsigned int pc;
263
      collect_register_by_name (regcache, "pc", &pc);
264
      return (CORE_ADDR) pc;
265
    }
266
  else
267
    {
268
      unsigned long pc;
269
      collect_register_by_name (regcache, "pc", &pc);
270
      return (CORE_ADDR) pc;
271
    }
272
}
273
 
274
static void
275
ppc_set_pc (struct regcache *regcache, CORE_ADDR pc)
276
{
277
  CORE_ADDR addr;
278
  int fd;
279
 
280
  if (parse_spufs_run (regcache, &fd, &addr))
281
    {
282
      unsigned int newpc = pc;
283
      (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4);
284
    }
285
  else if (register_size (0) == 4)
286
    {
287
      unsigned int newpc = pc;
288
      supply_register_by_name (regcache, "pc", &newpc);
289
    }
290
  else
291
    {
292
      unsigned long newpc = pc;
293
      supply_register_by_name (regcache, "pc", &newpc);
294
    }
295
}
296
 
297
 
298
static int
299
ppc_get_hwcap (unsigned long *valp)
300
{
301
  int wordsize = register_size (0);
302
  unsigned char *data = alloca (2 * wordsize);
303
  int offset = 0;
304
 
305
  while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
306
    {
307
      if (wordsize == 4)
308
        {
309
          unsigned int *data_p = (unsigned int *)data;
310
          if (data_p[0] == AT_HWCAP)
311
            {
312
              *valp = data_p[1];
313
              return 1;
314
            }
315
        }
316
      else
317
        {
318
          unsigned long *data_p = (unsigned long *)data;
319
          if (data_p[0] == AT_HWCAP)
320
            {
321
              *valp = data_p[1];
322
              return 1;
323
            }
324
        }
325
 
326
      offset += 2 * wordsize;
327
    }
328
 
329
  *valp = 0;
330
  return 0;
331
}
332
 
333
static void
334
ppc_arch_setup (void)
335
{
336
#ifdef __powerpc64__
337
  long msr;
338
  struct regcache *regcache;
339
 
340
  /* On a 64-bit host, assume 64-bit inferior process with no
341
     AltiVec registers.  Reset ppc_hwcap to ensure that the
342
     collect_register call below does not fail.  */
343
  init_registers_powerpc_64l ();
344
  ppc_hwcap = 0;
345
 
346
  /* Only if the high bit of the MSR is set, we actually have
347
     a 64-bit inferior.  */
348
  regcache = new_register_cache ();
349
  fetch_inferior_registers (regcache, find_regno ("msr"));
350
  collect_register_by_name (regcache, "msr", &msr);
351
  free_register_cache (regcache);
352
  if (msr < 0)
353
    {
354
      ppc_get_hwcap (&ppc_hwcap);
355
      if (ppc_hwcap & PPC_FEATURE_CELL)
356
        init_registers_powerpc_cell64l ();
357
      else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
358
        {
359
          /* Power ISA 2.05 (implemented by Power 6 and newer processors)
360
             increases the FPSCR from 32 bits to 64 bits. Even though Power 7
361
             supports this ISA version, it doesn't have PPC_FEATURE_ARCH_2_05
362
             set, only PPC_FEATURE_ARCH_2_06.  Since for now the only bits
363
             used in the higher half of the register are for Decimal Floating
364
             Point, we check if that feature is available to decide the size
365
             of the FPSCR.  */
366
          if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
367
            init_registers_powerpc_isa205_vsx64l ();
368
          else
369
            init_registers_powerpc_vsx64l ();
370
        }
371
      else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
372
        {
373
          if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
374
            init_registers_powerpc_isa205_altivec64l ();
375
          else
376
            init_registers_powerpc_altivec64l ();
377
        }
378
 
379
      return;
380
    }
381
#endif
382
 
383
  /* OK, we have a 32-bit inferior.  */
384
  init_registers_powerpc_32l ();
385
 
386
  ppc_get_hwcap (&ppc_hwcap);
387
  if (ppc_hwcap & PPC_FEATURE_CELL)
388
    init_registers_powerpc_cell32l ();
389
  else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
390
    {
391
      if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
392
        init_registers_powerpc_isa205_vsx32l ();
393
      else
394
        init_registers_powerpc_vsx32l ();
395
    }
396
  else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
397
    {
398
      if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
399
        init_registers_powerpc_isa205_altivec32l ();
400
      else
401
        init_registers_powerpc_altivec32l ();
402
    }
403
 
404
  /* On 32-bit machines, check for SPE registers.
405
     Set the low target's regmap field as appropriately.  */
406
#ifndef __powerpc64__
407
  the_low_target.regmap = ppc_regmap;
408
  if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
409
    {
410
      init_registers_powerpc_e500l ();
411
      the_low_target.regmap = ppc_regmap_e500;
412
   }
413
 
414
  /* If the FPSCR is 64-bit wide, we need to fetch the whole 64-bit
415
     slot and not just its second word.  The PT_FPSCR supplied in a
416
     32-bit GDB compilation doesn't reflect this.  */
417
  if (register_size (70) == 8)
418
    ppc_regmap[70] = (48 + 2*32) * sizeof (long);
419
#endif
420
}
421
 
422
/* Correct in either endianness.
423
   This instruction is "twge r2, r2", which GDB uses as a software
424
   breakpoint.  */
425
static const unsigned int ppc_breakpoint = 0x7d821008;
426
#define ppc_breakpoint_len 4
427
 
428
static int
429
ppc_breakpoint_at (CORE_ADDR where)
430
{
431
  unsigned int insn;
432
 
433
  if (where & ((CORE_ADDR)1 << 63))
434
    {
435
      char mem_annex[32];
436
      sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff));
437
      (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn,
438
                                NULL, where & 0xffffffff, 4);
439
      if (insn == 0x3fff)
440
        return 1;
441
    }
442
  else
443
    {
444
      (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
445
      if (insn == ppc_breakpoint)
446
        return 1;
447
      /* If necessary, recognize more trap instructions here.  GDB only uses
448
         the one.  */
449
    }
450
 
451
  return 0;
452
}
453
 
454
/* Provide only a fill function for the general register set.  ps_lgetregs
455
   will use this for NPTL support.  */
456
 
457
static void ppc_fill_gregset (struct regcache *regcache, void *buf)
458
{
459
  int i;
460
 
461
  for (i = 0; i < 32; i++)
462
    ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
463
 
464
  for (i = 64; i < 70; i++)
465
    ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
466
 
467
  for (i = 71; i < 73; i++)
468
    ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
469
}
470
 
471
#ifndef PTRACE_GETVSXREGS
472
#define PTRACE_GETVSXREGS 27
473
#define PTRACE_SETVSXREGS 28
474
#endif
475
 
476
#define SIZEOF_VSXREGS 32*8
477
 
478
static void
479
ppc_fill_vsxregset (struct regcache *regcache, void *buf)
480
{
481
  int i, base;
482
  char *regset = buf;
483
 
484
  if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
485
    return;
486
 
487
  base = find_regno ("vs0h");
488
  for (i = 0; i < 32; i++)
489
    collect_register (regcache, base + i, &regset[i * 8]);
490
}
491
 
492
static void
493
ppc_store_vsxregset (struct regcache *regcache, const void *buf)
494
{
495
  int i, base;
496
  const char *regset = buf;
497
 
498
  if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
499
    return;
500
 
501
  base = find_regno ("vs0h");
502
  for (i = 0; i < 32; i++)
503
    supply_register (regcache, base + i, &regset[i * 8]);
504
}
505
 
506
#ifndef PTRACE_GETVRREGS
507
#define PTRACE_GETVRREGS 18
508
#define PTRACE_SETVRREGS 19
509
#endif
510
 
511
#define SIZEOF_VRREGS 33*16+4
512
 
513
static void
514
ppc_fill_vrregset (struct regcache *regcache, void *buf)
515
{
516
  int i, base;
517
  char *regset = buf;
518
 
519
  if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
520
    return;
521
 
522
  base = find_regno ("vr0");
523
  for (i = 0; i < 32; i++)
524
    collect_register (regcache, base + i, &regset[i * 16]);
525
 
526
  collect_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
527
  collect_register_by_name (regcache, "vrsave", &regset[33 * 16]);
528
}
529
 
530
static void
531
ppc_store_vrregset (struct regcache *regcache, const void *buf)
532
{
533
  int i, base;
534
  const char *regset = buf;
535
 
536
  if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
537
    return;
538
 
539
  base = find_regno ("vr0");
540
  for (i = 0; i < 32; i++)
541
    supply_register (regcache, base + i, &regset[i * 16]);
542
 
543
  supply_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
544
  supply_register_by_name (regcache, "vrsave", &regset[33 * 16]);
545
}
546
 
547
#ifndef PTRACE_GETEVRREGS
548
#define PTRACE_GETEVRREGS       20
549
#define PTRACE_SETEVRREGS       21
550
#endif
551
 
552
struct gdb_evrregset_t
553
{
554
  unsigned long evr[32];
555
  unsigned long long acc;
556
  unsigned long spefscr;
557
};
558
 
559
static void
560
ppc_fill_evrregset (struct regcache *regcache, void *buf)
561
{
562
  int i, ev0;
563
  struct gdb_evrregset_t *regset = buf;
564
 
565
  if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
566
    return;
567
 
568
  ev0 = find_regno ("ev0h");
569
  for (i = 0; i < 32; i++)
570
    collect_register (regcache, ev0 + i, &regset->evr[i]);
571
 
572
  collect_register_by_name (regcache, "acc", &regset->acc);
573
  collect_register_by_name (regcache, "spefscr", &regset->spefscr);
574
}
575
 
576
static void
577
ppc_store_evrregset (struct regcache *regcache, const void *buf)
578
{
579
  int i, ev0;
580
  const struct gdb_evrregset_t *regset = buf;
581
 
582
  if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
583
    return;
584
 
585
  ev0 = find_regno ("ev0h");
586
  for (i = 0; i < 32; i++)
587
    supply_register (regcache, ev0 + i, &regset->evr[i]);
588
 
589
  supply_register_by_name (regcache, "acc", &regset->acc);
590
  supply_register_by_name (regcache, "spefscr", &regset->spefscr);
591
}
592
 
593
struct regset_info target_regsets[] = {
594
  /* List the extra register sets before GENERAL_REGS.  That way we will
595
     fetch them every time, but still fall back to PTRACE_PEEKUSER for the
596
     general registers.  Some kernels support these, but not the newer
597
     PPC_PTRACE_GETREGS.  */
598
  { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, SIZEOF_VSXREGS, EXTENDED_REGS,
599
  ppc_fill_vsxregset, ppc_store_vsxregset },
600
  { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, SIZEOF_VRREGS, EXTENDED_REGS,
601
    ppc_fill_vrregset, ppc_store_vrregset },
602
  { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 32 * 4 + 8 + 4, EXTENDED_REGS,
603
    ppc_fill_evrregset, ppc_store_evrregset },
604
  { 0, 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
605
  { 0, 0, 0, -1, -1, NULL, NULL }
606
};
607
 
608
struct linux_target_ops the_low_target = {
609
  ppc_arch_setup,
610
  ppc_num_regs,
611
  ppc_regmap,
612
  ppc_cannot_fetch_register,
613
  ppc_cannot_store_register,
614
  ppc_get_pc,
615
  ppc_set_pc,
616
  (const unsigned char *) &ppc_breakpoint,
617
  ppc_breakpoint_len,
618
  NULL,
619
  0,
620
  ppc_breakpoint_at,
621
  NULL,
622
  NULL,
623
  NULL,
624
  NULL,
625
  ppc_collect_ptrace_register,
626
  ppc_supply_ptrace_register,
627
};

powered by: WebSVN 2.1.0

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