qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v8] target-ppc: gdbstub allow byte swapping for


From: Alexander Graf
Subject: Re: [Qemu-devel] [PATCH v8] target-ppc: gdbstub allow byte swapping for reading/writing registers
Date: Sat, 05 Apr 2014 16:55:10 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.4.0


On 05.04.14 16:51, Andreas Färber wrote:
Am 04.04.2014 22:23, schrieb Thomas Falcon:
This patch allows registers to be properly read from and written to
when using the gdbstub to debug a ppc guest running in little
endian mode.  It accomplishes this goal by byte swapping the values of
any registers if the MSR:LE value is set.

Signed-off-by: Thomas Falcon <address@hidden>
---
Differences for v7:

Inlined the register_read() and register_write() wrapper functions
---
  target-ppc/cpu-qom.h |   1 +
  target-ppc/gdbstub.c | 125 +++++++++++++++++++++++++++++++++++++--------------
  2 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 47dc8e6..aab4977 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -111,6 +111,7 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, 
fprintf_function cpu_fprintf,
                          int flags);
  void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                               fprintf_function cpu_fprintf, int flags);
+void ppc_cpu_gdb_swap_register(uint8_t *buf, int reg, int len);
This is only ever used in gdbstub.c. Can we please keep it static there
to avoid a full ppc*-softmmu rebuild?

  hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
  int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
  int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
index 1c91090..594dd08 100644
--- a/target-ppc/gdbstub.c
+++ b/target-ppc/gdbstub.c
@@ -21,6 +21,58 @@
  #include "qemu-common.h"
  #include "exec/gdbstub.h"
+static int ppc_cpu_gdb_register_len(int n)
Nitpick: Since these two functions do not operate on the CPU, you could
just use ppc_gdb_* rather than ppc_cpu_gdb_*.

+{
+    switch (n) {
+    case 0 ... 31:
+        /* gprs */
+        return sizeof(target_ulong);
+    case 32 ... 63:
+        /* fprs */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        return 8;
+    case 66:
+        /* cr */
+        return 4;
+    case 64:
+        /* nip */
+    case 65:
+        /* msr */
+    case 67:
+        /* lr */
+    case 68:
+        /* ctr */
+    case 69:
+        /* xer */
+        return sizeof(target_ulong);
+    case 70:
+        /* fpscr */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        return sizeof(target_ulong);
+    default:
+        return 0;
+    }
+}
+
+
+/* The following functions are used to ensure the correct
+ * transfer of registers between a little endian ppc target
+ * and a big endian host by checking the LE bit in the Machine State Register
+ */
+
+void ppc_cpu_gdb_swap_register(uint8_t *mem_buf, int n, int len)
+{
+    if (len == 4) {
+        bswap32s((uint32_t *)mem_buf);
+    } else {
+        bswap64s((uint64_t *)mem_buf);
+    }
This logic assumes that len can only be either 4 or 8. Please use an
explicit len == 8 comparison and g_assert_not_reached() on unhandled len
values.

+}
+
  /* 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
@@ -32,23 +84,26 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
  {
      PowerPCCPU *cpu = POWERPC_CPU(cs);
      CPUPPCState *env = &cpu->env;
+    int r = ppc_cpu_gdb_register_len(n);
+
+    if (!r) {
+        return r;
+    }
if (n < 32) {
          /* gprs */
-        return gdb_get_regl(mem_buf, env->gpr[n]);
+        gdb_get_regl(mem_buf, env->gpr[n]);
      } else if (n < 64) {
          /* fprs */
-        if (gdb_has_xml) {
-            return 0;
-        }
I stumbled over dropping this not being related to Little Endian or
being mentioned in the commit message. Maybe mention that this is
replaced by ..._register_len() and returning early?

Just split the patch into 2 separate patches. One to extract the length calculation and another one to enable LE.


Alex




reply via email to

[Prev in Thread] Current Thread [Next in Thread]