fbsd-powerpc-low.c revision 303975
1230479Snetchild/* FreeBSD/PowerPC specific low level interface, for the remote server for 2230479Snetchild GDB. 3230479Snetchild Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 4230479Snetchild Free Software Foundation, Inc. 5230479Snetchild 6230479Snetchild This file is part of GDB. 7230479Snetchild 8230479Snetchild This program is free software; you can redistribute it and/or modify 9230479Snetchild it under the terms of the GNU General Public License as published by 10230479Snetchild the Free Software Foundation; either version 2 of the License, or 11230479Snetchild (at your option) any later version. 12230479Snetchild 13230479Snetchild This program is distributed in the hope that it will be useful, 14230479Snetchild but WITHOUT ANY WARRANTY; without even the implied warranty of 15230479Snetchild MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16230479Snetchild GNU General Public License for more details. 17230479Snetchild 18230479Snetchild You should have received a copy of the GNU General Public License 19230479Snetchild along with this program; if not, write to the Free Software 20230479Snetchild Foundation, Inc., 59 Temple Place - Suite 330, 21230479Snetchild Boston, MA 02111-1307, USA. */ 22 23#include <sys/cdefs.h> 24__FBSDID("$FreeBSD: releng/11.0/gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c 206624 2010-04-14 20:31:06Z imp $"); 25 26#include "server.h" 27#include "fbsd-low.h" 28 29#include <sys/procfs.h> 30#include <sys/ptrace.h> 31 32#define ppc_num_regs 71 33 34/* Currently, don't check/send MQ. */ 35static int ppc_regmap[] = 36 { 0, 4, 8, 12, 16, 20, 24, 28, 37 32, 36, 40, 44, 48, 52, 56, 60, 38 64, 68, 72, 76, 80, 84, 88, 92, 39 96, 100, 104, 108, 112, 116, 120, 124, 40#if 0 41 /* 42 * XXX on FreeBSD the gdbserver for PowerPC was only tested with FPU-less 43 * cores i.e. e500. Let's leave the original FPR references around in case 44 * someone picks up and brings support for AIM-like FPU machines. 45 */ 46 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24, 47 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56, 48 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88, 49 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120, 50 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152, 51 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184, 52 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, 53 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, 54#endif 55 -1, -1, -1, -1, -1, -1, -1, -1, 56 -1, -1, -1, -1, -1, -1, -1, -1, 57 -1, -1, -1, -1, -1, -1, -1, -1, 58 -1, -1, -1, -1, -1, -1, -1, -1, 59 144, -1, 132, 128, 140, 136, -1 60 }; 61 62static int 63ppc_cannot_store_register (int regno) 64{ 65 /* Some kernels do not allow us to store fpscr. */ 66 if (regno == find_regno ("fpscr")) 67 return 2; 68 69 return 0; 70} 71 72static int 73ppc_cannot_fetch_register (int regno) 74{ 75 return 0; 76} 77 78static CORE_ADDR 79ppc_get_pc (void) 80{ 81 unsigned long pc; 82 83 collect_register_by_name ("pc", &pc); 84 return (CORE_ADDR) pc; 85} 86 87static void 88ppc_set_pc (CORE_ADDR pc) 89{ 90 unsigned long newpc = pc; 91 92 supply_register_by_name ("pc", &newpc); 93} 94 95/* Correct in either endianness. Note that this file is 96 for PowerPC only, not PowerPC64. 97 This instruction is "twge r2, r2", which GDB uses as a software 98 breakpoint. */ 99static const unsigned long ppc_breakpoint = 0x7d821008; 100#define ppc_breakpoint_len 4 101 102static int 103ppc_breakpoint_at (CORE_ADDR where) 104{ 105 unsigned long insn; 106 107 (*the_target->read_memory) (where, (char *) &insn, 4); 108 if (insn == ppc_breakpoint) 109 return 1; 110 /* If necessary, recognize more trap instructions here. GDB only uses the 111 one. */ 112 return 0; 113} 114 115static void 116ppc_fill_gregset (void *buf) 117{ 118 int i; 119 120 for (i = 0; i < ppc_num_regs; i++) 121 if (ppc_regmap[i] != -1) 122 collect_register (i, ((char *) buf) + ppc_regmap[i]); 123 124} 125 126static void 127ppc_store_gregset (const void *buf) 128{ 129 int i; 130 131 for (i = 0; i < ppc_num_regs; i++) 132 if (ppc_regmap[i] != -1) 133 supply_register (i, ((char *) buf) + ppc_regmap[i]); 134 135} 136 137struct regset_info target_regsets[] = { 138 { PT_GETREGS, PT_SETREGS, sizeof (struct reg), 139 GENERAL_REGS, 140 ppc_fill_gregset, ppc_store_gregset }, 141 { 0, 0, -1, -1, NULL, NULL } 142}; 143 144struct fbsd_target_ops the_low_target = { 145 ppc_num_regs, 146 ppc_regmap, 147 ppc_cannot_fetch_register, 148 ppc_cannot_store_register, 149 ppc_get_pc, 150 ppc_set_pc, 151 (const char *) &ppc_breakpoint, 152 ppc_breakpoint_len, 153 NULL, 154 0, 155 ppc_breakpoint_at, 156}; 157