diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-06-29 11:59:00 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-06-29 11:59:00 +0100 |
commit | 2d80e0ab4b4326e340df7e0bcc687b2bc63c68d8 (patch) | |
tree | 199100356df3871e308e6aacba40170d962cea38 /target-ppc/gdbstub.c | |
parent | de6793e8c2a4d34e28e5ea385276249fc98109ec (diff) | |
parent | 79c0ff2cae1f24cb7e041ac2dbdcc329d2a86ba2 (diff) | |
download | hqemu-2d80e0ab4b4326e340df7e0bcc687b2bc63c68d8.zip hqemu-2d80e0ab4b4326e340df7e0bcc687b2bc63c68d8.tar.gz |
Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging
Patch queue for ppc - 2014-06-27
Changes include:
- instruction emulation fixes
- linux-user fixes
- mac99: layout fixes
- pseries: Initial VFIO support
- pseries: support for UUID
- pseries: support for -boot m
# gpg: Signature made Fri 27 Jun 2014 12:51:01 BST using RSA key ID 03FEDC60
# gpg: Can't check signature: public key not found
* remotes/agraf/tags/signed-ppc-for-upstream: (32 commits)
PPC: e500: Only create dt entries for existing serial ports
spapr_pci: Use XICS interrupt allocator and do not cache interrupts in PHB
vmstate: Add preallocation for migrating arrays (VMS_ALLOC flag)
xics: Implement xics_ics_free()
spapr: Remove @next_irq
spapr: Move interrupt allocator to xics
xics: Disable flags reset on xics reset
xics: Add xics_find_source()
xics: Add flags for interrupts
spapr: Add RTAS sysparm SPLPAR Characteristics
spapr: Add RTAS sysparm UUID
spapr: Fix RTAS sysparm DIAGNOSTICS_RUN_MODE
spapr: Add rtas_st_buffer utility function
spapr: Define a 2.1 pseries machine
spapr: Fix code design style (s/SPAPRMachine/sPAPRMachineState)
target-ppc: Add support for POWER8 pvr 0x4D0000
uninorth: Fix PCI hole size
mac99: Add motherboard devices before PCI cards
target-ppc: Remove unused gen_qemu_ld8s()
target-ppc: Remove unused IMM and d extract helpers
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-ppc/gdbstub.c')
-rw-r--r-- | target-ppc/gdbstub.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c index 381a3c7..694d303 100644 --- a/target-ppc/gdbstub.c +++ b/target-ppc/gdbstub.c @@ -21,6 +21,31 @@ #include "qemu-common.h" #include "exec/gdbstub.h" +static int ppc_gdb_register_len_apple(int n) +{ + switch (n) { + case 0 ... 31: + /* gprs */ + return 8; + case 32 ... 63: + /* fprs */ + return 8; + case 64 ... 95: + return 16; + case 64+32: /* nip */ + case 65+32: /* msr */ + case 67+32: /* lr */ + case 68+32: /* ctr */ + case 69+32: /* xer */ + case 70+32: /* fpscr */ + return 8; + case 66+32: /* cr */ + return 4; + default: + return 0; + } +} + static int ppc_gdb_register_len(int n) { switch (n) { @@ -132,6 +157,65 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return r; } +int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + int r = ppc_gdb_register_len_apple(n); + + if (!r) { + return r; + } + + if (n < 32) { + /* gprs */ + gdb_get_reg64(mem_buf, env->gpr[n]); + } else if (n < 64) { + /* fprs */ + stfq_p(mem_buf, env->fpr[n-32]); + } else if (n < 96) { + /* Altivec */ + stq_p(mem_buf, n - 64); + stq_p(mem_buf + 8, 0); + } else { + switch (n) { + case 64 + 32: + gdb_get_reg64(mem_buf, env->nip); + break; + case 65 + 32: + gdb_get_reg64(mem_buf, env->msr); + break; + case 66 + 32: + { + uint32_t cr = 0; + int i; + for (i = 0; i < 8; i++) { + cr |= env->crf[i] << (32 - ((i + 1) * 4)); + } + gdb_get_reg32(mem_buf, cr); + break; + } + case 67 + 32: + gdb_get_reg64(mem_buf, env->lr); + break; + case 68 + 32: + gdb_get_reg64(mem_buf, env->ctr); + break; + case 69 + 32: + gdb_get_reg64(mem_buf, env->xer); + break; + case 70 + 32: + gdb_get_reg64(mem_buf, env->fpscr); + break; + } + } + if (msr_le) { + /* If cpu is in LE mode, convert memory contents to LE. */ + ppc_gdb_swap_register(mem_buf, n, r); + } + return r; +} + int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -185,3 +269,56 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) } return r; } +int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + int r = ppc_gdb_register_len_apple(n); + + if (!r) { + return r; + } + if (msr_le) { + /* If cpu is in LE mode, convert memory contents to LE. */ + ppc_gdb_swap_register(mem_buf, n, r); + } + if (n < 32) { + /* gprs */ + env->gpr[n] = ldq_p(mem_buf); + } else if (n < 64) { + /* fprs */ + env->fpr[n-32] = ldfq_p(mem_buf); + } else { + switch (n) { + case 64 + 32: + env->nip = ldq_p(mem_buf); + break; + case 65 + 32: + ppc_store_msr(env, ldq_p(mem_buf)); + break; + case 66 + 32: + { + uint32_t cr = ldl_p(mem_buf); + int i; + for (i = 0; i < 8; i++) { + env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; + } + break; + } + case 67 + 32: + env->lr = ldq_p(mem_buf); + break; + case 68 + 32: + env->ctr = ldq_p(mem_buf); + break; + case 69 + 32: + env->xer = ldq_p(mem_buf); + break; + case 70 + 32: + /* fpscr */ + store_fpscr(env, ldq_p(mem_buf), 0xffffffff); + break; + } + } + return r; +} |