1 /* 2 * PowerPC gdb server stub 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * Copyright (c) 2013 SUSE LINUX Products GmbH 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 #include "qemu/osdep.h" 21 #include "qemu-common.h" 22 #include "cpu.h" 23 #include "exec/gdbstub.h" 24 25 static int ppc_gdb_register_len_apple(int n) 26 { 27 switch (n) { 28 case 0 ... 31: 29 /* gprs */ 30 return 8; 31 case 32 ... 63: 32 /* fprs */ 33 return 8; 34 case 64 ... 95: 35 return 16; 36 case 64+32: /* nip */ 37 case 65+32: /* msr */ 38 case 67+32: /* lr */ 39 case 68+32: /* ctr */ 40 case 69+32: /* xer */ 41 case 70+32: /* fpscr */ 42 return 8; 43 case 66+32: /* cr */ 44 return 4; 45 default: 46 return 0; 47 } 48 } 49 50 static int ppc_gdb_register_len(int n) 51 { 52 switch (n) { 53 case 0 ... 31: 54 /* gprs */ 55 return sizeof(target_ulong); 56 case 32 ... 63: 57 /* fprs */ 58 if (gdb_has_xml) { 59 return 0; 60 } 61 return 8; 62 case 66: 63 /* cr */ 64 return 4; 65 case 64: 66 /* nip */ 67 case 65: 68 /* msr */ 69 case 67: 70 /* lr */ 71 case 68: 72 /* ctr */ 73 case 69: 74 /* xer */ 75 return sizeof(target_ulong); 76 case 70: 77 /* fpscr */ 78 if (gdb_has_xml) { 79 return 0; 80 } 81 return sizeof(target_ulong); 82 default: 83 return 0; 84 } 85 } 86 87 /* We need to present the registers to gdb in the "current" memory ordering. 88 For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to 89 the proper ordering for the binary, and cannot be changed. 90 For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check 91 the current mode of the chip to see if we're running in little-endian. */ 92 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len) 93 { 94 #ifndef CONFIG_USER_ONLY 95 if (!msr_le) { 96 /* do nothing */ 97 } else if (len == 4) { 98 bswap32s((uint32_t *)mem_buf); 99 } else if (len == 8) { 100 bswap64s((uint64_t *)mem_buf); 101 } else { 102 g_assert_not_reached(); 103 } 104 #endif 105 } 106 107 /* Old gdb always expects FP registers. Newer (xml-aware) gdb only 108 * expects whatever the target description contains. Due to a 109 * historical mishap the FP registers appear in between core integer 110 * regs and PC, MSR, CR, and so forth. We hack round this by giving the 111 * FP regs zero size when talking to a newer gdb. 112 */ 113 114 int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) 115 { 116 PowerPCCPU *cpu = POWERPC_CPU(cs); 117 CPUPPCState *env = &cpu->env; 118 int r = ppc_gdb_register_len(n); 119 120 if (!r) { 121 return r; 122 } 123 124 if (n < 32) { 125 /* gprs */ 126 gdb_get_regl(mem_buf, env->gpr[n]); 127 } else if (n < 64) { 128 /* fprs */ 129 stfq_p(mem_buf, env->fpr[n-32]); 130 } else { 131 switch (n) { 132 case 64: 133 gdb_get_regl(mem_buf, env->nip); 134 break; 135 case 65: 136 gdb_get_regl(mem_buf, env->msr); 137 break; 138 case 66: 139 { 140 uint32_t cr = 0; 141 int i; 142 for (i = 0; i < 8; i++) { 143 cr |= env->crf[i] << (32 - ((i + 1) * 4)); 144 } 145 gdb_get_reg32(mem_buf, cr); 146 break; 147 } 148 case 67: 149 gdb_get_regl(mem_buf, env->lr); 150 break; 151 case 68: 152 gdb_get_regl(mem_buf, env->ctr); 153 break; 154 case 69: 155 gdb_get_regl(mem_buf, env->xer); 156 break; 157 case 70: 158 gdb_get_reg32(mem_buf, env->fpscr); 159 break; 160 } 161 } 162 ppc_maybe_bswap_register(env, mem_buf, r); 163 return r; 164 } 165 166 int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n) 167 { 168 PowerPCCPU *cpu = POWERPC_CPU(cs); 169 CPUPPCState *env = &cpu->env; 170 int r = ppc_gdb_register_len_apple(n); 171 172 if (!r) { 173 return r; 174 } 175 176 if (n < 32) { 177 /* gprs */ 178 gdb_get_reg64(mem_buf, env->gpr[n]); 179 } else if (n < 64) { 180 /* fprs */ 181 stfq_p(mem_buf, env->fpr[n-32]); 182 } else if (n < 96) { 183 /* Altivec */ 184 stq_p(mem_buf, n - 64); 185 stq_p(mem_buf + 8, 0); 186 } else { 187 switch (n) { 188 case 64 + 32: 189 gdb_get_reg64(mem_buf, env->nip); 190 break; 191 case 65 + 32: 192 gdb_get_reg64(mem_buf, env->msr); 193 break; 194 case 66 + 32: 195 { 196 uint32_t cr = 0; 197 int i; 198 for (i = 0; i < 8; i++) { 199 cr |= env->crf[i] << (32 - ((i + 1) * 4)); 200 } 201 gdb_get_reg32(mem_buf, cr); 202 break; 203 } 204 case 67 + 32: 205 gdb_get_reg64(mem_buf, env->lr); 206 break; 207 case 68 + 32: 208 gdb_get_reg64(mem_buf, env->ctr); 209 break; 210 case 69 + 32: 211 gdb_get_reg64(mem_buf, env->xer); 212 break; 213 case 70 + 32: 214 gdb_get_reg64(mem_buf, env->fpscr); 215 break; 216 } 217 } 218 ppc_maybe_bswap_register(env, mem_buf, r); 219 return r; 220 } 221 222 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 223 { 224 PowerPCCPU *cpu = POWERPC_CPU(cs); 225 CPUPPCState *env = &cpu->env; 226 int r = ppc_gdb_register_len(n); 227 228 if (!r) { 229 return r; 230 } 231 ppc_maybe_bswap_register(env, mem_buf, r); 232 if (n < 32) { 233 /* gprs */ 234 env->gpr[n] = ldtul_p(mem_buf); 235 } else if (n < 64) { 236 /* fprs */ 237 env->fpr[n-32] = ldfq_p(mem_buf); 238 } else { 239 switch (n) { 240 case 64: 241 env->nip = ldtul_p(mem_buf); 242 break; 243 case 65: 244 ppc_store_msr(env, ldtul_p(mem_buf)); 245 break; 246 case 66: 247 { 248 uint32_t cr = ldl_p(mem_buf); 249 int i; 250 for (i = 0; i < 8; i++) { 251 env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; 252 } 253 break; 254 } 255 case 67: 256 env->lr = ldtul_p(mem_buf); 257 break; 258 case 68: 259 env->ctr = ldtul_p(mem_buf); 260 break; 261 case 69: 262 env->xer = ldtul_p(mem_buf); 263 break; 264 case 70: 265 /* fpscr */ 266 store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); 267 break; 268 } 269 } 270 return r; 271 } 272 int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) 273 { 274 PowerPCCPU *cpu = POWERPC_CPU(cs); 275 CPUPPCState *env = &cpu->env; 276 int r = ppc_gdb_register_len_apple(n); 277 278 if (!r) { 279 return r; 280 } 281 ppc_maybe_bswap_register(env, mem_buf, r); 282 if (n < 32) { 283 /* gprs */ 284 env->gpr[n] = ldq_p(mem_buf); 285 } else if (n < 64) { 286 /* fprs */ 287 env->fpr[n-32] = ldfq_p(mem_buf); 288 } else { 289 switch (n) { 290 case 64 + 32: 291 env->nip = ldq_p(mem_buf); 292 break; 293 case 65 + 32: 294 ppc_store_msr(env, ldq_p(mem_buf)); 295 break; 296 case 66 + 32: 297 { 298 uint32_t cr = ldl_p(mem_buf); 299 int i; 300 for (i = 0; i < 8; i++) { 301 env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; 302 } 303 break; 304 } 305 case 67 + 32: 306 env->lr = ldq_p(mem_buf); 307 break; 308 case 68 + 32: 309 env->ctr = ldq_p(mem_buf); 310 break; 311 case 69 + 32: 312 env->xer = ldq_p(mem_buf); 313 break; 314 case 70 + 32: 315 /* fpscr */ 316 store_fpscr(env, ldq_p(mem_buf), 0xffffffff); 317 break; 318 } 319 } 320 return r; 321 } 322