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


Reply via email to