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 "exec/helper-proto.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_WORDS_BIGENDIAN is set to the proper ordering for the 92 * binary, and cannot be changed. For system mode, 93 * TARGET_WORDS_BIGENDIAN 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 (!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 { 106 g_assert_not_reached(); 107 } 108 #endif 109 } 110 111 /* 112 * Old gdb always expects FP registers. Newer (xml-aware) gdb only 113 * expects whatever the target description contains. Due to a 114 * historical mishap the FP registers appear in between core integer 115 * regs and PC, MSR, CR, and so forth. We hack round this by giving 116 * the FP regs zero size when talking to a newer gdb. 117 */ 118 119 int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n) 120 { 121 PowerPCCPU *cpu = POWERPC_CPU(cs); 122 CPUPPCState *env = &cpu->env; 123 uint8_t *mem_buf; 124 int r = ppc_gdb_register_len(n); 125 126 if (!r) { 127 return r; 128 } 129 130 if (n < 32) { 131 /* gprs */ 132 gdb_get_regl(buf, env->gpr[n]); 133 } else if (n < 64) { 134 /* fprs */ 135 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); 136 } else { 137 switch (n) { 138 case 64: 139 gdb_get_regl(buf, env->nip); 140 break; 141 case 65: 142 gdb_get_regl(buf, env->msr); 143 break; 144 case 66: 145 { 146 uint32_t cr = 0; 147 int i; 148 for (i = 0; i < 8; i++) { 149 cr |= env->crf[i] << (32 - ((i + 1) * 4)); 150 } 151 gdb_get_reg32(buf, cr); 152 break; 153 } 154 case 67: 155 gdb_get_regl(buf, env->lr); 156 break; 157 case 68: 158 gdb_get_regl(buf, env->ctr); 159 break; 160 case 69: 161 gdb_get_reg32(buf, env->xer); 162 break; 163 case 70: 164 gdb_get_reg32(buf, env->fpscr); 165 break; 166 } 167 } 168 mem_buf = buf->data + buf->len - r; 169 ppc_maybe_bswap_register(env, mem_buf, r); 170 return r; 171 } 172 173 int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n) 174 { 175 PowerPCCPU *cpu = POWERPC_CPU(cs); 176 CPUPPCState *env = &cpu->env; 177 uint8_t *mem_buf; 178 int r = ppc_gdb_register_len_apple(n); 179 180 if (!r) { 181 return r; 182 } 183 184 if (n < 32) { 185 /* gprs */ 186 gdb_get_reg64(buf, env->gpr[n]); 187 } else if (n < 64) { 188 /* fprs */ 189 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); 190 } else if (n < 96) { 191 /* Altivec */ 192 gdb_get_reg64(buf, n - 64); 193 gdb_get_reg64(buf, 0); 194 } else { 195 switch (n) { 196 case 64 + 32: 197 gdb_get_reg64(buf, env->nip); 198 break; 199 case 65 + 32: 200 gdb_get_reg64(buf, env->msr); 201 break; 202 case 66 + 32: 203 { 204 uint32_t cr = 0; 205 int i; 206 for (i = 0; i < 8; i++) { 207 cr |= env->crf[i] << (32 - ((i + 1) * 4)); 208 } 209 gdb_get_reg32(buf, cr); 210 break; 211 } 212 case 67 + 32: 213 gdb_get_reg64(buf, env->lr); 214 break; 215 case 68 + 32: 216 gdb_get_reg64(buf, env->ctr); 217 break; 218 case 69 + 32: 219 gdb_get_reg32(buf, env->xer); 220 break; 221 case 70 + 32: 222 gdb_get_reg64(buf, env->fpscr); 223 break; 224 } 225 } 226 mem_buf = buf->data + buf->len - r; 227 ppc_maybe_bswap_register(env, mem_buf, r); 228 return r; 229 } 230 231 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 232 { 233 PowerPCCPU *cpu = POWERPC_CPU(cs); 234 CPUPPCState *env = &cpu->env; 235 int r = ppc_gdb_register_len(n); 236 237 if (!r) { 238 return r; 239 } 240 ppc_maybe_bswap_register(env, mem_buf, r); 241 if (n < 32) { 242 /* gprs */ 243 env->gpr[n] = ldtul_p(mem_buf); 244 } else if (n < 64) { 245 /* fprs */ 246 *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf); 247 } else { 248 switch (n) { 249 case 64: 250 env->nip = ldtul_p(mem_buf); 251 break; 252 case 65: 253 ppc_store_msr(env, ldtul_p(mem_buf)); 254 break; 255 case 66: 256 { 257 uint32_t cr = ldl_p(mem_buf); 258 int i; 259 for (i = 0; i < 8; i++) { 260 env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; 261 } 262 break; 263 } 264 case 67: 265 env->lr = ldtul_p(mem_buf); 266 break; 267 case 68: 268 env->ctr = ldtul_p(mem_buf); 269 break; 270 case 69: 271 env->xer = ldl_p(mem_buf); 272 break; 273 case 70: 274 /* fpscr */ 275 store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); 276 break; 277 } 278 } 279 return r; 280 } 281 int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) 282 { 283 PowerPCCPU *cpu = POWERPC_CPU(cs); 284 CPUPPCState *env = &cpu->env; 285 int r = ppc_gdb_register_len_apple(n); 286 287 if (!r) { 288 return r; 289 } 290 ppc_maybe_bswap_register(env, mem_buf, r); 291 if (n < 32) { 292 /* gprs */ 293 env->gpr[n] = ldq_p(mem_buf); 294 } else if (n < 64) { 295 /* fprs */ 296 *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf); 297 } else { 298 switch (n) { 299 case 64 + 32: 300 env->nip = ldq_p(mem_buf); 301 break; 302 case 65 + 32: 303 ppc_store_msr(env, ldq_p(mem_buf)); 304 break; 305 case 66 + 32: 306 { 307 uint32_t cr = ldl_p(mem_buf); 308 int i; 309 for (i = 0; i < 8; i++) { 310 env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; 311 } 312 break; 313 } 314 case 67 + 32: 315 env->lr = ldq_p(mem_buf); 316 break; 317 case 68 + 32: 318 env->ctr = ldq_p(mem_buf); 319 break; 320 case 69 + 32: 321 env->xer = ldl_p(mem_buf); 322 break; 323 case 70 + 32: 324 /* fpscr */ 325 store_fpscr(env, ldq_p(mem_buf), 0xffffffff); 326 break; 327 } 328 } 329 return r; 330 } 331 332 #ifndef CONFIG_USER_ONLY 333 void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu) 334 { 335 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 336 CPUPPCState *env = &cpu->env; 337 GString *xml; 338 char *spr_name; 339 unsigned int num_regs = 0; 340 int i; 341 342 if (pcc->gdb_spr_xml) { 343 return; 344 } 345 346 xml = g_string_new("<?xml version=\"1.0\"?>"); 347 g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 348 g_string_append(xml, "<feature name=\"org.qemu.power.spr\">"); 349 350 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 351 ppc_spr_t *spr = &env->spr_cb[i]; 352 353 if (!spr->name) { 354 continue; 355 } 356 357 spr_name = g_ascii_strdown(spr->name, -1); 358 g_string_append_printf(xml, "<reg name=\"%s\"", spr_name); 359 g_free(spr_name); 360 361 g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS); 362 g_string_append(xml, " group=\"spr\"/>"); 363 364 /* 365 * GDB identifies registers based on the order they are 366 * presented in the XML. These ids will not match QEMU's 367 * representation (which follows the PowerISA). 368 * 369 * Store the position of the current register description so 370 * we can make the correspondence later. 371 */ 372 spr->gdb_id = num_regs; 373 num_regs++; 374 } 375 376 g_string_append(xml, "</feature>"); 377 378 pcc->gdb_num_sprs = num_regs; 379 pcc->gdb_spr_xml = g_string_free(xml, false); 380 } 381 382 const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name) 383 { 384 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); 385 386 if (strcmp(xml_name, "power-spr.xml") == 0) { 387 return pcc->gdb_spr_xml; 388 } 389 return NULL; 390 } 391 #endif 392 393 static bool avr_need_swap(CPUPPCState *env) 394 { 395 #ifdef HOST_WORDS_BIGENDIAN 396 return msr_le; 397 #else 398 return !msr_le; 399 #endif 400 } 401 402 #if !defined(CONFIG_USER_ONLY) 403 static int gdb_find_spr_idx(CPUPPCState *env, int n) 404 { 405 int i; 406 407 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 408 ppc_spr_t *spr = &env->spr_cb[i]; 409 410 if (spr->name && spr->gdb_id == n) { 411 return i; 412 } 413 } 414 return -1; 415 } 416 417 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) 418 { 419 int reg; 420 int len; 421 422 reg = gdb_find_spr_idx(env, n); 423 if (reg < 0) { 424 return 0; 425 } 426 427 len = TARGET_LONG_SIZE; 428 gdb_get_regl(buf, env->spr[reg]); 429 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); 430 return len; 431 } 432 433 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 434 { 435 int reg; 436 int len; 437 438 reg = gdb_find_spr_idx(env, n); 439 if (reg < 0) { 440 return 0; 441 } 442 443 len = TARGET_LONG_SIZE; 444 ppc_maybe_bswap_register(env, mem_buf, len); 445 env->spr[reg] = ldn_p(mem_buf, len); 446 447 return len; 448 } 449 #endif 450 451 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) 452 { 453 uint8_t *mem_buf; 454 if (n < 32) { 455 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); 456 mem_buf = gdb_get_reg_ptr(buf, 8); 457 ppc_maybe_bswap_register(env, mem_buf, 8); 458 return 8; 459 } 460 if (n == 32) { 461 gdb_get_reg32(buf, env->fpscr); 462 mem_buf = gdb_get_reg_ptr(buf, 4); 463 ppc_maybe_bswap_register(env, mem_buf, 4); 464 return 4; 465 } 466 return 0; 467 } 468 469 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 470 { 471 if (n < 32) { 472 ppc_maybe_bswap_register(env, mem_buf, 8); 473 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); 474 return 8; 475 } 476 if (n == 32) { 477 ppc_maybe_bswap_register(env, mem_buf, 4); 478 store_fpscr(env, ldl_p(mem_buf), 0xffffffff); 479 return 4; 480 } 481 return 0; 482 } 483 484 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) 485 { 486 uint8_t *mem_buf; 487 488 if (n < 32) { 489 ppc_avr_t *avr = cpu_avr_ptr(env, n); 490 if (!avr_need_swap(env)) { 491 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]); 492 } else { 493 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]); 494 } 495 mem_buf = gdb_get_reg_ptr(buf, 16); 496 ppc_maybe_bswap_register(env, mem_buf, 8); 497 ppc_maybe_bswap_register(env, mem_buf + 8, 8); 498 return 16; 499 } 500 if (n == 32) { 501 gdb_get_reg32(buf, ppc_get_vscr(env)); 502 mem_buf = gdb_get_reg_ptr(buf, 4); 503 ppc_maybe_bswap_register(env, mem_buf, 4); 504 return 4; 505 } 506 if (n == 33) { 507 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]); 508 mem_buf = gdb_get_reg_ptr(buf, 4); 509 ppc_maybe_bswap_register(env, mem_buf, 4); 510 return 4; 511 } 512 return 0; 513 } 514 515 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 516 { 517 if (n < 32) { 518 ppc_avr_t *avr = cpu_avr_ptr(env, n); 519 ppc_maybe_bswap_register(env, mem_buf, 8); 520 ppc_maybe_bswap_register(env, mem_buf + 8, 8); 521 if (!avr_need_swap(env)) { 522 avr->u64[0] = ldq_p(mem_buf); 523 avr->u64[1] = ldq_p(mem_buf + 8); 524 } else { 525 avr->u64[1] = ldq_p(mem_buf); 526 avr->u64[0] = ldq_p(mem_buf + 8); 527 } 528 return 16; 529 } 530 if (n == 32) { 531 ppc_maybe_bswap_register(env, mem_buf, 4); 532 ppc_store_vscr(env, ldl_p(mem_buf)); 533 return 4; 534 } 535 if (n == 33) { 536 ppc_maybe_bswap_register(env, mem_buf, 4); 537 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); 538 return 4; 539 } 540 return 0; 541 } 542 543 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) 544 { 545 if (n < 32) { 546 #if defined(TARGET_PPC64) 547 gdb_get_reg32(buf, env->gpr[n] >> 32); 548 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 549 #else 550 gdb_get_reg32(buf, env->gprh[n]); 551 #endif 552 return 4; 553 } 554 if (n == 32) { 555 gdb_get_reg64(buf, env->spe_acc); 556 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 557 return 8; 558 } 559 if (n == 33) { 560 gdb_get_reg32(buf, env->spe_fscr); 561 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 562 return 4; 563 } 564 return 0; 565 } 566 567 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 568 { 569 if (n < 32) { 570 #if defined(TARGET_PPC64) 571 target_ulong lo = (uint32_t)env->gpr[n]; 572 target_ulong hi; 573 574 ppc_maybe_bswap_register(env, mem_buf, 4); 575 576 hi = (target_ulong)ldl_p(mem_buf) << 32; 577 env->gpr[n] = lo | hi; 578 #else 579 env->gprh[n] = ldl_p(mem_buf); 580 #endif 581 return 4; 582 } 583 if (n == 32) { 584 ppc_maybe_bswap_register(env, mem_buf, 8); 585 env->spe_acc = ldq_p(mem_buf); 586 return 8; 587 } 588 if (n == 33) { 589 ppc_maybe_bswap_register(env, mem_buf, 4); 590 env->spe_fscr = ldl_p(mem_buf); 591 return 4; 592 } 593 return 0; 594 } 595 596 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) 597 { 598 if (n < 32) { 599 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n)); 600 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 601 return 8; 602 } 603 return 0; 604 } 605 606 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 607 { 608 if (n < 32) { 609 ppc_maybe_bswap_register(env, mem_buf, 8); 610 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf); 611 return 8; 612 } 613 return 0; 614 } 615 616 gchar *ppc_gdb_arch_name(CPUState *cs) 617 { 618 #if defined(TARGET_PPC64) 619 return g_strdup("powerpc:common64"); 620 #else 621 return g_strdup("powerpc:common"); 622 #endif 623 } 624 625 void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc) 626 { 627 if (pcc->insns_flags & PPC_FLOAT) { 628 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 629 33, "power-fpu.xml", 0); 630 } 631 if (pcc->insns_flags & PPC_ALTIVEC) { 632 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 633 34, "power-altivec.xml", 0); 634 } 635 if (pcc->insns_flags & PPC_SPE) { 636 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 637 34, "power-spe.xml", 0); 638 } 639 if (pcc->insns_flags2 & PPC2_VSX) { 640 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, 641 32, "power-vsx.xml", 0); 642 } 643 #ifndef CONFIG_USER_ONLY 644 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, 645 pcc->gdb_num_sprs, "power-spr.xml", 0); 646 #endif 647 } 648