public inbox for qemu-devel@nongnu.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] Hexagon system emulation - Part 3/3
@ 2026-03-11  4:20 Brian Cain
  2026-03-11  4:20 ` [PATCH v3 1/9] hw/hexagon: Add globalreg model Brian Cain
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo

This is Part 3 of the hexagon system emulation (sysemu) patch series,
adding the hw/hexagon board and machine support that ties together the
target infrastructure from Parts 1 and 2.

This part adds:
  - Global register model (hexagon_globalreg) for shared system
    registers across hardware threads
  - Global register tracing support
  - Machine configuration infrastructure and sa8775-cdsp0 definition
  - cfgbase support for hardware configuration base address
  - hexagon-softmmu build configuration (Kconfig, meson, default.mak)
  - The hexagon "virt" machine definition
  - A boot-serial qtest for hexagon

Changes since v2:
  - Dropped l2vic interrupt controller and QTimer device (deferred to
    a future series)
  - Removed hvx_contexts field and hvx-contexts property (HVX context
    management deferred to a future series)
  - arch_*_system_reg callers now go through globalreg_read/write
    directly (the abstraction layer from Part 2 v2 is no longer
    introduced)
  - Adapted to tip's header renames (hw/*.h -> hw/core/*.h)

Previous versions:
  v2: https://lore.kernel.org/qemu-devel/20250902034951.1948194-1-brian.cain@oss.qualcomm.com/
  v1: https://lore.kernel.org/qemu-devel/20250301172045.1295412-1-brian.cain@oss.qualcomm.com/

Brian Cain (8):
  hw/hexagon: Add globalreg model
  hw/hexagon: Add global register tracing
  hw/hexagon: Add machine configs for sysemu
  hw/hexagon: Add v68, sa8775-cdsp0 defs
  hw/hexagon: Modify "Standalone" symbols
  target/hexagon: add build config for softmmu
  hw/hexagon: Define hexagon "virt" machine
  tests/qtest: Add hexagon boot-serial-test

Sid Manning (1):
  hw/hexagon: Add support for cfgbase

 MAINTAINERS                                 |   3 +
 configs/devices/hexagon-softmmu/default.mak |   8 +
 configs/targets/hexagon-softmmu.mak         |   7 +
 meson.build                                 |   1 +
 include/hw/hexagon/hexagon.h                | 150 +++++++
 include/hw/hexagon/hexagon_globalreg.h      |  56 +++
 include/hw/hexagon/virt.h                   |  43 ++
 target/hexagon/cpu.h                        |   4 -
 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc   |  64 +++
 hw/hexagon/machine_cfg_v66g_1024.h.inc      |  64 +++
 hw/hexagon/machine_cfg_v68n_1024.h.inc      |  65 +++
 hw/hexagon/hexagon_dsp.c                    | 182 ++++++++
 hw/hexagon/hexagon_globalreg.c              | 313 ++++++++++++++
 hw/hexagon/virt.c                           | 453 ++++++++++++++++++++
 system/qdev-monitor.c                       |   2 +-
 target/hexagon/cpu.c                        |   1 -
 target/hexagon/translate.c                  |   1 +
 tests/qtest/boot-serial-test.c              |   8 +
 hw/Kconfig                                  |   1 +
 hw/hexagon/Kconfig                          |  15 +
 hw/hexagon/meson.build                      |   8 +
 hw/hexagon/trace-events                     |   3 +
 hw/meson.build                              |   1 +
 target/Kconfig                              |   1 +
 target/hexagon/Kconfig                      |   2 +
 target/hexagon/meson.build                  |  13 +-
 tests/qemu-iotests/testenv.py               |   1 +
 tests/qtest/meson.build                     |   2 +
 28 files changed, 1465 insertions(+), 7 deletions(-)
 create mode 100644 configs/devices/hexagon-softmmu/default.mak
 create mode 100644 configs/targets/hexagon-softmmu.mak
 create mode 100644 include/hw/hexagon/hexagon.h
 create mode 100644 include/hw/hexagon/hexagon_globalreg.h
 create mode 100644 include/hw/hexagon/virt.h
 create mode 100644 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
 create mode 100644 hw/hexagon/machine_cfg_v66g_1024.h.inc
 create mode 100644 hw/hexagon/machine_cfg_v68n_1024.h.inc
 create mode 100644 hw/hexagon/hexagon_dsp.c
 create mode 100644 hw/hexagon/hexagon_globalreg.c
 create mode 100644 hw/hexagon/virt.c
 create mode 100644 hw/hexagon/Kconfig
 create mode 100644 hw/hexagon/meson.build
 create mode 100644 hw/hexagon/trace-events
 create mode 100644 target/hexagon/Kconfig

-- 
2.34.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 1/9] hw/hexagon: Add globalreg model
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-16 17:58   ` Taylor Simpson
  2026-03-11  4:20 ` [PATCH v3 2/9] hw/hexagon: Add global register tracing Brian Cain
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo

Some of the system registers are shared among all threads
in the core.  This object contains the representation and
interface to the system registers.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 include/hw/hexagon/hexagon_globalreg.h |  56 ++++++
 hw/hexagon/hexagon_globalreg.c         | 240 +++++++++++++++++++++++++
 2 files changed, 296 insertions(+)
 create mode 100644 include/hw/hexagon/hexagon_globalreg.h
 create mode 100644 hw/hexagon/hexagon_globalreg.c

diff --git a/include/hw/hexagon/hexagon_globalreg.h b/include/hw/hexagon/hexagon_globalreg.h
new file mode 100644
index 00000000000..c9e72f30b0a
--- /dev/null
+++ b/include/hw/hexagon/hexagon_globalreg.h
@@ -0,0 +1,56 @@
+/*
+ * Hexagon Global Registers QOM Object
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HEXAGON_GLOBALREG_H
+#define HEXAGON_GLOBALREG_H
+
+#include "hw/core/qdev.h"
+#include "hw/core/sysbus.h"
+#include "qom/object.h"
+#include "target/hexagon/cpu.h"
+
+#define TYPE_HEXAGON_GLOBALREG "hexagon-globalreg"
+OBJECT_DECLARE_SIMPLE_TYPE(HexagonGlobalRegState, HEXAGON_GLOBALREG)
+
+struct HexagonGlobalRegState {
+    SysBusDevice parent_obj;
+
+    /* Array of system registers */
+    uint32_t regs[NUM_SREGS];
+
+    /* Global performance cycle counter base */
+    uint64_t g_pcycle_base;
+
+    /* Properties for global register reset values */
+    uint32_t boot_evb;           /* Boot Exception Vector Base (HEX_SREG_EVB) */
+    uint64_t config_table_addr;  /* Configuration table base */
+    uint32_t dsp_rev;           /* DSP revision register (HEX_SREG_REV) */
+
+    /* ISDB properties */
+    bool isdben_etm_enable;     /* ISDB ETM enable bit */
+    bool isdben_dfd_enable;     /* ISDB DFD enable bit */
+    bool isdben_trusted;        /* ISDB trusted mode bit */
+    bool isdben_secure;         /* ISDB secure mode bit */
+};
+
+/* Public interface functions */
+uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg,
+                                uint32_t htid);
+void hexagon_globalreg_write(HexagonGlobalRegState *s, uint32_t reg,
+                             uint32_t value, uint32_t htid);
+uint32_t hexagon_globalreg_masked_value(HexagonGlobalRegState *s, uint32_t reg,
+                                        uint32_t value);
+void hexagon_globalreg_write_masked(HexagonGlobalRegState *s, uint32_t reg,
+                                    uint32_t value);
+void hexagon_globalreg_reset(HexagonGlobalRegState *s);
+
+/* Global performance cycle counter access */
+uint64_t hexagon_globalreg_get_pcycle_base(HexagonGlobalRegState *s);
+void hexagon_globalreg_set_pcycle_base(HexagonGlobalRegState *s,
+                                       uint64_t value);
+
+#endif /* HEXAGON_GLOBALREG_H */
diff --git a/hw/hexagon/hexagon_globalreg.c b/hw/hexagon/hexagon_globalreg.c
new file mode 100644
index 00000000000..5187b91dcae
--- /dev/null
+++ b/hw/hexagon/hexagon_globalreg.c
@@ -0,0 +1,240 @@
+/*
+ * Hexagon Global Registers
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hexagon/hexagon.h"
+#include "hw/hexagon/hexagon_globalreg.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/sysbus.h"
+#include "hw/core/resettable.h"
+#include "migration/vmstate.h"
+#include "qom/object.h"
+#include "target/hexagon/cpu.h"
+#include "target/hexagon/hex_regs.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+
+#define IMMUTABLE (~0)
+#define INVALID_REG_VAL 0xdeadbeef
+
+/* Global system register mutability masks */
+static const uint32_t global_sreg_immut_masks[NUM_SREGS] = {
+    [HEX_SREG_EVB] = 0x000000ff,
+    [HEX_SREG_MODECTL] = IMMUTABLE,
+    [HEX_SREG_SYSCFG] = 0x80001c00,
+    [HEX_SREG_IPENDAD] = IMMUTABLE,
+    [HEX_SREG_VID] = 0xfc00fc00,
+    [HEX_SREG_VID1] = 0xfc00fc00,
+    [HEX_SREG_BESTWAIT] = 0xfffffe00,
+    [HEX_SREG_IAHL] = 0x00000000,
+    [HEX_SREG_SCHEDCFG] = 0xfffffee0,
+    [HEX_SREG_CFGBASE] = IMMUTABLE,
+    [HEX_SREG_DIAG] = 0x00000000,
+    [HEX_SREG_REV] = IMMUTABLE,
+    [HEX_SREG_ISDBST] = IMMUTABLE,
+    [HEX_SREG_ISDBCFG0] = 0xe0000000,
+    [HEX_SREG_BRKPTPC0] = 0x00000003,
+    [HEX_SREG_BRKPTCFG0] = 0xfc007000,
+    [HEX_SREG_BRKPTPC1] = 0x00000003,
+    [HEX_SREG_BRKPTCFG1] = 0xfc007000,
+    [HEX_SREG_ISDBMBXIN] = IMMUTABLE,
+    [HEX_SREG_ISDBMBXOUT] = 0x00000000,
+    [HEX_SREG_ISDBEN] = 0xfffffffe,
+    [HEX_SREG_TIMERLO] = IMMUTABLE,
+    [HEX_SREG_TIMERHI] = IMMUTABLE,
+};
+
+static void hexagon_globalreg_init(Object *obj)
+{
+    HexagonGlobalRegState *s = HEXAGON_GLOBALREG(obj);
+
+    memset(s->regs, 0, sizeof(uint32_t) * NUM_SREGS);
+}
+
+static inline uint32_t apply_write_mask(uint32_t new_val, uint32_t cur_val,
+                                        uint32_t reg_mask)
+{
+    if (reg_mask) {
+        return (new_val & ~reg_mask) | (cur_val & reg_mask);
+    }
+    return new_val;
+}
+
+uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg,
+                                uint32_t htid)
+{
+    g_assert(reg < NUM_SREGS);
+    g_assert(reg >= HEX_SREG_GLB_START);
+    g_assert(s);
+
+    uint32_t value = s->regs[reg];
+
+    return value;
+}
+
+void hexagon_globalreg_write(HexagonGlobalRegState *s, uint32_t reg,
+                             uint32_t value, uint32_t htid)
+{
+    g_assert(s);
+    g_assert(reg < NUM_SREGS);
+    g_assert(reg >= HEX_SREG_GLB_START);
+    s->regs[reg] = value;
+}
+
+uint32_t hexagon_globalreg_masked_value(HexagonGlobalRegState *s, uint32_t reg,
+                                        uint32_t value)
+{
+    g_assert(s);
+    g_assert(reg < NUM_SREGS);
+    g_assert(reg >= HEX_SREG_GLB_START);
+    const uint32_t reg_mask = global_sreg_immut_masks[reg];
+    return reg_mask == IMMUTABLE ?
+            s->regs[reg] :
+            apply_write_mask(value, s->regs[reg], reg_mask);
+}
+
+void hexagon_globalreg_write_masked(HexagonGlobalRegState *s, uint32_t reg,
+                                    uint32_t value)
+{
+    g_assert(s);
+    s->regs[reg] = hexagon_globalreg_masked_value(s, reg, value);
+}
+
+uint64_t hexagon_globalreg_get_pcycle_base(HexagonGlobalRegState *s)
+{
+    g_assert(s);
+    return s->g_pcycle_base;
+}
+
+void hexagon_globalreg_set_pcycle_base(HexagonGlobalRegState *s,
+                                       uint64_t value)
+{
+    g_assert(s);
+    s->g_pcycle_base = value;
+}
+
+static void do_hexagon_globalreg_reset(HexagonGlobalRegState *s)
+{
+    g_assert(s);
+    memset(s->regs, 0, sizeof(uint32_t) * NUM_SREGS);
+
+    s->g_pcycle_base = 0;
+
+    s->regs[HEX_SREG_EVB] = s->boot_evb;
+    s->regs[HEX_SREG_CFGBASE] = HEXAGON_CFG_ADDR_BASE(s->config_table_addr);
+    s->regs[HEX_SREG_REV] = s->dsp_rev;
+
+    uint32_t isdben_val = 0;
+    if (s->isdben_etm_enable) {
+        isdben_val |= (1 << 0);  /* ETM enable bit */
+    }
+    if (s->isdben_dfd_enable) {
+        isdben_val |= (1 << 1);  /* DFD enable bit */
+    }
+    if (s->isdben_trusted) {
+        isdben_val |= (1 << 2);  /* Trusted bit */
+    }
+    if (s->isdben_secure) {
+        isdben_val |= (1 << 3);  /* Secure bit */
+    }
+    s->regs[HEX_SREG_ISDBEN] = isdben_val;
+    s->regs[HEX_SREG_MODECTL] = 0x1;
+
+    /*
+     * These register indices are placeholders in these arrays
+     * and their actual values are synthesized from state elsewhere.
+     * We can initialize these with invalid values so that if we
+     * mistakenly generate reads, they will look obviously wrong.
+     */
+    s->regs[HEX_SREG_PCYCLELO] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PCYCLEHI] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_TIMERLO] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_TIMERHI] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT0] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT1] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT2] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT3] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT4] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT5] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT6] = INVALID_REG_VAL;
+    s->regs[HEX_SREG_PMUCNT7] = INVALID_REG_VAL;
+}
+
+static void hexagon_globalreg_realize(DeviceState *dev, Error **errp)
+{
+}
+
+void hexagon_globalreg_reset(HexagonGlobalRegState *s)
+{
+    do_hexagon_globalreg_reset(s);
+}
+
+static void hexagon_globalreg_reset_hold(Object *obj, ResetType type)
+{
+    HexagonGlobalRegState *s = HEXAGON_GLOBALREG(obj);
+    do_hexagon_globalreg_reset(s);
+}
+
+static const VMStateDescription vmstate_hexagon_globalreg = {
+    .name = "hexagon_globalreg",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]){
+        VMSTATE_UINT32_ARRAY(regs, HexagonGlobalRegState, NUM_SREGS),
+        VMSTATE_UINT64(g_pcycle_base, HexagonGlobalRegState),
+        VMSTATE_UINT32(boot_evb, HexagonGlobalRegState),
+        VMSTATE_UINT64(config_table_addr, HexagonGlobalRegState),
+        VMSTATE_UINT32(dsp_rev, HexagonGlobalRegState),
+        VMSTATE_BOOL(isdben_etm_enable, HexagonGlobalRegState),
+        VMSTATE_BOOL(isdben_dfd_enable, HexagonGlobalRegState),
+        VMSTATE_BOOL(isdben_trusted, HexagonGlobalRegState),
+        VMSTATE_BOOL(isdben_secure, HexagonGlobalRegState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const Property hexagon_globalreg_properties[] = {
+    DEFINE_PROP_UINT32("boot-evb", HexagonGlobalRegState, boot_evb, 0x0),
+    DEFINE_PROP_UINT64("config-table-addr", HexagonGlobalRegState,
+                       config_table_addr, 0xffffffffULL),
+    DEFINE_PROP_UINT32("dsp-rev", HexagonGlobalRegState, dsp_rev, 0),
+    DEFINE_PROP_BOOL("isdben-etm-enable", HexagonGlobalRegState,
+                     isdben_etm_enable, false),
+    DEFINE_PROP_BOOL("isdben-dfd-enable", HexagonGlobalRegState,
+                     isdben_dfd_enable, false),
+    DEFINE_PROP_BOOL("isdben-trusted", HexagonGlobalRegState,
+                     isdben_trusted, false),
+    DEFINE_PROP_BOOL("isdben-secure", HexagonGlobalRegState,
+                     isdben_secure, false),
+};
+
+static void hexagon_globalreg_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+    dc->realize = hexagon_globalreg_realize;
+    rc->phases.hold = hexagon_globalreg_reset_hold;
+    dc->vmsd = &vmstate_hexagon_globalreg;
+    dc->user_creatable = false;
+    device_class_set_props(dc, hexagon_globalreg_properties);
+}
+
+static const TypeInfo hexagon_globalreg_info = {
+    .name = TYPE_HEXAGON_GLOBALREG,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(HexagonGlobalRegState),
+    .instance_init = hexagon_globalreg_init,
+    .class_init = hexagon_globalreg_class_init,
+};
+
+static void hexagon_globalreg_register_types(void)
+{
+    type_register_static(&hexagon_globalreg_info);
+}
+
+type_init(hexagon_globalreg_register_types)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 2/9] hw/hexagon: Add global register tracing
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
  2026-03-11  4:20 ` [PATCH v3 1/9] hw/hexagon: Add globalreg model Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11 17:52   ` Philippe Mathieu-Daudé
  2026-03-16 18:02   ` Taylor Simpson
  2026-03-11  4:20 ` [PATCH v3 3/9] hw/hexagon: Add machine configs for sysemu Brian Cain
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Paolo Bonzini,
	Marc-André Lureau, Daniel P. Berrangé

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 meson.build                    |  1 +
 hw/hexagon/hexagon_globalreg.c | 73 ++++++++++++++++++++++++++++++++++
 hw/hexagon/trace-events        |  3 ++
 3 files changed, 77 insertions(+)
 create mode 100644 hw/hexagon/trace-events

diff --git a/meson.build b/meson.build
index 7b4e5bc72b5..286edfb99dc 100644
--- a/meson.build
+++ b/meson.build
@@ -3633,6 +3633,7 @@ if have_system
     'hw/display',
     'hw/dma',
     'hw/fsi',
+    'hw/hexagon',
     'hw/hyperv',
     'hw/i2c',
     'hw/i3c',
diff --git a/hw/hexagon/hexagon_globalreg.c b/hw/hexagon/hexagon_globalreg.c
index 5187b91dcae..a30c16cd7ba 100644
--- a/hw/hexagon/hexagon_globalreg.c
+++ b/hw/hexagon/hexagon_globalreg.c
@@ -16,11 +16,82 @@
 #include "target/hexagon/cpu.h"
 #include "target/hexagon/hex_regs.h"
 #include "qemu/log.h"
+#include "trace/trace-hw_hexagon.h"
 #include "qapi/error.h"
 
 #define IMMUTABLE (~0)
 #define INVALID_REG_VAL 0xdeadbeef
 
+static const char *hex_sreg_names[] = {
+    [HEX_SREG_SGP0] = "sgp0",
+    [HEX_SREG_SGP1] = "sgp1",
+    [HEX_SREG_STID] = "stid",
+    [HEX_SREG_ELR] = "elr",
+    [HEX_SREG_BADVA0] = "badva0",
+    [HEX_SREG_BADVA1] = "badva1",
+    [HEX_SREG_SSR] = "ssr",
+    [HEX_SREG_CCR] = "ccr",
+    [HEX_SREG_HTID] = "htid",
+    [HEX_SREG_BADVA] = "badva",
+    [HEX_SREG_IMASK] = "imask",
+    [HEX_SREG_GEVB] = "gevb",
+    [HEX_SREG_EVB] = "evb",
+    [HEX_SREG_MODECTL] = "modectl",
+    [HEX_SREG_SYSCFG] = "syscfg",
+    [HEX_SREG_IPENDAD] = "ipendad",
+    [HEX_SREG_VID] = "vid",
+    [HEX_SREG_VID1] = "vid1",
+    [HEX_SREG_BESTWAIT] = "bestwait",
+    [HEX_SREG_IEL] = "iel",
+    [HEX_SREG_SCHEDCFG] = "schedcfg",
+    [HEX_SREG_IAHL] = "iahl",
+    [HEX_SREG_CFGBASE] = "cfgbase",
+    [HEX_SREG_DIAG] = "diag",
+    [HEX_SREG_REV] = "rev",
+    [HEX_SREG_PCYCLELO] = "pcyclelo",
+    [HEX_SREG_PCYCLEHI] = "pcyclehi",
+    [HEX_SREG_ISDBST] = "isdbst",
+    [HEX_SREG_ISDBCFG0] = "isdbcfg0",
+    [HEX_SREG_ISDBCFG1] = "isdbcfg1",
+    [HEX_SREG_LIVELOCK] = "livelock",
+    [HEX_SREG_BRKPTPC0] = "brkptpc0",
+    [HEX_SREG_BRKPTCFG0] = "brkptcfg0",
+    [HEX_SREG_BRKPTPC1] = "brkptpc1",
+    [HEX_SREG_BRKPTCFG1] = "brkptcfg1",
+    [HEX_SREG_ISDBMBXIN] = "isdbmbxin",
+    [HEX_SREG_ISDBMBXOUT] = "isdbmbxout",
+    [HEX_SREG_ISDBEN] = "isdben",
+    [HEX_SREG_ISDBGPR] = "isdbgpr",
+    [HEX_SREG_PMUCNT4] = "pmucnt4",
+    [HEX_SREG_PMUCNT5] = "pmucnt5",
+    [HEX_SREG_PMUCNT6] = "pmucnt6",
+    [HEX_SREG_PMUCNT7] = "pmucnt7",
+    [HEX_SREG_PMUCNT0] = "pmucnt0",
+    [HEX_SREG_PMUCNT1] = "pmucnt1",
+    [HEX_SREG_PMUCNT2] = "pmucnt2",
+    [HEX_SREG_PMUCNT3] = "pmucnt3",
+    [HEX_SREG_PMUEVTCFG] = "pmuevtcfg",
+    [HEX_SREG_PMUSTID0] = "pmustid0",
+    [HEX_SREG_PMUEVTCFG1] = "pmuevtcfg1",
+    [HEX_SREG_PMUSTID1] = "pmustid1",
+    [HEX_SREG_TIMERLO] = "timerlo",
+    [HEX_SREG_TIMERHI] = "timerhi",
+    [HEX_SREG_PMUCFG] = "pmucfg",
+    [HEX_SREG_S59] = "s59",
+    [HEX_SREG_S60] = "s60",
+    [HEX_SREG_S61] = "s61",
+    [HEX_SREG_S62] = "s62",
+    [HEX_SREG_S63] = "s63",
+};
+
+static const char *get_sreg_name(uint32_t reg)
+{
+    if (reg < ARRAY_SIZE(hex_sreg_names) && hex_sreg_names[reg]) {
+        return hex_sreg_names[reg];
+    }
+    return "UNKNOWN";
+}
+
 /* Global system register mutability masks */
 static const uint32_t global_sreg_immut_masks[NUM_SREGS] = {
     [HEX_SREG_EVB] = 0x000000ff,
@@ -73,6 +144,7 @@ uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg,
 
     uint32_t value = s->regs[reg];
 
+    trace_hexagon_globalreg_read(htid, get_sreg_name(reg), value);
     return value;
 }
 
@@ -83,6 +155,7 @@ void hexagon_globalreg_write(HexagonGlobalRegState *s, uint32_t reg,
     g_assert(reg < NUM_SREGS);
     g_assert(reg >= HEX_SREG_GLB_START);
     s->regs[reg] = value;
+    trace_hexagon_globalreg_write(htid, get_sreg_name(reg), value);
 }
 
 uint32_t hexagon_globalreg_masked_value(HexagonGlobalRegState *s, uint32_t reg,
diff --git a/hw/hexagon/trace-events b/hw/hexagon/trace-events
new file mode 100644
index 00000000000..5d623ed2516
--- /dev/null
+++ b/hw/hexagon/trace-events
@@ -0,0 +1,3 @@
+# Hexagon global register access
+hexagon_globalreg_read(uint32_t htid, const char *reg_name, uint32_t value) "htid=%u reg=%s value=0x%x"
+hexagon_globalreg_write(uint32_t htid, const char *reg_name, uint32_t value) "htid=%u reg=%s value=0x%x"
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 3/9] hw/hexagon: Add machine configs for sysemu
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
  2026-03-11  4:20 ` [PATCH v3 1/9] hw/hexagon: Add globalreg model Brian Cain
  2026-03-11  4:20 ` [PATCH v3 2/9] hw/hexagon: Add global register tracing Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11  4:20 ` [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs Brian Cain
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Brian Cain,
	Markus Armbruster, Mike Lambert, Sid Manning, Paolo Bonzini,
	Daniel P. Berrangé, Eduardo Habkost

From: Brian Cain <bcain@quicinc.com>

Some header includes are modified here: these are uniquely required for
basic system emulation functionality and had not been required for linux-user.

Acked-by: Markus Armbruster <armbru@redhat.com>
Co-authored-by: Mike Lambert <mlambert@quicinc.com>
Co-authored-by: Sid Manning <sidneym@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 MAINTAINERS                            |   2 +
 include/hw/hexagon/hexagon.h           | 150 +++++++++++++++++++++++
 hw/hexagon/machine_cfg_v66g_1024.h.inc |  64 ++++++++++
 hw/hexagon/hexagon_dsp.c               | 157 +++++++++++++++++++++++++
 system/qdev-monitor.c                  |   2 +-
 target/hexagon/translate.c             |   1 +
 hw/Kconfig                             |   1 +
 hw/hexagon/Kconfig                     |   5 +
 hw/hexagon/meson.build                 |   6 +
 hw/meson.build                         |   1 +
 10 files changed, 388 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/hexagon/hexagon.h
 create mode 100644 hw/hexagon/machine_cfg_v66g_1024.h.inc
 create mode 100644 hw/hexagon/hexagon_dsp.c
 create mode 100644 hw/hexagon/Kconfig
 create mode 100644 hw/hexagon/meson.build

diff --git a/MAINTAINERS b/MAINTAINERS
index 17d1d93d595..d324701ae05 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -245,6 +245,8 @@ Hexagon TCG CPUs
 M: Brian Cain <brian.cain@oss.qualcomm.com>
 S: Supported
 F: target/hexagon/
+F: hw/hexagon/
+F: include/hw/hexagon/
 X: target/hexagon/idef-parser/
 X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
diff --git a/include/hw/hexagon/hexagon.h b/include/hw/hexagon/hexagon.h
new file mode 100644
index 00000000000..996f5423c39
--- /dev/null
+++ b/include/hw/hexagon/hexagon.h
@@ -0,0 +1,150 @@
+/*
+ * Hexagon Baseboard System emulation.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#ifndef HW_HEXAGON_H
+#define HW_HEXAGON_H
+
+#include "system/memory.h"
+
+struct hexagon_board_boot_info {
+    uint64_t ram_size;
+    const char *kernel_filename;
+    uint32_t kernel_elf_flags;
+};
+
+typedef enum {
+    unknown_rev = 0,
+    v66_rev = 0xa666,
+    v67_rev = 0x2667,
+    v68_rev = 0x8d68,
+    v69_rev = 0x8c69,
+    v71_rev = 0x8c71,
+    v73_rev = 0x8c73,
+    v73m_rev = 0xcc73,
+} Rev_t;
+#define HEXAGON_LATEST_REV v73
+#define HEXAGON_LATEST_REV_UPPER V73
+
+/*
+ * Config table address bases represent bits [35:16].
+ */
+#define HEXAGON_CFG_ADDR_BASE(addr) (((addr) >> 16) & 0x0fffff)
+
+#define HEXAGON_CFGSPACE_ENTRIES (128)
+
+union hexagon_config_table {
+    struct {
+        /* Base address of L2TCM space */
+        uint32_t l2tcm_base;
+        uint32_t reserved0;
+        /* Base address of subsystem space */
+        uint32_t subsystem_base;
+        /* Base address of ETM space */
+        uint32_t etm_base;
+        /* Base address of L2 configuration space */
+        uint32_t l2cfg_base;
+        uint32_t reserved1;
+        /* Base address of L1S */
+        uint32_t l1s0_base;
+        /* Base address of AXI2 */
+        uint32_t axi2_lowaddr;
+        /* Base address of streamer base */
+        uint32_t streamer_base;
+        uint32_t reserved2;
+        /* Base address of fast L2VIC */
+        uint32_t fastl2vic_base;
+        /* Number of entries in JTLB */
+        uint32_t jtlb_size_entries;
+        /* Coprocessor type */
+        uint32_t coproc_present;
+        /* Number of extension execution contexts available */
+        uint32_t ext_contexts;
+        /* Base address of Hexagon Vector Tightly Coupled Memory (VTCM) */
+        uint32_t vtcm_base;
+        /* Size of VTCM (in KB) */
+        uint32_t vtcm_size_kb;
+        /* L2 tag size */
+        uint32_t l2tag_size;
+        /* Amount of physical L2 memory in released version */
+        uint32_t l2ecomem_size;
+        /* Hardware threads available on the core */
+        uint32_t thread_enable_mask;
+        /* Base address of the ECC registers */
+        uint32_t eccreg_base;
+        /* L2 line size */
+        uint32_t l2line_size;
+        /* Small Core processor (also implies audio extension) */
+        uint32_t tiny_core;
+        /* Size of L2TCM */
+        uint32_t l2itcm_size;
+        /* Base address of L2-ITCM */
+        uint32_t l2itcm_base;
+        uint32_t reserved3;
+        /* DTM is present */
+        uint32_t dtm_present;
+        /* Version of the DMA */
+        uint32_t dma_version;
+        /* Native HVX vector length in log of bytes */
+        uint32_t hvx_vec_log_length;
+        /* Core ID of the multi-core */
+        uint32_t core_id;
+        /* Number of multi-core cores */
+        uint32_t core_count;
+        uint32_t coproc2_reg0;
+        uint32_t coproc2_reg1;
+        /* Supported HVX vector length */
+        uint32_t v2x_mode;
+        uint32_t coproc2_reg2;
+        uint32_t coproc2_reg3;
+        uint32_t coproc2_reg4;
+        uint32_t coproc2_reg5;
+        uint32_t coproc2_reg6;
+        uint32_t coproc2_reg7;
+        /* Voltage droop mitigation technique parameter */
+        uint32_t acd_preset;
+        /* Voltage droop mitigation technique parameter */
+        uint32_t mnd_preset;
+        /* L1 data cache size (in KB) */
+        uint32_t l1d_size_kb;
+        /* L1 instruction cache size in (KB) */
+        uint32_t l1i_size_kb;
+        /* L1 data cache write policy: see HexagonL1WritePolicy */
+        uint32_t l1d_write_policy;
+        /* VTCM bank width  */
+        uint32_t vtcm_bank_width;
+        uint32_t reserved4;
+        uint32_t reserved5;
+        uint32_t reserved6;
+        uint32_t coproc2_cvt_mpy_size;
+        uint32_t consistency_domain;
+        uint32_t capacity_domain;
+        uint32_t axi3_lowaddr;
+        uint32_t coproc2_int8_subcolumns;
+        uint32_t corecfg_present;
+        uint32_t coproc2_fp16_acc_exp;
+        uint32_t AXIM2_secondary_base;
+    };
+    uint32_t raw[HEXAGON_CFGSPACE_ENTRIES];
+};
+
+struct hexagon_machine_config {
+    /* Base address of config table */
+    uint32_t cfgbase;
+    /* Size of L2 TCM */
+    uint32_t l2tcm_size;
+    /* Base address of L2VIC */
+    uint32_t l2vic_base;
+    /* Size of L2VIC region */
+    uint32_t l2vic_size;
+    /* QTimer csr base */
+    uint32_t csr_base;
+    uint32_t qtmr_region;
+    union hexagon_config_table cfgtable;
+};
+
+#endif
diff --git a/hw/hexagon/machine_cfg_v66g_1024.h.inc b/hw/hexagon/machine_cfg_v66g_1024.h.inc
new file mode 100644
index 00000000000..44ba669a4b9
--- /dev/null
+++ b/hw/hexagon/machine_cfg_v66g_1024.h.inc
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+static struct hexagon_machine_config v66g_1024 = {
+    .cfgbase =        0xd8180000,
+    .l2tcm_size =     0x00000000,
+    .l2vic_base =     0xfc910000,
+    .l2vic_size =     0x00001000,
+    .csr_base =       0xfc900000,
+    .qtmr_region =    0xfc921000,
+    .cfgtable = {
+        .l2tcm_base = 0x0000d800,
+        .reserved0 = 0x0000d400,
+        .subsystem_base = 0x0000fc90,
+        .etm_base = 0x0000d805,
+        .l2cfg_base = 0x0000d81a,
+        .reserved1 = 0x00000000,
+        .l1s0_base = 0x0000d820,
+        .axi2_lowaddr = 0x00003000,
+        .streamer_base = 0x00000000,
+        .reserved2 = 0x0000d819,
+        .fastl2vic_base = 0x0000d81e,
+        .jtlb_size_entries = 0x00000080,
+        .coproc_present = 0x00000001,
+        .ext_contexts = 0x00000004,
+        .vtcm_base = 0x0000d820,
+        .vtcm_size_kb = 0x00000100,
+        .l2tag_size = 0x00000400,
+        .l2ecomem_size = 0x00000400,
+        .thread_enable_mask = 0x0000000f,
+        .eccreg_base = 0x0000d81f,
+        .l2line_size = 0x00000080,
+        .tiny_core = 0x00000000,
+        .l2itcm_size = 0x00000000,
+        .l2itcm_base = 0x0000d820,
+        .reserved3 = 0x00000000,
+        .dtm_present = 0x00000000,
+        .dma_version = 0x00000000,
+        .hvx_vec_log_length = 0x00000080,
+        .core_id = 0x00000000,
+        .core_count = 0x00000000,
+        .coproc2_reg0 = 0x00000000,
+        .coproc2_reg1 = 0x00000000,
+        .v2x_mode = 0x00000000,
+        .coproc2_reg2 = 0x00000000,
+        .coproc2_reg3 = 0x00000000,
+        .coproc2_reg4 = 0x00000000,
+        .coproc2_reg5 = 0x00000000,
+        .coproc2_reg6 = 0x00000000,
+        .coproc2_reg7 = 0x00000000,
+        .acd_preset = 0x00000000,
+        .mnd_preset = 0x00000000,
+        .l1d_size_kb = 0x00000000,
+        .l1i_size_kb = 0x00000000,
+        .l1d_write_policy = 0x00000000,
+        .vtcm_bank_width = 0x00000000,
+        .reserved4 = 0x00000000,
+        .reserved5 = 0x00000000,
+        .reserved6 = 0x00000000,
+        .coproc2_cvt_mpy_size = 0x00000000,
+        .consistency_domain = 0x00000000,
+        .capacity_domain = 0x00000000,
+        .axi3_lowaddr = 0x00000000,
+    },
+};
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
new file mode 100644
index 00000000000..56384536519
--- /dev/null
+++ b/hw/hexagon/hexagon_dsp.c
@@ -0,0 +1,157 @@
+/*
+ * Hexagon DSP Subsystem emulation.  This represents a generic DSP
+ * subsystem with few peripherals, like the Compute DSP.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "system/address-spaces.h"
+#include "hw/core/boards.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/hexagon/hexagon.h"
+#include "hw/hexagon/hexagon_globalreg.h"
+#include "hw/core/loader.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "elf.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+#include "system/system.h"
+#include "target/hexagon/internal.h"
+#include "system/reset.h"
+
+#include "machine_cfg_v66g_1024.h.inc"
+
+static void hex_symbol_callback(const char *st_name, int st_info,
+                                uint64_t st_value, uint64_t st_size)
+{
+}
+
+/* Board init.  */
+static struct hexagon_board_boot_info hexagon_binfo;
+
+static void hexagon_load_kernel(HexagonCPU *cpu)
+{
+    uint64_t pentry;
+    long kernel_size;
+
+    kernel_size = load_elf_ram_sym(hexagon_binfo.kernel_filename, NULL, NULL,
+                      NULL, &pentry, NULL, NULL,
+                      &hexagon_binfo.kernel_elf_flags, 0, EM_HEXAGON, 0, 0,
+                      &address_space_memory, false, hex_symbol_callback);
+
+    if (kernel_size <= 0) {
+        error_report("no kernel file '%s'",
+            hexagon_binfo.kernel_filename);
+        exit(1);
+    }
+
+    qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", pentry);
+}
+
+static void hexagon_init_bootstrap(MachineState *machine, HexagonCPU *cpu)
+{
+    if (machine->kernel_filename) {
+        hexagon_load_kernel(cpu);
+    }
+}
+
+static void do_cpu_reset(void *opaque)
+{
+    HexagonCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    cpu_reset(cs);
+}
+
+static void hexagon_common_init(MachineState *machine, Rev_t rev,
+                                struct hexagon_machine_config *m_cfg)
+{
+    memset(&hexagon_binfo, 0, sizeof(hexagon_binfo));
+    if (machine->kernel_filename) {
+        hexagon_binfo.ram_size = machine->ram_size;
+        hexagon_binfo.kernel_filename = machine->kernel_filename;
+    }
+
+    machine->enable_graphics = 0;
+
+    MemoryRegion *address_space = get_system_memory();
+
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
+    memory_region_init_ram(sram, NULL, "ddr.ram",
+        machine->ram_size, &error_fatal);
+    memory_region_add_subregion(address_space, 0x0, sram);
+
+    DeviceState *glob_regs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
+    qdev_prop_set_uint64(glob_regs_dev, "config-table-addr", m_cfg->cfgbase);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs_dev), &error_fatal);
+
+    for (int i = 0; i < machine->smp.cpus; i++) {
+        HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type));
+        qemu_register_reset(do_cpu_reset, cpu);
+
+        /*
+         * CPU #0 is the only CPU running at boot, others must be
+         * explicitly enabled via start instruction.
+         */
+        qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
+        if (i == 0) {
+            hexagon_init_bootstrap(machine, cpu);
+            if (!qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal)) {
+                return;
+            }
+        } else if (!qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal)) {
+            return;
+        }
+
+    }
+}
+
+static void init_mc(MachineClass *mc)
+{
+    mc->block_default_type = IF_SD;
+    mc->default_ram_size = 4 * GiB;
+    mc->no_parallel = 1;
+    mc->no_floppy = 1;
+    mc->no_cdrom = 1;
+    mc->no_serial = 1;
+    mc->is_default = false;
+    mc->max_cpus = 8;
+}
+
+/* ----------------------------------------------------------------- */
+/* Core-specific configuration settings are defined below this line. */
+/* Config table values defined in machine_configs.h.inc              */
+/* ----------------------------------------------------------------- */
+
+static void v66g_1024_config_init(MachineState *machine)
+{
+    hexagon_common_init(machine, v66_rev, &v66g_1024);
+}
+
+static void v66g_1024_init(ObjectClass *oc, const void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "Hexagon V66G_1024";
+    mc->init = v66g_1024_config_init;
+    init_mc(mc);
+    mc->is_default = true;
+    mc->default_cpu_type = TYPE_HEXAGON_CPU_V66;
+    mc->default_cpus = 4;
+}
+
+static const TypeInfo hexagon_machine_types[] = {
+    {
+        .name = MACHINE_TYPE_NAME("V66G_1024"),
+        .parent = TYPE_MACHINE,
+        .class_init = v66g_1024_init,
+    },
+};
+
+DEFINE_TYPES(hexagon_machine_types)
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 1ac6d9a8575..72abc9182a9 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -69,7 +69,7 @@ typedef struct QDevAlias
                               QEMU_ARCH_SPARC | \
                               QEMU_ARCH_XTENSA)
 #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
-#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
+#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K | QEMU_ARCH_HEXAGON)
 
 /* Please keep this table sorted by typename. */
 static const QDevAlias qdev_alias_table[] = {
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index e4a0993c88a..8ea8621a6f6 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -32,6 +32,7 @@
 #include "translate.h"
 #include "genptr.h"
 #include "printinsn.h"
+#include "exec/target_page.h"
 
 #define HELPER_H "helper.h"
 #include "exec/helper-info.c.inc"
diff --git a/hw/Kconfig b/hw/Kconfig
index b3ed092f7a8..dda3139be74 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -54,6 +54,7 @@ source arm/Kconfig
 source cpu/Kconfig
 source alpha/Kconfig
 source avr/Kconfig
+source hexagon/Kconfig
 source hppa/Kconfig
 source i386/Kconfig
 source loongarch/Kconfig
diff --git a/hw/hexagon/Kconfig b/hw/hexagon/Kconfig
new file mode 100644
index 00000000000..7b9577f68f7
--- /dev/null
+++ b/hw/hexagon/Kconfig
@@ -0,0 +1,5 @@
+config HEX_DSP
+    bool
+    default y
+    depends on HEXAGON && TCG
+    imply PTIMER
diff --git a/hw/hexagon/meson.build b/hw/hexagon/meson.build
new file mode 100644
index 00000000000..f528d2bc4ab
--- /dev/null
+++ b/hw/hexagon/meson.build
@@ -0,0 +1,6 @@
+hexagon_ss = ss.source_set()
+hexagon_ss.add(files('hexagon_tlb.c'))
+hexagon_ss.add(files('hexagon_globalreg.c'))
+hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hexagon_dsp.c'))
+
+hw_arch += {'hexagon': hexagon_ss}
diff --git a/hw/meson.build b/hw/meson.build
index ef65ba51950..7fa81db453e 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -3,6 +3,7 @@ subdir('alpha')
 subdir('arm')
 subdir('avr')
 subdir('hppa')
+subdir('hexagon')
 subdir('xenpv') # i386 uses it
 subdir('i386')
 subdir('loongarch')
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (2 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 3/9] hw/hexagon: Add machine configs for sysemu Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11 17:54   ` Philippe Mathieu-Daudé
  2026-03-11  4:20 ` [PATCH v3 5/9] hw/hexagon: Add support for cfgbase Brian Cain
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Brian Cain

From: Brian Cain <bcain@quicinc.com>

Acked-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc | 64 ++++++++++++++++++++++
 hw/hexagon/machine_cfg_v68n_1024.h.inc    | 65 +++++++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
 create mode 100644 hw/hexagon/machine_cfg_v68n_1024.h.inc

diff --git a/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
new file mode 100644
index 00000000000..3d787c104ff
--- /dev/null
+++ b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+static struct hexagon_machine_config SA8775P_cdsp0 = {
+    .cfgbase =         0x24000000 + 0x180000,
+    .l2tcm_size =      0x00000000,
+    .l2vic_base =      0x26300000 + 0x90000,
+    .l2vic_size =      0x00001000,
+    .csr_base =        0x26300000,
+    .qtmr_region =     0x26300000 + 0xA1000,
+    .cfgtable = {
+        .l2tcm_base = 0x00002400,
+        .reserved0 = 0x00000000,
+        .subsystem_base = 0x00002638,
+        .etm_base = 0x00002419,
+        .l2cfg_base = 0x0000241a,
+        .reserved1 = 0x0000241b,
+        .l1s0_base = 0x00002500,
+        .axi2_lowaddr = 0x00000000,
+        .streamer_base = 0x00000000,
+        .reserved2 = 0x00000000,
+        .fastl2vic_base = 0x0000241e,
+        .jtlb_size_entries = 0x00000080,
+        .coproc_present = 0x00000001,
+        .ext_contexts = 0x00000004,
+        .vtcm_base = 0x00002500,
+        .vtcm_size_kb = 0x00002000,
+        .l2tag_size = 0x00000400,
+        .l2ecomem_size = 0x00000000,
+        .thread_enable_mask = 0x0000003f,
+        .eccreg_base = 0x0000241f,
+        .l2line_size = 0x00000080,
+        .tiny_core = 0x00000000,
+        .l2itcm_size = 0x00000000,
+        .l2itcm_base = 0x00002400,
+        .reserved3 = 0x00000000,
+        .dtm_present = 0x00000000,
+        .dma_version = 0x00000003,
+        .hvx_vec_log_length = 0x00000007,
+        .core_id = 0x00000000,
+        .core_count = 0x00000000,
+        .coproc2_reg0 = 0x00000040,
+        .coproc2_reg1 = 0x00000020,
+        .v2x_mode = 0x00000001,
+        .coproc2_reg2 = 0x00000008,
+        .coproc2_reg3 = 0x00000020,
+        .coproc2_reg4 = 0x00000000,
+        .coproc2_reg5 = 0x00000002,
+        .coproc2_reg6 = 0x00000016,
+        .coproc2_reg7 = 0x00000006,
+        .acd_preset = 0x00000001,
+        .mnd_preset = 0x00000000,
+        .l1d_size_kb = 0x00000010,
+        .l1i_size_kb = 0x00000020,
+        .l1d_write_policy = 0x00000002,
+        .vtcm_bank_width = 0x00000080,
+        .reserved4 = 0x00000001,
+        .reserved5 = 0x00000000,
+        .reserved6 = 0x00000003,
+        .coproc2_cvt_mpy_size = 0x0000000a,
+        .consistency_domain = 0x000000e0,
+        .capacity_domain = 0x00000080,
+        .axi3_lowaddr = 0x00000000,
+    },
+};
diff --git a/hw/hexagon/machine_cfg_v68n_1024.h.inc b/hw/hexagon/machine_cfg_v68n_1024.h.inc
new file mode 100644
index 00000000000..734a12a2f12
--- /dev/null
+++ b/hw/hexagon/machine_cfg_v68n_1024.h.inc
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+static struct hexagon_machine_config v68n_1024 = {
+    .cfgbase =           0xde000000,
+    .l2tcm_size =        0x00000000,
+    .l2vic_base =        0xfc910000,
+    .l2vic_size =        0x00001000,
+    .csr_base =          0xfc900000,
+    .qtmr_region =       0xfc921000,
+    .cfgtable = {
+        .l2tcm_base = 0x0000d800,
+        .reserved0 = 0x00000000,
+        .subsystem_base = 0x0000fc90,
+        .etm_base = 0x0000d819,
+        .l2cfg_base = 0x0000d81a,
+        .reserved1 = 0x00000000,
+        .l1s0_base = 0x0000d840,
+        .axi2_lowaddr = 0x00003000,
+        .streamer_base = 0x0000d81c,
+        .reserved2 = 0x0000d81d,
+        .fastl2vic_base = 0x0000d81e,
+        .jtlb_size_entries = 0x00000080,
+        .coproc_present = 0x00000001,
+        .ext_contexts = 0x00000004,
+        .vtcm_base = 0x0000d840,
+        .vtcm_size_kb = 0x00001000,
+        .l2tag_size = 0x00000400,
+        .l2ecomem_size = 0x00000400,
+        .thread_enable_mask = 0x0000003f,
+        .eccreg_base = 0x0000d81f,
+        .l2line_size = 0x00000080,
+        .tiny_core = 0x00000000,
+        .l2itcm_size = 0x00000000,
+        .l2itcm_base = 0x0000d820,
+        .reserved3 = 0x00000000,
+        .dtm_present = 0x00000000,
+        .dma_version = 0x00000001,
+        .hvx_vec_log_length = 0x00000007,
+        .core_id = 0x00000000,
+        .core_count = 0x00000000,
+        .coproc2_reg0 = 0x00000040,
+        .coproc2_reg1 = 0x00000020,
+        .v2x_mode = 0x1f1f1f1f,
+        .coproc2_reg2 = 0x1f1f1f1f,
+        .coproc2_reg3 = 0x1f1f1f1f,
+        .coproc2_reg4 = 0x1f1f1f1f,
+        .coproc2_reg5 = 0x1f1f1f1f,
+        .coproc2_reg6 = 0x1f1f1f1f,
+        .coproc2_reg7 = 0x1f1f1f1f,
+        .acd_preset = 0x1f1f1f1f,
+        .mnd_preset = 0x1f1f1f1f,
+        .l1d_size_kb = 0x1f1f1f1f,
+        .l1i_size_kb = 0x1f1f1f1f,
+        .l1d_write_policy = 0x1f1f1f1f,
+        .vtcm_bank_width = 0x1f1f1f1f,
+        .reserved4 = 0x1f1f1f1f,
+        .reserved5 = 0x1f1f1f1f,
+        .reserved6 = 0x1f1f1f1f,
+        .coproc2_cvt_mpy_size = 0x1f1f1f1f,
+        .consistency_domain = 0x1f1f1f1f,
+        .capacity_domain = 0x1f1f1f1f,
+        .axi3_lowaddr = 0x1f1f1f1f,
+    },
+};
+
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 5/9] hw/hexagon: Add support for cfgbase
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (3 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11  4:20 ` [PATCH v3 6/9] hw/hexagon: Modify "Standalone" symbols Brian Cain
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Sid Manning

From: Sid Manning <sidneym@quicinc.com>

Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Sid Manning <sidneym@quicinc.com>
---
 hw/hexagon/hexagon_dsp.c | 10 ++++++++++
 target/hexagon/cpu.c     |  1 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index 56384536519..2a10a2e4b3b 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -82,6 +82,12 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
 
     MemoryRegion *address_space = get_system_memory();
 
+    MemoryRegion *config_table_rom = g_new(MemoryRegion, 1);
+    memory_region_init_rom(config_table_rom, NULL, "config_table.rom",
+                           sizeof(m_cfg->cfgtable), &error_fatal);
+    memory_region_add_subregion(address_space, m_cfg->cfgbase,
+                                config_table_rom);
+
     MemoryRegion *sram = g_new(MemoryRegion, 1);
     memory_region_init_ram(sram, NULL, "ddr.ram",
         machine->ram_size, &error_fatal);
@@ -110,6 +116,10 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
         }
 
     }
+
+    rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable,
+                          sizeof(m_cfg->cfgtable), m_cfg->cfgbase,
+                          &address_space_memory);
 }
 
 static void init_mc(MachineClass *mc)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index f6a8b23d28d..2079af10937 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -413,7 +413,6 @@ void hexagon_cpu_soft_reset(CPUHexagonState *env)
 }
 #endif
 
-
 static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
 {
     CPUState *cs = CPU(obj);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 6/9] hw/hexagon: Modify "Standalone" symbols
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (4 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 5/9] hw/hexagon: Add support for cfgbase Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11  4:20 ` [PATCH v3 7/9] target/hexagon: add build config for softmmu Brian Cain
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Brian Cain

From: Brian Cain <bcain@quicinc.com>

These symbols are used by Hexagon Standalone OS to indicate whether
the program should halt and wait for interrupts at startup.  For QEMU,
we want these programs to just continue crt0 startup through to the user
program's main().


Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 hw/hexagon/hexagon_dsp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index 2a10a2e4b3b..3863f020e74 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -28,9 +28,17 @@
 
 #include "machine_cfg_v66g_1024.h.inc"
 
+static hwaddr isdb_secure_flag;
+static hwaddr isdb_trusted_flag;
 static void hex_symbol_callback(const char *st_name, int st_info,
                                 uint64_t st_value, uint64_t st_size)
 {
+    if (!g_strcmp0("isdb_secure_flag", st_name)) {
+        isdb_secure_flag = st_value;
+    }
+    if (!g_strcmp0("isdb_trusted_flag", st_name)) {
+        isdb_trusted_flag = st_value;
+    }
 }
 
 /* Board init.  */
@@ -59,6 +67,13 @@ static void hexagon_init_bootstrap(MachineState *machine, HexagonCPU *cpu)
 {
     if (machine->kernel_filename) {
         hexagon_load_kernel(cpu);
+        uint32_t mem = 1;
+        if (isdb_secure_flag) {
+            cpu_physical_memory_write(isdb_secure_flag, &mem, sizeof(mem));
+        }
+        if (isdb_trusted_flag) {
+            cpu_physical_memory_write(isdb_trusted_flag, &mem, sizeof(mem));
+        }
     }
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 7/9] target/hexagon: add build config for softmmu
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (5 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 6/9] hw/hexagon: Modify "Standalone" symbols Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11 17:57   ` Philippe Mathieu-Daudé
  2026-03-18 13:14   ` Philippe Mathieu-Daudé
  2026-03-11  4:20 ` [PATCH v3 8/9] hw/hexagon: Define hexagon "virt" machine Brian Cain
  2026-03-11  4:20 ` [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test Brian Cain
  8 siblings, 2 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Paolo Bonzini

Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 MAINTAINERS                                 |  1 +
 configs/devices/hexagon-softmmu/default.mak |  7 +++++++
 configs/targets/hexagon-softmmu.mak         |  6 ++++++
 target/hexagon/cpu.h                        |  4 ----
 target/Kconfig                              |  1 +
 target/hexagon/Kconfig                      |  2 ++
 target/hexagon/meson.build                  | 13 ++++++++++++-
 7 files changed, 29 insertions(+), 5 deletions(-)
 create mode 100644 configs/devices/hexagon-softmmu/default.mak
 create mode 100644 configs/targets/hexagon-softmmu.mak
 create mode 100644 target/hexagon/Kconfig

diff --git a/MAINTAINERS b/MAINTAINERS
index d324701ae05..d9d4cda4d0b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -253,6 +253,7 @@ F: linux-user/hexagon/
 F: tests/tcg/hexagon/
 F: disas/hexagon.c
 F: configs/targets/hexagon-linux-user/default.mak
+F: configs/devices/hexagon-softmmu/default.mak
 F: docker/dockerfiles/debian-hexagon-cross.docker
 F: gdb-xml/hexagon*.xml
 F: docs/system/target-hexagon.rst
diff --git a/configs/devices/hexagon-softmmu/default.mak b/configs/devices/hexagon-softmmu/default.mak
new file mode 100644
index 00000000000..08e709aea72
--- /dev/null
+++ b/configs/devices/hexagon-softmmu/default.mak
@@ -0,0 +1,7 @@
+# Default configuration for hexagon-softmmu
+
+# Uncomment the following lines to disable these optional devices:
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_HEX_DSP=y
+# CONFIG_L2VIC=y
diff --git a/configs/targets/hexagon-softmmu.mak b/configs/targets/hexagon-softmmu.mak
new file mode 100644
index 00000000000..42e1e5c4f83
--- /dev/null
+++ b/configs/targets/hexagon-softmmu.mak
@@ -0,0 +1,6 @@
+# Default configuration for hexagon-softmmu
+
+TARGET_ARCH=hexagon
+TARGET_SUPPORTS_MTTCG=y
+TARGET_XML_FILES=gdb-xml/hexagon-core.xml gdb-xml/hexagon-hvx.xml
+TARGET_LONG_BITS=32
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 6168fea3b5f..93e4d488be9 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -35,10 +35,6 @@
 #include "mmvec/mmvec.h"
 #include "hw/core/registerfields.h"
 
-#ifndef CONFIG_USER_ONLY
-#error "Hexagon does not support system emulation"
-#endif
-
 #include "reg_fields.h"
 
 #define NUM_PREGS 4
diff --git a/target/Kconfig b/target/Kconfig
index 3c73e3bae01..0288a3f4164 100644
--- a/target/Kconfig
+++ b/target/Kconfig
@@ -16,6 +16,7 @@ source sh4/Kconfig
 source sparc/Kconfig
 source tricore/Kconfig
 source xtensa/Kconfig
+source hexagon/Kconfig
 
 config TARGET_BIG_ENDIAN
     bool
diff --git a/target/hexagon/Kconfig b/target/hexagon/Kconfig
new file mode 100644
index 00000000000..7e556f35063
--- /dev/null
+++ b/target/hexagon/Kconfig
@@ -0,0 +1,2 @@
+config HEXAGON
+    bool
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index 528beca3cd0..bc7a292e47b 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -235,6 +235,7 @@ decodetree_trans_funcs_generated = custom_target(
     command: [python, files('gen_trans_funcs.py'), semantics_generated, '@OUTPUT@'],
 )
 hexagon_ss.add(decodetree_trans_funcs_generated)
+hexagon_softmmu_ss = ss.source_set()
 
 hexagon_ss.add(files(
     'cpu.c',
@@ -253,6 +254,14 @@ hexagon_ss.add(files(
     'mmvec/system_ext_mmvec.c',
 ))
 
+hexagon_softmmu_ss.add(files(
+    'cpu_helper.c',
+    'hex_mmu.c',
+    'hex_interrupts.c',
+    'hexswi.c',
+    'machine.c',
+))
+
 #
 # Step 4.5
 # We use flex/bison based idef-parser to generate TCG code for a lot
@@ -262,7 +271,8 @@ hexagon_ss.add(files(
 #     idef-generated-enabled-instructions
 #
 idef_parser_enabled = get_option('hexagon_idef_parser')
-if idef_parser_enabled and 'hexagon-linux-user' in target_dirs
+if idef_parser_enabled and ('hexagon-linux-user' in target_dirs or
+                            'hexagon-softmmu' in target_dirs)
     idef_parser_input_generated = custom_target(
         'idef_parser_input.h.inc',
         output: 'idef_parser_input.h.inc',
@@ -390,3 +400,4 @@ analyze_funcs_generated = custom_target(
 hexagon_ss.add(analyze_funcs_generated)
 
 target_arch += {'hexagon': hexagon_ss}
+target_system_arch += {'hexagon': hexagon_softmmu_ss}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 8/9] hw/hexagon: Define hexagon "virt" machine
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (6 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 7/9] target/hexagon: add build config for softmmu Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-11  4:20 ` [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test Brian Cain
  8 siblings, 0 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Brian Cain,
	Paolo Bonzini, Kevin Wolf, Hanna Reitz,
	open list:Block layer core

From: Brian Cain <bcain@quicinc.com>

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 configs/devices/hexagon-softmmu/default.mak |   1 +
 configs/targets/hexagon-softmmu.mak         |   1 +
 include/hw/hexagon/virt.h                   |  43 ++
 hw/hexagon/virt.c                           | 453 ++++++++++++++++++++
 hw/hexagon/Kconfig                          |  10 +
 hw/hexagon/meson.build                      |   2 +
 tests/qemu-iotests/testenv.py               |   1 +
 7 files changed, 511 insertions(+)
 create mode 100644 include/hw/hexagon/virt.h
 create mode 100644 hw/hexagon/virt.c

diff --git a/configs/devices/hexagon-softmmu/default.mak b/configs/devices/hexagon-softmmu/default.mak
index 08e709aea72..37b4f9f3237 100644
--- a/configs/devices/hexagon-softmmu/default.mak
+++ b/configs/devices/hexagon-softmmu/default.mak
@@ -3,5 +3,6 @@
 # Uncomment the following lines to disable these optional devices:
 
 # Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_HEX_VIRT=y
 # CONFIG_HEX_DSP=y
 # CONFIG_L2VIC=y
diff --git a/configs/targets/hexagon-softmmu.mak b/configs/targets/hexagon-softmmu.mak
index 42e1e5c4f83..176bd3de784 100644
--- a/configs/targets/hexagon-softmmu.mak
+++ b/configs/targets/hexagon-softmmu.mak
@@ -4,3 +4,4 @@ TARGET_ARCH=hexagon
 TARGET_SUPPORTS_MTTCG=y
 TARGET_XML_FILES=gdb-xml/hexagon-core.xml gdb-xml/hexagon-hvx.xml
 TARGET_LONG_BITS=32
+TARGET_NEED_FDT=y
diff --git a/include/hw/hexagon/virt.h b/include/hw/hexagon/virt.h
new file mode 100644
index 00000000000..a54eac5cf00
--- /dev/null
+++ b/include/hw/hexagon/virt.h
@@ -0,0 +1,43 @@
+/*
+ * Definitions for hexagon virt board.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HEXAGONVIRT_H
+#define HW_HEXAGONVIRT_H
+
+#include "hw/core/boards.h"
+#include "target/hexagon/cpu.h"
+
+struct HexagonVirtMachineState {
+    /*< private >*/
+    MachineState parent_obj;
+
+    int fdt_size;
+    MemoryRegion *sys;
+    MemoryRegion cfgtable;
+    MemoryRegion ram;
+    MemoryRegion tcm;
+    MemoryRegion vtcm;
+    MemoryRegion bios;
+    DeviceState *l2vic;
+    Clock *apb_clk;
+};
+
+void hexagon_load_fdt(const struct HexagonVirtMachineState *vms);
+
+enum {
+    VIRT_UART0,
+    VIRT_QTMR0,
+    VIRT_QTMR1,
+    VIRT_GPT,
+    VIRT_MMIO,
+    VIRT_FDT,
+};
+
+#define TYPE_HEXAGON_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+OBJECT_DECLARE_SIMPLE_TYPE(HexagonVirtMachineState, HEXAGON_VIRT_MACHINE)
+
+#endif /* HW_HEXAGONVIRT_H */
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
new file mode 100644
index 00000000000..8b49be5dca5
--- /dev/null
+++ b/hw/hexagon/virt.c
@@ -0,0 +1,453 @@
+/*
+ * Hexagon virt emulation
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/hexagon/virt.h"
+#include "elf.h"
+#include "hw/char/pl011.h"
+#include "hw/core/clock.h"
+#include "hw/core/sysbus-fdt.h"
+#include "hw/hexagon/hexagon.h"
+#include "hw/hexagon/hexagon_globalreg.h"
+#include "hw/hexagon/hexagon_tlb.h"
+#include "hw/core/loader.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev-clock.h"
+#include "hw/core/register.h"
+#include "qemu/error-report.h"
+#include "qemu/guest-random.h"
+#include "qemu/units.h"
+#include "elf.h"
+#include "machine_cfg_v68n_1024.h.inc"
+#include "system/address-spaces.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
+#include "system/system.h"
+#include <libfdt.h>
+
+static const int VIRTIO_DEV_COUNT = 8;
+
+static const MemMapEntry base_memmap[] = {
+    [VIRT_UART0] = { 0x10000000, 0x00000200 },
+    [VIRT_MMIO] = { 0x11000000, 0x1000000, },
+    [VIRT_GPT] = { 0xab000000, 0x00001000 },
+    [VIRT_FDT] = { 0x99800000, 0x00400000 },
+};
+
+static const int irqmap[] = {
+    [VIRT_MMIO] = 18, /* ...to 18 + VIRTIO_DEV_COUNT - 1 */
+    [VIRT_GPT] = 12,
+    [VIRT_UART0] = 15,
+    [VIRT_QTMR0] = 2,
+    [VIRT_QTMR1] = 4,
+};
+
+
+static void create_fdt(HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    void *fdt = create_device_tree(&vms->fdt_size);
+
+    if (!fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    ms->fdt = fdt;
+
+    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
+    qemu_fdt_setprop_string(fdt, "/", "model", "hexagon-virt,qemu");
+    qemu_fdt_setprop_string(fdt, "/", "compatible", "qcom,sm8150");
+
+    qemu_fdt_add_subnode(fdt, "/soc");
+    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x1);
+    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
+
+    qemu_fdt_add_subnode(fdt, "/chosen");
+
+    uint8_t rng_seed[32];
+    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
+    qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
+}
+
+static void fdt_add_hvx(HexagonVirtMachineState *vms,
+                        const struct hexagon_machine_config *m_cfg,
+                        Error **errp)
+{
+    const MachineState *ms = MACHINE(vms);
+    uint32_t vtcm_size_bytes = m_cfg->cfgtable.vtcm_size_kb * 1024;
+    if (vtcm_size_bytes > 0) {
+        memory_region_init_ram(&vms->vtcm, NULL, "vtcm.ram", vtcm_size_bytes,
+                               errp);
+        memory_region_add_subregion(vms->sys, m_cfg->cfgtable.vtcm_base << 16,
+                                    &vms->vtcm);
+
+        qemu_fdt_add_subnode(ms->fdt, "/soc/vtcm");
+        qemu_fdt_setprop_string(ms->fdt, "/soc/vtcm", "compatible",
+                                "qcom,hexagon_vtcm");
+
+        assert(sizeof(m_cfg->cfgtable.vtcm_base) == sizeof(uint32_t));
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/vtcm", "reg", 0,
+                               m_cfg->cfgtable.vtcm_base << 16,
+                               vtcm_size_bytes);
+    }
+
+    if (m_cfg->cfgtable.ext_contexts > 0) {
+        qemu_fdt_add_subnode(ms->fdt, "/soc/hvx");
+        qemu_fdt_setprop_string(ms->fdt, "/soc/hvx", "compatible",
+                                "qcom,hexagon-hvx");
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/hvx", "qcom,hvx-max-ctxts",
+                               m_cfg->cfgtable.ext_contexts);
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/hvx", "qcom,hvx-vlength",
+                               m_cfg->cfgtable.hvx_vec_log_length);
+    }
+}
+
+static int32_t irq_hvm_ic_phandle = -1;
+static void fdt_add_hvm_pic_node(HexagonVirtMachineState *vms,
+                                 const struct hexagon_machine_config *m_cfg)
+{
+    MachineState *ms = MACHINE(vms);
+    irq_hvm_ic_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+
+    qemu_fdt_setprop_cell(ms->fdt, "/soc", "interrupt-parent",
+                          irq_hvm_ic_phandle);
+
+    qemu_fdt_add_subnode(ms->fdt, "/soc/interrupt-controller");
+    qemu_fdt_setprop_cell(ms->fdt, "/soc/interrupt-controller",
+                          "#address-cells", 2);
+    qemu_fdt_setprop_cell(ms->fdt, "/soc/interrupt-controller",
+                          "#interrupt-cells", 2);
+    qemu_fdt_setprop_string(ms->fdt, "/soc/interrupt-controller", "compatible",
+                            "qcom,h2-pic,hvm-pic");
+    qemu_fdt_setprop(ms->fdt, "/soc/interrupt-controller",
+                     "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop_cell(ms->fdt, "/soc/interrupt-controller", "phandle",
+                          irq_hvm_ic_phandle);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(vms->l2vic), 1,
+                    m_cfg->cfgtable.fastl2vic_base << 16);
+}
+
+
+static void fdt_add_gpt_node(HexagonVirtMachineState *vms)
+{
+    g_autofree char *name = NULL;
+    MachineState *ms = MACHINE(vms);
+
+    name = g_strdup_printf("/soc/gpt@%" PRIx64,
+                           (int64_t)base_memmap[VIRT_GPT].base);
+    qemu_fdt_add_subnode(ms->fdt, name);
+    qemu_fdt_setprop_string(ms->fdt, name, "compatible",
+                            "qcom,h2-timer,hvm-timer");
+    qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", irqmap[VIRT_GPT], 0);
+    qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0x0,
+                           base_memmap[VIRT_GPT].base,
+                           base_memmap[VIRT_GPT].size);
+}
+
+static int32_t clock_phandle = -1;
+static void fdt_add_clocks(const HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    clock_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+    qemu_fdt_add_subnode(ms->fdt, "/apb-pclk");
+    qemu_fdt_setprop_string(ms->fdt, "/apb-pclk", "compatible", "fixed-clock");
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "#clock-cells", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "clock-frequency", 24000000);
+    qemu_fdt_setprop_string(ms->fdt, "/apb-pclk", "clock-output-names",
+                            "clk24mhz");
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "phandle", clock_phandle);
+}
+
+static void fdt_add_uart(const HexagonVirtMachineState *vms, int uart)
+{
+    char *nodename;
+    hwaddr base = base_memmap[uart].base;
+    hwaddr size = base_memmap[uart].size;
+    assert(uart == 0);
+    int irq = irqmap[VIRT_UART0 + uart];
+    const char compat[] = "arm,pl011\0arm,primecell";
+    const char clocknames[] = "uartclk\0apb_pclk";
+    MachineState *ms = MACHINE(vms);
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_new(TYPE_PL011);
+    s = SYS_BUS_DEVICE(dev);
+    qdev_prop_set_chr(dev, "chardev", serial_hd(0));
+    qdev_connect_clock_in(dev, "clk", vms->apb_clk);
+    sysbus_realize_and_unref(s, &error_fatal);
+    sysbus_mmio_map(s, 0, base);
+    if (vms->l2vic) {
+        sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->l2vic, irq));
+    }
+
+    nodename = g_strdup_printf("/pl011@%" PRIx64, base);
+    qemu_fdt_add_subnode(ms->fdt, nodename);
+
+    /* Note that we can't use setprop_string because of the embedded NUL */
+    qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, base, size);
+    if (vms->l2vic) {
+        qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
+                               32 + irq, 0);
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+                              irq_hvm_ic_phandle);
+    }
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "clocks", clock_phandle,
+                           clock_phandle);
+    qemu_fdt_setprop(ms->fdt, nodename, "clock-names", clocknames,
+                     sizeof(clocknames));
+
+    qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+    qemu_fdt_add_subnode(ms->fdt, "/aliases");
+    qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial0", nodename);
+
+    g_free(nodename);
+}
+
+static void fdt_add_cpu_nodes(const HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    qemu_fdt_add_subnode(ms->fdt, "/cpus");
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
+
+    /* cpu nodes */
+    for (int num = ms->smp.cpus - 1; num >= 0; num--) {
+        char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
+        qemu_fdt_add_subnode(ms->fdt, nodename);
+        qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
+                              qemu_fdt_alloc_phandle(ms->fdt));
+        g_free(nodename);
+    }
+}
+
+
+static void fdt_add_virtio_devices(const HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    /* VirtIO MMIO devices */
+    for (int i = 0; i < VIRTIO_DEV_COUNT; i++) {
+        char *nodename;
+        int irq = irqmap[VIRT_MMIO] + i;
+        size_t size = base_memmap[VIRT_MMIO].size;
+        hwaddr base = base_memmap[VIRT_MMIO].base + i * size;
+
+        nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
+        qemu_fdt_add_subnode(ms->fdt, nodename);
+        qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "virtio,mmio");
+        qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 1,
+                                     size);
+        qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0);
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+                              irq_hvm_ic_phandle);
+
+        sysbus_create_simple(
+            "virtio-mmio", base,
+            qdev_get_gpio_in(vms->l2vic, irqmap[VIRT_MMIO] + i));
+
+        g_free(nodename);
+    }
+}
+
+static void virt_instance_init(Object *obj)
+{
+    HexagonVirtMachineState *vms = HEXAGON_VIRT_MACHINE(obj);
+
+    create_fdt(vms);
+}
+
+void hexagon_load_fdt(const HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    hwaddr fdt_addr = base_memmap[VIRT_FDT].base;
+    uint32_t fdtsize = vms->fdt_size;
+
+    g_assert(fdtsize <= base_memmap[VIRT_FDT].size);
+    /* copy in the device tree */
+    rom_add_blob_fixed_as("fdt", ms->fdt, fdtsize, fdt_addr,
+                          &address_space_memory);
+    qemu_register_reset_nosnapshotload(
+        qemu_fdt_randomize_seeds,
+        rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
+}
+
+static uint64_t load_kernel(const HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    uint64_t entry = 0;
+    if (load_elf_ram_sym(ms->kernel_filename, NULL, NULL, NULL, &entry, NULL,
+                         NULL, NULL, 0, EM_HEXAGON, 0, 0, &address_space_memory,
+                         false, NULL) > 0) {
+        return entry;
+    }
+    error_report("error loading '%s'", ms->kernel_filename);
+    exit(1);
+}
+
+static uint64_t load_bios(HexagonVirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    uint64_t bios_addr = 0x0;  /* Load BIOS at reset vector address 0x0 */
+    int bios_size;
+
+    bios_size = load_image_targphys(ms->firmware ?: "",
+                                    bios_addr, 64 * 1024, NULL);
+    if (bios_size < 0) {
+        error_report("Could not load BIOS '%s'", ms->firmware ?: "");
+        exit(1);
+    }
+
+    return bios_addr;  /* Return entry point at address 0x0 */
+}
+
+static void do_cpu_reset(void *opaque)
+{
+    HexagonCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    cpu_reset(cs);
+}
+
+static void virt_init(MachineState *ms)
+{
+    HexagonVirtMachineState *vms = HEXAGON_VIRT_MACHINE(ms);
+    const struct hexagon_machine_config *m_cfg = &v68n_1024;
+
+    qemu_fdt_setprop_string(ms->fdt, "/chosen", "bootargs", ms->kernel_cmdline);
+
+    vms->sys = get_system_memory();
+
+    /* Create APB clock for peripherals */
+    vms->apb_clk = clock_new(OBJECT(ms), "apb-pclk");
+    clock_set_hz(vms->apb_clk, 24000000);
+
+    memory_region_init_ram(&vms->ram, NULL, "ddr.ram", ms->ram_size,
+                           &error_fatal);
+    memory_region_add_subregion(vms->sys, 0x0, &vms->ram);
+
+    if (m_cfg->l2tcm_size) {
+        memory_region_init_ram(&vms->tcm, NULL, "tcm.ram", m_cfg->l2tcm_size,
+                               &error_fatal);
+        memory_region_add_subregion(vms->sys, m_cfg->cfgtable.l2tcm_base << 16,
+                                    &vms->tcm);
+    }
+
+    memory_region_init_rom(&vms->cfgtable, NULL, "config_table.rom",
+                           sizeof(m_cfg->cfgtable), &error_fatal);
+    memory_region_add_subregion(vms->sys, m_cfg->cfgbase, &vms->cfgtable);
+    fdt_add_hvx(vms, m_cfg, &error_fatal);
+    const char *cpu_model = ms->cpu_type;
+
+    if (!cpu_model) {
+        cpu_model = HEXAGON_CPU_TYPE_NAME("v73");
+    }
+
+    DeviceState *gsregs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
+    object_property_add_child(OBJECT(ms), "global-regs", OBJECT(gsregs_dev));
+    qdev_prop_set_uint64(gsregs_dev, "config-table-addr", m_cfg->cfgbase);
+    qdev_prop_set_uint32(gsregs_dev, "dsp-rev", v68_rev);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(gsregs_dev), &error_fatal);
+
+    DeviceState *tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
+    object_property_add_child(OBJECT(ms), "tlb", OBJECT(tlb_dev));
+    qdev_prop_set_uint32(tlb_dev, "num-entries",
+                         m_cfg->cfgtable.jtlb_size_entries);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(tlb_dev), &error_fatal);
+
+    HexagonCPU *cpu_0 = NULL;
+    for (int i = 0; i < ms->smp.cpus; i++) {
+        HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
+        qemu_register_reset(do_cpu_reset, cpu);
+
+        if (i == 0) {
+            cpu_0 = cpu;
+            if (ms->kernel_filename) {
+                uint64_t entry = load_kernel(vms);
+                qdev_prop_set_uint32(DEVICE(cpu_0), "exec-start-addr", entry);
+            } else if (ms->firmware) {
+                uint64_t entry = load_bios(vms);
+                qdev_prop_set_uint32(DEVICE(cpu_0), "exec-start-addr", entry);
+            }
+        }
+        qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
+        qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
+        object_property_set_link(OBJECT(cpu), "global-regs",
+                                 OBJECT(gsregs_dev), &error_fatal);
+        object_property_set_link(OBJECT(cpu), "tlb",
+                                 OBJECT(tlb_dev), &error_fatal);
+
+        if (!qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal)) {
+            return;
+        }
+    }
+    /* TODO: enable l2vic when l2vic device arrives */
+    if (object_class_by_name("l2vic")) {
+        vms->l2vic = sysbus_create_varargs(
+            "l2vic", m_cfg->l2vic_base,
+            qdev_get_gpio_in(DEVICE(cpu_0), 0),
+            qdev_get_gpio_in(DEVICE(cpu_0), 1),
+            qdev_get_gpio_in(DEVICE(cpu_0), 2),
+            qdev_get_gpio_in(DEVICE(cpu_0), 3),
+            qdev_get_gpio_in(DEVICE(cpu_0), 4),
+            qdev_get_gpio_in(DEVICE(cpu_0), 5),
+            qdev_get_gpio_in(DEVICE(cpu_0), 6),
+            qdev_get_gpio_in(DEVICE(cpu_0), 7), NULL);
+
+        fdt_add_hvm_pic_node(vms, m_cfg);
+        fdt_add_virtio_devices(vms);
+        fdt_add_gpt_node(vms);
+    }
+
+    fdt_add_cpu_nodes(vms);
+    fdt_add_clocks(vms);
+    fdt_add_uart(vms, VIRT_UART0);
+
+    rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable,
+                          sizeof(m_cfg->cfgtable), m_cfg->cfgbase,
+                          &address_space_memory);
+
+
+    hexagon_load_fdt(vms);
+}
+
+
+static void virt_class_init(ObjectClass *oc, const void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "Hexagon Virtual Machine";
+    mc->init = virt_init;
+    mc->default_cpu_type = HEXAGON_CPU_TYPE_NAME("v73");
+    mc->default_ram_size = 4 * GiB;
+    mc->max_cpus = 8;
+    mc->default_cpus = 8;
+    mc->is_default = false;
+    mc->default_kernel_irqchip_split = false;
+    mc->block_default_type = IF_VIRTIO;
+    mc->default_boot_order = NULL;
+    mc->no_cdrom = 1;
+    mc->numa_mem_supported = false;
+    mc->default_nic = "virtio-mmio-bus";
+}
+
+
+static const TypeInfo virt_machine_types[] = { {
+    .name = TYPE_HEXAGON_VIRT_MACHINE,
+    .parent = TYPE_MACHINE,
+    .instance_size = sizeof(HexagonVirtMachineState),
+    .class_init = virt_class_init,
+    .instance_init = virt_instance_init,
+} };
+
+DEFINE_TYPES(virt_machine_types)
diff --git a/hw/hexagon/Kconfig b/hw/hexagon/Kconfig
index 7b9577f68f7..dc74751d21e 100644
--- a/hw/hexagon/Kconfig
+++ b/hw/hexagon/Kconfig
@@ -3,3 +3,13 @@ config HEX_DSP
     default y
     depends on HEXAGON && TCG
     imply PTIMER
+
+config HEX_VIRT
+    bool
+    default y
+    depends on HEX_DSP && FDT
+    select DEVICE_TREE
+    select VIRTIO_MMIO
+    select PL011
+    select VIRTIO_BLK
+    select VIRTIO_SCSI
diff --git a/hw/hexagon/meson.build b/hw/hexagon/meson.build
index f528d2bc4ab..5b6a5e11a17 100644
--- a/hw/hexagon/meson.build
+++ b/hw/hexagon/meson.build
@@ -4,3 +4,5 @@ hexagon_ss.add(files('hexagon_globalreg.c'))
 hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hexagon_dsp.c'))
 
 hw_arch += {'hexagon': hexagon_ss}
+
+hexagon_ss.add(when: 'CONFIG_HEX_VIRT', if_true: files('virt.c'))
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index c357e6ebf50..86bcdf7cfad 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -259,6 +259,7 @@ def __init__(self, source_dir: str, build_dir: str,
             ('arm', 'virt'),
             ('aarch64', 'virt'),
             ('avr', 'mega2560'),
+            ('hexagon', 'virt'),
             ('m68k', 'virt'),
             ('or1k', 'virt'),
             ('riscv32', 'virt'),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test
  2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
                   ` (7 preceding siblings ...)
  2026-03-11  4:20 ` [PATCH v3 8/9] hw/hexagon: Define hexagon "virt" machine Brian Cain
@ 2026-03-11  4:20 ` Brian Cain
  2026-03-12 14:43   ` Fabiano Rosas
  8 siblings, 1 reply; 18+ messages in thread
From: Brian Cain @ 2026-03-11  4:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

Add boot-serial-test support for Hexagon architecture using the virt
machine.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 tests/qtest/boot-serial-test.c | 8 ++++++++
 tests/qtest/meson.build        | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index bcd0a9c50e7..37fee7a91c4 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -142,6 +142,13 @@ static const uint8_t kernel_stm32vldiscovery[] = {
     0x04, 0x38, 0x01, 0x40                  /* 0x40013804 = USART1 TXD */
 };
 
+static const uint8_t bios_hexagon[] = {
+    0x00, 0x40, 0x00, 0x01,                 /* immext(#0x10000000) */
+    0x00, 0xc0, 0x00, 0x78,                 /* r0 = ##0x10000000 */
+    0x54, 0xc0, 0x00, 0x3c,                 /* memb(r0+#0) = #0x54 Write 'T' */
+    0xf8, 0xff, 0xff, 0x59                  /* jump 0x0 ; Loop back to start */
+};
+
 typedef struct testdef {
     const char *arch;       /* Target architecture */
     const char *machine;    /* Name of the machine */
@@ -194,6 +201,7 @@ static const testdef_t tests[] = {
     { "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },
     { "arm", "stm32vldiscovery", "", "T",
       sizeof(kernel_stm32vldiscovery), kernel_stm32vldiscovery },
+    { "hexagon", "virt", "", "TT", sizeof(bios_hexagon), NULL, bios_hexagon },
 
     { NULL }
 };
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index ba9f59d2f8f..d83cb05cc8c 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -290,6 +290,8 @@ qtests_riscv64 = ['riscv-csr-test'] + \
    config_all_devices.has_key('CONFIG_RISCV_IOMMU') ?
    ['iommu-riscv-test'] : [])
 
+qtests_hexagon = ['boot-serial-test']
+
 qos_test_ss = ss.source_set()
 qos_test_ss.add(
   'ac97-test.c',
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 2/9] hw/hexagon: Add global register tracing
  2026-03-11  4:20 ` [PATCH v3 2/9] hw/hexagon: Add global register tracing Brian Cain
@ 2026-03-11 17:52   ` Philippe Mathieu-Daudé
  2026-03-16 18:02   ` Taylor Simpson
  1 sibling, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-03-11 17:52 UTC (permalink / raw)
  To: Brian Cain, qemu-devel
  Cc: ltaylorsimpson, matheus.bernardino, marco.liebel, quic_mburton,
	sid.manning, ale, anjo, Paolo Bonzini, Marc-André Lureau,
	Daniel P. Berrangé

On 11/3/26 05:20, Brian Cain wrote:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>   meson.build                    |  1 +
>   hw/hexagon/hexagon_globalreg.c | 73 ++++++++++++++++++++++++++++++++++
>   hw/hexagon/trace-events        |  3 ++
>   3 files changed, 77 insertions(+)
>   create mode 100644 hw/hexagon/trace-events


> diff --git a/hw/hexagon/hexagon_globalreg.c b/hw/hexagon/hexagon_globalreg.c
> index 5187b91dcae..a30c16cd7ba 100644
> --- a/hw/hexagon/hexagon_globalreg.c
> +++ b/hw/hexagon/hexagon_globalreg.c
> @@ -16,11 +16,82 @@
>   #include "target/hexagon/cpu.h"
>   #include "target/hexagon/hex_regs.h"
>   #include "qemu/log.h"
> +#include "trace/trace-hw_hexagon.h"

cat << 'EOF > hw/hexagon/trace.h
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "trace/trace-hw_hexagon.h"
EOF

Then #include "trace.h".

With that:
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

>   #include "qapi/error.h"
>   
>   #define IMMUTABLE (~0)
>   #define INVALID_REG_VAL 0xdeadbeef




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs
  2026-03-11  4:20 ` [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs Brian Cain
@ 2026-03-11 17:54   ` Philippe Mathieu-Daudé
  2026-03-11 21:51     ` Brian Cain
  0 siblings, 1 reply; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-03-11 17:54 UTC (permalink / raw)
  To: Brian Cain, qemu-devel
  Cc: ltaylorsimpson, matheus.bernardino, marco.liebel, quic_mburton,
	sid.manning, ale, anjo, Brian Cain

On 11/3/26 05:20, Brian Cain wrote:
> From: Brian Cain <bcain@quicinc.com>
> 
> Acked-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>   hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc | 64 ++++++++++++++++++++++
>   hw/hexagon/machine_cfg_v68n_1024.h.inc    | 65 +++++++++++++++++++++++
>   2 files changed, 129 insertions(+)
>   create mode 100644 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
>   create mode 100644 hw/hexagon/machine_cfg_v68n_1024.h.inc
> 
> diff --git a/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> new file mode 100644
> index 00000000000..3d787c104ff
> --- /dev/null
> +++ b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> @@ -0,0 +1,64 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +static 

const

   struct hexagon_machine_config SA8775P_cdsp0 = {
> +    .cfgbase =         0x24000000 + 0x180000,
> +    .l2tcm_size =      0x00000000,
> +    .l2vic_base =      0x26300000 + 0x90000,
> +    .l2vic_size =      0x00001000,
> +    .csr_base =        0x26300000,
> +    .qtmr_region =     0x26300000 + 0xA1000,
> +    .cfgtable = {
> +        .l2tcm_base = 0x00002400,
> +        .reserved0 = 0x00000000,
> +        .subsystem_base = 0x00002638,
> +        .etm_base = 0x00002419,
> +        .l2cfg_base = 0x0000241a,
> +        .reserved1 = 0x0000241b,
> +        .l1s0_base = 0x00002500,
> +        .axi2_lowaddr = 0x00000000,
> +        .streamer_base = 0x00000000,
> +        .reserved2 = 0x00000000,
> +        .fastl2vic_base = 0x0000241e,
> +        .jtlb_size_entries = 0x00000080,
> +        .coproc_present = 0x00000001,
> +        .ext_contexts = 0x00000004,
> +        .vtcm_base = 0x00002500,
> +        .vtcm_size_kb = 0x00002000,
> +        .l2tag_size = 0x00000400,
> +        .l2ecomem_size = 0x00000000,
> +        .thread_enable_mask = 0x0000003f,
> +        .eccreg_base = 0x0000241f,
> +        .l2line_size = 0x00000080,
> +        .tiny_core = 0x00000000,
> +        .l2itcm_size = 0x00000000,
> +        .l2itcm_base = 0x00002400,
> +        .reserved3 = 0x00000000,
> +        .dtm_present = 0x00000000,
> +        .dma_version = 0x00000003,
> +        .hvx_vec_log_length = 0x00000007,
> +        .core_id = 0x00000000,
> +        .core_count = 0x00000000,
> +        .coproc2_reg0 = 0x00000040,
> +        .coproc2_reg1 = 0x00000020,
> +        .v2x_mode = 0x00000001,
> +        .coproc2_reg2 = 0x00000008,
> +        .coproc2_reg3 = 0x00000020,
> +        .coproc2_reg4 = 0x00000000,
> +        .coproc2_reg5 = 0x00000002,
> +        .coproc2_reg6 = 0x00000016,
> +        .coproc2_reg7 = 0x00000006,
> +        .acd_preset = 0x00000001,
> +        .mnd_preset = 0x00000000,
> +        .l1d_size_kb = 0x00000010,
> +        .l1i_size_kb = 0x00000020,
> +        .l1d_write_policy = 0x00000002,
> +        .vtcm_bank_width = 0x00000080,
> +        .reserved4 = 0x00000001,
> +        .reserved5 = 0x00000000,
> +        .reserved6 = 0x00000003,
> +        .coproc2_cvt_mpy_size = 0x0000000a,
> +        .consistency_domain = 0x000000e0,
> +        .capacity_domain = 0x00000080,
> +        .axi3_lowaddr = 0x00000000,
> +    },
> +};
> diff --git a/hw/hexagon/machine_cfg_v68n_1024.h.inc b/hw/hexagon/machine_cfg_v68n_1024.h.inc
> new file mode 100644
> index 00000000000..734a12a2f12
> --- /dev/null
> +++ b/hw/hexagon/machine_cfg_v68n_1024.h.inc
> @@ -0,0 +1,65 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +static struct hexagon_machine_config v68n_1024 = {

Ditto.

> +    .cfgbase =           0xde000000,
> +    .l2tcm_size =        0x00000000,
> +    .l2vic_base =        0xfc910000,
> +    .l2vic_size =        0x00001000,
> +    .csr_base =          0xfc900000,
> +    .qtmr_region =       0xfc921000,
> +    .cfgtable = {
> +        .l2tcm_base = 0x0000d800,
> +        .reserved0 = 0x00000000,
> +        .subsystem_base = 0x0000fc90,
> +        .etm_base = 0x0000d819,
> +        .l2cfg_base = 0x0000d81a,
> +        .reserved1 = 0x00000000,
> +        .l1s0_base = 0x0000d840,
> +        .axi2_lowaddr = 0x00003000,
> +        .streamer_base = 0x0000d81c,
> +        .reserved2 = 0x0000d81d,
> +        .fastl2vic_base = 0x0000d81e,
> +        .jtlb_size_entries = 0x00000080,
> +        .coproc_present = 0x00000001,
> +        .ext_contexts = 0x00000004,
> +        .vtcm_base = 0x0000d840,
> +        .vtcm_size_kb = 0x00001000,
> +        .l2tag_size = 0x00000400,
> +        .l2ecomem_size = 0x00000400,
> +        .thread_enable_mask = 0x0000003f,
> +        .eccreg_base = 0x0000d81f,
> +        .l2line_size = 0x00000080,
> +        .tiny_core = 0x00000000,
> +        .l2itcm_size = 0x00000000,
> +        .l2itcm_base = 0x0000d820,
> +        .reserved3 = 0x00000000,
> +        .dtm_present = 0x00000000,
> +        .dma_version = 0x00000001,
> +        .hvx_vec_log_length = 0x00000007,
> +        .core_id = 0x00000000,
> +        .core_count = 0x00000000,
> +        .coproc2_reg0 = 0x00000040,
> +        .coproc2_reg1 = 0x00000020,
> +        .v2x_mode = 0x1f1f1f1f,
> +        .coproc2_reg2 = 0x1f1f1f1f,
> +        .coproc2_reg3 = 0x1f1f1f1f,
> +        .coproc2_reg4 = 0x1f1f1f1f,
> +        .coproc2_reg5 = 0x1f1f1f1f,
> +        .coproc2_reg6 = 0x1f1f1f1f,
> +        .coproc2_reg7 = 0x1f1f1f1f,
> +        .acd_preset = 0x1f1f1f1f,
> +        .mnd_preset = 0x1f1f1f1f,
> +        .l1d_size_kb = 0x1f1f1f1f,
> +        .l1i_size_kb = 0x1f1f1f1f,
> +        .l1d_write_policy = 0x1f1f1f1f,
> +        .vtcm_bank_width = 0x1f1f1f1f,
> +        .reserved4 = 0x1f1f1f1f,
> +        .reserved5 = 0x1f1f1f1f,
> +        .reserved6 = 0x1f1f1f1f,
> +        .coproc2_cvt_mpy_size = 0x1f1f1f1f,
> +        .consistency_domain = 0x1f1f1f1f,
> +        .capacity_domain = 0x1f1f1f1f,
> +        .axi3_lowaddr = 0x1f1f1f1f,
> +    },
> +};
> +

Are these configs generated?


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 7/9] target/hexagon: add build config for softmmu
  2026-03-11  4:20 ` [PATCH v3 7/9] target/hexagon: add build config for softmmu Brian Cain
@ 2026-03-11 17:57   ` Philippe Mathieu-Daudé
  2026-03-18 13:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-03-11 17:57 UTC (permalink / raw)
  To: Brian Cain, qemu-devel
  Cc: ltaylorsimpson, matheus.bernardino, marco.liebel, quic_mburton,
	sid.manning, ale, anjo, Paolo Bonzini

On 11/3/26 05:20, Brian Cain wrote:
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>   MAINTAINERS                                 |  1 +
>   configs/devices/hexagon-softmmu/default.mak |  7 +++++++
>   configs/targets/hexagon-softmmu.mak         |  6 ++++++
>   target/hexagon/cpu.h                        |  4 ----
>   target/Kconfig                              |  1 +
>   target/hexagon/Kconfig                      |  2 ++
>   target/hexagon/meson.build                  | 13 ++++++++++++-
>   7 files changed, 29 insertions(+), 5 deletions(-)
>   create mode 100644 configs/devices/hexagon-softmmu/default.mak
>   create mode 100644 configs/targets/hexagon-softmmu.mak
>   create mode 100644 target/hexagon/Kconfig


> diff --git a/configs/devices/hexagon-softmmu/default.mak b/configs/devices/hexagon-softmmu/default.mak
> new file mode 100644
> index 00000000000..08e709aea72
> --- /dev/null
> +++ b/configs/devices/hexagon-softmmu/default.mak
> @@ -0,0 +1,7 @@
> +# Default configuration for hexagon-softmmu
> +
> +# Uncomment the following lines to disable these optional devices:
> +
> +# Boards are selected by default, uncomment to keep out of the build.
> +# CONFIG_HEX_DSP=y
> +# CONFIG_L2VIC=y
> diff --git a/configs/targets/hexagon-softmmu.mak b/configs/targets/hexagon-softmmu.mak
> new file mode 100644
> index 00000000000..42e1e5c4f83
> --- /dev/null
> +++ b/configs/targets/hexagon-softmmu.mak
> @@ -0,0 +1,6 @@
> +# Default configuration for hexagon-softmmu
> +
> +TARGET_ARCH=hexagon
> +TARGET_SUPPORTS_MTTCG=y

See commit a3d40b5effa ("tcg: Convert TARGET_SUPPORTS_MTTCG
to TCGCPUOps::mttcg_supported field") from almost 1 year ago.

> +TARGET_XML_FILES=gdb-xml/hexagon-core.xml gdb-xml/hexagon-hvx.xml
> +TARGET_LONG_BITS=32



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs
  2026-03-11 17:54   ` Philippe Mathieu-Daudé
@ 2026-03-11 21:51     ` Brian Cain
  0 siblings, 0 replies; 18+ messages in thread
From: Brian Cain @ 2026-03-11 21:51 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel, ltaylorsimpson, matheus.bernardino, marco.liebel,
	quic_mburton, sid.manning, ale, anjo, Brian Cain

[-- Attachment #1: Type: text/plain, Size: 6503 bytes --]

On Wed, Mar 11, 2026 at 12:54 PM Philippe Mathieu-Daudé <philmd@linaro.org>
wrote:

> On 11/3/26 05:20, Brian Cain wrote:
> > From: Brian Cain <bcain@quicinc.com>
> >
> > Acked-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> >   hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc | 64 ++++++++++++++++++++++
> >   hw/hexagon/machine_cfg_v68n_1024.h.inc    | 65 +++++++++++++++++++++++
> >   2 files changed, 129 insertions(+)
> >   create mode 100644 hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> >   create mode 100644 hw/hexagon/machine_cfg_v68n_1024.h.inc
> >
> > diff --git a/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> > new file mode 100644
> > index 00000000000..3d787c104ff
> > --- /dev/null
> > +++ b/hw/hexagon/machine_cfg_sa8775_cdsp0.h.inc
> > @@ -0,0 +1,64 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +static
>
> const
>
>    struct hexagon_machine_config SA8775P_cdsp0 = {
> > +    .cfgbase =         0x24000000 + 0x180000,
> > +    .l2tcm_size =      0x00000000,
> > +    .l2vic_base =      0x26300000 + 0x90000,
> > +    .l2vic_size =      0x00001000,
> > +    .csr_base =        0x26300000,
> > +    .qtmr_region =     0x26300000 + 0xA1000,
> > +    .cfgtable = {
> > +        .l2tcm_base = 0x00002400,
> > +        .reserved0 = 0x00000000,
> > +        .subsystem_base = 0x00002638,
> > +        .etm_base = 0x00002419,
> > +        .l2cfg_base = 0x0000241a,
> > +        .reserved1 = 0x0000241b,
> > +        .l1s0_base = 0x00002500,
> > +        .axi2_lowaddr = 0x00000000,
> > +        .streamer_base = 0x00000000,
> > +        .reserved2 = 0x00000000,
> > +        .fastl2vic_base = 0x0000241e,
> > +        .jtlb_size_entries = 0x00000080,
> > +        .coproc_present = 0x00000001,
> > +        .ext_contexts = 0x00000004,
> > +        .vtcm_base = 0x00002500,
> > +        .vtcm_size_kb = 0x00002000,
> > +        .l2tag_size = 0x00000400,
> > +        .l2ecomem_size = 0x00000000,
> > +        .thread_enable_mask = 0x0000003f,
> > +        .eccreg_base = 0x0000241f,
> > +        .l2line_size = 0x00000080,
> > +        .tiny_core = 0x00000000,
> > +        .l2itcm_size = 0x00000000,
> > +        .l2itcm_base = 0x00002400,
> > +        .reserved3 = 0x00000000,
> > +        .dtm_present = 0x00000000,
> > +        .dma_version = 0x00000003,
> > +        .hvx_vec_log_length = 0x00000007,
> > +        .core_id = 0x00000000,
> > +        .core_count = 0x00000000,
> > +        .coproc2_reg0 = 0x00000040,
> > +        .coproc2_reg1 = 0x00000020,
> > +        .v2x_mode = 0x00000001,
> > +        .coproc2_reg2 = 0x00000008,
> > +        .coproc2_reg3 = 0x00000020,
> > +        .coproc2_reg4 = 0x00000000,
> > +        .coproc2_reg5 = 0x00000002,
> > +        .coproc2_reg6 = 0x00000016,
> > +        .coproc2_reg7 = 0x00000006,
> > +        .acd_preset = 0x00000001,
> > +        .mnd_preset = 0x00000000,
> > +        .l1d_size_kb = 0x00000010,
> > +        .l1i_size_kb = 0x00000020,
> > +        .l1d_write_policy = 0x00000002,
> > +        .vtcm_bank_width = 0x00000080,
> > +        .reserved4 = 0x00000001,
> > +        .reserved5 = 0x00000000,
> > +        .reserved6 = 0x00000003,
> > +        .coproc2_cvt_mpy_size = 0x0000000a,
> > +        .consistency_domain = 0x000000e0,
> > +        .capacity_domain = 0x00000080,
> > +        .axi3_lowaddr = 0x00000000,
> > +    },
> > +};
> > diff --git a/hw/hexagon/machine_cfg_v68n_1024.h.inc
> b/hw/hexagon/machine_cfg_v68n_1024.h.inc
> > new file mode 100644
> > index 00000000000..734a12a2f12
> > --- /dev/null
> > +++ b/hw/hexagon/machine_cfg_v68n_1024.h.inc
> > @@ -0,0 +1,65 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +static struct hexagon_machine_config v68n_1024 = {
>
> Ditto.
>
> > +    .cfgbase =           0xde000000,
> > +    .l2tcm_size =        0x00000000,
> > +    .l2vic_base =        0xfc910000,
> > +    .l2vic_size =        0x00001000,
> > +    .csr_base =          0xfc900000,
> > +    .qtmr_region =       0xfc921000,
> > +    .cfgtable = {
> > +        .l2tcm_base = 0x0000d800,
> > +        .reserved0 = 0x00000000,
> > +        .subsystem_base = 0x0000fc90,
> > +        .etm_base = 0x0000d819,
> > +        .l2cfg_base = 0x0000d81a,
> > +        .reserved1 = 0x00000000,
> > +        .l1s0_base = 0x0000d840,
> > +        .axi2_lowaddr = 0x00003000,
> > +        .streamer_base = 0x0000d81c,
> > +        .reserved2 = 0x0000d81d,
> > +        .fastl2vic_base = 0x0000d81e,
> > +        .jtlb_size_entries = 0x00000080,
> > +        .coproc_present = 0x00000001,
> > +        .ext_contexts = 0x00000004,
> > +        .vtcm_base = 0x0000d840,
> > +        .vtcm_size_kb = 0x00001000,
> > +        .l2tag_size = 0x00000400,
> > +        .l2ecomem_size = 0x00000400,
> > +        .thread_enable_mask = 0x0000003f,
> > +        .eccreg_base = 0x0000d81f,
> > +        .l2line_size = 0x00000080,
> > +        .tiny_core = 0x00000000,
> > +        .l2itcm_size = 0x00000000,
> > +        .l2itcm_base = 0x0000d820,
> > +        .reserved3 = 0x00000000,
> > +        .dtm_present = 0x00000000,
> > +        .dma_version = 0x00000001,
> > +        .hvx_vec_log_length = 0x00000007,
> > +        .core_id = 0x00000000,
> > +        .core_count = 0x00000000,
> > +        .coproc2_reg0 = 0x00000040,
> > +        .coproc2_reg1 = 0x00000020,
> > +        .v2x_mode = 0x1f1f1f1f,
> > +        .coproc2_reg2 = 0x1f1f1f1f,
> > +        .coproc2_reg3 = 0x1f1f1f1f,
> > +        .coproc2_reg4 = 0x1f1f1f1f,
> > +        .coproc2_reg5 = 0x1f1f1f1f,
> > +        .coproc2_reg6 = 0x1f1f1f1f,
> > +        .coproc2_reg7 = 0x1f1f1f1f,
> > +        .acd_preset = 0x1f1f1f1f,
> > +        .mnd_preset = 0x1f1f1f1f,
> > +        .l1d_size_kb = 0x1f1f1f1f,
> > +        .l1i_size_kb = 0x1f1f1f1f,
> > +        .l1d_write_policy = 0x1f1f1f1f,
> > +        .vtcm_bank_width = 0x1f1f1f1f,
> > +        .reserved4 = 0x1f1f1f1f,
> > +        .reserved5 = 0x1f1f1f1f,
> > +        .reserved6 = 0x1f1f1f1f,
> > +        .coproc2_cvt_mpy_size = 0x1f1f1f1f,
> > +        .consistency_domain = 0x1f1f1f1f,
> > +        .capacity_domain = 0x1f1f1f1f,
> > +        .axi3_lowaddr = 0x1f1f1f1f,
> > +    },
> > +};
> > +
>
> Are these configs generated?
>

No - but they are taken via a dump from a donor system.

[-- Attachment #2: Type: text/html, Size: 8450 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test
  2026-03-11  4:20 ` [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test Brian Cain
@ 2026-03-12 14:43   ` Fabiano Rosas
  0 siblings, 0 replies; 18+ messages in thread
From: Fabiano Rosas @ 2026-03-12 14:43 UTC (permalink / raw)
  To: Brian Cain, qemu-devel
  Cc: brian.cain, philmd, ltaylorsimpson, matheus.bernardino,
	marco.liebel, quic_mburton, sid.manning, ale, anjo,
	Laurent Vivier, Paolo Bonzini

Brian Cain <brian.cain@oss.qualcomm.com> writes:

> Add boot-serial-test support for Hexagon architecture using the virt
> machine.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>  tests/qtest/boot-serial-test.c | 8 ++++++++
>  tests/qtest/meson.build        | 2 ++
>  2 files changed, 10 insertions(+)
>
> diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
> index bcd0a9c50e7..37fee7a91c4 100644
> --- a/tests/qtest/boot-serial-test.c
> +++ b/tests/qtest/boot-serial-test.c
> @@ -142,6 +142,13 @@ static const uint8_t kernel_stm32vldiscovery[] = {
>      0x04, 0x38, 0x01, 0x40                  /* 0x40013804 = USART1 TXD */
>  };
>  
> +static const uint8_t bios_hexagon[] = {
> +    0x00, 0x40, 0x00, 0x01,                 /* immext(#0x10000000) */
> +    0x00, 0xc0, 0x00, 0x78,                 /* r0 = ##0x10000000 */
> +    0x54, 0xc0, 0x00, 0x3c,                 /* memb(r0+#0) = #0x54 Write 'T' */
> +    0xf8, 0xff, 0xff, 0x59                  /* jump 0x0 ; Loop back to start */
> +};
> +
>  typedef struct testdef {
>      const char *arch;       /* Target architecture */
>      const char *machine;    /* Name of the machine */
> @@ -194,6 +201,7 @@ static const testdef_t tests[] = {
>      { "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },
>      { "arm", "stm32vldiscovery", "", "T",
>        sizeof(kernel_stm32vldiscovery), kernel_stm32vldiscovery },
> +    { "hexagon", "virt", "", "TT", sizeof(bios_hexagon), NULL, bios_hexagon },
>  
>      { NULL }
>  };
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index ba9f59d2f8f..d83cb05cc8c 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -290,6 +290,8 @@ qtests_riscv64 = ['riscv-csr-test'] + \
>     config_all_devices.has_key('CONFIG_RISCV_IOMMU') ?
>     ['iommu-riscv-test'] : [])
>  
> +qtests_hexagon = ['boot-serial-test']
> +
>  qos_test_ss = ss.source_set()
>  qos_test_ss.add(
>    'ac97-test.c',

Reviewed-by: Fabiano Rosas <farosas@suse.de>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 1/9] hw/hexagon: Add globalreg model
  2026-03-11  4:20 ` [PATCH v3 1/9] hw/hexagon: Add globalreg model Brian Cain
@ 2026-03-16 17:58   ` Taylor Simpson
  0 siblings, 0 replies; 18+ messages in thread
From: Taylor Simpson @ 2026-03-16 17:58 UTC (permalink / raw)
  To: Brian Cain
  Cc: qemu-devel, philmd, matheus.bernardino, marco.liebel,
	quic_mburton, sid.manning, ale, anjo

[-- Attachment #1: Type: text/plain, Size: 3707 bytes --]

On Tue, Mar 10, 2026 at 10:20 PM Brian Cain <brian.cain@oss.qualcomm.com>
wrote:

> Some of the system registers are shared among all threads
> in the core.  This object contains the representation and
> interface to the system registers.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>  include/hw/hexagon/hexagon_globalreg.h |  56 ++++++
>  hw/hexagon/hexagon_globalreg.c         | 240 +++++++++++++++++++++++++
>  2 files changed, 296 insertions(+)
>  create mode 100644 include/hw/hexagon/hexagon_globalreg.h
>  create mode 100644 hw/hexagon/hexagon_globalreg.c
>
> diff --git a/include/hw/hexagon/hexagon_globalreg.h
> b/include/hw/hexagon/hexagon_globalreg.h
> new file mode 100644
> index 00000000000..c9e72f30b0a
> --- /dev/null
> +++ b/include/hw/hexagon/hexagon_globalreg.h
> @@ -0,0 +1,56 @@
> +/*
> + * Hexagon Global Registers QOM Object
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef HEXAGON_GLOBALREG_H
> +#define HEXAGON_GLOBALREG_H
> +
> +#include "hw/core/qdev.h"
> +#include "hw/core/sysbus.h"
> +#include "qom/object.h"
> +#include "target/hexagon/cpu.h"
> +
> +#define TYPE_HEXAGON_GLOBALREG "hexagon-globalreg"
> +OBJECT_DECLARE_SIMPLE_TYPE(HexagonGlobalRegState, HEXAGON_GLOBALREG)
> +
> +struct HexagonGlobalRegState {
> +    SysBusDevice parent_obj;
> +
> +    /* Array of system registers */
> +    uint32_t regs[NUM_SREGS];
> +
> +    /* Global performance cycle counter base */
> +    uint64_t g_pcycle_base;
> +
> +    /* Properties for global register reset values */
> +    uint32_t boot_evb;           /* Boot Exception Vector Base
> (HEX_SREG_EVB) */
> +    uint64_t config_table_addr;  /* Configuration table base */
> +    uint32_t dsp_rev;           /* DSP revision register (HEX_SREG_REV) */
> +
> +    /* ISDB properties */
> +    bool isdben_etm_enable;     /* ISDB ETM enable bit */
> +    bool isdben_dfd_enable;     /* ISDB DFD enable bit */
> +    bool isdben_trusted;        /* ISDB trusted mode bit */
> +    bool isdben_secure;         /* ISDB secure mode bit */
>

Should the TLB entries go in here also?


> +};
> +
> +/* Public interface functions */
> +uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg,
> +                                uint32_t htid);
>

Why is htid needed?


> +void hexagon_globalreg_write(HexagonGlobalRegState *s, uint32_t reg,
> +                             uint32_t value, uint32_t htid);
>

Ditto


> +uint32_t hexagon_globalreg_masked_value(HexagonGlobalRegState *s,
> uint32_t reg,
> +                                        uint32_t value);
> +void hexagon_globalreg_write_masked(HexagonGlobalRegState *s, uint32_t
> reg,
> +                                    uint32_t value);
> +void hexagon_globalreg_reset(HexagonGlobalRegState *s);
> +
> +/* Global performance cycle counter access */
> +uint64_t hexagon_globalreg_get_pcycle_base(HexagonGlobalRegState *s);
> +void hexagon_globalreg_set_pcycle_base(HexagonGlobalRegState *s,
> +                                       uint64_t value);
> +
> +#endif /* HEXAGON_GLOBALREG_H */
> diff --git a/hw/hexagon/hexagon_globalreg.c
> b/hw/hexagon/hexagon_globalreg.c
> new file mode 100644
> index 00000000000..5187b91dcae
> --- /dev/null
> +++ b/hw/hexagon/hexagon_globalreg.c
> @@ -0,0 +1,240 @@
> +static void hexagon_globalreg_init(Object *obj)
> +{
> +    HexagonGlobalRegState *s = HEXAGON_GLOBALREG(obj);
> +
> +    memset(s->regs, 0, sizeof(uint32_t) * NUM_SREGS);
>

Should we memset the whole thing?


> +}
>
>

[-- Attachment #2: Type: text/html, Size: 5128 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 2/9] hw/hexagon: Add global register tracing
  2026-03-11  4:20 ` [PATCH v3 2/9] hw/hexagon: Add global register tracing Brian Cain
  2026-03-11 17:52   ` Philippe Mathieu-Daudé
@ 2026-03-16 18:02   ` Taylor Simpson
  1 sibling, 0 replies; 18+ messages in thread
From: Taylor Simpson @ 2026-03-16 18:02 UTC (permalink / raw)
  To: Brian Cain
  Cc: qemu-devel, philmd, matheus.bernardino, marco.liebel,
	quic_mburton, sid.manning, ale, anjo, Paolo Bonzini,
	Marc-André Lureau, Daniel P. Berrangé

[-- Attachment #1: Type: text/plain, Size: 1439 bytes --]

On Tue, Mar 10, 2026 at 10:20 PM Brian Cain <brian.cain@oss.qualcomm.com>
wrote:

> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>  meson.build                    |  1 +
>  hw/hexagon/hexagon_globalreg.c | 73 ++++++++++++++++++++++++++++++++++
>  hw/hexagon/trace-events        |  3 ++
>  3 files changed, 77 insertions(+)
>  create mode 100644 hw/hexagon/trace-events
>
> diff --git a/meson.build b/meson.build
> index 7b4e5bc72b5..286edfb99dc 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -3633,6 +3633,7 @@ if have_system
>      'hw/display',
>      'hw/dma',
>      'hw/fsi',
> +    'hw/hexagon',
>      'hw/hyperv',
>      'hw/i2c',
>      'hw/i3c',
> diff --git a/hw/hexagon/hexagon_globalreg.c
> b/hw/hexagon/hexagon_globalreg.c
> index 5187b91dcae..a30c16cd7ba 100644
> --- a/hw/hexagon/hexagon_globalreg.c
> +++ b/hw/hexagon/hexagon_globalreg.c
> @@ -16,11 +16,82 @@
>  #include "target/hexagon/cpu.h"
>  #include "target/hexagon/hex_regs.h"
>  #include "qemu/log.h"
> +#include "trace/trace-hw_hexagon.h"
>  #include "qapi/error.h"
>
>  #define IMMUTABLE (~0)
>  #define INVALID_REG_VAL 0xdeadbeef
>
> +static const char *hex_sreg_names[] = {
> +    [HEX_SREG_SGP0] = "sgp0",
> +    [HEX_SREG_SGP1] = "sgp1",
> +    [HEX_SREG_STID] = "stid",
>

Why not use the array in cpu.c from an earlier patch?

[-- Attachment #2: Type: text/html, Size: 2190 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 7/9] target/hexagon: add build config for softmmu
  2026-03-11  4:20 ` [PATCH v3 7/9] target/hexagon: add build config for softmmu Brian Cain
  2026-03-11 17:57   ` Philippe Mathieu-Daudé
@ 2026-03-18 13:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-03-18 13:14 UTC (permalink / raw)
  To: Brian Cain, qemu-devel
  Cc: ltaylorsimpson, matheus.bernardino, marco.liebel, quic_mburton,
	sid.manning, ale, anjo, Paolo Bonzini

On 11/3/26 05:20, Brian Cain wrote:
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
>   MAINTAINERS                                 |  1 +
>   configs/devices/hexagon-softmmu/default.mak |  7 +++++++
>   configs/targets/hexagon-softmmu.mak         |  6 ++++++
>   target/hexagon/cpu.h                        |  4 ----
>   target/Kconfig                              |  1 +
>   target/hexagon/Kconfig                      |  2 ++
>   target/hexagon/meson.build                  | 13 ++++++++++++-
>   7 files changed, 29 insertions(+), 5 deletions(-)
>   create mode 100644 configs/devices/hexagon-softmmu/default.mak
>   create mode 100644 configs/targets/hexagon-softmmu.mak
>   create mode 100644 target/hexagon/Kconfig
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d324701ae05..d9d4cda4d0b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -253,6 +253,7 @@ F: linux-user/hexagon/
>   F: tests/tcg/hexagon/
>   F: disas/hexagon.c
>   F: configs/targets/hexagon-linux-user/default.mak
> +F: configs/devices/hexagon-softmmu/default.mak
>   F: docker/dockerfiles/debian-hexagon-cross.docker
>   F: gdb-xml/hexagon*.xml
>   F: docs/system/target-hexagon.rst
> diff --git a/configs/devices/hexagon-softmmu/default.mak b/configs/devices/hexagon-softmmu/default.mak
> new file mode 100644
> index 00000000000..08e709aea72
> --- /dev/null
> +++ b/configs/devices/hexagon-softmmu/default.mak
> @@ -0,0 +1,7 @@
> +# Default configuration for hexagon-softmmu
> +
> +# Uncomment the following lines to disable these optional devices:
> +
> +# Boards are selected by default, uncomment to keep out of the build.
> +# CONFIG_HEX_DSP=y
> +# CONFIG_L2VIC=y
> diff --git a/configs/targets/hexagon-softmmu.mak b/configs/targets/hexagon-softmmu.mak
> new file mode 100644
> index 00000000000..42e1e5c4f83
> --- /dev/null
> +++ b/configs/targets/hexagon-softmmu.mak
> @@ -0,0 +1,6 @@
> +# Default configuration for hexagon-softmmu
> +
> +TARGET_ARCH=hexagon
> +TARGET_SUPPORTS_MTTCG=y
> +TARGET_XML_FILES=gdb-xml/hexagon-core.xml gdb-xml/hexagon-hvx.xml
> +TARGET_LONG_BITS=32

Note, since we are trying to remove various legacy code, new system
targets must be introduced with:

TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y

Regards,

Phil.


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2026-03-18 13:15 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11  4:20 [PATCH v3 0/9] Hexagon system emulation - Part 3/3 Brian Cain
2026-03-11  4:20 ` [PATCH v3 1/9] hw/hexagon: Add globalreg model Brian Cain
2026-03-16 17:58   ` Taylor Simpson
2026-03-11  4:20 ` [PATCH v3 2/9] hw/hexagon: Add global register tracing Brian Cain
2026-03-11 17:52   ` Philippe Mathieu-Daudé
2026-03-16 18:02   ` Taylor Simpson
2026-03-11  4:20 ` [PATCH v3 3/9] hw/hexagon: Add machine configs for sysemu Brian Cain
2026-03-11  4:20 ` [PATCH v3 4/9] hw/hexagon: Add v68, sa8775-cdsp0 defs Brian Cain
2026-03-11 17:54   ` Philippe Mathieu-Daudé
2026-03-11 21:51     ` Brian Cain
2026-03-11  4:20 ` [PATCH v3 5/9] hw/hexagon: Add support for cfgbase Brian Cain
2026-03-11  4:20 ` [PATCH v3 6/9] hw/hexagon: Modify "Standalone" symbols Brian Cain
2026-03-11  4:20 ` [PATCH v3 7/9] target/hexagon: add build config for softmmu Brian Cain
2026-03-11 17:57   ` Philippe Mathieu-Daudé
2026-03-18 13:14   ` Philippe Mathieu-Daudé
2026-03-11  4:20 ` [PATCH v3 8/9] hw/hexagon: Define hexagon "virt" machine Brian Cain
2026-03-11  4:20 ` [PATCH v3 9/9] tests/qtest: Add hexagon boot-serial-test Brian Cain
2026-03-12 14:43   ` Fabiano Rosas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox