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