aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorAndreas Färber <afaerber@suse.de>2013-07-07 12:26:33 +0200
committerAndreas Färber <afaerber@suse.de>2013-07-26 23:24:01 +0200
commit0980bfabbc2e93d42c6b5ade578b371c36f6f23d (patch)
tree2bd0aa958a1281c84ad7bcdcdcabf6a9c237644b /target-ppc
parentf20f9df06e6f724d2ccdaf5f9a6dae45c061db75 (diff)
downloadqemu-0980bfabbc2e93d42c6b5ade578b371c36f6f23d.zip
qemu-0980bfabbc2e93d42c6b5ade578b371c36f6f23d.tar.gz
qemu-0980bfabbc2e93d42c6b5ade578b371c36f6f23d.tar.bz2
target-ppc: Move cpu_gdb_{read,write}_register()
Signed-off-by: Andreas Färber <afaerber@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/gdbstub.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
new file mode 100644
index 0000000..b834e60
--- /dev/null
+++ b/target-ppc/gdbstub.c
@@ -0,0 +1,122 @@
+/*
+ * PowerPC gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
+ * expects whatever the target description contains. Due to a
+ * historical mishap the FP registers appear in between core integer
+ * regs and PC, MSR, CR, and so forth. We hack round this by giving the
+ * FP regs zero size when talking to a newer gdb.
+ */
+
+static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+ if (n < 32) {
+ /* gprs */
+ GET_REGL(env->gpr[n]);
+ } else if (n < 64) {
+ /* fprs */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ stfq_p(mem_buf, env->fpr[n-32]);
+ return 8;
+ } else {
+ switch (n) {
+ case 64:
+ GET_REGL(env->nip);
+ case 65:
+ GET_REGL(env->msr);
+ case 66:
+ {
+ uint32_t cr = 0;
+ int i;
+ for (i = 0; i < 8; i++) {
+ cr |= env->crf[i] << (32 - ((i + 1) * 4));
+ }
+ GET_REG32(cr);
+ }
+ case 67:
+ GET_REGL(env->lr);
+ case 68:
+ GET_REGL(env->ctr);
+ case 69:
+ GET_REGL(env->xer);
+ case 70:
+ {
+ if (gdb_has_xml) {
+ return 0;
+ }
+ GET_REG32(env->fpscr);
+ }
+ }
+ }
+ return 0;
+}
+
+static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+ if (n < 32) {
+ /* gprs */
+ env->gpr[n] = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ } else if (n < 64) {
+ /* fprs */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ env->fpr[n-32] = ldfq_p(mem_buf);
+ return 8;
+ } else {
+ switch (n) {
+ case 64:
+ env->nip = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 65:
+ ppc_store_msr(env, ldtul_p(mem_buf));
+ return sizeof(target_ulong);
+ case 66:
+ {
+ uint32_t cr = ldl_p(mem_buf);
+ int i;
+ for (i = 0; i < 8; i++) {
+ env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
+ }
+ return 4;
+ }
+ case 67:
+ env->lr = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 68:
+ env->ctr = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 69:
+ env->xer = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 70:
+ /* fpscr */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+ return sizeof(target_ulong);
+ }
+ }
+ return 0;
+}