GDBserver
|
00001 /* GNU/Linux/PowerPC specific low level interface, for the remote server for 00002 GDB. 00003 Copyright (C) 1995-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "server.h" 00021 #include "linux-low.h" 00022 00023 #include <elf.h> 00024 #include <asm/ptrace.h> 00025 00026 /* These are in <asm/cputable.h> in current kernels. */ 00027 #define PPC_FEATURE_HAS_VSX 0x00000080 00028 #define PPC_FEATURE_HAS_ALTIVEC 0x10000000 00029 #define PPC_FEATURE_HAS_SPE 0x00800000 00030 #define PPC_FEATURE_CELL 0x00010000 00031 #define PPC_FEATURE_HAS_DFP 0x00000400 00032 00033 static unsigned long ppc_hwcap; 00034 00035 00036 /* Defined in auto-generated file powerpc-32l.c. */ 00037 void init_registers_powerpc_32l (void); 00038 extern const struct target_desc *tdesc_powerpc_32l; 00039 00040 /* Defined in auto-generated file powerpc-altivec32l.c. */ 00041 void init_registers_powerpc_altivec32l (void); 00042 extern const struct target_desc *tdesc_powerpc_altivec32l; 00043 00044 /* Defined in auto-generated file powerpc-cell32l.c. */ 00045 void init_registers_powerpc_cell32l (void); 00046 extern const struct target_desc *tdesc_powerpc_cell32l; 00047 00048 /* Defined in auto-generated file powerpc-vsx32l.c. */ 00049 void init_registers_powerpc_vsx32l (void); 00050 extern const struct target_desc *tdesc_powerpc_vsx32l; 00051 00052 /* Defined in auto-generated file powerpc-isa205-32l.c. */ 00053 void init_registers_powerpc_isa205_32l (void); 00054 extern const struct target_desc *tdesc_powerpc_isa205_32l; 00055 00056 /* Defined in auto-generated file powerpc-isa205-altivec32l.c. */ 00057 void init_registers_powerpc_isa205_altivec32l (void); 00058 extern const struct target_desc *tdesc_powerpc_isa205_altivec32l; 00059 00060 /* Defined in auto-generated file powerpc-isa205-vsx32l.c. */ 00061 void init_registers_powerpc_isa205_vsx32l (void); 00062 extern const struct target_desc *tdesc_powerpc_isa205_vsx32l; 00063 00064 /* Defined in auto-generated file powerpc-e500l.c. */ 00065 void init_registers_powerpc_e500l (void); 00066 extern const struct target_desc *tdesc_powerpc_e500l; 00067 00068 /* Defined in auto-generated file powerpc-64l.c. */ 00069 void init_registers_powerpc_64l (void); 00070 extern const struct target_desc *tdesc_powerpc_64l; 00071 00072 /* Defined in auto-generated file powerpc-altivec64l.c. */ 00073 void init_registers_powerpc_altivec64l (void); 00074 extern const struct target_desc *tdesc_powerpc_altivec64l; 00075 00076 /* Defined in auto-generated file powerpc-cell64l.c. */ 00077 void init_registers_powerpc_cell64l (void); 00078 extern const struct target_desc *tdesc_powerpc_cell64l; 00079 00080 /* Defined in auto-generated file powerpc-vsx64l.c. */ 00081 void init_registers_powerpc_vsx64l (void); 00082 extern const struct target_desc *tdesc_powerpc_vsx64l; 00083 00084 /* Defined in auto-generated file powerpc-isa205-64l.c. */ 00085 void init_registers_powerpc_isa205_64l (void); 00086 extern const struct target_desc *tdesc_powerpc_isa205_64l; 00087 00088 /* Defined in auto-generated file powerpc-isa205-altivec64l.c. */ 00089 void init_registers_powerpc_isa205_altivec64l (void); 00090 extern const struct target_desc *tdesc_powerpc_isa205_altivec64l; 00091 00092 /* Defined in auto-generated file powerpc-isa205-vsx64l.c. */ 00093 void init_registers_powerpc_isa205_vsx64l (void); 00094 extern const struct target_desc *tdesc_powerpc_isa205_vsx64l; 00095 00096 #define ppc_num_regs 73 00097 00098 /* This sometimes isn't defined. */ 00099 #ifndef PT_ORIG_R3 00100 #define PT_ORIG_R3 34 00101 #endif 00102 #ifndef PT_TRAP 00103 #define PT_TRAP 40 00104 #endif 00105 00106 #ifdef __powerpc64__ 00107 /* We use a constant for FPSCR instead of PT_FPSCR, because 00108 many shipped PPC64 kernels had the wrong value in ptrace.h. */ 00109 static int ppc_regmap[] = 00110 {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8, 00111 PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8, 00112 PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8, 00113 PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8, 00114 PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8, 00115 PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8, 00116 PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8, 00117 PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8, 00118 PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24, 00119 PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56, 00120 PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88, 00121 PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120, 00122 PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152, 00123 PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184, 00124 PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216, 00125 PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248, 00126 PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8, 00127 PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256, 00128 PT_ORIG_R3 * 8, PT_TRAP * 8 }; 00129 #else 00130 /* Currently, don't check/send MQ. */ 00131 static int ppc_regmap[] = 00132 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4, 00133 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4, 00134 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4, 00135 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4, 00136 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4, 00137 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4, 00138 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4, 00139 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4, 00140 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24, 00141 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56, 00142 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88, 00143 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120, 00144 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152, 00145 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184, 00146 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, 00147 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, 00148 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, 00149 PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, 00150 PT_ORIG_R3 * 4, PT_TRAP * 4 00151 }; 00152 00153 static int ppc_regmap_e500[] = 00154 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4, 00155 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4, 00156 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4, 00157 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4, 00158 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4, 00159 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4, 00160 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4, 00161 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4, 00162 -1, -1, -1, -1, 00163 -1, -1, -1, -1, 00164 -1, -1, -1, -1, 00165 -1, -1, -1, -1, 00166 -1, -1, -1, -1, 00167 -1, -1, -1, -1, 00168 -1, -1, -1, -1, 00169 -1, -1, -1, -1, 00170 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, 00171 PT_CTR * 4, PT_XER * 4, -1, 00172 PT_ORIG_R3 * 4, PT_TRAP * 4 00173 }; 00174 #endif 00175 00176 static int 00177 ppc_cannot_store_register (int regno) 00178 { 00179 const struct target_desc *tdesc = current_process ()->tdesc; 00180 00181 #ifndef __powerpc64__ 00182 /* Some kernels do not allow us to store fpscr. */ 00183 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE) 00184 && regno == find_regno (tdesc, "fpscr")) 00185 return 2; 00186 #endif 00187 00188 /* Some kernels do not allow us to store orig_r3 or trap. */ 00189 if (regno == find_regno (tdesc, "orig_r3") 00190 || regno == find_regno (tdesc, "trap")) 00191 return 2; 00192 00193 return 0; 00194 } 00195 00196 static int 00197 ppc_cannot_fetch_register (int regno) 00198 { 00199 return 0; 00200 } 00201 00202 static void 00203 ppc_collect_ptrace_register (struct regcache *regcache, int regno, char *buf) 00204 { 00205 int size = register_size (regcache->tdesc, regno); 00206 00207 memset (buf, 0, sizeof (long)); 00208 00209 if (size < sizeof (long)) 00210 collect_register (regcache, regno, buf + sizeof (long) - size); 00211 else 00212 collect_register (regcache, regno, buf); 00213 } 00214 00215 static void 00216 ppc_supply_ptrace_register (struct regcache *regcache, 00217 int regno, const char *buf) 00218 { 00219 int size = register_size (regcache->tdesc, regno); 00220 if (size < sizeof (long)) 00221 supply_register (regcache, regno, buf + sizeof (long) - size); 00222 else 00223 supply_register (regcache, regno, buf); 00224 } 00225 00226 00227 #define INSTR_SC 0x44000002 00228 #define NR_spu_run 0x0116 00229 00230 /* If the PPU thread is currently stopped on a spu_run system call, 00231 return to FD and ADDR the file handle and NPC parameter address 00232 used with the system call. Return non-zero if successful. */ 00233 static int 00234 parse_spufs_run (struct regcache *regcache, int *fd, CORE_ADDR *addr) 00235 { 00236 CORE_ADDR curr_pc; 00237 int curr_insn; 00238 int curr_r0; 00239 00240 if (register_size (regcache->tdesc, 0) == 4) 00241 { 00242 unsigned int pc, r0, r3, r4; 00243 collect_register_by_name (regcache, "pc", &pc); 00244 collect_register_by_name (regcache, "r0", &r0); 00245 collect_register_by_name (regcache, "orig_r3", &r3); 00246 collect_register_by_name (regcache, "r4", &r4); 00247 curr_pc = (CORE_ADDR) pc; 00248 curr_r0 = (int) r0; 00249 *fd = (int) r3; 00250 *addr = (CORE_ADDR) r4; 00251 } 00252 else 00253 { 00254 unsigned long pc, r0, r3, r4; 00255 collect_register_by_name (regcache, "pc", &pc); 00256 collect_register_by_name (regcache, "r0", &r0); 00257 collect_register_by_name (regcache, "orig_r3", &r3); 00258 collect_register_by_name (regcache, "r4", &r4); 00259 curr_pc = (CORE_ADDR) pc; 00260 curr_r0 = (int) r0; 00261 *fd = (int) r3; 00262 *addr = (CORE_ADDR) r4; 00263 } 00264 00265 /* Fetch instruction preceding current NIP. */ 00266 if ((*the_target->read_memory) (curr_pc - 4, 00267 (unsigned char *) &curr_insn, 4) != 0) 00268 return 0; 00269 /* It should be a "sc" instruction. */ 00270 if (curr_insn != INSTR_SC) 00271 return 0; 00272 /* System call number should be NR_spu_run. */ 00273 if (curr_r0 != NR_spu_run) 00274 return 0; 00275 00276 return 1; 00277 } 00278 00279 static CORE_ADDR 00280 ppc_get_pc (struct regcache *regcache) 00281 { 00282 CORE_ADDR addr; 00283 int fd; 00284 00285 if (parse_spufs_run (regcache, &fd, &addr)) 00286 { 00287 unsigned int pc; 00288 (*the_target->read_memory) (addr, (unsigned char *) &pc, 4); 00289 return ((CORE_ADDR)1 << 63) 00290 | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4); 00291 } 00292 else if (register_size (regcache->tdesc, 0) == 4) 00293 { 00294 unsigned int pc; 00295 collect_register_by_name (regcache, "pc", &pc); 00296 return (CORE_ADDR) pc; 00297 } 00298 else 00299 { 00300 unsigned long pc; 00301 collect_register_by_name (regcache, "pc", &pc); 00302 return (CORE_ADDR) pc; 00303 } 00304 } 00305 00306 static void 00307 ppc_set_pc (struct regcache *regcache, CORE_ADDR pc) 00308 { 00309 CORE_ADDR addr; 00310 int fd; 00311 00312 if (parse_spufs_run (regcache, &fd, &addr)) 00313 { 00314 unsigned int newpc = pc; 00315 (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4); 00316 } 00317 else if (register_size (regcache->tdesc, 0) == 4) 00318 { 00319 unsigned int newpc = pc; 00320 supply_register_by_name (regcache, "pc", &newpc); 00321 } 00322 else 00323 { 00324 unsigned long newpc = pc; 00325 supply_register_by_name (regcache, "pc", &newpc); 00326 } 00327 } 00328 00329 00330 static int 00331 ppc_get_hwcap (unsigned long *valp) 00332 { 00333 const struct target_desc *tdesc = current_process ()->tdesc; 00334 int wordsize = register_size (tdesc, 0); 00335 unsigned char *data = alloca (2 * wordsize); 00336 int offset = 0; 00337 00338 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize) 00339 { 00340 if (wordsize == 4) 00341 { 00342 unsigned int *data_p = (unsigned int *)data; 00343 if (data_p[0] == AT_HWCAP) 00344 { 00345 *valp = data_p[1]; 00346 return 1; 00347 } 00348 } 00349 else 00350 { 00351 unsigned long *data_p = (unsigned long *)data; 00352 if (data_p[0] == AT_HWCAP) 00353 { 00354 *valp = data_p[1]; 00355 return 1; 00356 } 00357 } 00358 00359 offset += 2 * wordsize; 00360 } 00361 00362 *valp = 0; 00363 return 0; 00364 } 00365 00366 /* Forward declaration. */ 00367 static struct usrregs_info ppc_usrregs_info; 00368 #ifndef __powerpc64__ 00369 static int ppc_regmap_adjusted; 00370 #endif 00371 00372 static void 00373 ppc_arch_setup (void) 00374 { 00375 const struct target_desc *tdesc; 00376 #ifdef __powerpc64__ 00377 long msr; 00378 struct regcache *regcache; 00379 00380 /* On a 64-bit host, assume 64-bit inferior process with no 00381 AltiVec registers. Reset ppc_hwcap to ensure that the 00382 collect_register call below does not fail. */ 00383 tdesc = tdesc_powerpc_64l; 00384 current_process ()->tdesc = tdesc; 00385 ppc_hwcap = 0; 00386 00387 /* Only if the high bit of the MSR is set, we actually have 00388 a 64-bit inferior. */ 00389 regcache = new_register_cache (tdesc); 00390 fetch_inferior_registers (regcache, find_regno (tdesc, "msr")); 00391 collect_register_by_name (regcache, "msr", &msr); 00392 free_register_cache (regcache); 00393 if (msr < 0) 00394 { 00395 ppc_get_hwcap (&ppc_hwcap); 00396 if (ppc_hwcap & PPC_FEATURE_CELL) 00397 tdesc = tdesc_powerpc_cell64l; 00398 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX) 00399 { 00400 /* Power ISA 2.05 (implemented by Power 6 and newer processors) 00401 increases the FPSCR from 32 bits to 64 bits. Even though Power 7 00402 supports this ISA version, it doesn't have PPC_FEATURE_ARCH_2_05 00403 set, only PPC_FEATURE_ARCH_2_06. Since for now the only bits 00404 used in the higher half of the register are for Decimal Floating 00405 Point, we check if that feature is available to decide the size 00406 of the FPSCR. */ 00407 if (ppc_hwcap & PPC_FEATURE_HAS_DFP) 00408 tdesc = tdesc_powerpc_isa205_vsx64l; 00409 else 00410 tdesc = tdesc_powerpc_vsx64l; 00411 } 00412 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC) 00413 { 00414 if (ppc_hwcap & PPC_FEATURE_HAS_DFP) 00415 tdesc = tdesc_powerpc_isa205_altivec64l; 00416 else 00417 tdesc = tdesc_powerpc_altivec64l; 00418 } 00419 00420 current_process ()->tdesc = tdesc; 00421 return; 00422 } 00423 #endif 00424 00425 /* OK, we have a 32-bit inferior. */ 00426 tdesc = tdesc_powerpc_32l; 00427 current_process ()->tdesc = tdesc; 00428 00429 ppc_get_hwcap (&ppc_hwcap); 00430 if (ppc_hwcap & PPC_FEATURE_CELL) 00431 tdesc = tdesc_powerpc_cell32l; 00432 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX) 00433 { 00434 if (ppc_hwcap & PPC_FEATURE_HAS_DFP) 00435 tdesc = tdesc_powerpc_isa205_vsx32l; 00436 else 00437 tdesc = tdesc_powerpc_vsx32l; 00438 } 00439 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC) 00440 { 00441 if (ppc_hwcap & PPC_FEATURE_HAS_DFP) 00442 tdesc = tdesc_powerpc_isa205_altivec32l; 00443 else 00444 tdesc = tdesc_powerpc_altivec32l; 00445 } 00446 00447 /* On 32-bit machines, check for SPE registers. 00448 Set the low target's regmap field as appropriately. */ 00449 #ifndef __powerpc64__ 00450 if (ppc_hwcap & PPC_FEATURE_HAS_SPE) 00451 tdesc = tdesc_powerpc_e500l; 00452 00453 if (!ppc_regmap_adjusted) 00454 { 00455 if (ppc_hwcap & PPC_FEATURE_HAS_SPE) 00456 ppc_usrregs_info.regmap = ppc_regmap_e500; 00457 00458 /* If the FPSCR is 64-bit wide, we need to fetch the whole 00459 64-bit slot and not just its second word. The PT_FPSCR 00460 supplied in a 32-bit GDB compilation doesn't reflect 00461 this. */ 00462 if (register_size (tdesc, 70) == 8) 00463 ppc_regmap[70] = (48 + 2*32) * sizeof (long); 00464 00465 ppc_regmap_adjusted = 1; 00466 } 00467 #endif 00468 current_process ()->tdesc = tdesc; 00469 } 00470 00471 /* Correct in either endianness. 00472 This instruction is "twge r2, r2", which GDB uses as a software 00473 breakpoint. */ 00474 static const unsigned int ppc_breakpoint = 0x7d821008; 00475 #define ppc_breakpoint_len 4 00476 00477 static int 00478 ppc_breakpoint_at (CORE_ADDR where) 00479 { 00480 unsigned int insn; 00481 00482 if (where & ((CORE_ADDR)1 << 63)) 00483 { 00484 char mem_annex[32]; 00485 sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff)); 00486 (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn, 00487 NULL, where & 0xffffffff, 4); 00488 if (insn == 0x3fff) 00489 return 1; 00490 } 00491 else 00492 { 00493 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); 00494 if (insn == ppc_breakpoint) 00495 return 1; 00496 /* If necessary, recognize more trap instructions here. GDB only uses 00497 the one. */ 00498 } 00499 00500 return 0; 00501 } 00502 00503 /* Provide only a fill function for the general register set. ps_lgetregs 00504 will use this for NPTL support. */ 00505 00506 static void ppc_fill_gregset (struct regcache *regcache, void *buf) 00507 { 00508 int i; 00509 00510 for (i = 0; i < 32; i++) 00511 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]); 00512 00513 for (i = 64; i < 70; i++) 00514 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]); 00515 00516 for (i = 71; i < 73; i++) 00517 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]); 00518 } 00519 00520 #ifndef PTRACE_GETVSXREGS 00521 #define PTRACE_GETVSXREGS 27 00522 #define PTRACE_SETVSXREGS 28 00523 #endif 00524 00525 #define SIZEOF_VSXREGS 32*8 00526 00527 static void 00528 ppc_fill_vsxregset (struct regcache *regcache, void *buf) 00529 { 00530 int i, base; 00531 char *regset = buf; 00532 00533 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX)) 00534 return; 00535 00536 base = find_regno (regcache->tdesc, "vs0h"); 00537 for (i = 0; i < 32; i++) 00538 collect_register (regcache, base + i, ®set[i * 8]); 00539 } 00540 00541 static void 00542 ppc_store_vsxregset (struct regcache *regcache, const void *buf) 00543 { 00544 int i, base; 00545 const char *regset = buf; 00546 00547 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX)) 00548 return; 00549 00550 base = find_regno (regcache->tdesc, "vs0h"); 00551 for (i = 0; i < 32; i++) 00552 supply_register (regcache, base + i, ®set[i * 8]); 00553 } 00554 00555 #ifndef PTRACE_GETVRREGS 00556 #define PTRACE_GETVRREGS 18 00557 #define PTRACE_SETVRREGS 19 00558 #endif 00559 00560 #define SIZEOF_VRREGS 33*16+4 00561 00562 static void 00563 ppc_fill_vrregset (struct regcache *regcache, void *buf) 00564 { 00565 int i, base; 00566 char *regset = buf; 00567 00568 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)) 00569 return; 00570 00571 base = find_regno (regcache->tdesc, "vr0"); 00572 for (i = 0; i < 32; i++) 00573 collect_register (regcache, base + i, ®set[i * 16]); 00574 00575 collect_register_by_name (regcache, "vscr", ®set[32 * 16 + 12]); 00576 collect_register_by_name (regcache, "vrsave", ®set[33 * 16]); 00577 } 00578 00579 static void 00580 ppc_store_vrregset (struct regcache *regcache, const void *buf) 00581 { 00582 int i, base; 00583 const char *regset = buf; 00584 00585 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)) 00586 return; 00587 00588 base = find_regno (regcache->tdesc, "vr0"); 00589 for (i = 0; i < 32; i++) 00590 supply_register (regcache, base + i, ®set[i * 16]); 00591 00592 supply_register_by_name (regcache, "vscr", ®set[32 * 16 + 12]); 00593 supply_register_by_name (regcache, "vrsave", ®set[33 * 16]); 00594 } 00595 00596 #ifndef PTRACE_GETEVRREGS 00597 #define PTRACE_GETEVRREGS 20 00598 #define PTRACE_SETEVRREGS 21 00599 #endif 00600 00601 struct gdb_evrregset_t 00602 { 00603 unsigned long evr[32]; 00604 unsigned long long acc; 00605 unsigned long spefscr; 00606 }; 00607 00608 static void 00609 ppc_fill_evrregset (struct regcache *regcache, void *buf) 00610 { 00611 int i, ev0; 00612 struct gdb_evrregset_t *regset = buf; 00613 00614 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE)) 00615 return; 00616 00617 ev0 = find_regno (regcache->tdesc, "ev0h"); 00618 for (i = 0; i < 32; i++) 00619 collect_register (regcache, ev0 + i, ®set->evr[i]); 00620 00621 collect_register_by_name (regcache, "acc", ®set->acc); 00622 collect_register_by_name (regcache, "spefscr", ®set->spefscr); 00623 } 00624 00625 static void 00626 ppc_store_evrregset (struct regcache *regcache, const void *buf) 00627 { 00628 int i, ev0; 00629 const struct gdb_evrregset_t *regset = buf; 00630 00631 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE)) 00632 return; 00633 00634 ev0 = find_regno (regcache->tdesc, "ev0h"); 00635 for (i = 0; i < 32; i++) 00636 supply_register (regcache, ev0 + i, ®set->evr[i]); 00637 00638 supply_register_by_name (regcache, "acc", ®set->acc); 00639 supply_register_by_name (regcache, "spefscr", ®set->spefscr); 00640 } 00641 00642 static struct regset_info ppc_regsets[] = { 00643 /* List the extra register sets before GENERAL_REGS. That way we will 00644 fetch them every time, but still fall back to PTRACE_PEEKUSER for the 00645 general registers. Some kernels support these, but not the newer 00646 PPC_PTRACE_GETREGS. */ 00647 { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, SIZEOF_VSXREGS, EXTENDED_REGS, 00648 ppc_fill_vsxregset, ppc_store_vsxregset }, 00649 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, SIZEOF_VRREGS, EXTENDED_REGS, 00650 ppc_fill_vrregset, ppc_store_vrregset }, 00651 { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 32 * 4 + 8 + 4, EXTENDED_REGS, 00652 ppc_fill_evrregset, ppc_store_evrregset }, 00653 { 0, 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL }, 00654 { 0, 0, 0, -1, -1, NULL, NULL } 00655 }; 00656 00657 static struct usrregs_info ppc_usrregs_info = 00658 { 00659 ppc_num_regs, 00660 ppc_regmap, 00661 }; 00662 00663 static struct regsets_info ppc_regsets_info = 00664 { 00665 ppc_regsets, /* regsets */ 00666 0, /* num_regsets */ 00667 NULL, /* disabled_regsets */ 00668 }; 00669 00670 static struct regs_info regs_info = 00671 { 00672 NULL, /* regset_bitmap */ 00673 &ppc_usrregs_info, 00674 &ppc_regsets_info 00675 }; 00676 00677 static const struct regs_info * 00678 ppc_regs_info (void) 00679 { 00680 return ®s_info; 00681 } 00682 00683 struct linux_target_ops the_low_target = { 00684 ppc_arch_setup, 00685 ppc_regs_info, 00686 ppc_cannot_fetch_register, 00687 ppc_cannot_store_register, 00688 NULL, /* fetch_register */ 00689 ppc_get_pc, 00690 ppc_set_pc, 00691 (const unsigned char *) &ppc_breakpoint, 00692 ppc_breakpoint_len, 00693 NULL, 00694 0, 00695 ppc_breakpoint_at, 00696 NULL, 00697 NULL, 00698 NULL, 00699 NULL, 00700 ppc_collect_ptrace_register, 00701 ppc_supply_ptrace_register, 00702 }; 00703 00704 void 00705 initialize_low_arch (void) 00706 { 00707 /* Initialize the Linux target descriptions. */ 00708 00709 init_registers_powerpc_32l (); 00710 init_registers_powerpc_altivec32l (); 00711 init_registers_powerpc_cell32l (); 00712 init_registers_powerpc_vsx32l (); 00713 init_registers_powerpc_isa205_32l (); 00714 init_registers_powerpc_isa205_altivec32l (); 00715 init_registers_powerpc_isa205_vsx32l (); 00716 init_registers_powerpc_e500l (); 00717 init_registers_powerpc_64l (); 00718 init_registers_powerpc_altivec64l (); 00719 init_registers_powerpc_cell64l (); 00720 init_registers_powerpc_vsx64l (); 00721 init_registers_powerpc_isa205_64l (); 00722 init_registers_powerpc_isa205_altivec64l (); 00723 init_registers_powerpc_isa205_vsx64l (); 00724 00725 initialize_regsets_info (&ppc_regsets_info); 00726 }