Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-ppc64-low.c
CommitLineData
eee84df1
DJ
1/* GNU/Linux/PowerPC64 specific low level interface, for the remote server for
2 GDB.
9b254dd1 3 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008
eee84df1
DJ
4 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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
eee84df1
DJ
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
eee84df1
DJ
20
21#include "server.h"
22#include "linux-low.h"
23
24#include <asm/ptrace.h>
25
26#define ppc_num_regs 71
27
28/* We use a constant for FPSCR instead of PT_FPSCR, because
29 many shipped PPC64 kernels had the wrong value in ptrace.h. */
30static int ppc_regmap[] =
31 {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8,
32 PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8,
33 PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8,
34 PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8,
35 PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8,
36 PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8,
37 PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8,
38 PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8,
39 PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24,
40 PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56,
41 PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88,
42 PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120,
43 PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152,
44 PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184,
45 PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216,
46 PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248,
47 PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8,
48 PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256 };
49
50static int
51ppc_cannot_store_register (int regno)
52{
53 return 0;
54}
55
56static int
57ppc_cannot_fetch_register (int regno)
58{
59 return 0;
60}
61
62static CORE_ADDR
63ppc_get_pc (void)
64{
65 unsigned long pc;
66
67 collect_register_by_name ("pc", &pc);
68 return (CORE_ADDR) pc;
69}
70
71static void
72ppc_set_pc (CORE_ADDR pc)
73{
74 unsigned long newpc = pc;
75
76 supply_register_by_name ("pc", &newpc);
77}
78
79/* Correct in either endianness.
80 This instruction is "twge r2, r2", which GDB uses as a software
81 breakpoint. */
82static const unsigned int ppc_breakpoint = 0x7d821008;
83#define ppc_breakpoint_len 4
84
85static int
86ppc_breakpoint_at (CORE_ADDR where)
87{
88 unsigned int insn;
89
f450004a 90 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
eee84df1
DJ
91 if (insn == ppc_breakpoint)
92 return 1;
93 /* If necessary, recognize more trap instructions here. GDB only uses the
94 one. */
95 return 0;
96}
97
e9d25b98
DJ
98/* Provide only a fill function for the general register set. ps_lgetregs
99 will use this for NPTL support. */
100
101static void ppc_fill_gregset (void *buf)
102{
103 int i;
104
105 for (i = 0; i < 32; i++)
106 collect_register (i, (char *) buf + ppc_regmap[i]);
107
108 for (i = 64; i < 70; i++)
109 collect_register (i, (char *) buf + ppc_regmap[i]);
110}
111
30ed0a8f
DJ
112#ifdef __ALTIVEC__
113
114#ifndef PTRACE_GETVRREGS
115#define PTRACE_GETVRREGS 18
116#define PTRACE_SETVRREGS 19
117#endif
118
119#define SIZEOF_VRREGS 33*16+4
120
121static void
122ppc_fill_vrregset (void *buf)
123{
124 int i, base;
125 char *regset = buf;
126
127 base = find_regno ("vr0");
128 for (i = 0; i < 32; i++)
129 collect_register (base + i, &regset[i * 16]);
130
131 collect_register_by_name ("vscr", &regset[32 * 16 + 12]);
132 collect_register_by_name ("vrsave", &regset[33 * 16]);
133}
134
135static void
136ppc_store_vrregset (const void *buf)
137{
138 int i, base;
139 const char *regset = buf;
140
141 base = find_regno ("vr0");
142 for (i = 0; i < 32; i++)
143 supply_register (base + i, &regset[i * 16]);
144
145 supply_register_by_name ("vscr", &regset[32 * 16 + 12]);
146 supply_register_by_name ("vrsave", &regset[33 * 16]);
147}
148
149#endif /* __ALTIVEC__ */
150
e9d25b98 151struct regset_info target_regsets[] = {
30ed0a8f
DJ
152 /* List the extra register sets before GENERAL_REGS. That way we will
153 fetch them every time, but still fall back to PTRACE_PEEKUSER for the
154 general registers. Some kernels support these, but not the newer
155 PPC_PTRACE_GETREGS. */
156#ifdef __ALTIVEC__
157 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS,
158 ppc_fill_vrregset, ppc_store_vrregset },
159#endif
e9d25b98
DJ
160 { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
161 { 0, 0, -1, -1, NULL, NULL }
162};
163
eee84df1
DJ
164struct linux_target_ops the_low_target = {
165 ppc_num_regs,
166 ppc_regmap,
167 ppc_cannot_fetch_register,
168 ppc_cannot_store_register,
169 ppc_get_pc,
170 ppc_set_pc,
f450004a 171 (const unsigned char *) &ppc_breakpoint,
eee84df1
DJ
172 ppc_breakpoint_len,
173 NULL,
174 0,
175 ppc_breakpoint_at,
5a1f5858
DJ
176 NULL,
177 NULL,
178 NULL,
179 NULL,
180 1
eee84df1 181};
This page took 0.17409 seconds and 4 git commands to generate.