On 2/28/2025 11:26 PM, Brian Cain wrote:
From: Brian Cain <bc...@quicinc.com>
Co-authored-by: Matheus Tavares Bernardino <quic_mathb...@quicinc.com>
Signed-off-by: Brian Cain <brian.c...@oss.qualcomm.com>
---
target/hexagon/cpu.h | 6 ++
target/hexagon/internal.h | 4 ++
target/hexagon/cpu.c | 17 ++++++
target/hexagon/gdbstub.c | 45 ++++++++++++++
target/hexagon/op_helper.c | 16 +++++
gdb-xml/hexagon-sys.xml | 116 +++++++++++++++++++++++++++++++++++++
6 files changed, 204 insertions(+)
create mode 100644 gdb-xml/hexagon-sys.xml
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index ddc1158d8e..b0ccaf36f9 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -183,6 +183,12 @@ G_NORETURN void
hexagon_raise_exception_err(CPUHexagonState *env,
uint32_t exception,
uintptr_t pc);
+#ifndef CONFIG_USER_ONLY
+uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg);
+uint32_t hexagon_sreg_read(CPUHexagonState *env, uint32_t reg);
+void hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t val);
+#endif
+
static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags)
{
diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h
index 7cf7bcaa6c..c24c360921 100644
--- a/target/hexagon/internal.h
+++ b/target/hexagon/internal.h
@@ -22,6 +22,10 @@
int hexagon_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int hexagon_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+#ifndef CONFIG_USER_ONLY
+int hexagon_sys_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
+int hexagon_sys_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
+#endif
int hexagon_hvx_gdb_read_register(CPUState *env, GByteArray *mem_buf, int n);
int hexagon_hvx_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 7c34d015a3..34c39cecd9 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -29,6 +29,10 @@
#include "cpu_helper.h"
#include "max.h"
+#ifndef CONFIG_USER_ONLY
+#include "sys_macros.h"
+#endif
+
static void hexagon_v66_cpu_init(Object *obj) { }
static void hexagon_v67_cpu_init(Object *obj) { }
static void hexagon_v68_cpu_init(Object *obj) { }
@@ -341,6 +345,12 @@ static void hexagon_cpu_realize(DeviceState *dev, Error
**errp)
hexagon_hvx_gdb_write_register,
gdb_find_static_feature("hexagon-hvx.xml"), 0);
+#ifndef CONFIG_USER_ONLY
+ gdb_register_coprocessor(cs, hexagon_sys_gdb_read_register,
+ hexagon_sys_gdb_write_register,
+ gdb_find_static_feature("hexagon-sys.xml"), 0);
+#endif
+
qemu_init_vcpu(cs);
cpu_reset(cs);
#ifndef CONFIG_USER_ONLY
@@ -400,6 +410,13 @@ static void hexagon_cpu_class_init(ObjectClass *c, void
*data)
cc->tcg_ops = &hexagon_tcg_ops;
}
+#ifndef CONFIG_USER_ONLY
+uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg)
+{
+ g_assert_not_reached();
+}
+#endif
+
#define DEFINE_CPU(type_name, initfn) \
{ \
.name = type_name, \
diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c
index 12d6b3bbcb..8476199b75 100644
--- a/target/hexagon/gdbstub.c
+++ b/target/hexagon/gdbstub.c
@@ -76,6 +76,51 @@ int hexagon_gdb_write_register(CPUState *cs, uint8_t
*mem_buf, int n)
g_assert_not_reached();
}
+#ifndef CONFIG_USER_ONLY
+int hexagon_sys_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+ CPUHexagonState *env = cpu_env(cs);
+
+ if (n < NUM_SREGS) {
+ return gdb_get_regl(mem_buf, hexagon_sreg_read(env, n));
+ }
+ n -= NUM_SREGS;
+
+ if (n < NUM_GREGS) {
+ return gdb_get_regl(mem_buf, hexagon_greg_read(env, n));
My mailer seems to have eaten his message but I can see on the list
archive that Taylor asked "Are all of these writable directly without
any checks?"
Good question. We have mutability masks that prevent the transfer
instructions from overwriting bits they shouldn't be able to. If we're
using that same interface for the gdbstub, it would probably make
sense. I'll check that and if it's not right I'll address it for v3.
+ }
+ n -= NUM_GREGS;
+
+ n -= TOTAL_PER_THREAD_REGS;
+
+ if (n < NUM_PREGS) {
+ env->pred[n] = ldtul_p(mem_buf) & 0xff;
+ return sizeof(uint8_t);
+ }
+
+ n -= NUM_PREGS;
+
+ g_assert_not_reached();
+}
+
+int hexagon_sys_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ CPUHexagonState *env = cpu_env(cs);
+
+ if (n < NUM_SREGS) {
+ hexagon_gdb_sreg_write(env, n, ldtul_p(mem_buf));
+ return sizeof(target_ulong);
+ }
+ n -= NUM_SREGS;
+
+ if (n < NUM_GREGS) {
+ return env->greg[n] = ldtul_p(mem_buf);
+ }
+ n -= NUM_GREGS;
+
+ g_assert_not_reached();
+}
+#endif
static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
{
int total = 0;
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 76b2475d88..fd9caafefc 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1465,6 +1465,17 @@ void HELPER(sreg_write)(CPUHexagonState *env, uint32_t
reg, uint32_t val)
sreg_write(env, reg, val);
}
+void hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t val)
+{
+ BQL_LOCK_GUARD();
+ sreg_write(env, reg, val);
+ /*
+ * The above is needed to run special logic for regs like syscfg, but it
+ * won't set read-only bits. This will:
+ */
+ arch_set_system_reg(env, reg, val);
+}
+
void HELPER(sreg_write_pair)(CPUHexagonState *env, uint32_t reg, uint64_t val)
{
BQL_LOCK_GUARD();
@@ -1508,6 +1519,11 @@ uint32_t HELPER(sreg_read)(CPUHexagonState *env,
uint32_t reg)
return sreg_read(env, reg);
}
+uint32_t hexagon_sreg_read(CPUHexagonState *env, uint32_t reg)
+{
+ return sreg_read(env, reg);
+}
+
uint64_t HELPER(sreg_read_pair)(CPUHexagonState *env, uint32_t reg)
{
BQL_LOCK_GUARD();
diff --git a/gdb-xml/hexagon-sys.xml b/gdb-xml/hexagon-sys.xml
new file mode 100644
index 0000000000..1d9c211722
--- /dev/null
+++ b/gdb-xml/hexagon-sys.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0"?>
+<!--
+ Copyright(c) 2023-2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+
+ This work is licensed under the terms of the GNU GPL, version 2 or
+ (at your option) any later version. See the COPYING file in the
+ top-level directory.
+
+ Note: this file is intended to be use with LLDB, so it contains fields
+ that may be unknown to GDB. For more information on such fields, please
+ see:
+
https://github.com/llvm/llvm-project/blob/287aa6c4536408413b860e61fca0318a27214cf3/lldb/docs/lldb-gdb-remote.txt#L738-L860
+
https://github.com/llvm/llvm-project/blob/287aa6c4536408413b860e61fca0318a27214cf3/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp#L4275-L4335
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.hexagon.sys">
+
+ <reg name="sgp0" bitsize="32" offset="4416" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="135" />
+ <reg name="sgp1" bitsize="32" offset="4420" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="136" />
+ <reg name="stid" bitsize="32" offset="4424" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="137" />
+ <reg name="elr" bitsize="32" offset="4428" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="138" />
+ <reg name="badva0" bitsize="32" offset="4432" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="139" />
+ <reg name="badva1" bitsize="32" offset="4436" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="140" />
+ <reg name="ssr" bitsize="32" offset="4440" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="141" />
+ <reg name="ccr" bitsize="32" offset="4444" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="142" />
+ <reg name="htid" bitsize="32" offset="4448" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="143" />
+ <reg name="badva" bitsize="32" offset="4452" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="144" />
+ <reg name="imask" bitsize="32" offset="4456" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="145" />
+ <reg name="gevb" bitsize="32" offset="4460" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="146" />
+ <reg name="rsv12" bitsize="32" offset="4464" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="147" />
+ <reg name="rsv13" bitsize="32" offset="4468" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="148" />
+ <reg name="rsv14" bitsize="32" offset="4472" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="149" />
+ <reg name="rsv15" bitsize="32" offset="4476" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="150" />
+ <reg name="evb" bitsize="32" offset="4480" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="151" />
+ <reg name="modectl" bitsize="32" offset="4484" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="152" />
+ <reg name="syscfg" bitsize="32" offset="4488" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="153" />
+ <reg name="free19" bitsize="32" offset="4492" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="154" />
+ <reg name="ipendad" bitsize="32" offset="4496" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="155" />
+ <reg name="vid" bitsize="32" offset="4500" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="156" />
+ <reg name="vid1" bitsize="32" offset="4504" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="157" />
+ <reg name="bestwait" bitsize="32" offset="4508" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="158" />
+ <reg name="free24" bitsize="32" offset="4512" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="159" />
+ <reg name="schedcfg" bitsize="32" offset="4516" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="160" />
+ <reg name="free26" bitsize="32" offset="4520" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="161" />
+ <reg name="cfgbase" bitsize="32" offset="4524" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="162" />
+ <reg name="diag" bitsize="32" offset="4528" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="163" />
+ <reg name="rev" bitsize="32" offset="4532" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="164" />
+ <reg name="pcyclelo" bitsize="32" offset="4536" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="165" />
+ <reg name="pcyclehi" bitsize="32" offset="4540" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="166" />
+ <reg name="isdbst" bitsize="32" offset="4544" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="167" />
+ <reg name="isdbcfg0" bitsize="32" offset="4548" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="168" />
+ <reg name="isdbcfg1" bitsize="32" offset="4552" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="169" />
+ <reg name="livelock" bitsize="32" offset="4556" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="170" />
+ <reg name="brkptpc0" bitsize="32" offset="4560" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="171" />
+ <reg name="brkptccfg0" bitsize="32" offset="4564" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="172" />
+ <reg name="brkptpc1" bitsize="32" offset="4568" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="173" />
+ <reg name="brkptcfg1" bitsize="32" offset="4572" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="174" />
+ <reg name="isdbmbxin" bitsize="32" offset="4576" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="175" />
+ <reg name="isdbmbxout" bitsize="32" offset="4580" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="176" />
+ <reg name="isdben" bitsize="32" offset="4584" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="177" />
+ <reg name="isdbgpr" bitsize="32" offset="4588" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="178" />
+ <reg name="pmucnt4" bitsize="32" offset="4592" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="179" />
+ <reg name="pmucnt5" bitsize="32" offset="4596" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="180" />
+ <reg name="pmucnt6" bitsize="32" offset="4600" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="181" />
+ <reg name="pmucnt7" bitsize="32" offset="4604" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="182" />
+ <reg name="pmucnt0" bitsize="32" offset="4608" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="183" />
+ <reg name="pmucnt1" bitsize="32" offset="4612" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="184" />
+ <reg name="pmucnt2" bitsize="32" offset="4616" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="185" />
+ <reg name="pmucnt3" bitsize="32" offset="4620" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="186" />
+ <reg name="pmuevtcfg" bitsize="32" offset="4624" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="187" />
+ <reg name="pmustid0" bitsize="32" offset="4628" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="188" />
+ <reg name="pmuevtcfg1" bitsize="32" offset="4632" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="189" />
+ <reg name="pmustid1" bitsize="32" offset="4636" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="190" />
+ <reg name="timerlo" bitsize="32" offset="4640" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="191" />
+ <reg name="timerhi" bitsize="32" offset="4644" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="192" />
+ <reg name="pmucfg" bitsize="32" offset="4648" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="193" />
+ <reg name="rsv59" bitsize="32" offset="4652" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="194" />
+ <reg name="rsv60" bitsize="32" offset="4656" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="195" />
+ <reg name="rsv61" bitsize="32" offset="4660" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="196" />
+ <reg name="rsv62" bitsize="32" offset="4664" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="197" />
+ <reg name="rsv63" bitsize="32" offset="4668" encoding="uint" format="hex" group="System
Registers" dwarf_regnum="198" />
+ <reg name="g0" bitsize="32" offset="4672" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="179" />
+ <reg name="g1" bitsize="32" offset="4676" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="180" />
+ <reg name="g2" bitsize="32" offset="4680" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="181" />
+ <reg name="g3" bitsize="32" offset="4684" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="182" />
+ <reg name="rsv4" bitsize="32" offset="4688" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="183" />
+ <reg name="rsv5" bitsize="32" offset="4692" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="184" />
+ <reg name="rsv6" bitsize="32" offset="4696" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="185" />
+ <reg name="rsv7" bitsize="32" offset="4700" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="186" />
+ <reg name="rsv8" bitsize="32" offset="4704" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="187" />
+ <reg name="rsv9" bitsize="32" offset="4708" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="188" />
+ <reg name="rsv10" bitsize="32" offset="4712" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="189" />
+ <reg name="rsv11" bitsize="32" offset="4716" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="190" />
+ <reg name="rsv12" bitsize="32" offset="4720" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="191" />
+ <reg name="rsv13" bitsize="32" offset="4724" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="192" />
+ <reg name="rsv14" bitsize="32" offset="4728" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="193" />
+ <reg name="rsv15" bitsize="32" offset="4732" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="194" />
+ <reg name="gpmucnt4" bitsize="32" offset="4736" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="195" />
+ <reg name="gpmucnt5" bitsize="32" offset="4740" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="196" />
+ <reg name="gpmucnt6" bitsize="32" offset="4744" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="197" />
+ <reg name="gpmucnt7" bitsize="32" offset="4748" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="198" />
+ <reg name="rsv20" bitsize="32" offset="4752" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="199" />
+ <reg name="rsv21" bitsize="32" offset="4756" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="200" />
+ <reg name="rsv22" bitsize="32" offset="4760" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="201" />
+ <reg name="rsv23" bitsize="32" offset="4764" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="202" />
+ <reg name="gpcyclelo" bitsize="32" offset="4768" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="203" />
+ <reg name="gpcyclehi" bitsize="32" offset="4772" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="204" />
+ <reg name="gpmucnt0" bitsize="32" offset="4776" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="205" />
+ <reg name="gpmucnt1" bitsize="32" offset="4780" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="206" />
+ <reg name="gpmucnt2" bitsize="32" offset="4784" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="207" />
+ <reg name="gpmucnt3" bitsize="32" offset="4788" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="208" />
+ <reg name="rsv30" bitsize="32" offset="4792" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="209" />
+ <reg name="rsv31" bitsize="32" offset="4796" encoding="uint" format="hex" group="Guest
Registers" dwarf_regnum="210" />
+
+</feature>