arch-power: Add multi-mode debugging support
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 12:20:49 +0000 (17:50 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:38 +0000 (14:02 +0530)
This adds multi-mode support for remote debugging via GDB
with the addition of the XML target description files for
both 32-bit and 64-bit variants of the Power architecture.
Proper byte order conversions have also been added.

Since, MSR has now been modeled to some extent, it is also
exposed by getRegs() but setRegs() does not modify it.
Similarly, the target descriptions require FPSCR to also
be part of the payload and hence, it has been added too.

Change-Id: I156fdccb791f161959dbb2c3dd8ab1e510d9cd4b
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
ext/gdb-xml/power-core.xml [new file with mode: 0644]
ext/gdb-xml/power-fpu.xml [new file with mode: 0644]
ext/gdb-xml/power.xml [deleted file]
ext/gdb-xml/power64-core.xml [new file with mode: 0644]
ext/gdb-xml/powerpc-32.xml [new file with mode: 0644]
ext/gdb-xml/powerpc-64.xml [new file with mode: 0644]
src/arch/power/SConscript
src/arch/power/remote_gdb.cc
src/arch/power/remote_gdb.hh

diff --git a/ext/gdb-xml/power-core.xml b/ext/gdb-xml/power-core.xml
new file mode 100644 (file)
index 0000000..6cf57b1
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+     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.power.core">
+  <reg name="r0" bitsize="32" type="uint32"/>
+  <reg name="r1" bitsize="32" type="uint32"/>
+  <reg name="r2" bitsize="32" type="uint32"/>
+  <reg name="r3" bitsize="32" type="uint32"/>
+  <reg name="r4" bitsize="32" type="uint32"/>
+  <reg name="r5" bitsize="32" type="uint32"/>
+  <reg name="r6" bitsize="32" type="uint32"/>
+  <reg name="r7" bitsize="32" type="uint32"/>
+  <reg name="r8" bitsize="32" type="uint32"/>
+  <reg name="r9" bitsize="32" type="uint32"/>
+  <reg name="r10" bitsize="32" type="uint32"/>
+  <reg name="r11" bitsize="32" type="uint32"/>
+  <reg name="r12" bitsize="32" type="uint32"/>
+  <reg name="r13" bitsize="32" type="uint32"/>
+  <reg name="r14" bitsize="32" type="uint32"/>
+  <reg name="r15" bitsize="32" type="uint32"/>
+  <reg name="r16" bitsize="32" type="uint32"/>
+  <reg name="r17" bitsize="32" type="uint32"/>
+  <reg name="r18" bitsize="32" type="uint32"/>
+  <reg name="r19" bitsize="32" type="uint32"/>
+  <reg name="r20" bitsize="32" type="uint32"/>
+  <reg name="r21" bitsize="32" type="uint32"/>
+  <reg name="r22" bitsize="32" type="uint32"/>
+  <reg name="r23" bitsize="32" type="uint32"/>
+  <reg name="r24" bitsize="32" type="uint32"/>
+  <reg name="r25" bitsize="32" type="uint32"/>
+  <reg name="r26" bitsize="32" type="uint32"/>
+  <reg name="r27" bitsize="32" type="uint32"/>
+  <reg name="r28" bitsize="32" type="uint32"/>
+  <reg name="r29" bitsize="32" type="uint32"/>
+  <reg name="r30" bitsize="32" type="uint32"/>
+  <reg name="r31" bitsize="32" type="uint32"/>
+
+  <reg name="pc" bitsize="32" type="code_ptr" regnum="64"/>
+  <reg name="msr" bitsize="32" type="uint32"/>
+  <reg name="cr" bitsize="32" type="uint32"/>
+  <reg name="lr" bitsize="32" type="code_ptr"/>
+  <reg name="ctr" bitsize="32" type="uint32"/>
+  <reg name="xer" bitsize="32" type="uint32"/>
+</feature>
diff --git a/ext/gdb-xml/power-fpu.xml b/ext/gdb-xml/power-fpu.xml
new file mode 100644 (file)
index 0000000..145eede
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+     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.power.fpu">
+  <reg name="f0" bitsize="64" type="ieee_double" regnum="32"/>
+  <reg name="f1" bitsize="64" type="ieee_double"/>
+  <reg name="f2" bitsize="64" type="ieee_double"/>
+  <reg name="f3" bitsize="64" type="ieee_double"/>
+  <reg name="f4" bitsize="64" type="ieee_double"/>
+  <reg name="f5" bitsize="64" type="ieee_double"/>
+  <reg name="f6" bitsize="64" type="ieee_double"/>
+  <reg name="f7" bitsize="64" type="ieee_double"/>
+  <reg name="f8" bitsize="64" type="ieee_double"/>
+  <reg name="f9" bitsize="64" type="ieee_double"/>
+  <reg name="f10" bitsize="64" type="ieee_double"/>
+  <reg name="f11" bitsize="64" type="ieee_double"/>
+  <reg name="f12" bitsize="64" type="ieee_double"/>
+  <reg name="f13" bitsize="64" type="ieee_double"/>
+  <reg name="f14" bitsize="64" type="ieee_double"/>
+  <reg name="f15" bitsize="64" type="ieee_double"/>
+  <reg name="f16" bitsize="64" type="ieee_double"/>
+  <reg name="f17" bitsize="64" type="ieee_double"/>
+  <reg name="f18" bitsize="64" type="ieee_double"/>
+  <reg name="f19" bitsize="64" type="ieee_double"/>
+  <reg name="f20" bitsize="64" type="ieee_double"/>
+  <reg name="f21" bitsize="64" type="ieee_double"/>
+  <reg name="f22" bitsize="64" type="ieee_double"/>
+  <reg name="f23" bitsize="64" type="ieee_double"/>
+  <reg name="f24" bitsize="64" type="ieee_double"/>
+  <reg name="f25" bitsize="64" type="ieee_double"/>
+  <reg name="f26" bitsize="64" type="ieee_double"/>
+  <reg name="f27" bitsize="64" type="ieee_double"/>
+  <reg name="f28" bitsize="64" type="ieee_double"/>
+  <reg name="f29" bitsize="64" type="ieee_double"/>
+  <reg name="f30" bitsize="64" type="ieee_double"/>
+  <reg name="f31" bitsize="64" type="ieee_double"/>
+
+  <reg name="fpscr" bitsize="32" group="float" regnum="70"/>
+</feature>
diff --git a/ext/gdb-xml/power.xml b/ext/gdb-xml/power.xml
deleted file mode 100644 (file)
index da5a07c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-GDB feature descriptor defining the structure of the G packet,
-i.e., the representation of register contents on the wire.
-This file does not model any real variant of PowerPC in particular
-(such as, RS/6000 or e500): it simply reflects BaseGdbRegCache's
-fields in power/remote_gdb.hh.
-
-As such, this description is something of an oversimplification
-relative to the XML files in the GDB source, in that it does not
-take into account possible variations in features resulting in
-non-sequential numbering of registers.
--->
-
-<target>
-  <architecture>powerpc</architecture>
-  <feature name="org.gnu.gdb.power">
-    <reg name="r0" bitsize="32"/>
-    <reg name="r1" bitsize="32"/>
-    <reg name="r2" bitsize="32"/>
-    <reg name="r3" bitsize="32"/>
-    <reg name="r4" bitsize="32"/>
-    <reg name="r5" bitsize="32"/>
-    <reg name="r6" bitsize="32"/>
-    <reg name="r7" bitsize="32"/>
-    <reg name="r8" bitsize="32"/>
-    <reg name="r9" bitsize="32"/>
-    <reg name="r10" bitsize="32"/>
-    <reg name="r11" bitsize="32"/>
-    <reg name="r12" bitsize="32"/>
-    <reg name="r13" bitsize="32"/>
-    <reg name="r14" bitsize="32"/>
-    <reg name="r15" bitsize="32"/>
-    <reg name="r16" bitsize="32"/>
-    <reg name="r17" bitsize="32"/>
-    <reg name="r18" bitsize="32"/>
-    <reg name="r19" bitsize="32"/>
-    <reg name="r20" bitsize="32"/>
-    <reg name="r21" bitsize="32"/>
-    <reg name="r22" bitsize="32"/>
-    <reg name="r23" bitsize="32"/>
-    <reg name="r24" bitsize="32"/>
-    <reg name="r25" bitsize="32"/>
-    <reg name="r26" bitsize="32"/>
-    <reg name="r27" bitsize="32"/>
-    <reg name="r28" bitsize="32"/>
-    <reg name="r29" bitsize="32"/>
-    <reg name="r30" bitsize="32"/>
-    <reg name="r31" bitsize="32"/>
-
-    <reg name="f0" bitsize="64" type="ieee_double" regnum="32"/>
-    <reg name="f1" bitsize="64" type="ieee_double"/>
-    <reg name="f2" bitsize="64" type="ieee_double"/>
-    <reg name="f3" bitsize="64" type="ieee_double"/>
-    <reg name="f4" bitsize="64" type="ieee_double"/>
-    <reg name="f5" bitsize="64" type="ieee_double"/>
-    <reg name="f6" bitsize="64" type="ieee_double"/>
-    <reg name="f7" bitsize="64" type="ieee_double"/>
-    <reg name="f8" bitsize="64" type="ieee_double"/>
-    <reg name="f9" bitsize="64" type="ieee_double"/>
-    <reg name="f10" bitsize="64" type="ieee_double"/>
-    <reg name="f11" bitsize="64" type="ieee_double"/>
-    <reg name="f12" bitsize="64" type="ieee_double"/>
-    <reg name="f13" bitsize="64" type="ieee_double"/>
-    <reg name="f14" bitsize="64" type="ieee_double"/>
-    <reg name="f15" bitsize="64" type="ieee_double"/>
-    <reg name="f16" bitsize="64" type="ieee_double"/>
-    <reg name="f17" bitsize="64" type="ieee_double"/>
-    <reg name="f18" bitsize="64" type="ieee_double"/>
-    <reg name="f19" bitsize="64" type="ieee_double"/>
-    <reg name="f20" bitsize="64" type="ieee_double"/>
-    <reg name="f21" bitsize="64" type="ieee_double"/>
-    <reg name="f22" bitsize="64" type="ieee_double"/>
-    <reg name="f23" bitsize="64" type="ieee_double"/>
-    <reg name="f24" bitsize="64" type="ieee_double"/>
-    <reg name="f25" bitsize="64" type="ieee_double"/>
-    <reg name="f26" bitsize="64" type="ieee_double"/>
-    <reg name="f27" bitsize="64" type="ieee_double"/>
-    <reg name="f28" bitsize="64" type="ieee_double"/>
-    <reg name="f29" bitsize="64" type="ieee_double"/>
-    <reg name="f30" bitsize="64" type="ieee_double"/>
-    <reg name="f31" bitsize="64" type="ieee_double"/>
-
-    <reg name="pc"  bitsize="32" type="code_ptr" regnum="64"/>
-    <reg name="msr" bitsize="32"/>
-    <reg name="cr"  bitsize="32"/>
-    <reg name="lr"  bitsize="32" type="code_ptr"/>
-    <reg name="ctr" bitsize="32"/>
-    <reg name="xer" bitsize="32"/>
-  </feature>
-</target>
diff --git a/ext/gdb-xml/power64-core.xml b/ext/gdb-xml/power64-core.xml
new file mode 100644 (file)
index 0000000..cd5bc6d
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+     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.power.core">
+  <reg name="r0" bitsize="64" type="uint64"/>
+  <reg name="r1" bitsize="64" type="uint64"/>
+  <reg name="r2" bitsize="64" type="uint64"/>
+  <reg name="r3" bitsize="64" type="uint64"/>
+  <reg name="r4" bitsize="64" type="uint64"/>
+  <reg name="r5" bitsize="64" type="uint64"/>
+  <reg name="r6" bitsize="64" type="uint64"/>
+  <reg name="r7" bitsize="64" type="uint64"/>
+  <reg name="r8" bitsize="64" type="uint64"/>
+  <reg name="r9" bitsize="64" type="uint64"/>
+  <reg name="r10" bitsize="64" type="uint64"/>
+  <reg name="r11" bitsize="64" type="uint64"/>
+  <reg name="r12" bitsize="64" type="uint64"/>
+  <reg name="r13" bitsize="64" type="uint64"/>
+  <reg name="r14" bitsize="64" type="uint64"/>
+  <reg name="r15" bitsize="64" type="uint64"/>
+  <reg name="r16" bitsize="64" type="uint64"/>
+  <reg name="r17" bitsize="64" type="uint64"/>
+  <reg name="r18" bitsize="64" type="uint64"/>
+  <reg name="r19" bitsize="64" type="uint64"/>
+  <reg name="r20" bitsize="64" type="uint64"/>
+  <reg name="r21" bitsize="64" type="uint64"/>
+  <reg name="r22" bitsize="64" type="uint64"/>
+  <reg name="r23" bitsize="64" type="uint64"/>
+  <reg name="r24" bitsize="64" type="uint64"/>
+  <reg name="r25" bitsize="64" type="uint64"/>
+  <reg name="r26" bitsize="64" type="uint64"/>
+  <reg name="r27" bitsize="64" type="uint64"/>
+  <reg name="r28" bitsize="64" type="uint64"/>
+  <reg name="r29" bitsize="64" type="uint64"/>
+  <reg name="r30" bitsize="64" type="uint64"/>
+  <reg name="r31" bitsize="64" type="uint64"/>
+
+  <reg name="pc" bitsize="64" type="code_ptr" regnum="64"/>
+  <reg name="msr" bitsize="64" type="uint64"/>
+  <reg name="cr" bitsize="32" type="uint32"/>
+  <reg name="lr" bitsize="64" type="code_ptr"/>
+  <reg name="ctr" bitsize="64" type="uint64"/>
+  <reg name="xer" bitsize="32" type="uint32"/>
+</feature>
diff --git a/ext/gdb-xml/powerpc-32.xml b/ext/gdb-xml/powerpc-32.xml
new file mode 100644 (file)
index 0000000..a537f92
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+     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.  -->
+
+<!-- PowerPC UISA - a PPC processor as viewed by user-level code.  A UISA-only
+     view of the PowerPC.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>powerpc:common</architecture>
+  <xi:include href="power-core.xml"/>
+  <xi:include href="power-fpu.xml"/>
+</target>
diff --git a/ext/gdb-xml/powerpc-64.xml b/ext/gdb-xml/powerpc-64.xml
new file mode 100644 (file)
index 0000000..a762f8c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2020 Free Software Foundation, Inc.
+
+     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.  -->
+
+<!-- PowerPC UISA - a PPC processor as viewed by user-level code.  A UISA-only
+     view of the PowerPC.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>powerpc:common64</architecture>
+  <xi:include href="power64-core.xml"/>
+  <xi:include href="power-fpu.xml"/>
+</target>
index cf79094a7402f4166998b9aad02121d4ae3452ef..9b297eba61294ce5d28838952d80fa34c986b71d 100644 (file)
@@ -60,4 +60,8 @@ if env['TARGET_ISA'] == 'power':
 
     ISADesc('isa/main.isa')
 
-    GdbXml('power.xml', 'gdb_xml_power')
+    GdbXml('power-core.xml', 'gdb_xml_power_core')
+    GdbXml('power64-core.xml', 'gdb_xml_power64_core')
+    GdbXml('power-fpu.xml', 'gdb_xml_power_fpu')
+    GdbXml('powerpc-32.xml', 'gdb_xml_powerpc_32')
+    GdbXml('powerpc-64.xml', 'gdb_xml_powerpc_64')
index d2e292e42e38c1891e8159980b57e09319598af1..57a41f5cc71d93a3834b5ed1443414c462f53a37 100644 (file)
 
 #include <string>
 
-#include "blobs/gdb_xml_power.hh"
+#include "blobs/gdb_xml_power64_core.hh"
+#include "blobs/gdb_xml_power_core.hh"
+#include "blobs/gdb_xml_power_fpu.hh"
+#include "blobs/gdb_xml_powerpc_32.hh"
+#include "blobs/gdb_xml_powerpc_64.hh"
 #include "cpu/thread_state.hh"
 #include "debug/GDBAcc.hh"
 #include "debug/GDBMisc.hh"
 using namespace PowerISA;
 
 RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc, int _port)
-    : BaseRemoteGDB(_system, tc, _port), regCache(this)
+    : BaseRemoteGDB(_system, tc, _port), regCache32(this), regCache64(this)
 {
 }
 
@@ -170,22 +174,27 @@ RemoteGDB::PowerGdbRegCache::getRegs(ThreadContext *context)
 {
     DPRINTF(GDBAcc, "getRegs in remotegdb \n");
 
+    Msr msr = context->readMiscRegNoEffect(MISCREG_MSR);
+    ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
+
     // Default order on 32-bit PowerPC:
     // R0-R31 (32-bit each), F0-F31 (64-bit IEEE754 double),
-    // PC, MSR, CR, LR, CTR, XER (32-bit each)
+    // PC, MSR, CR, LR, CTR, XER, FPSCR (32-bit each)
 
     for (int i = 0; i < NumIntArchRegs; i++)
-        r.gpr[i] = htobe((uint32_t)context->readIntReg(i));
+        r.gpr[i] = htog((uint32_t)context->readIntReg(i), order);
 
     for (int i = 0; i < NumFloatArchRegs; i++)
         r.fpr[i] = context->readFloatReg(i);
 
-    r.pc = htobe((uint32_t)context->pcState().pc());
-    r.msr = 0; // Is MSR modeled?
-    r.cr = htobe((uint32_t)context->readMiscReg(MISCREG_CR));
-    r.lr = htobe((uint32_t)context->readMiscReg(MISCREG_LR));
-    r.ctr = htobe((uint32_t)context->readMiscReg(MISCREG_CTR));
-    r.xer = htobe((uint32_t)context->readMiscReg(MISCREG_XER));
+    r.pc = htog((uint32_t)context->pcState().pc(), order);
+    r.msr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_MSR), order);
+    r.cr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_CR), order);
+    r.lr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_LR), order);
+    r.ctr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_CTR), order);
+    r.xer = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_XER), order);
+    r.fpscr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_FPSCR),
+                   order);
 }
 
 void
@@ -193,24 +202,90 @@ RemoteGDB::PowerGdbRegCache::setRegs(ThreadContext *context) const
 {
     DPRINTF(GDBAcc, "setRegs in remotegdb \n");
 
+    Msr msr = context->readMiscRegNoEffect(MISCREG_MSR);
+    ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
+
     for (int i = 0; i < NumIntArchRegs; i++)
-        context->setIntReg(i, betoh(r.gpr[i]));
+        context->setIntReg(i, gtoh(r.gpr[i], order));
 
     for (int i = 0; i < NumFloatArchRegs; i++)
         context->setFloatReg(i, r.fpr[i]);
 
-    context->pcState(betoh(r.pc));
-    // Is MSR modeled?
-    context->setMiscReg(MISCREG_CR, betoh(r.cr));
-    context->setMiscReg(MISCREG_LR, betoh(r.lr));
-    context->setMiscReg(MISCREG_CTR, betoh(r.ctr));
-    context->setMiscReg(MISCREG_XER, betoh(r.xer));
+    auto pc = context->pcState();
+    pc.byteOrder(order);
+    pc.set(gtoh(r.pc, order));
+    context->pcState(pc);
+    // Do not modify MSR
+    context->setMiscRegNoEffect(MISCREG_CR, gtoh(r.cr, order));
+    context->setMiscRegNoEffect(MISCREG_LR, gtoh(r.lr, order));
+    context->setMiscRegNoEffect(MISCREG_CTR, gtoh(r.ctr, order));
+    context->setMiscRegNoEffect(MISCREG_XER, gtoh(r.xer, order));
+    context->setMiscRegNoEffect(MISCREG_FPSCR, gtoh(r.fpscr, order));
+}
+
+void
+RemoteGDB::Power64GdbRegCache::getRegs(ThreadContext *context)
+{
+    DPRINTF(GDBAcc, "getRegs in remotegdb \n");
+
+    Msr msr = context->readMiscRegNoEffect(MISCREG_MSR);
+    ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
+
+    // Default order on 64-bit PowerPC:
+    // GPRR0-GPRR31 (64-bit each), FPR0-FPR31 (64-bit IEEE754 double),
+    // CIA, MSR, CR, LR, CTR, XER, FPSCR (only CR, XER, FPSCR are 32-bit
+    // each and the rest are 64-bit)
+
+    for (int i = 0; i < NumIntArchRegs; i++)
+        r.gpr[i] = htog(context->readIntReg(i), order);
+
+    for (int i = 0; i < NumFloatArchRegs; i++)
+        r.fpr[i] = context->readFloatReg(i);
+
+    r.pc = htog(context->pcState().pc(), order);
+    r.msr = htog(context->readMiscRegNoEffect(MISCREG_MSR), order);
+    r.cr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_CR), order);
+    r.lr = htog(context->readMiscRegNoEffect(MISCREG_LR), order);
+    r.ctr = htog(context->readMiscRegNoEffect(MISCREG_CTR), order);
+    r.xer = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_XER), order);
+    r.fpscr = htog((uint32_t)context->readMiscRegNoEffect(MISCREG_FPSCR),
+                   order);
+}
+
+void
+RemoteGDB::Power64GdbRegCache::setRegs(ThreadContext *context) const
+{
+    DPRINTF(GDBAcc, "setRegs in remotegdb \n");
+
+    Msr msr = context->readMiscRegNoEffect(MISCREG_MSR);
+    ByteOrder order = (msr.le ? ByteOrder::little : ByteOrder::big);
+
+    for (int i = 0; i < NumIntArchRegs; i++)
+        context->setIntReg(i, gtoh(r.gpr[i], order));
+
+    for (int i = 0; i < NumFloatArchRegs; i++)
+        context->setFloatReg(i, r.fpr[i]);
+
+    auto pc = context->pcState();
+    pc.byteOrder(order);
+    pc.set(gtoh(r.pc, order));
+    context->pcState(pc);
+    // Do not modify MSR
+    context->setMiscRegNoEffect(MISCREG_CR, gtoh(r.cr, order));
+    context->setMiscRegNoEffect(MISCREG_LR, gtoh(r.lr, order));
+    context->setMiscRegNoEffect(MISCREG_CTR, gtoh(r.ctr, order));
+    context->setMiscRegNoEffect(MISCREG_XER, gtoh(r.xer, order));
+    context->setMiscRegNoEffect(MISCREG_FPSCR, gtoh(r.fpscr, order));
 }
 
 BaseGdbRegCache*
 RemoteGDB::gdbRegs()
 {
-    return &regCache;
+    Msr msr = context()->readMiscRegNoEffect(MISCREG_MSR);
+    if (msr.sf)
+        return &regCache64;
+    else
+        return &regCache32;
 }
 
 bool
@@ -219,10 +294,20 @@ RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output)
 #define GDB_XML(x, s) \
         { x, std::string(reinterpret_cast<const char *>(Blobs::s), \
         Blobs::s ## _len) }
-    static const std::map<std::string, std::string> annexMap {
-        GDB_XML("target.xml", gdb_xml_power),
+    static const std::map<std::string, std::string> annexMap32{
+        GDB_XML("target.xml", gdb_xml_powerpc_32),
+        GDB_XML("power-core.xml", gdb_xml_power_core),
+        GDB_XML("power-fpu.xml", gdb_xml_power_fpu)
+    };
+    static const std::map<std::string, std::string> annexMap64{
+        GDB_XML("target.xml", gdb_xml_powerpc_64),
+        GDB_XML("power64-core.xml", gdb_xml_power64_core),
+        GDB_XML("power-fpu.xml", gdb_xml_power_fpu)
     };
 #undef GDB_XML
+
+    Msr msr = context()->readMiscRegNoEffect(MISCREG_MSR);
+    auto& annexMap = msr.sf ? annexMap64 : annexMap32;
     auto it = annexMap.find(annex);
     if (it == annexMap.end())
         return false;
index 3bb726e52a48e4e8e1d9c569783cbc7768dedfe7..50b4f795749ed457af68547fc1d09d6373667a77 100644 (file)
@@ -49,7 +49,7 @@ class RemoteGDB : public BaseRemoteGDB
     {
       using BaseGdbRegCache::BaseGdbRegCache;
       private:
-        struct {
+        struct M5_ATTR_PACKED {
             uint32_t gpr[NumIntArchRegs];
             uint64_t fpr[NumFloatArchRegs];
             uint32_t pc;
@@ -58,7 +58,9 @@ class RemoteGDB : public BaseRemoteGDB
             uint32_t lr;
             uint32_t ctr;
             uint32_t xer;
+            uint32_t fpscr;
         } r;
+
       public:
         char *data() const { return (char *)&r; }
         size_t size() const { return sizeof(r); }
@@ -71,16 +73,47 @@ class RemoteGDB : public BaseRemoteGDB
         }
     };
 
-    PowerGdbRegCache regCache;
+    class Power64GdbRegCache : public BaseGdbRegCache
+    {
+      using BaseGdbRegCache::BaseGdbRegCache;
+      private:
+        struct M5_ATTR_PACKED {
+            uint64_t gpr[NumIntArchRegs];
+            uint64_t fpr[NumFloatArchRegs];
+            uint64_t pc;
+            uint64_t msr;
+            uint32_t cr;
+            uint64_t lr;
+            uint64_t ctr;
+            uint32_t xer;
+            uint32_t fpscr;
+        } r;
+
+      public:
+        char *data() const { return (char *)&r; }
+        size_t size() const { return sizeof(r); }
+        void getRegs(ThreadContext*);
+        void setRegs(ThreadContext*) const;
+        const std::string
+        name() const
+        {
+            return gdb->name() + ".Power64GdbRegCache";
+        }
+    };
+
+    PowerGdbRegCache regCache32;
+    Power64GdbRegCache regCache64;
 
   public:
     RemoteGDB(System *_system, ThreadContext *tc, int _port);
     BaseGdbRegCache *gdbRegs();
+
     std::vector<std::string>
     availableFeatures() const
     {
         return {"qXfer:features:read+"};
     };
+
     bool getXferFeaturesRead(const std::string &annex, std::string &output);
 };