arch-arm: implement the GDB XML target description for ARM

The supported registers are essentially the same as before this patch,
but it is now trivial to make new registers visible in future commits.

Change-Id: Id15b7aeccca824c342e49a626d2877179474f3d4
Reviewed-on: https://gem5-review.googlesource.com/c/15138
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index c84c69b..a1063f0 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -105,3 +105,10 @@
 
     # Add files generated by the ISA description.
     ISADesc('isa/main.isa', decoder_splits=3, exec_splits=6)
+
+    GdbXml('arm/arm-with-neon.xml', 'gdb_xml_arm_target')
+    GdbXml('arm/arm-core.xml', 'gdb_xml_arm_core')
+    GdbXml('arm/arm-vfpv3.xml', 'gdb_xml_arm_vfpv3')
+    GdbXml('aarch64.xml', 'gdb_xml_aarch64_target')
+    GdbXml('aarch64-core.xml', 'gdb_xml_aarch64_core')
+    GdbXml('aarch64-fpu.xml', 'gdb_xml_aarch64_fpu')
diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc
index f3ffa85..05adfea 100644
--- a/src/arch/arm/remote_gdb.cc
+++ b/src/arch/arm/remote_gdb.cc
@@ -1,7 +1,7 @@
 /*
  * Copyright 2015 LabWare
  * Copyright 2014 Google Inc.
- * Copyright (c) 2010, 2013, 2016 ARM Limited
+ * Copyright (c) 2010, 2013, 2016, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -150,6 +150,12 @@
 #include "base/remote_gdb.hh"
 #include "base/socket.hh"
 #include "base/trace.hh"
+#include "blobs/gdb_xml_aarch64_core.hh"
+#include "blobs/gdb_xml_aarch64_fpu.hh"
+#include "blobs/gdb_xml_aarch64_target.hh"
+#include "blobs/gdb_xml_arm_core.hh"
+#include "blobs/gdb_xml_arm_target.hh"
+#include "blobs/gdb_xml_arm_vfpv3.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
 #include "cpu/thread_state.hh"
@@ -211,6 +217,8 @@
             base++;
         }
     }
+    r.fpsr = context->readMiscRegNoEffect(MISCREG_FPSR);
+    r.fpcr = context->readMiscRegNoEffect(MISCREG_FPCR);
 }
 
 void
@@ -238,6 +246,8 @@
             base++;
         }
     }
+    context->setMiscRegNoEffect(MISCREG_FPSR, r.fpsr);
+    context->setMiscRegNoEffect(MISCREG_FPCR, r.fpcr);
 }
 
 void
@@ -261,12 +271,13 @@
     r.gpr[13] = context->readIntReg(INTREG_SP);
     r.gpr[14] = context->readIntReg(INTREG_LR);
     r.gpr[15] = context->pcState().pc();
+    r.cpsr = context->readMiscRegNoEffect(MISCREG_CPSR);
 
     // One day somebody will implement transfer of FPRs correctly.
-    for (int i=0; i<8*3; i++) r.fpr[i] = 0;
+    for (int i = 0; i < 32; i++)
+        r.fpr[i] = 0;
 
     r.fpscr = context->readMiscRegNoEffect(MISCREG_FPSCR);
-    r.cpsr = context->readMiscRegNoEffect(MISCREG_CPSR);
 }
 
 void
@@ -299,6 +310,31 @@
     context->setMiscRegNoEffect(MISCREG_CPSR, r.cpsr);
 }
 
+bool
+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> annexMap32{
+        GDB_XML("target.xml", gdb_xml_arm_target),
+        GDB_XML("arm-core.xml", gdb_xml_arm_core),
+        GDB_XML("arm-vfpv3.xml", gdb_xml_arm_vfpv3),
+    };
+    static const std::map<std::string, std::string> annexMap64{
+        GDB_XML("target.xml", gdb_xml_aarch64_target),
+        GDB_XML("aarch64-core.xml", gdb_xml_aarch64_core),
+        GDB_XML("aarch64-fpu.xml", gdb_xml_aarch64_fpu),
+    };
+#undef GDB_XML
+    auto& annexMap = inAArch64(context()) ? annexMap64 : annexMap32;
+    auto it = annexMap.find(annex);
+    if (it == annexMap.end())
+        return false;
+    output = it->second;
+    return true;
+}
+
 BaseGdbRegCache*
 RemoteGDB::gdbRegs()
 {
diff --git a/src/arch/arm/remote_gdb.hh b/src/arch/arm/remote_gdb.hh
index 10fcb6d..3e4c5ef 100644
--- a/src/arch/arm/remote_gdb.hh
+++ b/src/arch/arm/remote_gdb.hh
@@ -1,7 +1,7 @@
 /*
  * Copyright 2015 LabWare
  * Copyright 2014 Google, Inc.
- * Copyright (c) 2013, 2016 ARM Limited
+ * Copyright (c) 2013, 2016, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -50,6 +50,7 @@
 
 #include <algorithm>
 
+#include "arch/arm/registers.hh"
 #include "arch/arm/utility.hh"
 #include "base/compiler.hh"
 #include "base/remote_gdb.hh"
@@ -71,9 +72,9 @@
       private:
         struct {
           uint32_t gpr[16];
-          uint32_t fpr[8*3];
-          uint32_t fpscr;
           uint32_t cpsr;
+          uint64_t fpr[32];
+          uint32_t fpscr;
         } M5_ATTR_PACKED r;
       public:
         char *data() const { return (char *)&r; }
@@ -97,6 +98,8 @@
           uint64_t pc;
           uint32_t cpsr;
           VecElem v[NumVecV8ArchRegs * NumVecElemPerVecReg];
+          uint32_t fpsr;
+          uint32_t fpcr;
         } M5_ATTR_PACKED r;
       public:
         char *data() const { return (char *)&r; }
@@ -116,6 +119,12 @@
   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);
 };
 } // namespace ArmISA