1/* GNU/Linux/PowerPC64 specific low level interface, for the remote server for 2 GDB. 3 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007 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 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 <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 90 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); 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 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 112struct regset_info target_regsets[] = { 113 { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL }, 114 { 0, 0, -1, -1, NULL, NULL } 115}; 116 117struct linux_target_ops the_low_target = { 118 ppc_num_regs, 119 ppc_regmap, 120 ppc_cannot_fetch_register, 121 ppc_cannot_store_register, 122 ppc_get_pc, 123 ppc_set_pc, 124 (const unsigned char *) &ppc_breakpoint, 125 ppc_breakpoint_len, 126 NULL, 127 0, 128 ppc_breakpoint_at, 129 NULL, 130 NULL, 131 NULL, 132 NULL, 133 1 134}; 135