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