]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/linux-ppc-low.c
Updated copyright notices for most files.
[thirdparty/binutils-gdb.git] / gdb / gdbserver / linux-ppc-low.c
CommitLineData
0a30fbc4
DJ
1/* GNU/Linux/PowerPC 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
0a30fbc4
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
0a30fbc4
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/>. */
0a30fbc4
DJ
20
21#include "server.h"
58caa3dc 22#include "linux-low.h"
0a30fbc4
DJ
23
24#include <asm/ptrace.h>
25
2ec06d2e 26#define ppc_num_regs 71
0a30fbc4
DJ
27
28/* Currently, don't check/send MQ. */
2ec06d2e 29static int ppc_regmap[] =
0a30fbc4
DJ
30 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
31 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
32 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
33 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
34 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
35 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
36 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
37 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
30ed0a8f
DJ
38#ifdef __SPE__
39 -1, -1, -1, -1,
40 -1, -1, -1, -1,
41 -1, -1, -1, -1,
42 -1, -1, -1, -1,
43 -1, -1, -1, -1,
44 -1, -1, -1, -1,
45 -1, -1, -1, -1,
46 -1, -1, -1, -1,
47#else
0a30fbc4
DJ
48 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24,
49 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56,
50 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88,
51 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120,
52 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152,
53 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184,
54 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216,
55 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248,
30ed0a8f 56#endif
0a30fbc4 57 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
30ed0a8f
DJ
58#ifdef __SPE__
59 PT_CTR * 4, PT_XER * 4, -1
60#else
61 PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4
62#endif
63 };
0a30fbc4 64
2ec06d2e
DJ
65static int
66ppc_cannot_store_register (int regno)
0a30fbc4 67{
30ed0a8f 68#ifndef __SPE__
bc1e36ca
DJ
69 /* Some kernels do not allow us to store fpscr. */
70 if (regno == find_regno ("fpscr"))
71 return 2;
30ed0a8f 72#endif
bc1e36ca 73
0a30fbc4
DJ
74 return 0;
75}
76
2ec06d2e
DJ
77static int
78ppc_cannot_fetch_register (int regno)
0a30fbc4
DJ
79{
80 return 0;
81}
82
0d62e5e8
DJ
83static CORE_ADDR
84ppc_get_pc (void)
85{
86 unsigned long pc;
87
88 collect_register_by_name ("pc", &pc);
89 return (CORE_ADDR) pc;
90}
91
92static void
93ppc_set_pc (CORE_ADDR pc)
94{
95 unsigned long newpc = pc;
96
97 supply_register_by_name ("pc", &newpc);
98}
99
100/* Correct in either endianness. Note that this file is
101 for PowerPC only, not PowerPC64.
102 This instruction is "twge r2, r2", which GDB uses as a software
103 breakpoint. */
104static const unsigned long ppc_breakpoint = 0x7d821008;
105#define ppc_breakpoint_len 4
106
107static int
108ppc_breakpoint_at (CORE_ADDR where)
109{
110 unsigned long insn;
111
f450004a 112 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
0d62e5e8
DJ
113 if (insn == ppc_breakpoint)
114 return 1;
115 /* If necessary, recognize more trap instructions here. GDB only uses the
116 one. */
117 return 0;
118}
119
e9d25b98
DJ
120/* Provide only a fill function for the general register set. ps_lgetregs
121 will use this for NPTL support. */
122
123static void ppc_fill_gregset (void *buf)
124{
125 int i;
126
127 for (i = 0; i < 32; i++)
128 collect_register (i, (char *) buf + ppc_regmap[i]);
129
130 for (i = 64; i < 70; i++)
131 collect_register (i, (char *) buf + ppc_regmap[i]);
132}
133
30ed0a8f
DJ
134#ifdef __ALTIVEC__
135
136#ifndef PTRACE_GETVRREGS
137#define PTRACE_GETVRREGS 18
138#define PTRACE_SETVRREGS 19
139#endif
140
141#define SIZEOF_VRREGS 33*16+4
142
143static void
144ppc_fill_vrregset (void *buf)
145{
146 int i, base;
147 char *regset = buf;
148
149 base = find_regno ("vr0");
150 for (i = 0; i < 32; i++)
151 collect_register (base + i, &regset[i * 16]);
152
153 collect_register_by_name ("vscr", &regset[32 * 16 + 12]);
154 collect_register_by_name ("vrsave", &regset[33 * 16]);
155}
156
157static void
158ppc_store_vrregset (const void *buf)
159{
160 int i, base;
161 const char *regset = buf;
162
163 base = find_regno ("vr0");
164 for (i = 0; i < 32; i++)
165 supply_register (base + i, &regset[i * 16]);
166
167 supply_register_by_name ("vscr", &regset[32 * 16 + 12]);
168 supply_register_by_name ("vrsave", &regset[33 * 16]);
169}
170
171#endif /* __ALTIVEC__ */
172
173#ifdef __SPE__
174
175#ifndef PTRACE_GETEVRREGS
176#define PTRACE_GETEVRREGS 20
177#define PTRACE_SETEVRREGS 21
178#endif
179
180struct gdb_evrregset_t
181{
182 unsigned long evr[32];
183 unsigned long long acc;
184 unsigned long spefscr;
185};
186
187static void
188ppc_fill_evrregset (void *buf)
189{
190 int i, ev0;
191 struct gdb_evrregset_t *regset = buf;
192
193 ev0 = find_regno ("ev0h");
194 for (i = 0; i < 32; i++)
195 collect_register (ev0 + i, &regset->evr[i]);
196
197 collect_register_by_name ("acc", &regset->acc);
198 collect_register_by_name ("spefscr", &regset->spefscr);
199}
200
201static void
202ppc_store_evrregset (const void *buf)
203{
204 int i, ev0;
205 const struct gdb_evrregset_t *regset = buf;
206
207 ev0 = find_regno ("ev0h");
208 for (i = 0; i < 32; i++)
209 supply_register (ev0 + i, &regset->evr[i]);
210
211 supply_register_by_name ("acc", &regset->acc);
212 supply_register_by_name ("spefscr", &regset->spefscr);
213}
214#endif /* __SPE__ */
215
e9d25b98 216struct regset_info target_regsets[] = {
30ed0a8f
DJ
217 /* List the extra register sets before GENERAL_REGS. That way we will
218 fetch them every time, but still fall back to PTRACE_PEEKUSER for the
219 general registers. Some kernels support these, but not the newer
220 PPC_PTRACE_GETREGS. */
221#ifdef __ALTIVEC__
222 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS,
223 ppc_fill_vrregset, ppc_store_vrregset },
224#endif
225#ifdef __SPE__
226 { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 32 * 4 + 8 + 4, EXTENDED_REGS,
227 ppc_fill_evrregset, ppc_store_evrregset },
228#endif
e9d25b98
DJ
229 { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
230 { 0, 0, -1, -1, NULL, NULL }
231};
232
2ec06d2e
DJ
233struct linux_target_ops the_low_target = {
234 ppc_num_regs,
235 ppc_regmap,
236 ppc_cannot_fetch_register,
237 ppc_cannot_store_register,
0d62e5e8
DJ
238 ppc_get_pc,
239 ppc_set_pc,
f450004a 240 (const unsigned char *) &ppc_breakpoint,
0d62e5e8
DJ
241 ppc_breakpoint_len,
242 NULL,
243 0,
244 ppc_breakpoint_at,
2ec06d2e 245};