Add GDB register access for the active HLX context and register the feature for V85 CPUs with HLX support.
Signed-off-by: Marco Liebel <[email protected]> --- configs/targets/hexagon-linux-user.mak | 2 +- configs/targets/hexagon-softmmu.mak | 2 +- gdbstub/gdb-xml/hexagon-hlx.xml | 51 ++++++++++++++++++++++++++ target/hexagon/cpu.c | 18 +++++++++ target/hexagon/gdbstub.c | 46 +++++++++++++++++++++++ target/hexagon/internal.h | 2 + 6 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 gdbstub/gdb-xml/hexagon-hlx.xml diff --git a/configs/targets/hexagon-linux-user.mak b/configs/targets/hexagon-linux-user.mak index 51fde5d60e..10ae1943a5 100644 --- a/configs/targets/hexagon-linux-user.mak +++ b/configs/targets/hexagon-linux-user.mak @@ -1,5 +1,5 @@ TARGET_ARCH=hexagon -TARGET_XML_FILES=hexagon-core.xml hexagon-hvx.xml +TARGET_XML_FILES=hexagon-core.xml hexagon-hvx.xml hexagon-hlx.xml TARGET_SYSTBL=syscall.tbl TARGET_SYSTBL_ABI=common,32,hexagon,time32,stat64,rlimit,renameat TARGET_LONG_BITS=32 diff --git a/configs/targets/hexagon-softmmu.mak b/configs/targets/hexagon-softmmu.mak index 1ba6420d20..8c3a9cd4b1 100644 --- a/configs/targets/hexagon-softmmu.mak +++ b/configs/targets/hexagon-softmmu.mak @@ -1,7 +1,7 @@ # Default configuration for hexagon-softmmu TARGET_ARCH=hexagon -TARGET_XML_FILES=hexagon-core.xml hexagon-hvx.xml hexagon-sys.xml +TARGET_XML_FILES=hexagon-core.xml hexagon-hvx.xml hexagon-sys.xml hexagon-hlx.xml TARGET_LONG_BITS=32 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y diff --git a/gdbstub/gdb-xml/hexagon-hlx.xml b/gdbstub/gdb-xml/hexagon-hlx.xml new file mode 100644 index 0000000000..91040762ea --- /dev/null +++ b/gdbstub/gdb-xml/hexagon-hlx.xml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> +<!-- + Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + SPDX-License-Identifier: GPL-2.0-or-later + + LLDB uses fields that GDB can ignore. See: + https://github.com/llvm/llvm-project/blob/287aa6c4536408413b860e61fca0318a27214cf3/lldb/docs/lldb-gdb-remote.txt#L738-L860 +--> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.hexagon.hlx"> + + <!-- Sixteen 2048-byte HLX L-registers. --> + <vector id="hlx_ud" type="uint64" count="256"/> + <vector id="hlx_d" type="int64" count="256"/> + <vector id="hlx_uw" type="uint32" count="512"/> + <vector id="hlx_w" type="int32" count="512"/> + <vector id="hlx_uh" type="uint16" count="1024"/> + <vector id="hlx_h" type="int16" count="1024"/> + <vector id="hlx_ub" type="uint8" count="2048"/> + <vector id="hlx_b" type="int8" count="2048"/> + <union id="hlx_vec"> + <field name="ud" type="hlx_ud"/> + <field name="d" type="hlx_d"/> + <field name="uw" type="hlx_uw"/> + <field name="w" type="hlx_w"/> + <field name="uh" type="hlx_uh"/> + <field name="h" type="hlx_h"/> + <field name="ub" type="hlx_ub"/> + <field name="b" type="hlx_b"/> + </union> + + <!-- dwarf_regnums 124-139 follow HVX q0-q3. --> + <reg name="l0" bitsize="16384" offset="0" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="124"/> + <reg name="l1" bitsize="16384" offset="2048" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="125"/> + <reg name="l2" bitsize="16384" offset="4096" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="126"/> + <reg name="l3" bitsize="16384" offset="6144" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="127"/> + <reg name="l4" bitsize="16384" offset="8192" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="128"/> + <reg name="l5" bitsize="16384" offset="10240" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="129"/> + <reg name="l6" bitsize="16384" offset="12288" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="130"/> + <reg name="l7" bitsize="16384" offset="14336" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="131"/> + <reg name="l8" bitsize="16384" offset="16384" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="132"/> + <reg name="l9" bitsize="16384" offset="18432" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="133"/> + <reg name="l10" bitsize="16384" offset="20480" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="134"/> + <reg name="l11" bitsize="16384" offset="22528" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="135"/> + <reg name="l12" bitsize="16384" offset="24576" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="136"/> + <reg name="l13" bitsize="16384" offset="26624" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="137"/> + <reg name="l14" bitsize="16384" offset="28672" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="138"/> + <reg name="l15" bitsize="16384" offset="30720" encoding="vector" format="hex" group="HLX Vector Registers" dwarf_regnum="139"/> + +</feature> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index c3930ab4e4..dfa9e1d3af 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -540,6 +540,18 @@ static void hexagon_cpu_disas_set_info(const CPUState *cs, info->target_info = &cpu->cfg; } +static bool hexagon_cpu_has_hlx(HexagonCPU *cpu) +{ + if (cpu->cfg.hex_def->hex_version < HEX_VER_V85) { + return false; + } +#ifdef CONFIG_USER_ONLY + return true; +#else + return cpu->hlx && cpu->hlx->num_contexts > 0; +#endif +} + static void hexagon_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -559,6 +571,12 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp) hexagon_hvx_gdb_write_register, gdb_find_static_feature("hexagon-hvx.xml")); + if (hexagon_cpu_has_hlx(cpu)) { + gdb_register_coprocessor(cs, hexagon_hlx_gdb_read_register, + hexagon_hlx_gdb_write_register, + gdb_find_static_feature("hexagon-hlx.xml")); + } + #ifndef CONFIG_USER_ONLY gdb_register_coprocessor(cs, hexagon_sys_gdb_read_register, hexagon_sys_gdb_write_register, diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c index 5b79e42c4d..1065f3a826 100644 --- a/target/hexagon/gdbstub.c +++ b/target/hexagon/gdbstub.c @@ -217,3 +217,49 @@ int hexagon_hvx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) g_assert_not_reached(); } + +int hexagon_hlx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ + CPUHexagonState *env = cpu_env(cs); + int total = 0; + + BQL_LOCK_GUARD(); + + if (n < 0 || n >= NUM_LREGS) { + g_assert_not_reached(); + } + + /* Return zeroes when no HLX context is active. */ + if (env->hlx_ctx == NULL) { + for (int i = 0; i < HLX_VEC_SIZE_BYTES; i++) { + g_byte_array_append(mem_buf, (const guint8 *)"\0", 1); + } + return HLX_VEC_SIZE_BYTES; + } + + for (int i = 0; i < (int)ARRAY_SIZE(env->hlx_ctx->LRegs[n].uw); i++) { + total += gdb_get_reg32(mem_buf, env->hlx_ctx->LRegs[n].uw[i]); + } + return total; +} + +int hexagon_hlx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ + CPUHexagonState *env = cpu_env(cs); + BQL_LOCK_GUARD(); + + if (n < 0 || n >= NUM_LREGS) { + g_assert_not_reached(); + } + + /* Ignore writes without an active context. */ + if (env->hlx_ctx == NULL) { + return HLX_VEC_SIZE_BYTES; + } + + for (int i = 0; i < (int)ARRAY_SIZE(env->hlx_ctx->LRegs[n].uw); i++) { + env->hlx_ctx->LRegs[n].uw[i] = ldl_le_p(mem_buf); + mem_buf += 4; + } + return HLX_VEC_SIZE_BYTES; +} diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h index 073de10284..6def331a83 100644 --- a/target/hexagon/internal.h +++ b/target/hexagon/internal.h @@ -24,6 +24,8 @@ int hexagon_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hexagon_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); 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); +int hexagon_hlx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n); +int hexagon_hlx_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n); #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); -- 2.43.0
