> -----Original Message-----
> From: Richard Henderson <richard.hender...@linaro.org>
> Sent: Thursday, March 20, 2025 10:34 AM
> To: Sid Manning <sidn...@quicinc.com>; ltaylorsimp...@gmail.com;
> 'Philippe Mathieu-Daudé' <phi...@linaro.org>; 'Brian Cain'
> <brian.c...@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: Matheus Bernardino (QUIC) <quic_mathb...@quicinc.com>;
> a...@rev.ng; a...@rev.ng; Marco Liebel (QUIC)
> <quic_mlie...@quicinc.com>; alex.ben...@linaro.org; Mark Burton (QUIC)
> <quic_mbur...@quicinc.com>; Brian Cain <bc...@quicinc.com>
> Subject: Re: [PATCH 28/38] target/hexagon: Initialize htid, modectl regs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
> 
> On 3/19/25 09:08, Sid Manning wrote:
> >
> >
> >> -----Original Message-----
> >> From: Richard Henderson <richard.hender...@linaro.org>
> >> Sent: Thursday, March 13, 2025 2:07 PM
> >> To: ltaylorsimp...@gmail.com; 'Philippe Mathieu-Daudé'
> >> <phi...@linaro.org>; 'Brian Cain' <brian.c...@oss.qualcomm.com>;
> >> qemu- de...@nongnu.org
> >> Cc: Matheus Bernardino (QUIC) <quic_mathb...@quicinc.com>;
> >> a...@rev.ng; a...@rev.ng; Marco Liebel (QUIC)
> >> <quic_mlie...@quicinc.com>; alex.ben...@linaro.org; Mark Burton
> >> (QUIC) <quic_mbur...@quicinc.com>; Sid Manning
> <sidn...@quicinc.com>;
> >> Brian Cain <bc...@quicinc.com>
> >> Subject: Re: [PATCH 28/38] target/hexagon: Initialize htid, modectl
> >> regs
> >>
> >> WARNING: This email originated from outside of Qualcomm. Please be
> >> wary of any links or attachments, and do not enable macros.
> >>
> >> On 3/13/25 11:47, ltaylorsimp...@gmail.com wrote:
> >>> What we are trying to model is an instance of a Hexagon that has a
> >>> number
> >> of threads and some resources that are shared.  The shared resources
> >> include the TLB and global S registers.  The initial thought was to
> >> tie the shared resources to the thread with cpu_index == 0.  If we
> >> were to model a Qualcomm SoC, there would be multiple ARM cores and
> >> multiple Hexagon instances.  Each Hexagon instance would have
> >> distinct shared resources.  So, you are correct that using cpu_index is not
> going to scale.
> >>>
> >>> What is the recommended way to model this?  I see a "nr_threads"
> >>> field in
> >> CPUCore but no clear way to find the threads.  PPC has some cores
> >> that add a "threads" field.  Should we follow this approach?
> >>
> >> I recommend that the shared resources be modeled as a separate
> >> Object, which is linked via object_property_add_link to all of the cpus 
> >> that
> use it.
> >>
> > [Sid Manning]
> > Hi Richard,
> > An example of shared resources would be the system registers.  They are
> broken down into 2 regions.  Each thread has its own copy of system
> registers 0-15 while registers 16-63 are global.  Right now CPUHexagonState
> contains a pointer, g_sreg which points back to cpu[0]'s state thus keeping
> one copy of the global registers, accesses are done with BQL held to avoid
> race conditions.
> >
> > Your suggestion is to create a new object to represent the set of global
> system registers, I tried this:
> >
> > #define TYPE_HEXAGON_G_SREG "hexagon.global_sreg"
> > OBJECT_DECLARE_SIMPLE_TYPE(HexagonGlobalSREGState,
> HEXAGON_G_SREG)
> > struct HexagonGlobalSREGState {
> >      SysBusDevice parent_obj;
> 
> SysBusDevice is more than you need -- Object is sufficient here.
[Sid Manning] 
Thanks!  Will change that to Object.

> 
> >      uint32_t regs[64];
> > };
> >
> > In our virtual machine init:
> > vms->g_sreg =
> HEXAGON_G_SREG(qdev_new(TYPE_HEXAGON_G_SREG));
> >
> > and
> >   object_property_set_link(OBJECT(cpu), "global-sreg",
> > OBJECT(vms->g_sreg), &error_abort);
> >
> > to attach the global regs to the cpu, but the above doesn't update cpu
> elements the same way calls to qdev_prop_set_uint32 will do,
> object_property_set_link doesn’t error out and returns true.
> 
> Did you add the DEFINE_PROP_LINK to match?  I'd expect something like
> 
>      DEFINE_PROP_LINK("global-sreg", HexagonCPU, g_sreg,
>                       TYPE_HEXAGON_G_SREG, HexagonGlobalSREGState *),
> 
> Beyond that, I guess I'd have to see an actual patch to work out what's
> wrong.
[Sid Manning] 
Yes, PROP_LINK above is almost exactly what I added.

Below is a patch representing what I tried.  I hoped that cpu->global_sreg 
would be updated after the call to object_property_set_link but it was not, in 
the patch below I manually set it.

diff --git a/hw/hexagon/sysreg.h b/hw/hexagon/sysreg.h
new file mode 100644
index 0000000000..d7204896cf
--- /dev/null
+++ b/hw/hexagon/sysreg.h
@@ -0,0 +1,47 @@
+/*
+ * Hexagon system reg
+ * FIXME
+ */
+
+#ifndef HW_HEXAGON_HART_H
+#define HW_HEXAGON_HART_H
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define NUM_SREGS 64
+struct HexagonGlobalSREGState {
+    struct Object parent_obj;
+    uint32_t regs[NUM_SREGS];
+};
+
+#define TYPE_HEXAGON_G_SREG "hexagon.global_sreg"
+OBJECT_DECLARE_SIMPLE_TYPE(HexagonGlobalSREGState, HEXAGON_G_SREG)
+
+static void hexagon_global_sreg_init(Object *obj)
+{
+    HexagonGlobalSREGState *s = HEXAGON_G_SREG(obj);
+    /*
+     * The first 16 registers are thread local and should not come from
+     * this structure
+     */
+    for (int i = 0; i < 16; i++) {
+        s->regs[i] = 0xffffffff;
+    }
+}
+
+static const TypeInfo hexagon_sreg_info = {
+    .name          = TYPE_HEXAGON_G_SREG,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(struct HexagonGlobalSREGState),
+    .instance_init = hexagon_global_sreg_init,
+};
+
+__attribute__ ((unused))
+static void hexagon_sreg_register_types(void)
+{
+    type_register_static(&hexagon_sreg_info);
+}
+#endif
+#endif
+
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index 1e7ac4e5b7..d2d599ac1d 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -10,12 +10,14 @@
 #include "hw/char/pl011.h"
 #include "hw/core/sysbus-fdt.h"
 #include "hw/hexagon/hexagon.h"
+#include "hw/hexagon/sysreg.h"
 #include "hw/hexagon/virt.h"
 #include "hw/loader.h"
 #include "hw/qdev-properties.h"
 #include "hw/register.h"
 #include "hw/timer/qct-qtimer.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
 #include "qemu/guest-random.h"
 #include "qemu/units.h"
 #include "elf.h"
@@ -335,6 +337,7 @@ static void virt_init(MachineState *ms)
         cpu_model = HEXAGON_CPU_TYPE_NAME("v73");
     }
 
+    vms->g_sreg = HEXAGON_G_SREG(qdev_new(TYPE_HEXAGON_G_SREG));
     HexagonCPU *cpu_0 = NULL;
     for (int i = 0; i < ms->smp.cpus; i++) {
         HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
@@ -356,6 +359,14 @@ static void virt_init(MachineState *ms)
         qdev_prop_set_uint32(DEVICE(cpu), "qtimer-base-addr", 
m_cfg->qtmr_region);
         qdev_prop_set_uint32(DEVICE(cpu), "jtlb-entries",
                              m_cfg->cfgtable.jtlb_size_entries);
+        bool rc = object_property_set_link(OBJECT(cpu), "global-sreg",
+                                           OBJECT(vms->g_sreg), &error_abort);
+        g_assert(rc == true);
+
+        /* This is doing what I think object_property_set_link should do.*/
+        cpu->global_sreg = vms->g_sreg;
+
+
 
         if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
             return;
@@ -413,3 +424,5 @@ static const TypeInfo virt_machine_types[] = { {
 } };
 
 DEFINE_TYPES(virt_machine_types)
+
+type_init(hexagon_sreg_register_types)
diff --git a/include/hw/hexagon/virt.h b/include/hw/hexagon/virt.h
index 0c165a786d..dcd09d50b1 100644
--- a/include/hw/hexagon/virt.h
+++ b/include/hw/hexagon/virt.h
@@ -9,6 +9,7 @@
 #define HW_HEXAGONVIRT_H
 
 #include "hw/boards.h"
+#include "hw/hexagon/sysreg.h"
 #include "target/hexagon/cpu.h"
 
 struct HexagonVirtMachineState {
@@ -22,6 +23,7 @@ struct HexagonVirtMachineState {
     MemoryRegion tcm;
     MemoryRegion vtcm;
     DeviceState *l2vic;
+    HexagonGlobalSREGState *g_sreg;
 };
 
 void hexagon_load_fdt(const struct HexagonVirtMachineState *vms);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index c649aef99e..9773ee0be8 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -80,6 +80,8 @@ static const Property hexagon_cpu_properties[] = {
     DEFINE_PROP_UINT32("exec-start-addr", HexagonCPU, boot_addr, 
0xffffffffULL),
     DEFINE_PROP_UINT64("config-table-addr", HexagonCPU, config_table_addr,
                        0xffffffffULL),
+    DEFINE_PROP_LINK("global-sreg", HexagonCPU, global_sreg,
+                     TYPE_HEXAGON_G_SREG, HexagonGlobalSREGState *),
 #endif
     DEFINE_PROP_UINT32("dsp-rev", HexagonCPU, rev_reg, 0),
     DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
@@ -378,6 +380,11 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType 
type)
     CPUState *cs = CPU(obj);
     HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(obj);
     CPUHexagonState *env = cpu_env(cs);
+#ifndef CONFIG_USER_ONLY
+    HexagonCPU *cpu = HEXAGON_CPU(cs);
+    env->g_sreg = cpu->global_sreg->regs;
+#endif
+
 
     if (mcc->parent_phases.hold) {
         mcc->parent_phases.hold(obj, type);
@@ -389,11 +396,6 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType 
type)
     set_float_default_nan_pattern(0b11111111, &env->fp_status);
 
 #ifndef CONFIG_USER_ONLY
-    HexagonCPU *cpu = HEXAGON_CPU(cs);
-
-    if (cs->cpu_index == 0) {
-        memset(env->g_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
-    }
     memset(env->t_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
     memset(env->greg, 0, sizeof(target_ulong) * NUM_GREGS);
 
@@ -468,13 +470,6 @@ static void hexagon_cpu_realize(DeviceState *dev, Error 
**errp)
     CPUHexagonState *env = cpu_env(cs);
 #ifndef CONFIG_USER_ONLY
     hex_mmu_realize(env);
-    if (cs->cpu_index == 0) {
-        env->g_sreg = g_new0(target_ulong, NUM_SREGS);
-    } else {
-        CPUState *cpu0 = qemu_get_cpu(0);
-        CPUHexagonState *env0 = cpu_env(cpu0);
-        env->g_sreg = env0->g_sreg;
-    }
 #endif
     if (cs->cpu_index == 0) {
         env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 8b334068e2..716dd8253b 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -19,10 +19,10 @@
 #define HEXAGON_CPU_H
 
 #include "fpu/softfloat-types.h"
+#include "hw/hexagon/sysreg.h"
 
 #define NUM_GREGS 32
 #define GREG_WRITES_MAX 32
-#define NUM_SREGS 64
 #define SREG_WRITES_MAX 64
 
 #include "cpu-qom.h"
@@ -199,6 +199,7 @@ struct ArchCPU {
     uint32_t hvx_contexts;
     uint32_t boot_addr;
     uint64_t config_table_addr;
+    HexagonGlobalSREGState *global_sreg;
 #endif
 };



> 
> 
> r~

Reply via email to