diff mbox

[v6,11/24] target-arm: Add AArch64 gdbstub support

Message ID 1378235544-22290-12-git-send-email-peter.maydell@linaro.org
State Accepted
Commit 96c04212ba80d4f9630a5e82681285eeb41af9cc
Headers show

Commit Message

Peter Maydell Sept. 3, 2013, 7:12 p.m. UTC
From: Alexander Graf <agraf@suse.de>

We want to be able to debug AArch64 guests. So let's add the respective gdb
stub functions and xml descriptions that allow us to do so.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: John Rigby <john.rigby@linaro.org>
Message-id: 1368505980-17151-6-git-send-email-john.rigby@linaro.org
[PMM: dropped unused fp regs XML for now; moved 64 bit only functions
 to new gdbstub64.c; these are hooked up in AArch64CPU, not via
 ifdefs in ARMCPU]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdb-xml/aarch64-core.xml |   46 +++++++++++++++++++++++++++++
 target-arm/Makefile.objs |    2 +-
 target-arm/cpu-qom.h     |    2 ++
 target-arm/cpu64.c       |    4 +++
 target-arm/gdbstub64.c   |   73 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 gdb-xml/aarch64-core.xml
 create mode 100644 target-arm/gdbstub64.c
diff mbox

Patch

diff --git a/gdb-xml/aarch64-core.xml b/gdb-xml/aarch64-core.xml
new file mode 100644
index 0000000..e1e9dc3
--- /dev/null
+++ b/gdb-xml/aarch64-core.xml
@@ -0,0 +1,46 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2009-2012 Free Software Foundation, Inc.
+     Contributed by ARM Ltd.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.aarch64.core">
+  <reg name="x0" bitsize="64"/>
+  <reg name="x1" bitsize="64"/>
+  <reg name="x2" bitsize="64"/>
+  <reg name="x3" bitsize="64"/>
+  <reg name="x4" bitsize="64"/>
+  <reg name="x5" bitsize="64"/>
+  <reg name="x6" bitsize="64"/>
+  <reg name="x7" bitsize="64"/>
+  <reg name="x8" bitsize="64"/>
+  <reg name="x9" bitsize="64"/>
+  <reg name="x10" bitsize="64"/>
+  <reg name="x11" bitsize="64"/>
+  <reg name="x12" bitsize="64"/>
+  <reg name="x13" bitsize="64"/>
+  <reg name="x14" bitsize="64"/>
+  <reg name="x15" bitsize="64"/>
+  <reg name="x16" bitsize="64"/>
+  <reg name="x17" bitsize="64"/>
+  <reg name="x18" bitsize="64"/>
+  <reg name="x19" bitsize="64"/>
+  <reg name="x20" bitsize="64"/>
+  <reg name="x21" bitsize="64"/>
+  <reg name="x22" bitsize="64"/>
+  <reg name="x23" bitsize="64"/>
+  <reg name="x24" bitsize="64"/>
+  <reg name="x25" bitsize="64"/>
+  <reg name="x26" bitsize="64"/>
+  <reg name="x27" bitsize="64"/>
+  <reg name="x28" bitsize="64"/>
+  <reg name="x29" bitsize="64"/>
+  <reg name="x30" bitsize="64"/>
+  <reg name="sp" bitsize="64" type="data_ptr"/>
+
+  <reg name="pc" bitsize="64" type="code_ptr"/>
+  <reg name="cpsr" bitsize="32"/>
+</feature>
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index a11d76e..6453f5c 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -5,4 +5,4 @@  obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
 obj-y += gdbstub.o
-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o
+obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o gdbstub64.o
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 6502a7b..b55306a 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -176,6 +176,8 @@  void arm_gt_vtimer_cb(void *opaque);
 #ifdef TARGET_AARCH64
 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
                             fprintf_function cpu_fprintf, int flags);
+int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 #endif
 
 #endif
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 4428f6c..3e99c21 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -73,6 +73,10 @@  static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
     CPUClass *cc = CPU_CLASS(oc);
 
     cc->dump_state = aarch64_cpu_dump_state;
+    cc->gdb_read_register = aarch64_cpu_gdb_read_register;
+    cc->gdb_write_register = aarch64_cpu_gdb_write_register;
+    cc->gdb_num_core_regs = 34;
+    cc->gdb_core_xml_file = "aarch64-core.xml";
 }
 
 static void aarch64_cpu_register(const ARMCPUInfo *info)
diff --git a/target-arm/gdbstub64.c b/target-arm/gdbstub64.c
new file mode 100644
index 0000000..7cb6a7c
--- /dev/null
+++ b/target-arm/gdbstub64.c
@@ -0,0 +1,73 @@ 
+/*
+ * ARM gdb server stub: AArch64 specific functions.
+ *
+ * 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/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+
+    if (n < 31) {
+        /* Core integer register.  */
+        return gdb_get_reg64(mem_buf, env->xregs[n]);
+    }
+    switch (n) {
+    case 31:
+        return gdb_get_reg64(mem_buf, env->xregs[31]);
+        break;
+    case 32:
+        return gdb_get_reg64(mem_buf, env->pc);
+        break;
+    case 33:
+        return gdb_get_reg32(mem_buf, env->pstate);
+    }
+    /* Unknown register.  */
+    return 0;
+}
+
+int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    uint64_t tmp;
+
+    tmp = ldq_p(mem_buf);
+
+    if (n < 31) {
+        /* Core integer register.  */
+        env->xregs[n] = tmp;
+        return 8;
+    }
+    switch (n) {
+    case 31:
+        env->xregs[31] = tmp;
+        return 8;
+    case 32:
+        env->pc = tmp;
+        return 8;
+    case 33:
+        /* CPSR */
+        env->pstate = tmp;
+        return 4;
+    }
+    /* Unknown register.  */
+    return 0;
+}