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.1 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 "cpu.h" 22 #include "exec/gdbstub.h" 23 #include "gdbstub/helpers.h" 24 #include "internal.h" 25 26 static int ppc_gdb_register_len_apple(int n) 27 { 28 switch (n) { 29 case 0 ... 31: 30 /* gprs */ 31 return 8; 32 case 32 ... 63: 33 /* fprs */ 34 return 8; 35 case 64 ... 95: 36 return 16; 37 case 64 + 32: /* nip */ 38 case 65 + 32: /* msr */ 39 case 67 + 32: /* lr */ 40 case 68 + 32: /* ctr */ 41 case 70 + 32: /* fpscr */ 42 return 8; 43 case 66 + 32: /* cr */ 44 case 69 + 32: /* xer */ 45 return 4; 46 default: 47 return 0; 48 } 49 } 50 51 static int ppc_gdb_register_len(int n) 52 { 53 switch (n) { 54 case 0 ... 31: 55 /* gprs */ 56 return sizeof(target_ulong); 57 case 32 ... 63: 58 /* fprs */ 59 if (gdb_has_xml) { 60 return 0; 61 } 62 return 8; 63 case 66: 64 /* cr */ 65 case 69: 66 /* xer */ 67 return 4; 68 case 64: 69 /* nip */ 70 case 65: 71 /* msr */ 72 case 67: 73 /* lr */ 74 case 68: 75 /* ctr */ 76 return sizeof(target_ulong); 77 case 70: 78 /* fpscr */ 79 if (gdb_has_xml) { 80 return 0; 81 } 82 return sizeof(target_ulong); 83 default: 84 return 0; 85 } 86 } 87 88 /* 89 * We need to present the registers to gdb in the "current" memory 90 * ordering. For user-only mode we get this for free; 91 * TARGET_BIG_ENDIAN is set to the proper ordering for the 92 * binary, and cannot be changed. For system mode, 93 * TARGET_BIG_ENDIAN is always set, and we must check the current 94 * mode of the chip to see if we're running in little-endian. 95 */ 96 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len) 97 { 98 #ifndef CONFIG_USER_ONLY 99 if (!FIELD_EX64(env->msr, MSR, LE)) { 100 /* do nothing */ 101 } else if (len == 4) { 102 bswap32s((uint32_t *)mem_buf); 103 } else if (len == 8) { 104 bswap64s((uint64_t *)mem_buf); 105 } else if (len == 16) { 106 bswap128s((Int128 *)mem_buf); 107 } else { 108 g_assert_not_reached(); 109 } 110 #endif 111 } 112 113 /* 114 * Old gdb always expects FP registers. Newer (xml-aware) gdb only 115 * expects whatever the target description contains. Due to a 116 * historical mishap the FP registers appear in between core integer 117 * regs and PC, MSR, CR, and so forth. We hack round this by giving 118 * the FP regs zero size when talking to a newer gdb. 119 */ 120 121 int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n) 122 { 123 PowerPCCPU *cpu = POWERPC_CPU(cs); 124 CPUPPCState *env = &cpu->env; 125 uint8_t *mem_buf; 126 int r = ppc_gdb_register_len(n); 127 128 if (!r) { 129 return r; 130 } 131 132 if (n < 32) { 133 /* gprs */ 134 gdb_get_regl(buf, env->gpr[n]); 135 } else if (n < 64) { 136 /* fprs */ 137 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); 138 } else { 139 switch (n) { 140 case 64: 141 gdb_get_regl(buf, env->nip); 142 break; 143 case 65: 144 gdb_get_regl(buf, env->msr); 145 break; 146 case 66: 147 { 148 uint32_t cr = ppc_get_cr(env); 149 gdb_get_reg32(buf, cr); 150 break; 151 } 152 case 67: 153 gdb_get_regl(buf, env->lr); 154 break; 155 case 68: 156 gdb_get_regl(buf, env->ctr); 157 break; 158 case 69: 159 gdb_get_reg32(buf, cpu_read_xer(env)); 160 break; 161 case 70: 162 gdb_get_reg32(buf, env->fpscr); 163 break; 164 } 165 } 166 mem_buf = buf->data + buf->len - r; 167 ppc_maybe_bswap_register(env, mem_buf, r); 168 return r; 169 } 170 171 int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n) 172 { 173 PowerPCCPU *cpu = POWERPC_CPU(cs); 174 CPUPPCState *env = &cpu->env; 175 uint8_t *mem_buf; 176 int r = ppc_gdb_register_len_apple(n); 177 178 if (!r) { 179 return r; 180 } 181 182 if (n < 32) { 183 /* gprs */ 184 gdb_get_reg64(buf, env->gpr[n]); 185 } else if (n < 64) { 186 /* fprs */ 187 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); 188 } else if (n < 96) { 189 /* Altivec */ 190 gdb_get_reg64(buf, n - 64); 191 gdb_get_reg64(buf, 0); 192 } else { 193 switch (n) { 194 case 64 + 32: 195 gdb_get_reg64(buf, env->nip); 196 break; 197 case 65 + 32: 198 gdb_get_reg64(buf, env->msr); 199 break; 200 case 66 + 32: 201 { 202 uint32_t cr = ppc_get_cr(env); 203 gdb_get_reg32(buf, cr); 204 break; 205 } 206 case 67 + 32: 207 gdb_get_reg64(buf, env->lr); 208 break; 209 case 68 + 32: 210 gdb_get_reg64(buf, env->ctr); 211 break; 212 case 69 + 32: 213 gdb_get_reg32(buf, cpu_read_xer(env)); 214 break; 215 case 70 + 32: 216 gdb_get_reg64(buf, env->fpscr); 217 break; 218 } 219 } 220 mem_buf = buf->data + buf->len - r; 221 ppc_maybe_bswap_register(env, mem_buf, r); 222 return r; 223 } 224 225 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 226 { 227 PowerPCCPU *cpu = POWERPC_CPU(cs); 228 CPUPPCState *env = &cpu->env; 229 int r = ppc_gdb_register_len(n); 230 231 if (!r) { 232 return r; 233 } 234 ppc_maybe_bswap_register(env, mem_buf, r); 235 if (n < 32) { 236 /* gprs */ 237 env->gpr[n] = ldtul_p(mem_buf); 238 } else if (n < 64) { 239 /* fprs */ 240 *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf); 241 } else { 242 switch (n) { 243 case 64: 244 env->nip = ldtul_p(mem_buf); 245 break; 246 case 65: 247 ppc_store_msr(env, ldtul_p(mem_buf)); 248 break; 249 case 66: 250 { 251 uint32_t cr = ldl_p(mem_buf); 252 ppc_set_cr(env, cr); 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 cpu_write_xer(env, ldl_p(mem_buf)); 263 break; 264 case 70: 265 /* fpscr */ 266 ppc_store_fpscr(env, ldtul_p(mem_buf)); 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 *cpu_fpr_ptr(env, n - 32) = ldq_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 ppc_set_cr(env, cr); 300 break; 301 } 302 case 67 + 32: 303 env->lr = ldq_p(mem_buf); 304 break; 305 case 68 + 32: 306 env->ctr = ldq_p(mem_buf); 307 break; 308 case 69 + 32: 309 cpu_write_xer(env, ldl_p(mem_buf)); 310 break; 311 case 70 + 32: 312 /* fpscr */ 313 ppc_store_fpscr(env, ldq_p(mem_buf)); 314 break; 315 } 316 } 317 return r; 318 } 319 320 #ifndef CONFIG_USER_ONLY 321 void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu) 322 { 323 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 324 CPUPPCState *env = &cpu->env; 325 GString *xml; 326 char *spr_name; 327 unsigned int num_regs = 0; 328 int i; 329 330 if (pcc->gdb_spr_xml) { 331 return; 332 } 333 334 xml = g_string_new("<?xml version=\"1.0\"?>"); 335 g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 336 g_string_append(xml, "<feature name=\"org.qemu.power.spr\">"); 337 338 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 339 ppc_spr_t *spr = &env->spr_cb[i]; 340 341 if (!spr->name) { 342 continue; 343 } 344 345 spr_name = g_ascii_strdown(spr->name, -1); 346 g_string_append_printf(xml, "<reg name=\"%s\"", spr_name); 347 g_free(spr_name); 348 349 g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS); 350 g_string_append(xml, " group=\"spr\"/>"); 351 352 /* 353 * GDB identifies registers based on the order they are 354 * presented in the XML. These ids will not match QEMU's 355 * representation (which follows the PowerISA). 356 * 357 * Store the position of the current register description so 358 * we can make the correspondence later. 359 */ 360 spr->gdb_id = num_regs; 361 num_regs++; 362 } 363 364 g_string_append(xml, "</feature>"); 365 366 pcc->gdb_num_sprs = num_regs; 367 pcc->gdb_spr_xml = g_string_free(xml, false); 368 } 369 370 const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name) 371 { 372 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); 373 374 if (strcmp(xml_name, "power-spr.xml") == 0) { 375 return pcc->gdb_spr_xml; 376 } 377 return NULL; 378 } 379 #endif 380 381 #if !defined(CONFIG_USER_ONLY) 382 static int gdb_find_spr_idx(CPUPPCState *env, int n) 383 { 384 int i; 385 386 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 387 ppc_spr_t *spr = &env->spr_cb[i]; 388 389 if (spr->name && spr->gdb_id == n) { 390 return i; 391 } 392 } 393 return -1; 394 } 395 396 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) 397 { 398 int reg; 399 int len; 400 401 reg = gdb_find_spr_idx(env, n); 402 if (reg < 0) { 403 return 0; 404 } 405 406 len = TARGET_LONG_SIZE; 407 gdb_get_regl(buf, env->spr[reg]); 408 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); 409 return len; 410 } 411 412 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 413 { 414 int reg; 415 int len; 416 417 reg = gdb_find_spr_idx(env, n); 418 if (reg < 0) { 419 return 0; 420 } 421 422 len = TARGET_LONG_SIZE; 423 ppc_maybe_bswap_register(env, mem_buf, len); 424 env->spr[reg] = ldn_p(mem_buf, len); 425 426 return len; 427 } 428 #endif 429 430 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) 431 { 432 uint8_t *mem_buf; 433 if (n < 32) { 434 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); 435 mem_buf = gdb_get_reg_ptr(buf, 8); 436 ppc_maybe_bswap_register(env, mem_buf, 8); 437 return 8; 438 } 439 if (n == 32) { 440 gdb_get_reg32(buf, env->fpscr); 441 mem_buf = gdb_get_reg_ptr(buf, 4); 442 ppc_maybe_bswap_register(env, mem_buf, 4); 443 return 4; 444 } 445 return 0; 446 } 447 448 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 449 { 450 if (n < 32) { 451 ppc_maybe_bswap_register(env, mem_buf, 8); 452 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); 453 return 8; 454 } 455 if (n == 32) { 456 ppc_maybe_bswap_register(env, mem_buf, 4); 457 ppc_store_fpscr(env, ldl_p(mem_buf)); 458 return 4; 459 } 460 return 0; 461 } 462 463 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) 464 { 465 uint8_t *mem_buf; 466 467 if (n < 32) { 468 ppc_avr_t *avr = cpu_avr_ptr(env, n); 469 gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1)); 470 mem_buf = gdb_get_reg_ptr(buf, 16); 471 ppc_maybe_bswap_register(env, mem_buf, 16); 472 return 16; 473 } 474 if (n == 32) { 475 gdb_get_reg32(buf, ppc_get_vscr(env)); 476 mem_buf = gdb_get_reg_ptr(buf, 4); 477 ppc_maybe_bswap_register(env, mem_buf, 4); 478 return 4; 479 } 480 if (n == 33) { 481 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]); 482 mem_buf = gdb_get_reg_ptr(buf, 4); 483 ppc_maybe_bswap_register(env, mem_buf, 4); 484 return 4; 485 } 486 return 0; 487 } 488 489 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 490 { 491 if (n < 32) { 492 ppc_avr_t *avr = cpu_avr_ptr(env, n); 493 ppc_maybe_bswap_register(env, mem_buf, 16); 494 avr->VsrD(0) = ldq_p(mem_buf); 495 avr->VsrD(1) = ldq_p(mem_buf + 8); 496 return 16; 497 } 498 if (n == 32) { 499 ppc_maybe_bswap_register(env, mem_buf, 4); 500 ppc_store_vscr(env, ldl_p(mem_buf)); 501 return 4; 502 } 503 if (n == 33) { 504 ppc_maybe_bswap_register(env, mem_buf, 4); 505 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); 506 return 4; 507 } 508 return 0; 509 } 510 511 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) 512 { 513 if (n < 32) { 514 #if defined(TARGET_PPC64) 515 gdb_get_reg32(buf, env->gpr[n] >> 32); 516 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 517 #else 518 gdb_get_reg32(buf, env->gprh[n]); 519 #endif 520 return 4; 521 } 522 if (n == 32) { 523 gdb_get_reg64(buf, env->spe_acc); 524 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 525 return 8; 526 } 527 if (n == 33) { 528 gdb_get_reg32(buf, env->spe_fscr); 529 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 530 return 4; 531 } 532 return 0; 533 } 534 535 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 536 { 537 if (n < 32) { 538 #if defined(TARGET_PPC64) 539 target_ulong lo = (uint32_t)env->gpr[n]; 540 target_ulong hi; 541 542 ppc_maybe_bswap_register(env, mem_buf, 4); 543 544 hi = (target_ulong)ldl_p(mem_buf) << 32; 545 env->gpr[n] = lo | hi; 546 #else 547 env->gprh[n] = ldl_p(mem_buf); 548 #endif 549 return 4; 550 } 551 if (n == 32) { 552 ppc_maybe_bswap_register(env, mem_buf, 8); 553 env->spe_acc = ldq_p(mem_buf); 554 return 8; 555 } 556 if (n == 33) { 557 ppc_maybe_bswap_register(env, mem_buf, 4); 558 env->spe_fscr = ldl_p(mem_buf); 559 return 4; 560 } 561 return 0; 562 } 563 564 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) 565 { 566 if (n < 32) { 567 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n)); 568 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 569 return 8; 570 } 571 return 0; 572 } 573 574 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 575 { 576 if (n < 32) { 577 ppc_maybe_bswap_register(env, mem_buf, 8); 578 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf); 579 return 8; 580 } 581 return 0; 582 } 583 584 gchar *ppc_gdb_arch_name(CPUState *cs) 585 { 586 #if defined(TARGET_PPC64) 587 return g_strdup("powerpc:common64"); 588 #else 589 return g_strdup("powerpc:common"); 590 #endif 591 } 592 593 void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc) 594 { 595 if (pcc->insns_flags & PPC_FLOAT) { 596 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 597 33, "power-fpu.xml", 0); 598 } 599 if (pcc->insns_flags & PPC_ALTIVEC) { 600 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 601 34, "power-altivec.xml", 0); 602 } 603 if (pcc->insns_flags & PPC_SPE) { 604 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 605 34, "power-spe.xml", 0); 606 } 607 if (pcc->insns_flags2 & PPC2_VSX) { 608 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, 609 32, "power-vsx.xml", 0); 610 } 611 #ifndef CONFIG_USER_ONLY 612 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, 613 pcc->gdb_num_sprs, "power-spr.xml", 0); 614 #endif 615 } 616