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)); + } + 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> -- 2.34.1