GDBserver
|
00001 /* Copyright (C) 2009-2013 Free Software Foundation, Inc. 00002 00003 This file is part of GDB. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 #include "server.h" 00019 #include "lynx-low.h" 00020 00021 #include <stdint.h> 00022 #include <stddef.h> 00023 #include <limits.h> 00024 #include <sys/ptrace.h> 00025 00026 /* The following two typedefs are defined in a .h file which is not 00027 in the standard include path (/sys/include/family/ppc/ucontext.h), 00028 so we just duplicate them here. */ 00029 00030 /* General register context */ 00031 typedef struct usr_econtext_s 00032 { 00033 uint32_t uec_iregs[32]; 00034 uint32_t uec_inum; 00035 uint32_t uec_srr0; 00036 uint32_t uec_srr1; 00037 uint32_t uec_lr; 00038 uint32_t uec_ctr; 00039 uint32_t uec_cr; 00040 uint32_t uec_xer; 00041 uint32_t uec_dar; 00042 uint32_t uec_mq; 00043 uint32_t uec_msr; 00044 uint32_t uec_sregs[16]; 00045 uint32_t uec_ss_count; 00046 uint32_t uec_ss_addr1; 00047 uint32_t uec_ss_addr2; 00048 uint32_t uec_ss_code1; 00049 uint32_t uec_ss_code2; 00050 } usr_econtext_t; 00051 00052 /* Floating point register context */ 00053 typedef struct usr_fcontext_s 00054 { 00055 uint64_t ufc_freg[32]; 00056 uint32_t ufc_fpscr[2]; 00057 } usr_fcontext_t; 00058 00059 /* Index of for various registers inside the regcache. */ 00060 #define R0_REGNUM 0 00061 #define F0_REGNUM 32 00062 #define PC_REGNUM 64 00063 #define MSR_REGNUM 65 00064 #define CR_REGNUM 66 00065 #define LR_REGNUM 67 00066 #define CTR_REGNUM 68 00067 #define XER_REGNUM 69 00068 #define FPSCR_REGNUM 70 00069 00070 /* Defined in auto-generated file powerpc-32.c. */ 00071 extern void init_registers_powerpc_32 (void); 00072 extern const struct target_desc *tdesc_powerpc_32; 00073 00074 /* The fill_function for the general-purpose register set. */ 00075 00076 static void 00077 lynx_ppc_fill_gregset (struct regcache *regcache, char *buf) 00078 { 00079 int i; 00080 00081 /* r0 - r31 */ 00082 for (i = 0; i < 32; i++) 00083 collect_register (regcache, R0_REGNUM + i, 00084 buf + offsetof (usr_econtext_t, uec_iregs[i])); 00085 00086 /* The other registers provided in the GP register context. */ 00087 collect_register (regcache, PC_REGNUM, 00088 buf + offsetof (usr_econtext_t, uec_srr0)); 00089 collect_register (regcache, MSR_REGNUM, 00090 buf + offsetof (usr_econtext_t, uec_srr1)); 00091 collect_register (regcache, CR_REGNUM, 00092 buf + offsetof (usr_econtext_t, uec_cr)); 00093 collect_register (regcache, LR_REGNUM, 00094 buf + offsetof (usr_econtext_t, uec_lr)); 00095 collect_register (regcache, CTR_REGNUM, 00096 buf + offsetof (usr_econtext_t, uec_ctr)); 00097 collect_register (regcache, XER_REGNUM, 00098 buf + offsetof (usr_econtext_t, uec_xer)); 00099 } 00100 00101 /* The store_function for the general-purpose register set. */ 00102 00103 static void 00104 lynx_ppc_store_gregset (struct regcache *regcache, const char *buf) 00105 { 00106 int i; 00107 00108 /* r0 - r31 */ 00109 for (i = 0; i < 32; i++) 00110 supply_register (regcache, R0_REGNUM + i, 00111 buf + offsetof (usr_econtext_t, uec_iregs[i])); 00112 00113 /* The other registers provided in the GP register context. */ 00114 supply_register (regcache, PC_REGNUM, 00115 buf + offsetof (usr_econtext_t, uec_srr0)); 00116 supply_register (regcache, MSR_REGNUM, 00117 buf + offsetof (usr_econtext_t, uec_srr1)); 00118 supply_register (regcache, CR_REGNUM, 00119 buf + offsetof (usr_econtext_t, uec_cr)); 00120 supply_register (regcache, LR_REGNUM, 00121 buf + offsetof (usr_econtext_t, uec_lr)); 00122 supply_register (regcache, CTR_REGNUM, 00123 buf + offsetof (usr_econtext_t, uec_ctr)); 00124 supply_register (regcache, XER_REGNUM, 00125 buf + offsetof (usr_econtext_t, uec_xer)); 00126 } 00127 00128 /* The fill_function for the floating-point register set. */ 00129 00130 static void 00131 lynx_ppc_fill_fpregset (struct regcache *regcache, char *buf) 00132 { 00133 int i; 00134 00135 /* f0 - f31 */ 00136 for (i = 0; i < 32; i++) 00137 collect_register (regcache, F0_REGNUM + i, 00138 buf + offsetof (usr_fcontext_t, ufc_freg[i])); 00139 00140 /* fpscr */ 00141 collect_register (regcache, FPSCR_REGNUM, 00142 buf + offsetof (usr_fcontext_t, ufc_fpscr)); 00143 } 00144 00145 /* The store_function for the floating-point register set. */ 00146 00147 static void 00148 lynx_ppc_store_fpregset (struct regcache *regcache, const char *buf) 00149 { 00150 int i; 00151 00152 /* f0 - f31 */ 00153 for (i = 0; i < 32; i++) 00154 supply_register (regcache, F0_REGNUM + i, 00155 buf + offsetof (usr_fcontext_t, ufc_freg[i])); 00156 00157 /* fpscr */ 00158 supply_register (regcache, FPSCR_REGNUM, 00159 buf + offsetof (usr_fcontext_t, ufc_fpscr)); 00160 } 00161 00162 /* Implements the lynx_target_ops.arch_setup routine. */ 00163 00164 static void 00165 lynx_ppc_arch_setup (void) 00166 { 00167 init_registers_powerpc_32 (); 00168 lynx_tdesc = tdesc_powerpc_32; 00169 } 00170 00171 /* Description of all the powerpc-lynx register sets. */ 00172 00173 struct lynx_regset_info lynx_target_regsets[] = { 00174 /* General Purpose Registers. */ 00175 {PTRACE_GETREGS, PTRACE_SETREGS, sizeof(usr_econtext_t), 00176 lynx_ppc_fill_gregset, lynx_ppc_store_gregset}, 00177 /* Floating Point Registers. */ 00178 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t), 00179 lynx_ppc_fill_fpregset, lynx_ppc_store_fpregset }, 00180 /* End of list marker. */ 00181 {0, 0, -1, NULL, NULL } 00182 }; 00183 00184 /* The lynx_target_ops vector for powerpc-lynxos. */ 00185 00186 struct lynx_target_ops the_low_target = { 00187 lynx_ppc_arch_setup, 00188 };