GDBserver
|
00001 /* GNU/Linux/BFIN specific low level interface, for the remote server for GDB. 00002 00003 Copyright (C) 2005-2013 Free Software Foundation, Inc. 00004 00005 Contributed by Analog Devices, Inc. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "server.h" 00023 #include "linux-low.h" 00024 #include "libiberty.h" 00025 #include <asm/ptrace.h> 00026 00027 /* Defined in auto-generated file reg-bfin.c. */ 00028 void init_registers_bfin (void); 00029 extern const struct target_desc *tdesc_bfin; 00030 00031 static int bfin_regmap[] = 00032 { 00033 PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7, 00034 PT_P0, PT_P1, PT_P2, PT_P3, PT_P4, PT_P5, PT_USP, PT_FP, 00035 PT_I0, PT_I1, PT_I2, PT_I3, PT_M0, PT_M1, PT_M2, PT_M3, 00036 PT_B0, PT_B1, PT_B2, PT_B3, PT_L0, PT_L1, PT_L2, PT_L3, 00037 PT_A0X, PT_A0W, PT_A1X, PT_A1W, PT_ASTAT, PT_RETS, 00038 PT_LC0, PT_LT0, PT_LB0, PT_LC1, PT_LT1, PT_LB1, 00039 -1 /* PT_CYCLES */, -1 /* PT_CYCLES2 */, 00040 -1 /* PT_USP */, PT_SEQSTAT, PT_SYSCFG, PT_PC, PT_RETX, PT_RETN, PT_RETE, 00041 PT_PC, 00042 }; 00043 00044 #define bfin_num_regs ARRAY_SIZE (bfin_regmap) 00045 00046 static int 00047 bfin_cannot_store_register (int regno) 00048 { 00049 return (regno >= bfin_num_regs); 00050 } 00051 00052 static int 00053 bfin_cannot_fetch_register (int regno) 00054 { 00055 return (regno >= bfin_num_regs); 00056 } 00057 00058 static CORE_ADDR 00059 bfin_get_pc (struct regcache *regcache) 00060 { 00061 unsigned long pc; 00062 00063 collect_register_by_name (regcache, "pc", &pc); 00064 00065 return pc; 00066 } 00067 00068 static void 00069 bfin_set_pc (struct regcache *regcache, CORE_ADDR pc) 00070 { 00071 unsigned long newpc = pc; 00072 00073 supply_register_by_name (regcache, "pc", &newpc); 00074 } 00075 00076 #define bfin_breakpoint_len 2 00077 static const unsigned char bfin_breakpoint[bfin_breakpoint_len] = {0xa1, 0x00}; 00078 00079 static int 00080 bfin_breakpoint_at (CORE_ADDR where) 00081 { 00082 unsigned char insn[bfin_breakpoint_len]; 00083 00084 read_inferior_memory(where, insn, bfin_breakpoint_len); 00085 if (insn[0] == bfin_breakpoint[0] 00086 && insn[1] == bfin_breakpoint[1]) 00087 return 1; 00088 00089 /* If necessary, recognize more trap instructions here. GDB only uses the 00090 one. */ 00091 return 0; 00092 } 00093 00094 static void 00095 bfin_arch_setup (void) 00096 { 00097 current_process ()->tdesc = tdesc_bfin; 00098 } 00099 00100 static struct usrregs_info bfin_usrregs_info = 00101 { 00102 bfin_num_regs, 00103 bfin_regmap, 00104 }; 00105 00106 static struct regs_info regs_info = 00107 { 00108 NULL, /* regset_bitmap */ 00109 &bfin_usrregs_info, 00110 }; 00111 00112 static const struct regs_info * 00113 bfin_regs_info (void) 00114 { 00115 return ®s_info; 00116 } 00117 00118 struct linux_target_ops the_low_target = { 00119 bfin_arch_setup, 00120 bfin_regs_info, 00121 bfin_cannot_fetch_register, 00122 bfin_cannot_store_register, 00123 NULL, /* fetch_register */ 00124 bfin_get_pc, 00125 bfin_set_pc, 00126 bfin_breakpoint, 00127 bfin_breakpoint_len, 00128 NULL, /* breakpoint_reinsert_addr */ 00129 2, 00130 bfin_breakpoint_at, 00131 }; 00132 00133 00134 void 00135 initialize_low_arch (void) 00136 { 00137 init_registers_bfin (); 00138 }