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 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 331 ppc_spr_t *spr = &env->spr_cb[i]; 332 333 if (!spr->name) { 334 continue; 335 } 336 337 /* 338 * GDB identifies registers based on the order they are 339 * presented in the XML. These ids will not match QEMU's 340 * representation (which follows the PowerISA). 341 * 342 * Store the position of the current register description so 343 * we can make the correspondence later. 344 */ 345 spr->gdb_id = num_regs; 346 num_regs++; 347 } 348 349 if (pcc->gdb_spr_xml) { 350 return; 351 } 352 353 xml = g_string_new("<?xml version=\"1.0\"?>"); 354 g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 355 g_string_append(xml, "<feature name=\"org.qemu.power.spr\">"); 356 357 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 358 ppc_spr_t *spr = &env->spr_cb[i]; 359 360 if (!spr->name) { 361 continue; 362 } 363 364 spr_name = g_ascii_strdown(spr->name, -1); 365 g_string_append_printf(xml, "<reg name=\"%s\"", spr_name); 366 g_free(spr_name); 367 368 g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS); 369 g_string_append(xml, " group=\"spr\"/>"); 370 } 371 372 g_string_append(xml, "</feature>"); 373 374 pcc->gdb_num_sprs = num_regs; 375 pcc->gdb_spr_xml = g_string_free(xml, false); 376 } 377 378 const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name) 379 { 380 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); 381 382 if (strcmp(xml_name, "power-spr.xml") == 0) { 383 return pcc->gdb_spr_xml; 384 } 385 return NULL; 386 } 387 #endif 388 389 #if !defined(CONFIG_USER_ONLY) 390 static int gdb_find_spr_idx(CPUPPCState *env, int n) 391 { 392 int i; 393 394 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { 395 ppc_spr_t *spr = &env->spr_cb[i]; 396 397 if (spr->name && spr->gdb_id == n) { 398 return i; 399 } 400 } 401 return -1; 402 } 403 404 static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) 405 { 406 int reg; 407 int len; 408 409 reg = gdb_find_spr_idx(env, n); 410 if (reg < 0) { 411 return 0; 412 } 413 414 len = TARGET_LONG_SIZE; 415 gdb_get_regl(buf, env->spr[reg]); 416 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); 417 return len; 418 } 419 420 static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 421 { 422 int reg; 423 int len; 424 425 reg = gdb_find_spr_idx(env, n); 426 if (reg < 0) { 427 return 0; 428 } 429 430 len = TARGET_LONG_SIZE; 431 ppc_maybe_bswap_register(env, mem_buf, len); 432 env->spr[reg] = ldn_p(mem_buf, len); 433 434 return len; 435 } 436 #endif 437 438 static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) 439 { 440 uint8_t *mem_buf; 441 if (n < 32) { 442 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); 443 mem_buf = gdb_get_reg_ptr(buf, 8); 444 ppc_maybe_bswap_register(env, mem_buf, 8); 445 return 8; 446 } 447 if (n == 32) { 448 gdb_get_reg32(buf, env->fpscr); 449 mem_buf = gdb_get_reg_ptr(buf, 4); 450 ppc_maybe_bswap_register(env, mem_buf, 4); 451 return 4; 452 } 453 return 0; 454 } 455 456 static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 457 { 458 if (n < 32) { 459 ppc_maybe_bswap_register(env, mem_buf, 8); 460 *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); 461 return 8; 462 } 463 if (n == 32) { 464 ppc_maybe_bswap_register(env, mem_buf, 4); 465 ppc_store_fpscr(env, ldl_p(mem_buf)); 466 return 4; 467 } 468 return 0; 469 } 470 471 static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) 472 { 473 uint8_t *mem_buf; 474 475 if (n < 32) { 476 ppc_avr_t *avr = cpu_avr_ptr(env, n); 477 gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1)); 478 mem_buf = gdb_get_reg_ptr(buf, 16); 479 ppc_maybe_bswap_register(env, mem_buf, 16); 480 return 16; 481 } 482 if (n == 32) { 483 gdb_get_reg32(buf, ppc_get_vscr(env)); 484 mem_buf = gdb_get_reg_ptr(buf, 4); 485 ppc_maybe_bswap_register(env, mem_buf, 4); 486 return 4; 487 } 488 if (n == 33) { 489 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]); 490 mem_buf = gdb_get_reg_ptr(buf, 4); 491 ppc_maybe_bswap_register(env, mem_buf, 4); 492 return 4; 493 } 494 return 0; 495 } 496 497 static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 498 { 499 if (n < 32) { 500 ppc_avr_t *avr = cpu_avr_ptr(env, n); 501 ppc_maybe_bswap_register(env, mem_buf, 16); 502 avr->VsrD(0) = ldq_p(mem_buf); 503 avr->VsrD(1) = ldq_p(mem_buf + 8); 504 return 16; 505 } 506 if (n == 32) { 507 ppc_maybe_bswap_register(env, mem_buf, 4); 508 ppc_store_vscr(env, ldl_p(mem_buf)); 509 return 4; 510 } 511 if (n == 33) { 512 ppc_maybe_bswap_register(env, mem_buf, 4); 513 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); 514 return 4; 515 } 516 return 0; 517 } 518 519 static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) 520 { 521 if (n < 32) { 522 #if defined(TARGET_PPC64) 523 gdb_get_reg32(buf, env->gpr[n] >> 32); 524 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 525 #else 526 gdb_get_reg32(buf, env->gprh[n]); 527 #endif 528 return 4; 529 } 530 if (n == 32) { 531 gdb_get_reg64(buf, env->spe_acc); 532 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 533 return 8; 534 } 535 if (n == 33) { 536 gdb_get_reg32(buf, env->spe_fscr); 537 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); 538 return 4; 539 } 540 return 0; 541 } 542 543 static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 544 { 545 if (n < 32) { 546 #if defined(TARGET_PPC64) 547 target_ulong lo = (uint32_t)env->gpr[n]; 548 target_ulong hi; 549 550 ppc_maybe_bswap_register(env, mem_buf, 4); 551 552 hi = (target_ulong)ldl_p(mem_buf) << 32; 553 env->gpr[n] = lo | hi; 554 #else 555 env->gprh[n] = ldl_p(mem_buf); 556 #endif 557 return 4; 558 } 559 if (n == 32) { 560 ppc_maybe_bswap_register(env, mem_buf, 8); 561 env->spe_acc = ldq_p(mem_buf); 562 return 8; 563 } 564 if (n == 33) { 565 ppc_maybe_bswap_register(env, mem_buf, 4); 566 env->spe_fscr = ldl_p(mem_buf); 567 return 4; 568 } 569 return 0; 570 } 571 572 static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) 573 { 574 if (n < 32) { 575 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n)); 576 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); 577 return 8; 578 } 579 return 0; 580 } 581 582 static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) 583 { 584 if (n < 32) { 585 ppc_maybe_bswap_register(env, mem_buf, 8); 586 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf); 587 return 8; 588 } 589 return 0; 590 } 591 592 gchar *ppc_gdb_arch_name(CPUState *cs) 593 { 594 #if defined(TARGET_PPC64) 595 return g_strdup("powerpc:common64"); 596 #else 597 return g_strdup("powerpc:common"); 598 #endif 599 } 600 601 void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc) 602 { 603 if (pcc->insns_flags & PPC_FLOAT) { 604 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 605 33, "power-fpu.xml", 0); 606 } 607 if (pcc->insns_flags & PPC_ALTIVEC) { 608 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 609 34, "power-altivec.xml", 0); 610 } 611 if (pcc->insns_flags & PPC_SPE) { 612 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 613 34, "power-spe.xml", 0); 614 } 615 if (pcc->insns_flags2 & PPC2_VSX) { 616 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, 617 32, "power-vsx.xml", 0); 618 } 619 #ifndef CONFIG_USER_ONLY 620 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, 621 pcc->gdb_num_sprs, "power-spr.xml", 0); 622 #endif 623 } 624