* [PATCH 00/39] hexagon system emu, part 2/3
@ 2025-03-01 5:28 Brian Cain
2025-03-01 5:28 ` [PATCH 01/39] target/hexagon: Implement ciad helper Brian Cain
` (38 more replies)
0 siblings, 39 replies; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym
hexagon architecture system emulation: part 2/3
This series includes the k0 and TLB locking implementation. This was briefly
discussed on-list at https://lists.nongnu.org/archive/html/qemu-devel/2024-01/msg04801.html
and perhaps we can continue/follow-up discussion on the relevant patch(es)
in this series.
Brian Cain (38):
target/hexagon: Implement ciad helper
target/hexagon: Implement {c,}swi helpers
target/hexagon: Implement iassign{r,w} helpers
target/hexagon: Implement start/stop helpers
target/hexagon: Implement modify SSR
target/hexagon: Implement {g,s}etimask helpers
target/hexagon: Implement wait helper
target/hexagon: Implement get_exe_mode()
target/hexagon: Implement arch_get_system_reg()
target/hexagon: Implement arch_{s,g}et_{thread,system}_reg()
target/hexagon: Add representation to count cycles
target/hexagon: Add implementation of cycle counters
target/hexagon: Implement modify_syscfg()
target/hexagon: Add system event, cause codes
target/hexagon: Implement hex_tlb_entry_get_perm()
target/hexagon: Implement hex_tlb_lookup_by_asid()
target/hexagon: Implement software interrupt
target/hexagon: Implement exec_interrupt, set_irq
target/hexagon: Implement hexagon_tlb_fill()
target/hexagon: Implement siad inst
target/hexagon: Implement hexagon_resume_threads()
target/hexagon: Implement setprio, resched
target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug()
target/hexagon: Add exec-start-addr prop
target/hexagon: Add hexagon_cpu_mmu_index()
target/hexagon: Decode trap1, rte as COF
target/hexagon: Implement hexagon_find_last_irq()
target/hexagon: Implement modify_ssr, resched, pending_interrupt
target/hexagon: Add pkt_ends_tb to translation
target/hexagon: Add next_PC, {s,g}reg writes
target/hexagon: Add implicit sysreg writes
target/hexagon: Define system, guest reg names
target/hexagon: initialize sys/guest reg TCGvs
target/hexagon: Add TLB, k0 {un,}lock
target/hexagon: Define gen_precise_exception()
target/hexagon: Add TCG overrides for transfer insts
target/hexagon: Add support for loadw_phys
target/hexagon: Add pcycle setting functionality
Matheus Tavares Bernardino (1):
target/hexagon: Add guest reg reading functionality
target/hexagon/cpu.h | 51 +++-
target/hexagon/cpu_bits.h | 56 +++-
target/hexagon/cpu_helper.h | 19 +-
target/hexagon/gen_tcg.h | 7 -
target/hexagon/gen_tcg_sys.h | 25 ++
target/hexagon/helper.h | 5 +-
target/hexagon/hexswi.h | 17 ++
target/hexagon/internal.h | 2 +
target/hexagon/sys_macros.h | 8 +-
target/hexagon/translate.h | 5 +
target/hexagon/reg_fields_def.h.inc | 11 +
target/hexagon/cpu.c | 336 +++++++++++++++++++-
target/hexagon/cpu_helper.c | 374 ++++++++++++++++++++++-
target/hexagon/decode.c | 14 +
target/hexagon/genptr.c | 7 +-
target/hexagon/hex_mmu.c | 80 ++++-
target/hexagon/hexswi.c | 258 ++++++++++++++++
target/hexagon/machine.c | 25 +-
target/hexagon/op_helper.c | 423 ++++++++++++++++++++++++--
target/hexagon/translate.c | 315 +++++++++++++++++--
target/hexagon/hex_common.py | 3 +
target/hexagon/imported/encode_pp.def | 1 +
target/hexagon/imported/ldst.idef | 3 +
23 files changed, 1938 insertions(+), 107 deletions(-)
create mode 100644 target/hexagon/hexswi.h
create mode 100644 target/hexagon/hexswi.c
--
2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* [PATCH 01/39] target/hexagon: Implement ciad helper
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 16:08 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 02/39] target/hexagon: Implement {c,}swi helpers Brian Cain
` (37 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
ciad is the clear interrupt auto disable instruction.
This instruction is defined in the Qualcomm Hexagon V71 Programmer's Reference
Manual -
https://docs.qualcomm.com/bundle/publicresource/80-N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
See §11.9.2 SYSTEM MONITOR.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 39 ++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index fd9caafefc..b28a18adf6 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -34,6 +34,11 @@
#include "op_helper.h"
#include "cpu_helper.h"
#include "translate.h"
+#ifndef CONFIG_USER_ONLY
+#include "hex_mmu.h"
+#include "hw/intc/l2vic.h"
+#include "hex_interrupts.h"
+#endif
#define SF_BIAS 127
#define SF_MANTBITS 23
@@ -1338,9 +1343,36 @@ void HELPER(vwhist128qm)(CPUHexagonState *env, int32_t uiV)
}
#ifndef CONFIG_USER_ONLY
+static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int val)
+{
+ g_assert((offset == L2VIC_VID_0) || (offset == L2VIC_VID_1));
+ CPUState *cs = env_cpu(env);
+ HexagonCPU *cpu = HEXAGON_CPU(cs);
+ const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
+ cpu_physical_memory_write(pend_mem, &val, sizeof(val));
+}
+
+static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t offset)
+{
+ /*
+ * currently only l2vic is the only attached it uses vid0, remove
+ * the assert below if anther is added
+ */
+ hexagon_set_vid(env, offset, L2VIC_CIAD_INSTRUCTION);
+}
+
void HELPER(ciad)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ uint32_t ipendad;
+ uint32_t iad;
+
+ BQL_LOCK_GUARD();
+ ipendad = READ_SREG(HEX_SREG_IPENDAD);
+ iad = fGET_FIELD(ipendad, IPENDAD_IAD);
+ fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask));
+ arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
+ hexagon_clear_last_irq(env, L2VIC_VID_0);
+ hex_interrupt_update(env);
}
void HELPER(siad)(CPUHexagonState *env, uint32_t mask)
@@ -1416,11 +1448,6 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t val)
g_assert_not_reached();
}
-static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int val)
-{
- g_assert_not_reached();
-}
-
static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
{
g_assert_not_reached();
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 02/39] target/hexagon: Implement {c,}swi helpers
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
2025-03-01 5:28 ` [PATCH 01/39] target/hexagon: Implement ciad helper Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 16:09 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers Brian Cain
` (36 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
{c,}swi are the "software interrupt"/"Cancel pending interrupts" instructions.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index b28a18adf6..fed5cc2715 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1382,12 +1382,14 @@ void HELPER(siad)(CPUHexagonState *env, uint32_t mask)
void HELPER(swi)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ BQL_LOCK_GUARD();
+ hex_raise_interrupts(env, mask, CPU_INTERRUPT_SWI);
}
void HELPER(cswi)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ BQL_LOCK_GUARD();
+ hex_clear_interrupts(env, mask, CPU_INTERRUPT_SWI);
}
void HELPER(iassignw)(CPUHexagonState *env, uint32_t src)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
2025-03-01 5:28 ` [PATCH 01/39] target/hexagon: Implement ciad helper Brian Cain
2025-03-01 5:28 ` [PATCH 02/39] target/hexagon: Implement {c,}swi helpers Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 16:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 04/39] target/hexagon: Implement start/stop helpers Brian Cain
` (35 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
iassign{r,w} are the "Interrupt to thread assignment {read,write}"
instructions.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 48 ++++++++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index fed5cc2715..ded6c80d62 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1394,12 +1394,56 @@ void HELPER(cswi)(CPUHexagonState *env, uint32_t mask)
void HELPER(iassignw)(CPUHexagonState *env, uint32_t src)
{
- g_assert_not_reached();
+ uint32_t modectl;
+ uint32_t thread_enabled_mask;
+ CPUState *cpu;
+
+ BQL_LOCK_GUARD();
+ modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+
+ CPU_FOREACH(cpu) {
+ CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
+ uint32_t thread_id_mask = 0x1 << thread_env->threadId;
+ if (thread_enabled_mask & thread_id_mask) {
+ uint32_t imask = arch_get_system_reg(thread_env, HEX_SREG_IMASK);
+ uint32_t intbitpos = (src >> 16) & 0xF;
+ uint32_t val = (src >> thread_env->threadId) & 0x1;
+ imask = deposit32(imask, intbitpos, 1, val);
+ arch_set_system_reg(thread_env, HEX_SREG_IMASK, imask);
+
+ qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld
+ ", new imask 0x%" PRIx32 "\n", __func__,
+ thread_env->threadId, imask);
+ }
+ }
+ hex_interrupt_update(env);
}
uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src)
{
- g_assert_not_reached();
+ uint32_t modectl;
+ uint32_t thread_enabled_mask;
+ uint32_t intbitpos;
+ uint32_t dest_reg;
+ CPUState *cpu;
+
+ BQL_LOCK_GUARD();
+ modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+ /* src fields are in same position as modectl, but mean different things */
+ intbitpos = GET_FIELD(MODECTL_W, src);
+ dest_reg = 0;
+ CPU_FOREACH(cpu) {
+ CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
+ uint32_t thread_id_mask = 0x1 << thread_env->threadId;
+ if (thread_enabled_mask & thread_id_mask) {
+ uint32_t imask = arch_get_system_reg(thread_env, HEX_SREG_IMASK);
+ dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId;
+ }
+ }
+
+ return dest_reg;
}
void HELPER(start)(CPUHexagonState *env, uint32_t imask)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 04/39] target/hexagon: Implement start/stop helpers
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (2 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 16:35 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 05/39] target/hexagon: Implement modify SSR Brian Cain
` (34 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 3 ++
target/hexagon/cpu_bits.h | 1 +
target/hexagon/cpu_helper.h | 3 ++
target/hexagon/cpu.c | 14 +++++-
target/hexagon/cpu_helper.c | 94 +++++++++++++++++++++++++++++++++++++
target/hexagon/op_helper.c | 4 +-
6 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 894219fd20..1549c4f1f0 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -41,6 +41,7 @@ typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
#define REG_WRITES_MAX 32
#define PRED_WRITES_MAX 5 /* 4 insns + endloop */
#define VSTORES_MAX 2
+#define VECTOR_UNIT_MAX 8
#ifndef CONFIG_USER_ONLY
#define CPU_INTERRUPT_SWI CPU_INTERRUPT_TGT_INT_0
@@ -178,6 +179,7 @@ struct ArchCPU {
#ifndef CONFIG_USER_ONLY
uint32_t num_tlbs;
uint32_t l2vic_base_addr;
+ uint32_t hvx_contexts;
#endif
};
@@ -194,6 +196,7 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg);
uint32_t hexagon_sreg_read(CPUHexagonState *env, uint32_t reg);
void hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t val);
+void hexagon_cpu_soft_reset(CPUHexagonState *env);
#endif
#include "exec/cpu-all.h"
diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h
index b559a7ba88..610094a759 100644
--- a/target/hexagon/cpu_bits.h
+++ b/target/hexagon/cpu_bits.h
@@ -52,6 +52,7 @@ enum hex_event {
enum hex_cause {
HEX_CAUSE_NONE = -1,
+ HEX_CAUSE_RESET = 0x000,
HEX_CAUSE_TRAP0 = 0x172,
HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
HEX_CAUSE_INVALID_PACKET = 0x015,
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index 6f0c6697ad..95a0cc0788 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -17,6 +17,9 @@ void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, uint32_t);
void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
int get_exe_mode(CPUHexagonState *env);
void clear_wait_mode(CPUHexagonState *env);
+void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause);
+void hexagon_start_threads(CPUHexagonState *env, uint32_t mask);
+void hexagon_stop_thread(CPUHexagonState *env);
static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
uint32_t val)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index cb56b929cf..84a96a194b 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -32,6 +32,7 @@
#ifndef CONFIG_USER_ONLY
#include "sys_macros.h"
+#include "qemu/main-loop.h"
#endif
static void hexagon_v66_cpu_init(Object *obj) { }
@@ -61,6 +62,7 @@ static const Property hexagon_cpu_properties[] = {
DEFINE_PROP_UINT32("jtlb-entries", HexagonCPU, num_tlbs, MAX_TLB_ENTRIES),
DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
0xffffffffULL),
+ DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
#endif
DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
@@ -295,9 +297,18 @@ static void mmu_reset(CPUHexagonState *env)
memset(env->hex_tlb, 0, sizeof(*env->hex_tlb));
}
}
+
+void hexagon_cpu_soft_reset(CPUHexagonState *env)
+{
+ BQL_LOCK_GUARD();
+ arch_set_system_reg(env, HEX_SREG_SSR, 0);
+ hexagon_ssr_set_cause(env, HEX_CAUSE_RESET);
+
+ target_ulong evb = arch_get_system_reg(env, HEX_SREG_EVB);
+ arch_set_thread_reg(env, HEX_REG_PC, evb);
+}
#endif
-
static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
{
CPUState *cs = CPU(obj);
@@ -327,6 +338,7 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
}
mmu_reset(env);
arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index);
+ hexagon_cpu_soft_reset(env);
memset(env->t_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
memset(env->greg, 0, sizeof(target_ulong) * NUM_GREGS);
env->threadId = cs->cpu_index;
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 9373e491d6..e151c6335a 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -84,8 +84,102 @@ void clear_wait_mode(CPUHexagonState *env)
SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W, thread_wait_mask);
}
+void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause)
+{
+ g_assert(bql_locked());
+
+ const uint32_t old = arch_get_system_reg(env, HEX_SREG_SSR);
+ SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_EX, 1);
+ SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_CAUSE, cause);
+ const uint32_t new = arch_get_system_reg(env, HEX_SREG_SSR);
+
+ hexagon_modify_ssr(env, new, old);
+}
+
+
int get_exe_mode(CPUHexagonState *env)
{
g_assert_not_reached();
}
+
+static void set_enable_mask(CPUHexagonState *env)
+{
+ g_assert(bql_locked());
+
+ const uint32_t modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+ thread_enabled_mask |= 0x1 << env->threadId;
+ SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_E, thread_enabled_mask);
+}
+
+static uint32_t clear_enable_mask(CPUHexagonState *env)
+{
+ g_assert(bql_locked());
+
+ const uint32_t modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+ thread_enabled_mask &= ~(0x1 << env->threadId);
+ SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_E, thread_enabled_mask);
+ return thread_enabled_mask;
+}
+static void do_start_thread(CPUState *cs, run_on_cpu_data tbd)
+{
+ BQL_LOCK_GUARD();
+
+ CPUHexagonState *env = cpu_env(cs);
+
+ hexagon_cpu_soft_reset(env);
+
+ set_enable_mask(env);
+
+ cs->halted = 0;
+ cs->exception_index = HEX_EVENT_NONE;
+ cpu_resume(cs);
+}
+
+void hexagon_start_threads(CPUHexagonState *current_env, uint32_t mask)
+{
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *env = cpu_env(cs);
+ if (!(mask & (0x1 << env->threadId))) {
+ continue;
+ }
+
+ if (current_env->threadId != env->threadId) {
+ async_safe_run_on_cpu(cs, do_start_thread, RUN_ON_CPU_NULL);
+ }
+ }
+}
+
+/*
+ * When we have all threads stopped, the return
+ * value to the shell is register 2 from thread 0.
+ */
+static target_ulong get_thread0_r2(void)
+{
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *thread = cpu_env(cs);
+ if (thread->threadId == 0) {
+ return thread->gpr[2];
+ }
+ }
+ g_assert_not_reached();
+}
+
+void hexagon_stop_thread(CPUHexagonState *env)
+
+{
+ BQL_LOCK_GUARD();
+
+ uint32_t thread_enabled_mask = clear_enable_mask(env);
+ CPUState *cs = env_cpu(env);
+ cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+ if (!thread_enabled_mask) {
+ /* All threads are stopped, exit */
+ exit(get_thread0_r2());
+ }
+}
+
#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index ded6c80d62..9f79b1a20c 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1448,12 +1448,12 @@ uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src)
void HELPER(start)(CPUHexagonState *env, uint32_t imask)
{
- g_assert_not_reached();
+ hexagon_start_threads(env, imask);
}
void HELPER(stop)(CPUHexagonState *env)
{
- g_assert_not_reached();
+ hexagon_stop_thread(env);
}
void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (3 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 04/39] target/hexagon: Implement start/stop helpers Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 17:37 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers Brian Cain
` (33 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
The per-vCPU System Status Register controls many modal behaviors of the
system architecture. When the SSR is updated, we trigger the necessary
effects for interrupts, privilege/MMU, and HVX context mapping.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu_helper.c | 100 +++++++++++++++++++++++++++++++++++-
1 file changed, 99 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index e151c6335a..3e2364a7b0 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -14,6 +14,8 @@
#else
#include "hw/boards.h"
#include "hw/hexagon/hexagon.h"
+#include "hex_interrupts.h"
+#include "hex_mmu.h"
#endif
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
@@ -69,9 +71,105 @@ void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
g_assert_not_reached();
}
+static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS];
+static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS];
+
+/*
+ * EXT_CONTEXTS
+ * SSR.XA 2 4 6 8
+ * 000 HVX Context 0 HVX Context 0 HVX Context 0 HVX Context 0
+ * 001 HVX Context 1 HVX Context 1 HVX Context 1 HVX Context 1
+ * 010 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 2
+ * 011 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 3
+ * 100 HVX Context 0 HVX Context 0 HVX Context 4 HVX Context 4
+ * 101 HVX Context 1 HVX Context 1 HVX Context 5 HVX Context 5
+ * 110 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 6
+ * 111 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 7
+ */
+static int parse_context_idx(CPUHexagonState *env, uint8_t XA)
+{
+ int ret;
+ HexagonCPU *cpu = env_archcpu(env);
+ if (cpu->hvx_contexts == 6 && XA >= 6) {
+ ret = XA - 6 + 2;
+ } else {
+ ret = XA % cpu->hvx_contexts;
+ }
+ g_assert(ret >= 0 && ret < VECTOR_UNIT_MAX);
+ return ret;
+}
+
+static void check_overcommitted_hvx(CPUHexagonState *env, uint32_t ssr)
+{
+ if (!GET_FIELD(SSR_XE, ssr)) {
+ return;
+ }
+
+ uint8_t XA = GET_SSR_FIELD(SSR_XA, ssr);
+
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *env_ = cpu_env(cs);
+ if (env_ == env) {
+ continue;
+ }
+ /* Check if another thread has the XE bit set and same XA */
+ uint32_t ssr_ = arch_get_system_reg(env_, HEX_SREG_SSR);
+ if (GET_SSR_FIELD(SSR_XE2, ssr_) && GET_FIELD(SSR_XA, ssr_) == XA) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "setting SSR.XA '%d' on thread %d but thread"
+ " %d has same extension active\n", XA, env->threadId,
+ env_->threadId);
+ }
+ }
+}
+
void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old)
{
- g_assert_not_reached();
+ g_assert(bql_locked());
+
+ bool old_EX = GET_SSR_FIELD(SSR_EX, old);
+ bool old_UM = GET_SSR_FIELD(SSR_UM, old);
+ bool old_GM = GET_SSR_FIELD(SSR_GM, old);
+ bool old_IE = GET_SSR_FIELD(SSR_IE, old);
+ uint8_t old_XA = GET_SSR_FIELD(SSR_XA, old);
+ bool new_EX = GET_SSR_FIELD(SSR_EX, new);
+ bool new_UM = GET_SSR_FIELD(SSR_UM, new);
+ bool new_GM = GET_SSR_FIELD(SSR_GM, new);
+ bool new_IE = GET_SSR_FIELD(SSR_IE, new);
+ uint8_t new_XA = GET_SSR_FIELD(SSR_XA, new);
+
+ if ((old_EX != new_EX) ||
+ (old_UM != new_UM) ||
+ (old_GM != new_GM)) {
+ hex_mmu_mode_change(env);
+ }
+
+ uint8_t old_asid = GET_SSR_FIELD(SSR_ASID, old);
+ uint8_t new_asid = GET_SSR_FIELD(SSR_ASID, new);
+ if (new_asid != old_asid) {
+ CPUState *cs = env_cpu(env);
+ tlb_flush(cs);
+ }
+
+ if (old_XA != new_XA) {
+ int old_unit = parse_context_idx(env, old_XA);
+ int new_unit = parse_context_idx(env, new_XA);
+
+ /* Ownership exchange */
+ memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
+ memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
+ memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
+ memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
+
+ check_overcommitted_hvx(env, new);
+ }
+
+ /* See if the interrupts have been enabled or we have exited EX mode */
+ if ((new_IE && !old_IE) ||
+ (!new_EX && old_EX)) {
+ hex_interrupt_update(env);
+ }
}
void clear_wait_mode(CPUHexagonState *env)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (4 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 05/39] target/hexagon: Implement modify SSR Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 17:44 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 07/39] target/hexagon: Implement wait helper Brian Cain
` (32 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 9f79b1a20c..83088cfaa3 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1468,12 +1468,39 @@ void HELPER(resume)(CPUHexagonState *env, uint32_t mask)
uint32_t HELPER(getimask)(CPUHexagonState *env, uint32_t tid)
{
- g_assert_not_reached();
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ HexagonCPU *found_cpu = HEXAGON_CPU(cs);
+ CPUHexagonState *found_env = &found_cpu->env;
+ if (found_env->threadId == tid) {
+ target_ulong imask = arch_get_system_reg(found_env, HEX_SREG_IMASK);
+ qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask = 0x%x\n",
+ __func__, env->threadId,
+ (unsigned)GET_FIELD(IMASK_MASK, imask));
+ return GET_FIELD(IMASK_MASK, imask);
+ }
+ }
+ return 0;
}
void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t imask)
{
- g_assert_not_reached();
+ CPUState *cs;
+
+ BQL_LOCK_GUARD();
+ CPU_FOREACH(cs) {
+ HexagonCPU *found_cpu = HEXAGON_CPU(cs);
+ CPUHexagonState *found_env = &found_cpu->env;
+
+ if (pred == found_env->threadId) {
+ SET_SYSTEM_FIELD(found_env, HEX_SREG_IMASK, IMASK_MASK, imask);
+ qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask 0x%x\n",
+ __func__, found_env->threadId, imask);
+ hex_interrupt_update(env);
+ return;
+ }
+ }
+ hex_interrupt_update(env);
}
static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 07/39] target/hexagon: Implement wait helper
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (5 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 18:37 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 08/39] target/hexagon: Implement get_exe_mode() Brian Cain
` (31 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu_helper.h | 1 +
target/hexagon/cpu_helper.c | 40 +++++++++++++++++++++++++++++++++++++
target/hexagon/op_helper.c | 6 +++++-
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index 95a0cc0788..e8d89d8526 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -20,6 +20,7 @@ void clear_wait_mode(CPUHexagonState *env);
void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause);
void hexagon_start_threads(CPUHexagonState *env, uint32_t mask);
void hexagon_stop_thread(CPUHexagonState *env);
+void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC);
static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
uint32_t val)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 3e2364a7b0..e64568b9fc 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -71,6 +71,46 @@ void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
g_assert_not_reached();
}
+static void set_wait_mode(CPUHexagonState *env)
+{
+ g_assert(bql_locked());
+
+ const uint32_t modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
+ thread_wait_mask |= 0x1 << env->threadId;
+ SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W, thread_wait_mask);
+}
+
+void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC)
+{
+ g_assert(bql_locked());
+
+ if (qemu_loglevel_mask(LOG_GUEST_ERROR) &&
+ (env->k0_lock_state != HEX_LOCK_UNLOCKED ||
+ env->tlb_lock_state != HEX_LOCK_UNLOCKED)) {
+ qemu_log("WARNING: executing wait() with acquired lock"
+ "may lead to deadlock\n");
+ }
+ g_assert(get_exe_mode(env) != HEX_EXE_MODE_WAIT);
+
+ CPUState *cs = env_cpu(env);
+ /*
+ * The addtion of cpu_has_work is borrowed from arm's wfi helper
+ * and is critical for our stability
+ */
+ if ((cs->exception_index != HEX_EVENT_NONE) ||
+ (cpu_has_work(cs))) {
+ qemu_log_mask(CPU_LOG_INT,
+ "%s: thread %d skipping WAIT mode, have some work\n",
+ __func__, env->threadId);
+ return;
+ }
+ set_wait_mode(env);
+ env->wait_next_pc = PC + 4;
+
+ cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+}
+
static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS];
static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS];
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 83088cfaa3..03bed11f6e 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1458,7 +1458,11 @@ void HELPER(stop)(CPUHexagonState *env)
void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
{
- g_assert_not_reached();
+ BQL_LOCK_GUARD();
+
+ if (!fIN_DEBUG_MODE(env->threadId)) {
+ hexagon_wait_thread(env, PC);
+ }
}
void HELPER(resume)(CPUHexagonState *env, uint32_t mask)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 08/39] target/hexagon: Implement get_exe_mode()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (6 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 07/39] target/hexagon: Implement wait helper Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 18:43 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 09/39] target/hexagon: Implement arch_get_system_reg() Brian Cain
` (30 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/reg_fields_def.h.inc | 11 +++++++++++
target/hexagon/cpu_helper.c | 24 ++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/target/hexagon/reg_fields_def.h.inc b/target/hexagon/reg_fields_def.h.inc
index 156a3514e7..50b8c26f8b 100644
--- a/target/hexagon/reg_fields_def.h.inc
+++ b/target/hexagon/reg_fields_def.h.inc
@@ -135,3 +135,14 @@ DEF_REG_FIELD(CCR_GRE, 27, 1)
DEF_REG_FIELD(CCR_VV1, 29, 1)
DEF_REG_FIELD(CCR_VV2, 30, 1)
DEF_REG_FIELD(CCR_VV3, 31, 1)
+
+/* ISDB ST fields */
+DEF_REG_FIELD(ISDBST_WAITRUN, 24, 8)
+DEF_REG_FIELD(ISDBST_ONOFF, 16, 8)
+DEF_REG_FIELD(ISDBST_DEBUGMODE, 8, 8)
+DEF_REG_FIELD(ISDBST_STUFFSTATUS, 5, 1)
+DEF_REG_FIELD(ISDBST_CMDSTATUS, 4, 1)
+DEF_REG_FIELD(ISDBST_PROCMODE, 3, 1)
+DEF_REG_FIELD(ISDBST_MBXINSTATUS, 2, 1)
+DEF_REG_FIELD(ISDBST_MBXOUTSTATUS, 1, 1)
+DEF_REG_FIELD(ISDBST_READY, 0, 1)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index e64568b9fc..e0dd120cd4 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -237,6 +237,30 @@ void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause)
int get_exe_mode(CPUHexagonState *env)
{
+ g_assert(bql_locked());
+
+ target_ulong modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+ bool E_bit = thread_enabled_mask & (0x1 << env->threadId);
+ uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
+ bool W_bit = thread_wait_mask & (0x1 << env->threadId);
+ target_ulong isdbst = arch_get_system_reg(env, HEX_SREG_ISDBST);
+ uint32_t debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst);
+ bool D_bit = debugmode & (0x1 << env->threadId);
+
+ /* Figure 4-2 */
+ if (!D_bit && !W_bit && !E_bit) {
+ return HEX_EXE_MODE_OFF;
+ }
+ if (!D_bit && !W_bit && E_bit) {
+ return HEX_EXE_MODE_RUN;
+ }
+ if (!D_bit && W_bit && E_bit) {
+ return HEX_EXE_MODE_WAIT;
+ }
+ if (D_bit && !W_bit && E_bit) {
+ return HEX_EXE_MODE_DEBUG;
+ }
g_assert_not_reached();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 09/39] target/hexagon: Implement arch_get_system_reg()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (7 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 08/39] target/hexagon: Implement get_exe_mode() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 18:46 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg() Brian Cain via
` (29 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu_helper.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index e0dd120cd4..0b0802bfb9 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -36,7 +36,14 @@ uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index)
uint32_t arch_get_system_reg(CPUHexagonState *env, uint32_t reg)
{
- g_assert_not_reached();
+ if (reg == HEX_SREG_PCYCLELO) {
+ return hexagon_get_sys_pcycle_count_low(env);
+ } else if (reg == HEX_SREG_PCYCLEHI) {
+ return hexagon_get_sys_pcycle_count_high(env);
+ }
+
+ g_assert(reg < NUM_SREGS);
+ return reg < HEX_SREG_GLB_START ? env->t_sreg[reg] : env->g_sreg[reg];
}
uint64_t hexagon_get_sys_pcycle_count(CPUHexagonState *env)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (8 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 09/39] target/hexagon: Implement arch_get_system_reg() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain via
2025-03-17 19:24 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 11/39] target/hexagon: Add representation to count cycles Brian Cain
` (28 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain via @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu_helper.h | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index e8d89d8526..1cdf4f8dd0 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -26,20 +26,27 @@ static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
uint32_t val)
{
g_assert(reg < TOTAL_PER_THREAD_REGS);
- g_assert_not_reached();
+ env->gpr[reg] = val;
}
static inline uint32_t arch_get_thread_reg(CPUHexagonState *env, uint32_t reg)
{
g_assert(reg < TOTAL_PER_THREAD_REGS);
- g_assert_not_reached();
+ return env->gpr[reg];
}
+#ifndef CONFIG_USER_ONLY
static inline void arch_set_system_reg(CPUHexagonState *env, uint32_t reg,
uint32_t val)
{
- g_assert_not_reached();
+ g_assert(reg < NUM_SREGS);
+ if (reg < HEX_SREG_GLB_START) {
+ env->t_sreg[reg] = val;
+ } else {
+ env->g_sreg[reg] = val;
+ }
}
+#endif
uint32_t arch_get_system_reg(CPUHexagonState *env, uint32_t reg);
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 11/39] target/hexagon: Add representation to count cycles
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (9 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg() Brian Cain via
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:33 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 12/39] target/hexagon: Add implementation of cycle counters Brian Cain
` (27 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
The PCYCLE register can be enabled to indicate accumulated clock cycles.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 3 ++-
target/hexagon/cpu.c | 3 +++
target/hexagon/machine.c | 25 ++++++++++++++++++++++++-
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 1549c4f1f0..4b9c9873dc 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -113,7 +113,8 @@ typedef struct CPUArchState {
target_ulong stack_start;
uint8_t slot_cancelled;
-
+ uint64_t t_cycle_count;
+ uint64_t *g_pcycle_base;
#ifndef CONFIG_USER_ONLY
/* Some system registers are per thread and some are global. */
target_ulong t_sreg[NUM_SREGS];
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 84a96a194b..89a051b41d 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -335,6 +335,7 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
if (cs->cpu_index == 0) {
arch_set_system_reg(env, HEX_SREG_MODECTL, 0x1);
+ *(env->g_pcycle_base) = 0;
}
mmu_reset(env);
arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index);
@@ -396,10 +397,12 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp)
#ifndef CONFIG_USER_ONLY
if (cs->cpu_index == 0) {
env->g_sreg = g_new0(target_ulong, NUM_SREGS);
+ env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
} else {
CPUState *cpu0 = qemu_get_cpu(0);
CPUHexagonState *env0 = cpu_env(cpu0);
env->g_sreg = env0->g_sreg;
+ env->g_pcycle_base = env0->g_pcycle_base;
}
#endif
diff --git a/target/hexagon/machine.c b/target/hexagon/machine.c
index fcdbacf9fd..4baa22d51f 100644
--- a/target/hexagon/machine.c
+++ b/target/hexagon/machine.c
@@ -9,6 +9,27 @@
#include "cpu.h"
#include "hex_mmu.h"
+static int get_u64_ptr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field)
+{
+ uint64_t *p = pv;
+ *p = qemu_get_be64(f);
+ return 0;
+}
+
+static int put_u64_ptr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ qemu_put_be64(f, *((uint64_t *)pv));
+ return 0;
+}
+
+const VMStateInfo vmstate_info_uint64_ptr = {
+ .name = "uint64_t_pointer",
+ .get = get_u64_ptr,
+ .put = put_u64_ptr,
+};
+
static int get_hex_tlb_ptr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
@@ -35,7 +56,6 @@ const VMStateInfo vmstate_info_hex_tlb_ptr = {
.put = put_hex_tlb_ptr,
};
-
const VMStateDescription vmstate_hexagon_cpu = {
.name = "cpu",
.version_id = 0,
@@ -56,6 +76,9 @@ const VMStateDescription vmstate_hexagon_cpu = {
VMSTATE_UINTTL(env.wait_next_pc, HexagonCPU),
VMSTATE_POINTER(env.hex_tlb, HexagonCPU, 0,
vmstate_info_hex_tlb_ptr, CPUHexagonTLBContext *),
+ VMSTATE_UINT64(env.t_cycle_count, HexagonCPU),
+ VMSTATE_POINTER(env.g_pcycle_base, HexagonCPU, 0,
+ vmstate_info_uint64_ptr, uint64_t *),
VMSTATE_END_OF_LIST()
},
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 12/39] target/hexagon: Add implementation of cycle counters
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (10 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 11/39] target/hexagon: Add representation to count cycles Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 19:50 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 13/39] target/hexagon: Implement modify_syscfg() Brian Cain
` (26 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Co-authored-by: Sid Manning <sidneym@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 25 ++++++++++++++++++++++---
target/hexagon/translate.h | 2 ++
target/hexagon/cpu_helper.c | 12 +++++++++---
target/hexagon/translate.c | 27 +++++++++++++++++++++++++++
4 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 4b9c9873dc..7e2ea838c5 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -27,11 +27,15 @@
#include "cpu-qom.h"
#include "exec/cpu-defs.h"
+#include "exec/cpu-common.h"
#include "hex_regs.h"
#include "mmvec/mmvec.h"
#include "hw/registerfields.h"
+#ifndef CONFIG_USER_ONLY
+#include "reg_fields.h"
typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
+#endif
#define NUM_PREGS 4
#define TOTAL_PER_THREAD_REGS 64
@@ -188,6 +192,7 @@ struct ArchCPU {
FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
+FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1)
G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
uint32_t exception,
@@ -201,6 +206,11 @@ void hexagon_cpu_soft_reset(CPUHexagonState *env);
#endif
#include "exec/cpu-all.h"
+
+#ifndef CONFIG_USER_ONLY
+#include "cpu_helper.h"
+#endif
+
static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags)
{
@@ -210,16 +220,27 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
if (*pc == env->gpr[HEX_REG_SA0]) {
hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
}
- *flags = hex_flags;
if (*pc & PCALIGN_MASK) {
hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0);
}
#ifndef CONFIG_USER_ONLY
+ target_ulong syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+
+ bool pcycle_enabled = extract32(syscfg,
+ reg_field_info[SYSCFG_PCYCLEEN].offset,
+ reg_field_info[SYSCFG_PCYCLEEN].width);
+
hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
cpu_mmu_index(env_cpu(env), false));
+
+ if (pcycle_enabled) {
+ hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, 1);
+ }
#else
+ hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, true);
hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX, MMU_USER_IDX);
#endif
+ *flags = hex_flags;
}
typedef HexagonCPU ArchCPU;
@@ -228,6 +249,4 @@ void hexagon_translate_init(void);
void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
-#include "exec/cpu-all.h"
-
#endif /* HEXAGON_CPU_H */
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 0eaa3db03e..9bc4b3ce8b 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -83,6 +83,8 @@ typedef struct DisasContext {
TCGv new_pred_value[NUM_PREGS];
TCGv branch_taken;
TCGv dczero_addr;
+ bool pcycle_enabled;
+ uint32_t num_cycles;
} DisasContext;
bool is_gather_store_insn(DisasContext *ctx);
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 0b0802bfb9..1d9b9f8bef 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -48,17 +48,23 @@ uint32_t arch_get_system_reg(CPUHexagonState *env, uint32_t reg)
uint64_t hexagon_get_sys_pcycle_count(CPUHexagonState *env)
{
- g_assert_not_reached();
+ uint64_t cycles = 0;
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *env_ = cpu_env(cs);
+ cycles += env_->t_cycle_count;
+ }
+ return *(env->g_pcycle_base) + cycles;
}
uint32_t hexagon_get_sys_pcycle_count_high(CPUHexagonState *env)
{
- g_assert_not_reached();
+ return hexagon_get_sys_pcycle_count(env) >> 32;
}
uint32_t hexagon_get_sys_pcycle_count_low(CPUHexagonState *env)
{
- g_assert_not_reached();
+ return extract64(hexagon_get_sys_pcycle_count(env), 0, 32);
}
void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env,
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9119e42ff7..060df6e5eb 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -57,6 +57,7 @@ TCGv_i64 hex_store_val64[STORES_MAX];
TCGv hex_llsc_addr;
TCGv hex_llsc_val;
TCGv_i64 hex_llsc_val_i64;
+TCGv_i64 hex_cycle_count;
TCGv hex_vstore_addr[VSTORES_MAX];
TCGv hex_vstore_size[VSTORES_MAX];
TCGv hex_vstore_pending[VSTORES_MAX];
@@ -125,6 +126,22 @@ static void gen_exception_raw(int excp)
gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
}
+#ifndef CONFIG_USER_ONLY
+static inline void gen_precise_exception(int excp, target_ulong PC)
+{
+ tcg_gen_movi_tl(hex_cause_code, excp);
+ gen_exception(HEX_EVENT_PRECISE, PC);
+}
+
+static inline void gen_pcycle_counters(DisasContext *ctx)
+{
+ if (ctx->pcycle_enabled) {
+ tcg_gen_addi_i64(hex_cycle_count, hex_cycle_count, ctx->num_cycles);
+ ctx->num_cycles = 0;
+ }
+}
+#endif
+
static void gen_exec_counters(DisasContext *ctx)
{
tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT],
@@ -133,6 +150,10 @@ static void gen_exec_counters(DisasContext *ctx)
hex_gpr[HEX_REG_QEMU_INSN_CNT], ctx->num_insns);
tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_HVX_CNT],
hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
+
+#ifndef CONFIG_USER_ONLY
+ gen_pcycle_counters(ctx);
+#endif
}
static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
@@ -785,6 +806,7 @@ static void gen_commit_hvx(DisasContext *ctx)
}
}
+static const int PCYCLES_PER_PACKET = 3;
static void update_exec_counters(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
@@ -804,6 +826,7 @@ static void update_exec_counters(DisasContext *ctx)
}
ctx->num_packets++;
+ ctx->num_cycles += PCYCLES_PER_PACKET;
ctx->num_insns += num_real_insns;
ctx->num_hvx_insns += num_hvx_insns;
}
@@ -946,11 +969,13 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
ctx->mem_idx = FIELD_EX32(hex_flags, TB_FLAGS, MMU_INDEX);
ctx->num_packets = 0;
+ ctx->num_cycles = 0;
ctx->num_insns = 0;
ctx->num_hvx_insns = 0;
ctx->branch_cond = TCG_COND_NEVER;
ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
ctx->short_circuit = hex_cpu->short_circuit;
+ ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS, PCYCLE_ENABLED);
}
static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
@@ -1077,6 +1102,8 @@ void hexagon_translate_init(void)
offsetof(CPUHexagonState, llsc_val), "llsc_val");
hex_llsc_val_i64 = tcg_global_mem_new_i64(tcg_env,
offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
+ hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
+ offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
for (i = 0; i < STORES_MAX; i++) {
snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
hex_store_addr[i] = tcg_global_mem_new(tcg_env,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 13/39] target/hexagon: Implement modify_syscfg()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (11 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 12/39] target/hexagon: Add implementation of cycle counters Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 21:12 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 14/39] target/hexagon: Add system event, cause codes Brian Cain
` (25 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 51 +++++++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 03bed11f6e..42805d0f1d 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1522,7 +1522,56 @@ static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
static void modify_syscfg(CPUHexagonState *env, uint32_t val)
{
- g_assert_not_reached();
+ g_assert(bql_locked());
+
+ uint32_t old;
+ uint32_t syscfg_read_only_mask = 0x80001c00;
+ uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+
+ /* clear read-only bits if they are set in the new value. */
+ val &= ~syscfg_read_only_mask;
+ /* if read-only are currently set in syscfg keep them set. */
+ val |= (syscfg & syscfg_read_only_mask);
+
+ uint32_t tmp = val;
+ old = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+ arch_set_system_reg(env, HEX_SREG_SYSCFG, tmp);
+
+ /* Check for change in MMU enable */
+ target_ulong old_mmu_enable = GET_SYSCFG_FIELD(SYSCFG_MMUEN, old);
+ uint8_t old_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, old);
+ uint8_t old_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, old);
+ target_ulong new_mmu_enable =
+ GET_SYSCFG_FIELD(SYSCFG_MMUEN, val);
+ if (new_mmu_enable && !old_mmu_enable) {
+ hex_mmu_on(env);
+ } else if (!new_mmu_enable && old_mmu_enable) {
+ hex_mmu_off(env);
+ }
+
+ /* Changing pcycle enable from 0 to 1 resets the counters */
+ uint8_t new_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, val);
+ CPUState *cs;
+ if (old_en == 0 && new_en == 1) {
+ CPU_FOREACH(cs) {
+ CPUHexagonState *_env = cpu_env(cs);
+ _env->t_cycle_count = 0;
+ }
+ }
+
+ /* See if global interrupts are turned on */
+ uint8_t new_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, val);
+ if (!old_gie && new_gie) {
+ qemu_log_mask(CPU_LOG_INT, "%s: global interrupts enabled\n", __func__);
+ hex_interrupt_update(env);
+ }
+
+ if (qemu_loglevel_mask(LOG_UNIMP)) {
+ int new_v2x = GET_SYSCFG_FIELD(SYSCFG_V2X, val);
+ if (!new_v2x) {
+ qemu_log("HVX: 64 byte vector length is unsupported\n");
+ }
+ }
}
static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 14/39] target/hexagon: Add system event, cause codes
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (12 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 13/39] target/hexagon: Implement modify_syscfg() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:40 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm() Brian Cain
` (24 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 10 ++++++-
target/hexagon/cpu_bits.h | 55 ++++++++++++++++++++++++++++-----------
2 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 7e2ea838c5..dabee310c5 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -67,6 +67,15 @@ typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
#define MMU_GUEST_IDX 1
#define MMU_KERNEL_IDX 2
+#define HEXAGON_CPU_IRQ_0 0
+#define HEXAGON_CPU_IRQ_1 1
+#define HEXAGON_CPU_IRQ_2 2
+#define HEXAGON_CPU_IRQ_3 3
+#define HEXAGON_CPU_IRQ_4 4
+#define HEXAGON_CPU_IRQ_5 5
+#define HEXAGON_CPU_IRQ_6 6
+#define HEXAGON_CPU_IRQ_7 7
+
typedef enum {
HEX_LOCK_UNLOCKED = 0,
HEX_LOCK_WAITING = 1,
@@ -75,7 +84,6 @@ typedef enum {
} hex_lock_state_t;
#endif
-
#define CPU_RESOLVING_TYPE TYPE_HEXAGON_CPU
typedef struct {
diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h
index 610094a759..c7cc426ec8 100644
--- a/target/hexagon/cpu_bits.h
+++ b/target/hexagon/cpu_bits.h
@@ -24,14 +24,16 @@
#define PCALIGN_MASK (PCALIGN - 1)
enum hex_event {
- HEX_EVENT_NONE = -1,
- HEX_EVENT_TRAP0 = 0x008,
- HEX_EVENT_FETCH_NO_UPAGE = 0x012,
- HEX_EVENT_INVALID_PACKET = 0x015,
- HEX_EVENT_INVALID_OPCODE = 0x015,
- HEX_EVENT_PC_NOT_ALIGNED = 0x01e,
- HEX_EVENT_PRIV_NO_UREAD = 0x024,
- HEX_EVENT_PRIV_NO_UWRITE = 0x025,
+ HEX_EVENT_NONE = -1,
+ HEX_EVENT_RESET = 0x0,
+ HEX_EVENT_IMPRECISE = 0x1,
+ HEX_EVENT_PRECISE = 0x2,
+ HEX_EVENT_TLB_MISS_X = 0x4,
+ HEX_EVENT_TLB_MISS_RW = 0x6,
+ HEX_EVENT_TRAP0 = 0x8,
+ HEX_EVENT_TRAP1 = 0x9,
+ HEX_EVENT_FPTRAP = 0xb,
+ HEX_EVENT_DEBUG = 0xc,
HEX_EVENT_INT0 = 0x10,
HEX_EVENT_INT1 = 0x11,
HEX_EVENT_INT2 = 0x12,
@@ -53,15 +55,38 @@ enum hex_event {
enum hex_cause {
HEX_CAUSE_NONE = -1,
HEX_CAUSE_RESET = 0x000,
- HEX_CAUSE_TRAP0 = 0x172,
- HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
- HEX_CAUSE_INVALID_PACKET = 0x015,
- HEX_CAUSE_INVALID_OPCODE = 0x015,
- HEX_CAUSE_PC_NOT_ALIGNED = 0x01e,
- HEX_CAUSE_PRIV_NO_UREAD = 0x024,
- HEX_CAUSE_PRIV_NO_UWRITE = 0x025,
+ HEX_CAUSE_BIU_PRECISE = 0x001,
+ HEX_CAUSE_UNSUPORTED_HVX_64B = 0x002, /* QEMU-specific */
+ HEX_CAUSE_DOUBLE_EXCEPT = 0x003,
+ HEX_CAUSE_TRAP0 = 0x008,
+ HEX_CAUSE_TRAP1 = 0x009,
+ HEX_CAUSE_FETCH_NO_XPAGE = 0x011,
+ HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
+ HEX_CAUSE_INVALID_PACKET = 0x015,
+ HEX_CAUSE_INVALID_OPCODE = 0x015,
+ HEX_CAUSE_NO_COPROC_ENABLE = 0x016,
+ HEX_CAUSE_NO_COPROC2_ENABLE = 0x018,
HEX_CAUSE_PRIV_USER_NO_GINSN = 0x01a,
HEX_CAUSE_PRIV_USER_NO_SINSN = 0x01b,
+ HEX_CAUSE_REG_WRITE_CONFLICT = 0x01d,
+ HEX_CAUSE_PC_NOT_ALIGNED = 0x01e,
+ HEX_CAUSE_MISALIGNED_LOAD = 0x020,
+ HEX_CAUSE_MISALIGNED_STORE = 0x021,
+ HEX_CAUSE_PRIV_NO_READ = 0x022,
+ HEX_CAUSE_PRIV_NO_WRITE = 0x023,
+ HEX_CAUSE_PRIV_NO_UREAD = 0x024,
+ HEX_CAUSE_PRIV_NO_UWRITE = 0x025,
+ HEX_CAUSE_COPROC_LDST = 0x026,
+ HEX_CAUSE_STACK_LIMIT = 0x027,
+ HEX_CAUSE_VWCTRL_WINDOW_MISS = 0x029,
+ HEX_CAUSE_IMPRECISE_NMI = 0x043,
+ HEX_CAUSE_IMPRECISE_MULTI_TLB_MATCH = 0x044,
+ HEX_CAUSE_TLBMISSX_CAUSE_NORMAL = 0x060,
+ HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE = 0x061,
+ HEX_CAUSE_TLBMISSRW_CAUSE_READ = 0x070,
+ HEX_CAUSE_TLBMISSRW_CAUSE_WRITE = 0x071,
+ HEX_CAUSE_DEBUG_SINGLESTEP = 0x80,
+ HEX_CAUSE_FPTRAP_CAUSE_BADFLOAT = 0x0bf,
HEX_CAUSE_INT0 = 0x0c0,
HEX_CAUSE_INT1 = 0x0c1,
HEX_CAUSE_INT2 = 0x0c2,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (13 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 14/39] target/hexagon: Add system event, cause codes Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:37 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid() Brian Cain
` (23 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/hex_mmu.c | 54 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index 54c4ba2dbf..d2297c036d 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -267,7 +267,59 @@ static inline void hex_tlb_entry_get_perm(CPUHexagonState *env, uint64_t entry,
int mmu_idx, int *prot,
int32_t *excp)
{
- g_assert_not_reached();
+ bool perm_x = GET_TLB_FIELD(entry, PTE_X);
+ bool perm_w = GET_TLB_FIELD(entry, PTE_W);
+ bool perm_r = GET_TLB_FIELD(entry, PTE_R);
+ bool perm_u = GET_TLB_FIELD(entry, PTE_U);
+ bool user_idx = mmu_idx == MMU_USER_IDX;
+
+ if (mmu_idx == MMU_KERNEL_IDX) {
+ *prot = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return;
+ }
+
+ *prot = PAGE_VALID;
+ switch (access_type) {
+ case MMU_INST_FETCH:
+ if (user_idx && !perm_u) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_FETCH_NO_UPAGE;
+ } else if (!perm_x) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_FETCH_NO_XPAGE;
+ }
+ break;
+ case MMU_DATA_LOAD:
+ if (user_idx && !perm_u) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_PRIV_NO_UREAD;
+ } else if (!perm_r) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_PRIV_NO_READ;
+ }
+ break;
+ case MMU_DATA_STORE:
+ if (user_idx && !perm_u) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_PRIV_NO_UWRITE;
+ } else if (!perm_w) {
+ *excp = HEX_EVENT_PRECISE;
+ env->cause_code = HEX_CAUSE_PRIV_NO_WRITE;
+ }
+ break;
+ }
+
+ if (!user_idx || perm_u) {
+ if (perm_x) {
+ *prot |= PAGE_EXEC;
+ }
+ if (perm_r) {
+ *prot |= PAGE_READ;
+ }
+ if (perm_w) {
+ *prot |= PAGE_WRITE;
+ }
+ }
}
static inline bool hex_tlb_entry_match(CPUHexagonState *env, uint64_t entry,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (14 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:42 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 17/39] target/hexagon: Implement software interrupt Brian Cain
` (22 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/hex_mmu.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index d2297c036d..07ad8e9616 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -362,7 +362,31 @@ bool hex_tlb_find_match(CPUHexagonState *env, target_ulong VA,
static uint32_t hex_tlb_lookup_by_asid(CPUHexagonState *env, uint32_t asid,
uint32_t VA)
{
- g_assert_not_reached();
+ uint32_t not_found = 0x80000000;
+ uint32_t idx = not_found;
+ int i;
+
+ HexagonCPU *cpu = env_archcpu(env);
+ for (i = 0; i < cpu->num_tlbs; i++) {
+ uint64_t entry = env->hex_tlb->entries[i];
+ if (hex_tlb_entry_match_noperm(entry, asid, VA)) {
+ if (idx != not_found) {
+ env->cause_code = HEX_CAUSE_IMPRECISE_MULTI_TLB_MATCH;
+ break;
+ }
+ idx = i;
+ }
+ }
+
+ if (idx == not_found) {
+ qemu_log_mask(CPU_LOG_MMU, "%s: 0x%x, 0x%08x => NOT FOUND\n",
+ __func__, asid, VA);
+ } else {
+ qemu_log_mask(CPU_LOG_MMU, "%s: 0x%x, 0x%08x => %d\n",
+ __func__, asid, VA, idx);
+ }
+
+ return idx;
}
/* Called from tlbp instruction */
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 17/39] target/hexagon: Implement software interrupt
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (15 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 21:28 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq Brian Cain
` (21 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain, Mike Lambert
From: Brian Cain <bcain@quicinc.com>
Co-authored-by: Mike Lambert <mlambert@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 1 -
target/hexagon/hexswi.h | 17 +++
target/hexagon/cpu.c | 2 +
target/hexagon/hexswi.c | 258 +++++++++++++++++++++++++++++++++++++
target/hexagon/op_helper.c | 1 +
5 files changed, 278 insertions(+), 1 deletion(-)
create mode 100644 target/hexagon/hexswi.h
create mode 100644 target/hexagon/hexswi.c
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index dabee310c5..045581d7be 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -256,5 +256,4 @@ typedef HexagonCPU ArchCPU;
void hexagon_translate_init(void);
void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
int *max_insns, vaddr pc, void *host_pc);
-
#endif /* HEXAGON_CPU_H */
diff --git a/target/hexagon/hexswi.h b/target/hexagon/hexswi.h
new file mode 100644
index 0000000000..5d232cb06c
--- /dev/null
+++ b/target/hexagon/hexswi.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright(c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HEXSWI_H
+#define HEXSWI_H
+
+
+#include "cpu.h"
+
+void hexagon_cpu_do_interrupt(CPUState *cpu);
+void register_trap_exception(CPUHexagonState *env, int type, int imm,
+ target_ulong PC);
+
+#endif /* HEXSWI_H */
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 89a051b41d..843be8221f 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -33,6 +33,8 @@
#ifndef CONFIG_USER_ONLY
#include "sys_macros.h"
#include "qemu/main-loop.h"
+#include "hex_interrupts.h"
+#include "hexswi.h"
#endif
static void hexagon_v66_cpu_init(Object *obj) { }
diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c
new file mode 100644
index 0000000000..5fcf9b2be9
--- /dev/null
+++ b/target/hexagon/hexswi.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright(c) 2019-2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#ifdef CONFIG_USER_ONLY
+#include "exec/helper-proto.h"
+#include "qemu.h"
+#endif
+#include "exec/cpu_ldst.h"
+#include "exec/exec-all.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "arch.h"
+#include "internal.h"
+#include "macros.h"
+#include "sys_macros.h"
+#include "tcg/tcg-op.h"
+#ifndef CONFIG_USER_ONLY
+#include "hex_mmu.h"
+#include "hexswi.h"
+#endif
+
+#ifndef CONFIG_USER_ONLY
+
+
+static void set_addresses(CPUHexagonState *env, target_ulong pc_offset,
+ target_ulong exception_index)
+
+{
+ arch_set_system_reg(env, HEX_SREG_ELR,
+ arch_get_thread_reg(env, HEX_REG_PC) + pc_offset);
+ arch_set_thread_reg(env, HEX_REG_PC,
+ arch_get_system_reg(env, HEX_SREG_EVB) |
+ (exception_index << 2));
+}
+
+static const char *event_name[] = {
+ [HEX_EVENT_RESET] = "HEX_EVENT_RESET",
+ [HEX_EVENT_IMPRECISE] = "HEX_EVENT_IMPRECISE",
+ [HEX_EVENT_TLB_MISS_X] = "HEX_EVENT_TLB_MISS_X",
+ [HEX_EVENT_TLB_MISS_RW] = "HEX_EVENT_TLB_MISS_RW",
+ [HEX_EVENT_TRAP0] = "HEX_EVENT_TRAP0",
+ [HEX_EVENT_TRAP1] = "HEX_EVENT_TRAP1",
+ [HEX_EVENT_FPTRAP] = "HEX_EVENT_FPTRAP",
+ [HEX_EVENT_DEBUG] = "HEX_EVENT_DEBUG",
+ [HEX_EVENT_INT0] = "HEX_EVENT_INT0",
+ [HEX_EVENT_INT1] = "HEX_EVENT_INT1",
+ [HEX_EVENT_INT2] = "HEX_EVENT_INT2",
+ [HEX_EVENT_INT3] = "HEX_EVENT_INT3",
+ [HEX_EVENT_INT4] = "HEX_EVENT_INT4",
+ [HEX_EVENT_INT5] = "HEX_EVENT_INT5",
+ [HEX_EVENT_INT6] = "HEX_EVENT_INT6",
+ [HEX_EVENT_INT7] = "HEX_EVENT_INT7",
+ [HEX_EVENT_INT8] = "HEX_EVENT_INT8",
+ [HEX_EVENT_INT9] = "HEX_EVENT_INT9",
+ [HEX_EVENT_INTA] = "HEX_EVENT_INTA",
+ [HEX_EVENT_INTB] = "HEX_EVENT_INTB",
+ [HEX_EVENT_INTC] = "HEX_EVENT_INTC",
+ [HEX_EVENT_INTD] = "HEX_EVENT_INTD",
+ [HEX_EVENT_INTE] = "HEX_EVENT_INTE",
+ [HEX_EVENT_INTF] = "HEX_EVENT_INTF"
+};
+
+void hexagon_cpu_do_interrupt(CPUState *cs)
+
+{
+ CPUHexagonState *env = cpu_env(cs);
+ BQL_LOCK_GUARD();
+
+ qemu_log_mask(CPU_LOG_INT, "\t%s: event 0x%x:%s, cause 0x%x(%d)\n",
+ __func__, cs->exception_index,
+ event_name[cs->exception_index], env->cause_code,
+ env->cause_code);
+
+ env->llsc_addr = ~0;
+
+ uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+ if (GET_SSR_FIELD(SSR_EX, ssr) == 1) {
+ arch_set_system_reg(env, HEX_SREG_DIAG, env->cause_code);
+ env->cause_code = HEX_CAUSE_DOUBLE_EXCEPT;
+ cs->exception_index = HEX_EVENT_PRECISE;
+ }
+
+ switch (cs->exception_index) {
+ case HEX_EVENT_TRAP0:
+ if (env->cause_code == 0) {
+ qemu_log_mask(LOG_UNIMP,
+ "trap0 is unhandled, no semihosting available\n");
+ }
+
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 4, cs->exception_index);
+ break;
+
+ case HEX_EVENT_TRAP1:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 4, cs->exception_index);
+ break;
+
+ case HEX_EVENT_TLB_MISS_X:
+ switch (env->cause_code) {
+ case HEX_CAUSE_TLBMISSX_CAUSE_NORMAL:
+ case HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE:
+ qemu_log_mask(CPU_LOG_MMU,
+ "TLB miss EX exception (0x%x) caught: "
+ "Cause code (0x%x) "
+ "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
+ ", BADVA = 0x%" PRIx32 "\n",
+ cs->exception_index, env->cause_code, env->threadId,
+ arch_get_thread_reg(env, HEX_REG_PC),
+ arch_get_system_reg(env, HEX_SREG_BADVA));
+
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ break;
+
+ default:
+ cpu_abort(cs,
+ "1:Hexagon exception %d/0x%x: "
+ "Unknown cause code %d/0x%x\n",
+ cs->exception_index, cs->exception_index, env->cause_code,
+ env->cause_code);
+ break;
+ }
+ break;
+
+ case HEX_EVENT_TLB_MISS_RW:
+ switch (env->cause_code) {
+ case HEX_CAUSE_TLBMISSRW_CAUSE_READ:
+ case HEX_CAUSE_TLBMISSRW_CAUSE_WRITE:
+ qemu_log_mask(CPU_LOG_MMU,
+ "TLB miss RW exception (0x%x) caught: "
+ "Cause code (0x%x) "
+ "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
+ ", BADVA = 0x%" PRIx32 "\n",
+ cs->exception_index, env->cause_code, env->threadId,
+ env->gpr[HEX_REG_PC],
+ arch_get_system_reg(env, HEX_SREG_BADVA));
+
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised */
+ break;
+
+ default:
+ cpu_abort(cs,
+ "2:Hexagon exception %d/0x%x: "
+ "Unknown cause code %d/0x%x\n",
+ cs->exception_index, cs->exception_index, env->cause_code,
+ env->cause_code);
+ break;
+ }
+ break;
+
+ case HEX_EVENT_FPTRAP:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ arch_set_thread_reg(env, HEX_REG_PC,
+ arch_get_system_reg(env, HEX_SREG_EVB) |
+ (cs->exception_index << 2));
+ break;
+
+ case HEX_EVENT_DEBUG:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ qemu_log_mask(LOG_UNIMP, "single-step exception is not handled\n");
+ break;
+
+ case HEX_EVENT_PRECISE:
+ switch (env->cause_code) {
+ case HEX_CAUSE_FETCH_NO_XPAGE:
+ case HEX_CAUSE_FETCH_NO_UPAGE:
+ case HEX_CAUSE_PRIV_NO_READ:
+ case HEX_CAUSE_PRIV_NO_UREAD:
+ case HEX_CAUSE_PRIV_NO_WRITE:
+ case HEX_CAUSE_PRIV_NO_UWRITE:
+ case HEX_CAUSE_MISALIGNED_LOAD:
+ case HEX_CAUSE_MISALIGNED_STORE:
+ case HEX_CAUSE_PC_NOT_ALIGNED:
+ qemu_log_mask(CPU_LOG_MMU,
+ "MMU permission exception (0x%x) caught: "
+ "Cause code (0x%x) "
+ "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
+ ", BADVA = 0x%" PRIx32 "\n",
+ cs->exception_index, env->cause_code, env->threadId,
+ env->gpr[HEX_REG_PC],
+ arch_get_system_reg(env, HEX_SREG_BADVA));
+
+
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised */
+ break;
+
+ case HEX_CAUSE_DOUBLE_EXCEPT:
+ case HEX_CAUSE_PRIV_USER_NO_SINSN:
+ case HEX_CAUSE_PRIV_USER_NO_GINSN:
+ case HEX_CAUSE_INVALID_OPCODE:
+ case HEX_CAUSE_NO_COPROC_ENABLE:
+ case HEX_CAUSE_NO_COPROC2_ENABLE:
+ case HEX_CAUSE_UNSUPORTED_HVX_64B:
+ case HEX_CAUSE_REG_WRITE_CONFLICT:
+ case HEX_CAUSE_VWCTRL_WINDOW_MISS:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ break;
+
+ case HEX_CAUSE_COPROC_LDST:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ break;
+
+ case HEX_CAUSE_STACK_LIMIT:
+ hexagon_ssr_set_cause(env, env->cause_code);
+ set_addresses(env, 0, cs->exception_index);
+ break;
+
+ default:
+ cpu_abort(cs,
+ "3:Hexagon exception %d/0x%x: "
+ "Unknown cause code %d/0x%x\n",
+ cs->exception_index, cs->exception_index, env->cause_code,
+ env->cause_code);
+ break;
+ }
+ break;
+
+ case HEX_EVENT_IMPRECISE:
+ qemu_log_mask(LOG_UNIMP,
+ "Imprecise exception: this case is not yet handled");
+ break;
+
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "Hexagon Unsupported exception 0x%x/0x%x\n",
+ cs->exception_index, env->cause_code);
+ break;
+ }
+
+ cs->exception_index = HEX_EVENT_NONE;
+}
+
+void register_trap_exception(CPUHexagonState *env, int traptype, int imm,
+ target_ulong PC)
+{
+ CPUState *cs = env_cpu(env);
+
+ cs->exception_index = (traptype == 0) ? HEX_EVENT_TRAP0 : HEX_EVENT_TRAP1;
+ ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
+
+ env->cause_code = imm;
+ env->gpr[HEX_REG_PC] = PC;
+ cpu_loop_exit(cs);
+}
+#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 42805d0f1d..687e7f45c2 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -38,6 +38,7 @@
#include "hex_mmu.h"
#include "hw/intc/l2vic.h"
#include "hex_interrupts.h"
+#include "hexswi.h"
#endif
#define SF_BIAS 127
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (16 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 17/39] target/hexagon: Implement software interrupt Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 21:33 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill() Brian Cain
` (20 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 5 +++
target/hexagon/cpu.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 045581d7be..d28c1249f3 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -207,6 +207,11 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
uintptr_t pc);
#ifndef CONFIG_USER_ONLY
+/*
+ * @return true if the @a thread_env hardware thread is
+ * not stopped.
+ */
+bool hexagon_thread_is_enabled(CPUHexagonState *thread_env);
uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg);
uint32_t hexagon_sreg_read(CPUHexagonState *env, uint32_t reg);
void hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t val);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 843be8221f..e9f24581a6 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -31,6 +31,7 @@
#include "hex_mmu.h"
#ifndef CONFIG_USER_ONLY
+#include "macros.h"
#include "sys_macros.h"
#include "qemu/main-loop.h"
#include "hex_interrupts.h"
@@ -278,9 +279,28 @@ static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
cpu_env(cs)->gpr[HEX_REG_PC] = tb->pc;
}
+#ifndef CONFIG_USER_ONLY
+bool hexagon_thread_is_enabled(CPUHexagonState *env)
+{
+ target_ulong modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+ uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+ bool E_bit = thread_enabled_mask & (0x1 << env->threadId);
+
+ return E_bit;
+}
+#endif
+
static bool hexagon_cpu_has_work(CPUState *cs)
{
+#ifndef CONFIG_USER_ONLY
+ CPUHexagonState *env = cpu_env(cs);
+
+ return hexagon_thread_is_enabled(env) &&
+ (cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_SWI
+ | CPU_INTERRUPT_K0_UNLOCK | CPU_INTERRUPT_TLB_UNLOCK));
+#else
return true;
+#endif
}
static void hexagon_restore_state_to_opc(CPUState *cs,
@@ -411,19 +431,72 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp)
mcc->parent_realize(dev, errp);
}
+#if !defined(CONFIG_USER_ONLY)
+static void hexagon_cpu_set_irq(void *opaque, int irq, int level)
+{
+ HexagonCPU *cpu = HEXAGON_CPU(opaque);
+ CPUState *cs = CPU(cpu);
+ CPUHexagonState *env = cpu_env(cs);
+
+ switch (irq) {
+ case HEXAGON_CPU_IRQ_0 ... HEXAGON_CPU_IRQ_7:
+ qemu_log_mask(CPU_LOG_INT, "%s: irq %d, level %d\n",
+ __func__, irq, level);
+ if (level) {
+ hex_raise_interrupts(env, 1 << irq, CPU_INTERRUPT_HARD);
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+#endif
+
+
static void hexagon_cpu_init(Object *obj)
{
+#if !defined(CONFIG_USER_ONLY)
+ HexagonCPU *cpu = HEXAGON_CPU(obj);
+ qdev_init_gpio_in(DEVICE(cpu), hexagon_cpu_set_irq, 8);
+#endif
}
#include "hw/core/tcg-cpu-ops.h"
+#ifndef CONFIG_USER_ONLY
+
+static bool hexagon_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+ CPUHexagonState *env = cpu_env(cs);
+ if (interrupt_request & CPU_INTERRUPT_TLB_UNLOCK) {
+ cs->halted = false;
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_TLB_UNLOCK);
+ return true;
+ }
+ if (interrupt_request & CPU_INTERRUPT_K0_UNLOCK) {
+ cs->halted = false;
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_K0_UNLOCK);
+ return true;
+ }
+ if (interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_SWI)) {
+ return hex_check_interrupts(env);
+ }
+ return false;
+}
+
+#endif
+
static const TCGCPUOps hexagon_tcg_ops = {
.initialize = hexagon_translate_init,
.translate_code = hexagon_translate_code,
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
.restore_state_to_opc = hexagon_restore_state_to_opc,
+#if !defined(CONFIG_USER_ONLY)
+ .cpu_exec_interrupt = hexagon_cpu_exec_interrupt,
+#endif /* !CONFIG_USER_ONLY */
};
+
static void hexagon_cpu_class_init(ObjectClass *c, void *data)
{
HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c);
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (17 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:55 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 20/39] target/hexagon: Implement siad inst Brian Cain
` (19 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.c | 133 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 132 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index e9f24581a6..a548d575a7 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -463,7 +463,137 @@ static void hexagon_cpu_init(Object *obj)
#include "hw/core/tcg-cpu-ops.h"
-#ifndef CONFIG_USER_ONLY
+#if !defined(CONFIG_USER_ONLY)
+static bool get_physical_address(CPUHexagonState *env, hwaddr *phys, int *prot,
+ int *size, int32_t *excp, target_ulong address,
+ MMUAccessType access_type, int mmu_idx)
+
+{
+ if (hexagon_cpu_mmu_enabled(env)) {
+ return hex_tlb_find_match(env, address, access_type, phys, prot, size,
+ excp, mmu_idx);
+ } else {
+ *phys = address & 0xFFFFFFFF;
+ *prot = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ *size = TARGET_PAGE_SIZE;
+ return true;
+ }
+}
+
+/* qemu seems to only want to know about TARGET_PAGE_SIZE pages */
+static void find_qemu_subpage(vaddr *addr, hwaddr *phys, int page_size)
+{
+ vaddr page_start = *addr & ~((vaddr)(page_size - 1));
+ vaddr offset = ((*addr - page_start) / TARGET_PAGE_SIZE) * TARGET_PAGE_SIZE;
+ *addr = page_start + offset;
+ *phys += offset;
+}
+
+
+#define INVALID_BADVA 0xbadabada
+
+static void set_badva_regs(CPUHexagonState *env, target_ulong VA, int slot,
+ MMUAccessType access_type)
+{
+ arch_set_system_reg(env, HEX_SREG_BADVA, VA);
+
+ if (access_type == MMU_INST_FETCH || slot == 0) {
+ arch_set_system_reg(env, HEX_SREG_BADVA0, VA);
+ arch_set_system_reg(env, HEX_SREG_BADVA1, INVALID_BADVA);
+ SET_SSR_FIELD(env, SSR_V0, 1);
+ SET_SSR_FIELD(env, SSR_V1, 0);
+ SET_SSR_FIELD(env, SSR_BVS, 0);
+ } else if (slot == 1) {
+ arch_set_system_reg(env, HEX_SREG_BADVA0, INVALID_BADVA);
+ arch_set_system_reg(env, HEX_SREG_BADVA1, VA);
+ SET_SSR_FIELD(env, SSR_V0, 0);
+ SET_SSR_FIELD(env, SSR_V1, 1);
+ SET_SSR_FIELD(env, SSR_BVS, 1);
+ } else {
+ g_assert_not_reached();
+ }
+}
+
+static void raise_tlbmiss_exception(CPUState *cs, target_ulong VA, int slot,
+ MMUAccessType access_type)
+{
+ CPUHexagonState *env = cpu_env(cs);
+
+ set_badva_regs(env, VA, slot, access_type);
+
+ switch (access_type) {
+ case MMU_INST_FETCH:
+ cs->exception_index = HEX_EVENT_TLB_MISS_X;
+ if ((VA & ~TARGET_PAGE_MASK) == 0) {
+ env->cause_code = HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE;
+ } else {
+ env->cause_code = HEX_CAUSE_TLBMISSX_CAUSE_NORMAL;
+ }
+ break;
+ case MMU_DATA_LOAD:
+ cs->exception_index = HEX_EVENT_TLB_MISS_RW;
+ env->cause_code = HEX_CAUSE_TLBMISSRW_CAUSE_READ;
+ break;
+ case MMU_DATA_STORE:
+ cs->exception_index = HEX_EVENT_TLB_MISS_RW;
+ env->cause_code = HEX_CAUSE_TLBMISSRW_CAUSE_WRITE;
+ break;
+ }
+}
+
+static void raise_perm_exception(CPUState *cs, target_ulong VA, int slot,
+ MMUAccessType access_type, int32_t excp)
+{
+ CPUHexagonState *env = cpu_env(cs);
+
+ set_badva_regs(env, VA, slot, access_type);
+ cs->exception_index = excp;
+}
+
+static const char *access_type_names[] = { "MMU_DATA_LOAD ", "MMU_DATA_STORE",
+ "MMU_INST_FETCH" };
+
+static const char *mmu_idx_names[] = { "MMU_USER_IDX", "MMU_GUEST_IDX",
+ "MMU_KERNEL_IDX" };
+
+static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx, bool probe,
+ uintptr_t retaddr)
+{
+ CPUHexagonState *env = cpu_env(cs);
+ static int slot = 0 /* This is always zero for now */;
+ hwaddr phys;
+ int prot = 0;
+ int page_size = 0;
+ int32_t excp = 0;
+ bool ret = 0;
+
+ qemu_log_mask(
+ CPU_LOG_MMU,
+ "%s: tid = 0x%x, pc = 0x%08" PRIx32 ", vaddr = 0x%08" VADDR_PRIx
+ ", size = %d, %s,\tprobe = %d, %s\n",
+ __func__, env->threadId, env->gpr[HEX_REG_PC], address, size,
+ access_type_names[access_type], probe, mmu_idx_names[mmu_idx]);
+ ret = get_physical_address(env, &phys, &prot, &page_size, &excp, address,
+ access_type, mmu_idx);
+ if (ret) {
+ if (!excp) {
+ find_qemu_subpage(&address, &phys, page_size);
+ tlb_set_page(cs, address, phys, prot, mmu_idx, TARGET_PAGE_SIZE);
+ return ret;
+ } else {
+ raise_perm_exception(cs, address, slot, access_type, excp);
+ do_raise_exception(env, cs->exception_index, env->gpr[HEX_REG_PC],
+ retaddr);
+ }
+ }
+ if (probe) {
+ return false;
+ }
+ raise_tlbmiss_exception(cs, address, slot, access_type);
+ do_raise_exception(env, cs->exception_index, env->gpr[HEX_REG_PC], retaddr);
+}
+
static bool hexagon_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
@@ -493,6 +623,7 @@ static const TCGCPUOps hexagon_tcg_ops = {
.restore_state_to_opc = hexagon_restore_state_to_opc,
#if !defined(CONFIG_USER_ONLY)
.cpu_exec_interrupt = hexagon_cpu_exec_interrupt,
+ .tlb_fill = hexagon_tlb_fill,
#endif /* !CONFIG_USER_ONLY */
};
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 20/39] target/hexagon: Implement siad inst
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (18 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 19:57 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads() Brian Cain
` (18 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
siad is the 'Set interrupt auto disable' instruction.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 687e7f45c2..118f112487 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1378,7 +1378,15 @@ void HELPER(ciad)(CPUHexagonState *env, uint32_t mask)
void HELPER(siad)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ uint32_t ipendad;
+ uint32_t iad;
+
+ BQL_LOCK_GUARD();
+ ipendad = READ_SREG(HEX_SREG_IPENDAD);
+ iad = fGET_FIELD(ipendad, IPENDAD_IAD);
+ fSET_FIELD(ipendad, IPENDAD_IAD, iad | mask);
+ arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
+ hex_interrupt_update(env);
}
void HELPER(swi)(CPUHexagonState *env, uint32_t mask)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (19 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 20/39] target/hexagon: Implement siad inst Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 21:36 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 22/39] target/hexagon: Implement setprio, resched Brian Cain
` (17 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 1 +
target/hexagon/cpu_helper.h | 1 +
target/hexagon/cpu_helper.c | 37 +++++++++++++++++++++++++++++++++++++
target/hexagon/op_helper.c | 3 ++-
4 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index d28c1249f3..baa48ec051 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -45,6 +45,7 @@ typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
#define REG_WRITES_MAX 32
#define PRED_WRITES_MAX 5 /* 4 insns + endloop */
#define VSTORES_MAX 2
+#define THREADS_MAX 8
#define VECTOR_UNIT_MAX 8
#ifndef CONFIG_USER_ONLY
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index 1cdf4f8dd0..0723485e79 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -21,6 +21,7 @@ void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause);
void hexagon_start_threads(CPUHexagonState *env, uint32_t mask);
void hexagon_stop_thread(CPUHexagonState *env);
void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC);
+void hexagon_resume_threads(CPUHexagonState *env, uint32_t mask);
static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
uint32_t val)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 1d9b9f8bef..cc1a896542 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -124,6 +124,43 @@ void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC)
cpu_interrupt(cs, CPU_INTERRUPT_HALT);
}
+static void hexagon_resume_thread(CPUHexagonState *env)
+{
+ CPUState *cs = env_cpu(env);
+ clear_wait_mode(env);
+ /*
+ * The wait instruction keeps the PC pointing to itself
+ * so that it has an opportunity to check for interrupts.
+ *
+ * When we come out of wait mode, adjust the PC to the
+ * next executable instruction.
+ */
+ env->gpr[HEX_REG_PC] = env->wait_next_pc;
+ cs = env_cpu(env);
+ ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
+ cs->halted = false;
+ cs->exception_index = HEX_EVENT_NONE;
+ qemu_cpu_kick(cs);
+}
+
+void hexagon_resume_threads(CPUHexagonState *current_env, uint32_t mask)
+{
+ CPUState *cs;
+ CPUHexagonState *env;
+
+ g_assert(bql_locked());
+ CPU_FOREACH(cs) {
+ env = cpu_env(cs);
+ g_assert(env->threadId < THREADS_MAX);
+ if ((mask & (0x1 << env->threadId))) {
+ if (get_exe_mode(env) == HEX_EXE_MODE_WAIT) {
+ hexagon_resume_thread(env);
+ }
+ }
+ }
+}
+
+
static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS];
static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS];
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 118f112487..0dce133d3a 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1476,7 +1476,8 @@ void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
void HELPER(resume)(CPUHexagonState *env, uint32_t mask)
{
- g_assert_not_reached();
+ BQL_LOCK_GUARD();
+ hexagon_resume_threads(env, mask);
}
uint32_t HELPER(getimask)(CPUHexagonState *env, uint32_t tid)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 22/39] target/hexagon: Implement setprio, resched
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (20 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-20 19:44 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug() Brian Cain
` (16 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
The hardware-assisted scheduler helps manage tasks on the run queue
and interrupt steering.
This instruction is defined in the Qualcomm Hexagon V71 Programmer's Reference
Manual -
https://docs.qualcomm.com/bundle/publicresource/80-N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
See §11.9.2 SYSTEM MONITOR.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 65 ++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 0dce133d3a..d0dc4afac7 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1465,6 +1465,57 @@ void HELPER(stop)(CPUHexagonState *env)
hexagon_stop_thread(env);
}
+static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env)
+{
+ uint32_t schedcfg;
+ uint32_t schedcfg_en;
+ int int_number;
+ CPUState *cs;
+ uint32_t lowest_th_prio = 0; /* 0 is highest prio */
+ uint32_t bestwait_reg;
+ uint32_t best_prio;
+
+ BQL_LOCK_GUARD();
+ qemu_log_mask(CPU_LOG_INT, "%s: check resched\n", __func__);
+ schedcfg = arch_get_system_reg(env, HEX_SREG_SCHEDCFG);
+ schedcfg_en = GET_FIELD(SCHEDCFG_EN, schedcfg);
+ int_number = GET_FIELD(SCHEDCFG_INTNO, schedcfg);
+
+ if (!schedcfg_en) {
+ return;
+ }
+
+ CPU_FOREACH(cs) {
+ HexagonCPU *thread = HEXAGON_CPU(cs);
+ CPUHexagonState *thread_env = &(thread->env);
+ uint32_t th_prio = GET_FIELD(
+ STID_PRIO, arch_get_system_reg(thread_env, HEX_SREG_STID));
+ if (!hexagon_thread_is_enabled(thread_env)) {
+ continue;
+ }
+
+ lowest_th_prio = (lowest_th_prio > th_prio)
+ ? lowest_th_prio
+ : th_prio;
+ }
+
+ bestwait_reg = arch_get_system_reg(env, HEX_SREG_BESTWAIT);
+ best_prio = GET_FIELD(BESTWAIT_PRIO, bestwait_reg);
+
+ /*
+ * If the lowest priority thread is lower priority than the
+ * value in the BESTWAIT register, we must raise the reschedule
+ * interrupt on the lowest priority thread.
+ */
+ if (lowest_th_prio > best_prio) {
+ qemu_log_mask(CPU_LOG_INT,
+ "%s: raising resched int %d, cur PC 0x" TARGET_FMT_lx "\n",
+ __func__, int_number, arch_get_thread_reg(env, HEX_REG_PC));
+ SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO, 0x1ff);
+ hex_raise_interrupts(env, 1 << int_number, CPU_INTERRUPT_SWI);
+ }
+}
+
void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
{
BQL_LOCK_GUARD();
@@ -1715,6 +1766,20 @@ uint64_t HELPER(greg_read_pair)(CPUHexagonState *env, uint32_t reg)
void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio)
{
+ CPUState *cs;
+
+ BQL_LOCK_GUARD();
+ CPU_FOREACH(cs) {
+ HexagonCPU *found_cpu = HEXAGON_CPU(cs);
+ CPUHexagonState *found_env = &found_cpu->env;
+ if (thread == found_env->threadId) {
+ SET_SYSTEM_FIELD(found_env, HEX_SREG_STID, STID_PRIO, prio);
+ qemu_log_mask(CPU_LOG_INT, "%s: tid %d prio = 0x%x\n",
+ __func__, found_env->threadId, prio);
+ resched(env);
+ return;
+ }
+ }
g_assert_not_reached();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (21 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 22/39] target/hexagon: Implement setprio, resched Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-20 20:02 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 24/39] target/hexagon: Add exec-start-addr prop Brian Cain
` (15 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index a548d575a7..9f4cfd03c4 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -489,6 +489,24 @@ static void find_qemu_subpage(vaddr *addr, hwaddr *phys, int page_size)
*phys += offset;
}
+static hwaddr hexagon_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+ CPUHexagonState *env = cpu_env(cs);
+ hwaddr phys_addr;
+ int prot;
+ int page_size = 0;
+ int32_t excp = 0;
+ int mmu_idx = MMU_KERNEL_IDX;
+
+ if (get_physical_address(env, &phys_addr, &prot, &page_size, &excp,
+ addr, 0, mmu_idx)) {
+ find_qemu_subpage(&addr, &phys_addr, page_size);
+ return phys_addr;
+ }
+
+ return -1;
+}
+
#define INVALID_BADVA 0xbadabada
@@ -595,6 +613,12 @@ static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size,
}
+#include "hw/core/sysemu-cpu-ops.h"
+
+static const struct SysemuCPUOps hexagon_sysemu_ops = {
+ .get_phys_page_debug = hexagon_cpu_get_phys_page_debug,
+};
+
static bool hexagon_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
CPUHexagonState *env = cpu_env(cs);
@@ -624,6 +648,8 @@ static const TCGCPUOps hexagon_tcg_ops = {
#if !defined(CONFIG_USER_ONLY)
.cpu_exec_interrupt = hexagon_cpu_exec_interrupt,
.tlb_fill = hexagon_tlb_fill,
+ .cpu_exec_halt = hexagon_cpu_has_work,
+ .do_interrupt = hexagon_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
};
@@ -653,9 +679,12 @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
cc->gdb_core_xml_file = "hexagon-core.xml";
cc->disas_set_info = hexagon_cpu_disas_set_info;
#ifndef CONFIG_USER_ONLY
+ cc->sysemu_ops = &hexagon_sysemu_ops;
dc->vmsd = &vmstate_hexagon_cpu;
#endif
+#ifdef CONFIG_TCG
cc->tcg_ops = &hexagon_tcg_ops;
+#endif
}
#ifndef CONFIG_USER_ONLY
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 24/39] target/hexagon: Add exec-start-addr prop
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (22 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:03 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index() Brian Cain
` (14 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 1 +
target/hexagon/cpu.c | 7 ++-----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index baa48ec051..4667a1f748 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -194,6 +194,7 @@ struct ArchCPU {
uint32_t num_tlbs;
uint32_t l2vic_base_addr;
uint32_t hvx_contexts;
+ uint32_t boot_addr;
#endif
};
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 9f4cfd03c4..7afdcbf9d0 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -66,6 +66,7 @@ static const Property hexagon_cpu_properties[] = {
DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
0xffffffffULL),
DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
+ DEFINE_PROP_UINT32("exec-start-addr", HexagonCPU, boot_addr, 0xffffffffULL),
#endif
DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
@@ -362,8 +363,6 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
mmu_reset(env);
arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index);
hexagon_cpu_soft_reset(env);
- memset(env->t_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
- memset(env->greg, 0, sizeof(target_ulong) * NUM_GREGS);
env->threadId = cs->cpu_index;
env->tlb_lock_state = HEX_LOCK_UNLOCKED;
env->k0_lock_state = HEX_LOCK_UNLOCKED;
@@ -372,6 +371,7 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
env->next_PC = 0;
env->wait_next_pc = 0;
env->cause_code = -1;
+ arch_set_thread_reg(env, HEX_REG_PC, cpu->boot_addr);
#endif
}
@@ -414,9 +414,6 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp)
#ifndef CONFIG_USER_ONLY
CPUHexagonState *env = cpu_env(cs);
hex_mmu_realize(env);
-#endif
- cpu_reset(cs);
-#ifndef CONFIG_USER_ONLY
if (cs->cpu_index == 0) {
env->g_sreg = g_new0(target_ulong, NUM_SREGS);
env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (23 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 24/39] target/hexagon: Add exec-start-addr prop Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:07 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 26/39] target/hexagon: Decode trap1, rte as COF Brian Cain
` (13 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu_helper.h | 1 +
target/hexagon/cpu.c | 23 +++++++++++++++++++++
target/hexagon/cpu_helper.c | 41 +++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+)
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index 0723485e79..0a5134204f 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -15,6 +15,7 @@ void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t);
void hexagon_set_sys_pcycle_count_low(CPUHexagonState *env, uint32_t);
void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, uint32_t);
void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
+int get_cpu_mode(CPUHexagonState *env);
int get_exe_mode(CPUHexagonState *env);
void clear_wait_mode(CPUHexagonState *env);
void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 7afdcbf9d0..c7c470b099 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -650,6 +650,28 @@ static const TCGCPUOps hexagon_tcg_ops = {
#endif /* !CONFIG_USER_ONLY */
};
+static int hexagon_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+#ifndef CONFIG_USER_ONLY
+ BQL_LOCK_GUARD();
+ CPUHexagonState *env = cpu_env(cs);
+ uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+ uint8_t mmuen = GET_SYSCFG_FIELD(SYSCFG_MMUEN, syscfg);
+ if (!mmuen) {
+ return MMU_KERNEL_IDX;
+ }
+
+ int cpu_mode = get_cpu_mode(env);
+ if (cpu_mode == HEX_CPU_MODE_MONITOR) {
+ return MMU_KERNEL_IDX;
+ } else if (cpu_mode == HEX_CPU_MODE_GUEST) {
+ return MMU_GUEST_IDX;
+ }
+#endif
+
+ return MMU_USER_IDX;
+}
+
static void hexagon_cpu_class_init(ObjectClass *c, void *data)
{
@@ -667,6 +689,7 @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
cc->class_by_name = hexagon_cpu_class_by_name;
cc->has_work = hexagon_cpu_has_work;
+ cc->mmu_index = hexagon_cpu_mmu_index;
cc->dump_state = hexagon_dump_state;
cc->set_pc = hexagon_cpu_set_pc;
cc->get_pc = hexagon_cpu_get_pc;
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index cc1a896542..9c44cb7950 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -394,4 +394,45 @@ void hexagon_stop_thread(CPUHexagonState *env)
}
}
+static int sys_in_monitor_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) != 0) ||
+ ((GET_SSR_FIELD(SSR_EX, ssr) == 0) && (GET_SSR_FIELD(SSR_UM, ssr) == 0)))
+ return 1;
+ return 0;
+}
+
+static int sys_in_guest_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) == 0) &&
+ (GET_SSR_FIELD(SSR_UM, ssr) != 0) &&
+ (GET_SSR_FIELD(SSR_GM, ssr) != 0))
+ return 1;
+ return 0;
+}
+
+static int sys_in_user_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) == 0) &&
+ (GET_SSR_FIELD(SSR_UM, ssr) != 0) &&
+ (GET_SSR_FIELD(SSR_GM, ssr) == 0))
+ return 1;
+ return 0;
+}
+
+int get_cpu_mode(CPUHexagonState *env)
+
+{
+ uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+
+ if (sys_in_monitor_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_MONITOR;
+ } else if (sys_in_guest_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_GUEST;
+ } else if (sys_in_user_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_USER;
+ }
+ return HEX_CPU_MODE_MONITOR;
+}
+
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 26/39] target/hexagon: Decode trap1, rte as COF
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (24 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:08 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq() Brian Cain
` (12 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Also: handle rte instructions at the end of the packet.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/decode.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 23deba2426..5d0beeeaf2 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -193,6 +193,8 @@ static bool decode_opcode_can_jump(int opcode)
if ((GET_ATTRIB(opcode, A_JUMP)) ||
(GET_ATTRIB(opcode, A_CALL)) ||
(opcode == J2_trap0) ||
+ (opcode == J2_trap1) ||
+ (opcode == J2_rte) ||
(opcode == J2_pause)) {
/* Exception to A_JUMP attribute */
if (opcode == J4_hintjumpr) {
@@ -371,6 +373,18 @@ static void decode_shuffle_for_execution(Packet *packet)
break;
}
}
+ /*
+ * And at the very very very end, move any RTE's, since they update
+ * user/supervisor mode.
+ */
+#if !defined(CONFIG_USER_ONLY)
+ for (i = 0; i < last_insn; i++) {
+ if (packet->insn[i].opcode == J2_rte) {
+ decode_send_insn_to(packet, i, last_insn);
+ break;
+ }
+ }
+#endif
}
static void
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (25 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 26/39] target/hexagon: Decode trap1, rte as COF Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:09 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt Brian Cain
` (11 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index d0dc4afac7..f3ffac81b6 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1637,7 +1637,13 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t val)
static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
{
- g_assert_not_reached();
+ int offset = (vid == HEX_SREG_VID) ? L2VIC_VID_0 : L2VIC_VID_1;
+ CPUState *cs = env_cpu(env);
+ HexagonCPU *cpu = HEXAGON_CPU(cs);
+ const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
+ uint32_t irq;
+ cpu_physical_memory_read(pend_mem, &irq, sizeof(irq));
+ return irq;
}
static void hexagon_read_timer(CPUHexagonState *env, uint32_t *low,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (26 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:12 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation Brian Cain
` (10 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/helper.h | 3 +++
target/hexagon/op_helper.c | 20 ++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h
index 730eaf8b9a..3df663baeb 100644
--- a/target/hexagon/helper.h
+++ b/target/hexagon/helper.h
@@ -129,4 +129,7 @@ DEF_HELPER_1(stop, void, env)
DEF_HELPER_2(wait, void, env, i32)
DEF_HELPER_2(resume, void, env, i32)
DEF_HELPER_2(nmi, void, env, i32)
+DEF_HELPER_1(resched, void, env)
+DEF_HELPER_3(modify_ssr, void, env, i32, i32)
+DEF_HELPER_1(pending_interrupt, void, env)
#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index f3ffac81b6..702c3dd3c6 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1178,6 +1178,15 @@ float64 HELPER(dfmpyhh)(CPUHexagonState *env, float64 RxxV,
return RxxV;
}
+#ifndef CONFIG_USER_ONLY
+void HELPER(modify_ssr)(CPUHexagonState *env, uint32_t new, uint32_t old)
+{
+ BQL_LOCK_GUARD();
+ hexagon_modify_ssr(env, new, old);
+}
+#endif
+
+
/* Histogram instructions */
void HELPER(vhist)(CPUHexagonState *env)
@@ -1516,6 +1525,11 @@ static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env)
}
}
+void HELPER(resched)(CPUHexagonState *env)
+{
+ resched(env);
+}
+
void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
{
BQL_LOCK_GUARD();
@@ -1793,6 +1807,12 @@ void HELPER(nmi)(CPUHexagonState *env, uint32_t thread_mask)
{
g_assert_not_reached();
}
+
+void HELPER(pending_interrupt)(CPUHexagonState *env)
+{
+ BQL_LOCK_GUARD();
+ hex_interrupt_update(env);
+}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (27 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-17 20:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes Brian Cain
` (9 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/translate.h | 1 +
target/hexagon/translate.c | 99 +++++++++++++++++++++++++++++++++++++-
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 9bc4b3ce8b..c9533fee1f 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -84,6 +84,7 @@ typedef struct DisasContext {
TCGv branch_taken;
TCGv dczero_addr;
bool pcycle_enabled;
+ bool pkt_ends_tb;
uint32_t num_cycles;
} DisasContext;
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 060df6e5eb..475726388a 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -259,6 +259,18 @@ static bool check_for_attrib(Packet *pkt, int attrib)
return false;
}
+#ifndef CONFIG_USER_ONLY
+static bool check_for_opcode(Packet *pkt, uint16_t opcode)
+{
+ for (int i = 0; i < pkt->num_insns; i++) {
+ if (pkt->insn[i].opcode == opcode) {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
static bool need_slot_cancelled(Packet *pkt)
{
/* We only need slot_cancelled for conditional store instructions */
@@ -272,6 +284,90 @@ static bool need_slot_cancelled(Packet *pkt)
return false;
}
+#ifndef CONFIG_USER_ONLY
+static bool sreg_write_to_global(int reg_num)
+{
+ return reg_num == HEX_SREG_SSR ||
+ reg_num == HEX_SREG_STID ||
+ reg_num == HEX_SREG_IMASK ||
+ reg_num == HEX_SREG_IPENDAD ||
+ reg_num == HEX_SREG_BESTWAIT ||
+ reg_num == HEX_SREG_SCHEDCFG;
+}
+
+static bool has_sreg_write_to_global(Packet const *pkt)
+{
+ for (int i = 0; i < pkt->num_insns; i++) {
+ Insn const *insn = &pkt->insn[i];
+ uint16_t opcode = insn->opcode;
+ if (opcode == Y2_tfrsrcr) {
+ /* Write to a single sreg */
+ int reg_num = insn->regno[0];
+ if (sreg_write_to_global(reg_num)) {
+ return true;
+ }
+ } else if (opcode == Y4_tfrspcp) {
+ /* Write to a sreg pair */
+ int reg_num = insn->regno[0];
+ if (sreg_write_to_global(reg_num)) {
+ return true;
+ }
+ if (sreg_write_to_global(reg_num + 1)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+#endif
+
+static bool pkt_ends_tb(Packet *pkt)
+{
+ if (pkt->pkt_has_cof) {
+ return true;
+ }
+#ifndef CONFIG_USER_ONLY
+ /* System mode instructions that end TLB */
+ if (check_for_opcode(pkt, Y2_swi) ||
+ check_for_opcode(pkt, Y2_cswi) ||
+ check_for_opcode(pkt, Y2_ciad) ||
+ check_for_opcode(pkt, Y4_siad) ||
+ check_for_opcode(pkt, Y2_wait) ||
+ check_for_opcode(pkt, Y2_resume) ||
+ check_for_opcode(pkt, Y2_iassignw) ||
+ check_for_opcode(pkt, Y2_setimask) ||
+ check_for_opcode(pkt, Y4_nmi) ||
+ check_for_opcode(pkt, Y2_setprio) ||
+ check_for_opcode(pkt, Y2_start) ||
+ check_for_opcode(pkt, Y2_stop) ||
+ check_for_opcode(pkt, Y2_k0lock) ||
+ check_for_opcode(pkt, Y2_k0unlock) ||
+ check_for_opcode(pkt, Y2_tlblock) ||
+ check_for_opcode(pkt, Y2_tlbunlock) ||
+ check_for_opcode(pkt, Y2_break) ||
+ check_for_opcode(pkt, Y2_isync) ||
+ check_for_opcode(pkt, Y2_syncht) ||
+ check_for_opcode(pkt, Y2_tlbp) ||
+ check_for_opcode(pkt, Y2_tlbw) ||
+ check_for_opcode(pkt, Y5_ctlbw) ||
+ check_for_opcode(pkt, Y5_tlbasidi)) {
+ return true;
+ }
+
+ /*
+ * Check for sreg writes that would end the TB
+ */
+ if (check_for_attrib(pkt, A_IMPLICIT_WRITES_SSR)) {
+ return true;
+ }
+ if (has_sreg_write_to_global(pkt)) {
+ return true;
+ }
+#endif
+ return false;
+}
+
+
static bool need_next_PC(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
@@ -473,6 +569,7 @@ static void gen_start_packet(DisasContext *ctx)
tcg_gen_movi_tl(hex_slot_cancelled, 0);
}
ctx->branch_taken = NULL;
+ ctx->pkt_ends_tb = pkt_ends_tb(pkt);
if (pkt->pkt_has_cof) {
ctx->branch_taken = tcg_temp_new();
if (pkt->pkt_has_multi_cof) {
@@ -927,7 +1024,7 @@ static void gen_commit_packet(DisasContext *ctx)
pkt->vhist_insn->generate(ctx);
}
- if (pkt->pkt_has_cof) {
+ if (ctx->pkt_ends_tb || ctx->base.is_jmp == DISAS_NORETURN) {
gen_end_tb(ctx);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (28 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-18 18:50 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 31/39] target/hexagon: Add implicit sysreg writes Brian Cain
` (8 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/cpu.h | 2 +-
target/hexagon/translate.h | 2 +
target/hexagon/genptr.c | 7 +-
target/hexagon/translate.c | 142 ++++++++++++++++++++++++++++++++-----
4 files changed, 132 insertions(+), 21 deletions(-)
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 4667a1f748..73c3bb34b0 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -142,9 +142,9 @@ typedef struct CPUArchState {
hex_lock_state_t k0_lock_state;
target_ulong tlb_lock_count;
target_ulong k0_lock_count;
- target_ulong next_PC;
CPUHexagonTLBContext *hex_tlb;
#endif
+ target_ulong next_PC;
target_ulong new_value_usr;
MemLog mem_log_stores[STORES_MAX];
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index c9533fee1f..ad1a2f4045 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -85,6 +85,7 @@ typedef struct DisasContext {
TCGv dczero_addr;
bool pcycle_enabled;
bool pkt_ends_tb;
+ bool need_next_pc;
uint32_t num_cycles;
} DisasContext;
@@ -306,6 +307,7 @@ static inline void ctx_log_qreg_read(DisasContext *ctx,
}
extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
+extern TCGv hex_next_PC;
extern TCGv hex_pred[NUM_PREGS];
extern TCGv hex_slot_cancelled;
extern TCGv hex_new_value_usr;
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 5554c9515c..afc7e5f3a5 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -634,14 +634,15 @@ static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr,
tcg_gen_brcondi_tl(cond, pred, 0, pred_false);
}
+ TCGv PC_wr = ctx->need_next_pc ? hex_next_PC : hex_gpr[HEX_REG_PC];
if (ctx->pkt->pkt_has_multi_cof) {
/* If there are multiple branches in a packet, ignore the second one */
- tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
+ tcg_gen_movcond_tl(TCG_COND_NE, PC_wr,
ctx->branch_taken, tcg_constant_tl(0),
- hex_gpr[HEX_REG_PC], addr);
+ PC_wr, addr);
tcg_gen_movi_tl(ctx->branch_taken, 1);
} else {
- tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
+ tcg_gen_mov_tl(PC_wr, addr);
}
if (cond != TCG_COND_ALWAYS) {
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 475726388a..d4b22acb72 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -49,6 +49,7 @@ static const AnalyzeInsn opcode_analyze[XX_LAST_OPCODE] = {
TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
TCGv hex_pred[NUM_PREGS];
TCGv hex_slot_cancelled;
+TCGv hex_next_PC;
TCGv hex_new_value_usr;
TCGv hex_store_addr[STORES_MAX];
TCGv hex_store_width[STORES_MAX];
@@ -61,12 +62,14 @@ TCGv_i64 hex_cycle_count;
TCGv hex_vstore_addr[VSTORES_MAX];
TCGv hex_vstore_size[VSTORES_MAX];
TCGv hex_vstore_pending[VSTORES_MAX];
+static bool need_next_PC(DisasContext *ctx);
#ifndef CONFIG_USER_ONLY
TCGv hex_greg[NUM_GREGS];
TCGv hex_t_sreg[NUM_SREGS];
TCGv_ptr hex_g_sreg_ptr;
TCGv hex_g_sreg[NUM_SREGS];
+TCGv hex_cause_code;
#endif
static const char * const hexagon_prednames[] = {
@@ -184,6 +187,9 @@ static void gen_end_tb(DisasContext *ctx)
gen_exec_counters(ctx);
+ if (ctx->need_next_pc) {
+ tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
+ }
if (ctx->branch_cond != TCG_COND_NEVER) {
if (ctx->branch_cond != TCG_COND_ALWAYS) {
TCGLabel *skip = gen_new_label();
@@ -371,18 +377,24 @@ static bool pkt_ends_tb(Packet *pkt)
static bool need_next_PC(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
-
- /* Check for conditional control flow or HW loop end */
- for (int i = 0; i < pkt->num_insns; i++) {
- uint16_t opcode = pkt->insn[i].opcode;
- if (GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode, A_COF)) {
- return true;
- }
- if (GET_ATTRIB(opcode, A_HWLOOP0_END) ||
- GET_ATTRIB(opcode, A_HWLOOP1_END)) {
- return true;
+ if (pkt->pkt_has_cof || ctx->pkt_ends_tb) {
+ for (int i = 0; i < pkt->num_insns; i++) {
+ uint16_t opcode = pkt->insn[i].opcode;
+ if ((GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode, A_COF)) ||
+ GET_ATTRIB(opcode, A_HWLOOP0_END) ||
+ GET_ATTRIB(opcode, A_HWLOOP1_END)) {
+ return true;
+ }
}
}
+ /*
+ * We end the TB on some instructions that do not change the flow (for
+ * other reasons). In these cases, we must set pc too, as the insn won't
+ * do it themselves.
+ */
+ if (ctx->pkt_ends_tb && !check_for_attrib(pkt, A_COF)) {
+ return true;
+ }
return false;
}
@@ -523,7 +535,14 @@ static void analyze_packet(DisasContext *ctx)
static void gen_start_packet(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
+#ifndef CONFIG_USER_ONLY
+ target_ulong next_PC = (check_for_opcode(pkt, Y2_k0lock) ||
+ check_for_opcode(pkt, Y2_tlblock)) ?
+ ctx->base.pc_next :
+ ctx->base.pc_next + pkt->encod_pkt_size_in_bytes;
+#else
target_ulong next_PC = ctx->base.pc_next + pkt->encod_pkt_size_in_bytes;
+#endif
int i;
/* Clear out the disassembly context */
@@ -531,6 +550,10 @@ static void gen_start_packet(DisasContext *ctx)
ctx->reg_log_idx = 0;
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
+#ifndef CONFIG_USER_ONLY
+ ctx->greg_log_idx = 0;
+ ctx->sreg_log_idx = 0;
+#endif
ctx->preg_log_idx = 0;
bitmap_zero(ctx->pregs_written, NUM_PREGS);
ctx->future_vregs_idx = 0;
@@ -563,21 +586,41 @@ static void gen_start_packet(DisasContext *ctx)
* gen phase, so clear it again.
*/
bitmap_zero(ctx->pregs_written, NUM_PREGS);
+#ifndef CONFIG_USER_ONLY
+ for (i = 0; i < NUM_SREGS; i++) {
+ ctx->t_sreg_new_value[i] = NULL;
+ }
+ for (i = 0; i < ctx->sreg_log_idx; i++) {
+ int reg_num = ctx->sreg_log[i];
+ if (reg_num < HEX_SREG_GLB_START) {
+ ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
+ tcg_gen_mov_tl(ctx->t_sreg_new_value[reg_num], hex_t_sreg[reg_num]);
+ }
+ }
+ for (i = 0; i < NUM_GREGS; i++) {
+ ctx->greg_new_value[i] = NULL;
+ }
+ for (i = 0; i < ctx->greg_log_idx; i++) {
+ int reg_num = ctx->greg_log[i];
+ ctx->greg_new_value[reg_num] = tcg_temp_new();
+ }
+#endif
/* Initialize the runtime state for packet semantics */
if (need_slot_cancelled(pkt)) {
tcg_gen_movi_tl(hex_slot_cancelled, 0);
}
ctx->branch_taken = NULL;
- ctx->pkt_ends_tb = pkt_ends_tb(pkt);
if (pkt->pkt_has_cof) {
ctx->branch_taken = tcg_temp_new();
- if (pkt->pkt_has_multi_cof) {
- tcg_gen_movi_tl(ctx->branch_taken, 0);
- }
- if (need_next_PC(ctx)) {
- tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC);
- }
+ }
+ if (pkt->pkt_has_multi_cof) {
+ tcg_gen_movi_tl(ctx->branch_taken, 0);
+ }
+ ctx->pkt_ends_tb = pkt_ends_tb(pkt);
+ ctx->need_next_pc = need_next_PC(ctx);
+ if (ctx->need_next_pc) {
+ tcg_gen_movi_tl(hex_next_PC, next_PC);
}
/* Preload the predicated registers into get_result_gpr(ctx, i) */
@@ -713,6 +756,59 @@ static void gen_reg_writes(DisasContext *ctx)
}
}
+#ifndef CONFIG_USER_ONLY
+static void gen_greg_writes(DisasContext *ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx->greg_log_idx; i++) {
+ int reg_num = ctx->greg_log[i];
+
+ tcg_gen_mov_tl(hex_greg[reg_num], ctx->greg_new_value[reg_num]);
+ }
+}
+
+
+static void gen_sreg_writes(DisasContext *ctx)
+{
+ int i;
+
+ TCGv old_reg = tcg_temp_new();
+ for (i = 0; i < ctx->sreg_log_idx; i++) {
+ int reg_num = ctx->sreg_log[i];
+
+ if (reg_num == HEX_SREG_SSR) {
+ tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
+ tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx->t_sreg_new_value[reg_num]);
+ gen_helper_modify_ssr(tcg_env, ctx->t_sreg_new_value[reg_num],
+ old_reg);
+ /* This can change processor state, so end the TB */
+ ctx->base.is_jmp = DISAS_NORETURN;
+ } else if ((reg_num == HEX_SREG_STID) ||
+ (reg_num == HEX_SREG_IMASK) ||
+ (reg_num == HEX_SREG_IPENDAD)) {
+ if (reg_num < HEX_SREG_GLB_START) {
+ tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
+ tcg_gen_mov_tl(hex_t_sreg[reg_num],
+ ctx->t_sreg_new_value[reg_num]);
+ }
+ /* This can change the interrupt state, so end the TB */
+ gen_helper_pending_interrupt(tcg_env);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ } else if ((reg_num == HEX_SREG_BESTWAIT) ||
+ (reg_num == HEX_SREG_SCHEDCFG)) {
+ /* This can trigger resched interrupt, so end the TB */
+ gen_helper_resched(tcg_env);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ }
+
+ if (reg_num < HEX_SREG_GLB_START) {
+ tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx->t_sreg_new_value[reg_num]);
+ }
+ }
+}
+#endif
+
static void gen_pred_writes(DisasContext *ctx)
{
/* Early exit if not needed or the log is empty */
@@ -1012,6 +1108,10 @@ static void gen_commit_packet(DisasContext *ctx)
process_store_log(ctx);
gen_reg_writes(ctx);
+#if !defined(CONFIG_USER_ONLY)
+ gen_greg_writes(ctx);
+ gen_sreg_writes(ctx);
+#endif
gen_pred_writes(ctx);
if (pkt->pkt_has_hvx) {
gen_commit_hvx(ctx);
@@ -1073,6 +1173,7 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
ctx->short_circuit = hex_cpu->short_circuit;
ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS, PCYCLE_ENABLED);
+ ctx->need_next_pc = false;
}
static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
@@ -1201,6 +1302,13 @@ void hexagon_translate_init(void)
offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
+#ifndef CONFIG_USER_ONLY
+ hex_cause_code = tcg_global_mem_new(tcg_env,
+ offsetof(CPUHexagonState, cause_code), "cause_code");
+#endif
+ hex_next_PC = tcg_global_mem_new(tcg_env,
+ offsetof(CPUHexagonState, next_PC), "next_PC");
+
for (i = 0; i < STORES_MAX; i++) {
snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
hex_store_addr[i] = tcg_global_mem_new(tcg_env,
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 31/39] target/hexagon: Add implicit sysreg writes
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (29 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-18 19:18 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 32/39] target/hexagon: Define system, guest reg names Brian Cain
` (7 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/translate.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index d4b22acb72..ff881d1060 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -426,6 +426,16 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum)
}
}
+#ifndef CONFIG_USER_ONLY
+static void mark_implicit_sreg_write(DisasContext *ctx, int attrib, int snum)
+{
+ uint16_t opcode = ctx->insn->opcode;
+ if (GET_ATTRIB(opcode, attrib)) {
+ ctx_log_sreg_write(ctx, snum);
+ }
+}
+#endif
+
static void mark_implicit_reg_writes(DisasContext *ctx)
{
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_FP, HEX_REG_FP);
@@ -437,6 +447,12 @@ static void mark_implicit_reg_writes(DisasContext *ctx)
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1);
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_USR, HEX_REG_USR);
mark_implicit_reg_write(ctx, A_FPOP, HEX_REG_USR);
+
+#ifndef CONFIG_USER_ONLY
+ mark_implicit_sreg_write(ctx, A_IMPLICIT_WRITES_SGP0, HEX_SREG_SGP0);
+ mark_implicit_sreg_write(ctx, A_IMPLICIT_WRITES_SGP1, HEX_SREG_SGP1);
+ mark_implicit_sreg_write(ctx, A_IMPLICIT_WRITES_SSR, HEX_SREG_SSR);
+#endif
}
static void mark_implicit_pred_write(DisasContext *ctx, int attrib, int pnum)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 32/39] target/hexagon: Define system, guest reg names
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (30 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 31/39] target/hexagon: Add implicit sysreg writes Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 16:48 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs Brian Cain
` (6 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/internal.h | 2 ++
target/hexagon/cpu.c | 29 +++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h
index 120cfde7b9..fd2397b9ef 100644
--- a/target/hexagon/internal.h
+++ b/target/hexagon/internal.h
@@ -34,6 +34,8 @@ void hexagon_debug_qreg(CPUHexagonState *env, int regnum);
void hexagon_debug(CPUHexagonState *env);
extern const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS];
+extern const char * const hexagon_sregnames[];
+extern const char * const hexagon_gregnames[];
void G_NORETURN do_raise_exception(CPUHexagonState *env,
uint32_t exception,
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index c7c470b099..3c4776232e 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -85,6 +85,35 @@ const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
"c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31",
};
+#ifndef CONFIG_USER_ONLY
+const char * const hexagon_sregnames[] = {
+ "sgp0", "sgp1", "stid", "elr", "badva0",
+ "badva1", "ssr", "ccr", "htid", "badva",
+ "imask", "gevb", "vwctrl", "s13", "s14",
+ "s15", "evb", "modectl", "syscfg", "segment",
+ "ipendad", "vid", "vid1", "bestwait", "s24",
+ "schedcfg", "s26", "cfgbase", "diag", "rev",
+ "pcyclelo", "pcyclehi", "isdbst", "isdbcfg0", "isdbcfg1",
+ "livelock", "brkptpc0", "brkptcfg0", "brkptpc1", "brkptcfg1",
+ "isdbmbxin", "isdbmbxout", "isdben", "isdbgpr", "pmucnt4",
+ "pmucnt5", "pmucnt6", "pmucnt7", "pmucnt0", "pmucnt1",
+ "pmucnt2", "pmucnt3", "pmuevtcfg", "pmustid0", "pmuevtcfg1",
+ "pmustid1", "timerlo", "timerhi", "pmucfg", "rgdr2",
+ "rgdr", "turkey", "duck", "chicken",
+};
+
+G_STATIC_ASSERT(NUM_SREGS == ARRAY_SIZE(hexagon_sregnames));
+
+const char * const hexagon_gregnames[] = {
+ "gelr", "gsr", "gosp", "gbadva", "gcommit1t",
+ "gcommit2t", "gcommit3t", "gcommit4t", "gcommit5t", "gcommit6t",
+ "gpcycle1t", "gpcycle2t", "gpcycle3t", "gpcycle4t", "gpcycle5t",
+ "gpcycle6t", "gpmucnt4", "gpmucnt5", "gpmucnt6", "gpmucnt7",
+ "gcommit7t", "gcommit8t", "gpcycle7t", "gpcycle8t", "gpcyclelo",
+ "gpcyclehi", "gpmucnt0", "gpmucnt1", "gpmucnt2", "gpmucnt3",
+ "g30", "g31",
+};
+#endif
/*
* One of the main debugging techniques is to use "-d cpu" and compare against
* LLDB output when single stepping. However, the target and qemu put the
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (31 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 32/39] target/hexagon: Define system, guest reg names Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 16:53 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock Brian Cain
` (5 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/translate.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index ff881d1060..248ed60f29 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -1295,6 +1295,26 @@ void hexagon_translate_init(void)
opcode_init();
+#ifndef CONFIG_USER_ONLY
+ for (i = 0; i < NUM_GREGS; i++) {
+ hex_greg[i] = tcg_global_mem_new(tcg_env,
+ offsetof(CPUHexagonState, greg[i]),
+ hexagon_gregnames[i]);
+ }
+ hex_g_sreg_ptr = tcg_global_mem_new_ptr(tcg_env,
+ offsetof(CPUHexagonState, g_sreg), "hex_g_sreg_ptr");
+ for (i = 0; i < NUM_SREGS; i++) {
+ if (i < HEX_SREG_GLB_START) {
+ hex_t_sreg[i] = tcg_global_mem_new(tcg_env,
+ offsetof(CPUHexagonState, t_sreg[i]),
+ hexagon_sregnames[i]);
+ } else {
+ hex_g_sreg[i] = tcg_global_mem_new(hex_g_sreg_ptr,
+ i * sizeof(target_ulong),
+ hexagon_sregnames[i]);
+ }
+ }
+#endif
for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) {
hex_gpr[i] = tcg_global_mem_new(tcg_env,
offsetof(CPUHexagonState, gpr[i]),
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (32 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-03 16:24 ` Brian Cain
2025-03-19 17:01 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 35/39] target/hexagon: Define gen_precise_exception() Brian Cain
` (4 subsequent siblings)
38 siblings, 2 replies; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/sys_macros.h | 8 +--
target/hexagon/op_helper.c | 104 ++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 4 deletions(-)
diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
index 3c4c3c7aa5..e5dc1ce0ab 100644
--- a/target/hexagon/sys_macros.h
+++ b/target/hexagon/sys_macros.h
@@ -143,11 +143,11 @@
#define fDCINVIDX(REG)
#define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in qemu */
-#define fSET_TLB_LOCK() g_assert_not_reached()
-#define fCLEAR_TLB_LOCK() g_assert_not_reached()
+#define fSET_TLB_LOCK() hex_tlb_lock(env);
+#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
-#define fSET_K0_LOCK() g_assert_not_reached()
-#define fCLEAR_K0_LOCK() g_assert_not_reached()
+#define fSET_K0_LOCK() hex_k0_lock(env);
+#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
#define fTLB_IDXMASK(INDEX) \
((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)->num_tlbs)) - 1))
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 702c3dd3c6..f3b14fbf58 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState *env, uint32_t new, uint32_t old)
BQL_LOCK_GUARD();
hexagon_modify_ssr(env, new, old);
}
+
+static void hex_k0_lock(CPUHexagonState *env)
+{
+ BQL_LOCK_GUARD();
+ g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
+
+ uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+ if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) {
+ if (env->k0_lock_state == HEX_LOCK_QUEUED) {
+ env->next_PC += 4;
+ env->k0_lock_count++;
+ env->k0_lock_state = HEX_LOCK_OWNER;
+ SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
+ return;
+ }
+ if (env->k0_lock_state == HEX_LOCK_OWNER) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Double k0lock at PC: 0x%x, thread may hang\n",
+ env->next_PC);
+ env->next_PC += 4;
+ CPUState *cs = env_cpu(env);
+ cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+ return;
+ }
+ env->k0_lock_state = HEX_LOCK_WAITING;
+ CPUState *cs = env_cpu(env);
+ cpu_interrupt(cs, CPU_INTERRUPT_HALT);
+ } else {
+ env->next_PC += 4;
+ env->k0_lock_count++;
+ env->k0_lock_state = HEX_LOCK_OWNER;
+ SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
+ }
+
+}
+
+static void hex_k0_unlock(CPUHexagonState *env)
+{
+ BQL_LOCK_GUARD();
+ g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
+
+ /* Nothing to do if the k0 isn't locked by this thread */
+ uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+ if ((GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg) == 0) ||
+ (env->k0_lock_state != HEX_LOCK_OWNER)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "thread %d attempted to unlock k0 without having the "
+ "lock, k0_lock state = %d, syscfg:k0 = %d\n",
+ env->threadId, env->k0_lock_state,
+ GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg));
+ g_assert(env->k0_lock_state != HEX_LOCK_WAITING);
+ return;
+ }
+
+ env->k0_lock_count--;
+ env->k0_lock_state = HEX_LOCK_UNLOCKED;
+ SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 0);
+
+ /* Look for a thread to unlock */
+ unsigned int this_threadId = env->threadId;
+ CPUHexagonState *unlock_thread = NULL;
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *thread = cpu_env(cs);
+
+ /*
+ * The hardware implements round-robin fairness, so we look for threads
+ * starting at env->threadId + 1 and incrementing modulo the number of
+ * threads.
+ *
+ * To implement this, we check if thread is a earlier in the modulo
+ * sequence than unlock_thread.
+ * if unlock thread is higher than this thread
+ * thread must be between this thread and unlock_thread
+ * else
+ * thread higher than this thread is ahead of unlock_thread
+ * thread must be lower then unlock thread
+ */
+ if (thread->k0_lock_state == HEX_LOCK_WAITING) {
+ if (!unlock_thread) {
+ unlock_thread = thread;
+ } else if (unlock_thread->threadId > this_threadId) {
+ if (this_threadId < thread->threadId &&
+ thread->threadId < unlock_thread->threadId) {
+ unlock_thread = thread;
+ }
+ } else {
+ if (thread->threadId > this_threadId) {
+ unlock_thread = thread;
+ }
+ if (thread->threadId < unlock_thread->threadId) {
+ unlock_thread = thread;
+ }
+ }
+ }
+ }
+ if (unlock_thread) {
+ cs = env_cpu(unlock_thread);
+ unlock_thread->k0_lock_state = HEX_LOCK_QUEUED;
+ SET_SYSCFG_FIELD(unlock_thread, SYSCFG_K0LOCK, 1);
+ cpu_interrupt(cs, CPU_INTERRUPT_K0_UNLOCK);
+ }
+
+}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 35/39] target/hexagon: Define gen_precise_exception()
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (33 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 17:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts Brian Cain
` (3 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Add PC to raise_exception helper
Replace the fGEN_TCG_J2_trap0 macro override with the fTRAP()-generated
system helper instead.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/gen_tcg.h | 7 -------
target/hexagon/helper.h | 2 +-
target/hexagon/op_helper.c | 10 ++++------
target/hexagon/translate.c | 13 ++++++++-----
4 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 71f8a0e2d0..146aadc737 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1370,13 +1370,6 @@
#define fGEN_TCG_S2_storew_rl_st_vi(SHORTCODE) SHORTCODE
#define fGEN_TCG_S4_stored_rl_st_vi(SHORTCODE) SHORTCODE
-#define fGEN_TCG_J2_trap0(SHORTCODE) \
- do { \
- uiV = uiV; \
- tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->pkt->pc); \
- TCGv excp = tcg_constant_tl(HEX_EVENT_TRAP0); \
- gen_helper_raise_exception(tcg_env, excp); \
- } while (0)
#endif
#define fGEN_TCG_A2_nop(SHORTCODE) do { } while (0)
diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h
index 3df663baeb..5bcb2f4809 100644
--- a/target/hexagon/helper.h
+++ b/target/hexagon/helper.h
@@ -18,7 +18,7 @@
#include "internal.h"
#include "helper_protos_generated.h.inc"
-DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_RETURN, noreturn, env, i32)
+DEF_HELPER_FLAGS_3(raise_exception, TCG_CALL_NO_RETURN, noreturn, env, i32, i32)
DEF_HELPER_2(commit_store, void, env, int)
DEF_HELPER_3(gather_store, void, env, i32, int)
DEF_HELPER_1(commit_hvx_stores, void, env)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index f3b14fbf58..3bd4e2a872 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -69,15 +69,13 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
uint32_t exception,
uintptr_t pc)
{
- CPUState *cs = env_cpu(env);
- qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
- cs->exception_index = exception;
- cpu_loop_exit_restore(cs, pc);
+ do_raise_exception(env, exception, pc, 0);
}
-G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp)
+G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp,
+ target_ulong PC)
{
- hexagon_raise_exception_err(env, excp, 0);
+ hexagon_raise_exception_err(env, excp, PC);
}
void log_store32(CPUHexagonState *env, target_ulong addr,
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 248ed60f29..f4133a1049 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -124,9 +124,10 @@ intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
return offset;
}
-static void gen_exception_raw(int excp)
+static void gen_exception(int excp, target_ulong PC)
{
- gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
+ gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp),
+ tcg_constant_tl(PC));
}
#ifndef CONFIG_USER_ONLY
@@ -221,9 +222,11 @@ static void gen_end_tb(DisasContext *ctx)
void hex_gen_exception_end_tb(DisasContext *ctx, int excp)
{
- gen_exec_counters(ctx);
- tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC);
- gen_exception_raw(excp);
+#ifdef CONFIG_USER_ONLY
+ gen_exception(excp, ctx->pkt->pc);
+#else
+ gen_precise_exception(excp, ctx->pkt->pc);
+#endif
ctx->base.is_jmp = DISAS_NORETURN;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (34 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 35/39] target/hexagon: Define gen_precise_exception() Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 17:22 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 37/39] target/hexagon: Add support for loadw_phys Brian Cain
` (2 subsequent siblings)
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/gen_tcg_sys.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/target/hexagon/gen_tcg_sys.h b/target/hexagon/gen_tcg_sys.h
index 6d73a18db4..e56553462f 100644
--- a/target/hexagon/gen_tcg_sys.h
+++ b/target/hexagon/gen_tcg_sys.h
@@ -81,6 +81,31 @@
gen_helper_stop(tcg_env); \
} while (0)
+#define fGEN_TCG_Y2_tfrscrr(SHORTCODE) \
+ tcg_gen_mov_tl(RdV, SsV)
+
+#define fGEN_TCG_Y2_tfrsrcr(SHORTCODE) \
+ tcg_gen_mov_tl(SdV, RsV)
+
+#define fGEN_TCG_Y4_tfrscpp(SHORTCODE) \
+ tcg_gen_mov_i64(RddV, SssV)
+
+#define fGEN_TCG_Y4_tfrspcp(SHORTCODE) \
+ tcg_gen_mov_i64(SddV, RssV)
+
+#define fGEN_TCG_G4_tfrgcrr(SHORTCODE) \
+ tcg_gen_mov_tl(RdV, GsV)
+
+#define fGEN_TCG_G4_tfrgrcr(SHORTCODE) \
+ tcg_gen_mov_tl(GdV, RsV)
+
+#define fGEN_TCG_G4_tfrgcpp(SHORTCODE) \
+ tcg_gen_mov_i64(RddV, GssV)
+
+#define fGEN_TCG_G4_tfrgpcp(SHORTCODE) \
+ tcg_gen_mov_i64(GddV, RssV)
+
+
/*
* rte (return from exception)
* Clear the EX bit in SSR
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 37/39] target/hexagon: Add support for loadw_phys
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (35 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-20 20:04 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 38/39] target/hexagon: Add guest reg reading functionality Brian Cain
2025-03-01 5:28 ` [PATCH 39/39] target/hexagon: Add pcycle setting functionality Brian Cain
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym,
Brian Cain
From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/hex_common.py | 3 +++
target/hexagon/imported/encode_pp.def | 1 +
target/hexagon/imported/ldst.idef | 3 +++
3 files changed, 7 insertions(+)
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 7b5bb2cd46..5e84efb403 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -266,6 +266,9 @@ def need_slot(tag):
and "A_CVI_GATHER" not in attribdict[tag]
and ("A_STORE" in attribdict[tag]
or "A_LOAD" in attribdict[tag])
+ and tag != "L4_loadw_phys"
+ and tag != "L6_memcpy"
+ and tag != "Y6_dmlink"
):
return 1
else:
diff --git a/target/hexagon/imported/encode_pp.def b/target/hexagon/imported/encode_pp.def
index 37faf62b1b..41e4ab9e3a 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -388,6 +388,7 @@ DEF_ENC32(L4_return_fnew_pnt, ICLASS_LD" 011 0 000 sssss PP1010vv ---ddddd")
/** Load Acquire Store Release Encoding **/
+DEF_ENC32(L4_loadw_phys, ICLASS_LD" 001 0 000 sssss PP1ttttt -00ddddd")
DEF_ENC32(L2_loadw_locked, ICLASS_LD" 001 0 000 sssss PP000--- 000ddddd")
DEF_ENC32(L4_loadd_locked, ICLASS_LD" 001 0 000 sssss PP010--- 000ddddd")
diff --git a/target/hexagon/imported/ldst.idef b/target/hexagon/imported/ldst.idef
index 53198176a9..4e1e5d5326 100644
--- a/target/hexagon/imported/ldst.idef
+++ b/target/hexagon/imported/ldst.idef
@@ -203,6 +203,9 @@ Q6INSN(S2_storew_locked,"memw_locked(Rs32,Pd4)=Rt32", ATTRIBS(A_REGWRSIZE_4B,A_M
Q6INSN(L4_loadd_locked,"Rdd32=memd_locked(Rs32)", ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_LOAD,A_RESTRICT_SLOT0ONLY,A_RESTRICT_PACKET_AXOK,A_NOTE_AXOK), "Load double with lock",
{ fEA_REG(RsV); fLOAD_LOCKED(1,8,u,EA,RddV) })
+Q6INSN(L4_loadw_phys,"Rd32=memw_phys(Rs32,Rt32)", ATTRIBS(A_REGWRSIZE_4B,A_PRIV,A_RESTRICT_SLOT0ONLY,A_NOTE_PRIV,A_MEMSIZE_4B,A_LOAD,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET), "Load word from physical address",
+{ fLOAD_PHYS(1,4,u,RsV,RtV,RdV); })
+
Q6INSN(S4_stored_locked,"memd_locked(Rs32,Pd4)=Rtt32", ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_STORE,A_RESTRICT_SLOT0ONLY,A_RESTRICT_PACKET_AXOK,A_NOTE_AXOK,A_RESTRICT_LATEPRED,A_NOTE_LATEPRED), "Store word with lock",
{ fEA_REG(RsV); fSTORE_LOCKED(1,8,EA,RttV,PdV) })
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 38/39] target/hexagon: Add guest reg reading functionality
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (36 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 37/39] target/hexagon: Add support for loadw_phys Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 18:36 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 39/39] target/hexagon: Add pcycle setting functionality Brian Cain
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym
From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
---
target/hexagon/cpu.c | 19 ++++++++++++++++++-
target/hexagon/op_helper.c | 19 +++++++++++++++++--
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 3c4776232e..80f5e23794 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -739,7 +739,24 @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
#ifndef CONFIG_USER_ONLY
uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg)
{
- g_assert_not_reached();
+ target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+ int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
+
+ if (reg <= HEX_GREG_G3) {
+ return env->greg[reg];
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO:
+ return ssr_ce ? hexagon_get_sys_pcycle_count_low(env) : 0;
+
+ case HEX_GREG_GPCYCLEHI:
+ return ssr_ce ? hexagon_get_sys_pcycle_count_high(env) : 0;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "reading greg %" PRId32
+ " not yet supported.\n", reg);
+ return 0;
+ }
}
#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 3bd4e2a872..28b555e873 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1877,13 +1877,28 @@ uint64_t HELPER(sreg_read_pair)(CPUHexagonState *env, uint32_t reg)
}
uint32_t HELPER(greg_read)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ return hexagon_greg_read(env, reg);
}
uint64_t HELPER(greg_read_pair)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ if (reg == HEX_GREG_G0 || reg == HEX_GREG_G2) {
+ return (uint64_t)(env->greg[reg]) |
+ (((uint64_t)(env->greg[reg + 1])) << 32);
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO: {
+ target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+ int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
+ return ssr_ce ? hexagon_get_sys_pcycle_count(env) : 0;
+ }
+ default:
+ return (uint64_t)hexagon_greg_read(env, reg) |
+ ((uint64_t)(hexagon_greg_read(env, reg + 1)) << 32);
+ }
}
void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* [PATCH 39/39] target/hexagon: Add pcycle setting functionality
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
` (37 preceding siblings ...)
2025-03-01 5:28 ` [PATCH 38/39] target/hexagon: Add guest reg reading functionality Brian Cain
@ 2025-03-01 5:28 ` Brian Cain
2025-03-19 18:49 ` ltaylorsimpson
38 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-01 5:28 UTC (permalink / raw)
To: qemu-devel
Cc: brian.cain, richard.henderson, philmd, quic_mathbern, ale, anjo,
quic_mliebel, ltaylorsimpson, alex.bennee, quic_mburton, sidneym
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
---
target/hexagon/cpu.c | 10 +++++++---
target/hexagon/cpu_helper.c | 17 ++++++++++++++---
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 80f5e23794..4ca6add834 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -440,19 +440,23 @@ static void hexagon_cpu_realize(DeviceState *dev, Error **errp)
#endif
qemu_init_vcpu(cs);
-#ifndef CONFIG_USER_ONLY
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);
- env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
} else {
CPUState *cpu0 = qemu_get_cpu(0);
CPUHexagonState *env0 = cpu_env(cpu0);
env->g_sreg = env0->g_sreg;
- env->g_pcycle_base = env0->g_pcycle_base;
}
#endif
+ if (cs->cpu_index == 0) {
+ env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
+ } else {
+ CPUState *cpu0 = qemu_get_cpu(0);
+ env->g_pcycle_base = cpu_env(cpu0)->g_pcycle_base;
+ }
mcc->parent_realize(dev, errp);
}
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 9c44cb7950..08c749e9fa 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -70,18 +70,29 @@ uint32_t hexagon_get_sys_pcycle_count_low(CPUHexagonState *env)
void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env,
uint32_t cycles_hi)
{
- g_assert_not_reached();
+ uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
+ uint64_t cycles =
+ ((uint64_t)cycles_hi << 32) | extract64(cur_cycles, 0, 32);
+ hexagon_set_sys_pcycle_count(env, cycles);
}
void hexagon_set_sys_pcycle_count_low(CPUHexagonState *env,
uint32_t cycles_lo)
{
- g_assert_not_reached();
+ uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
+ uint64_t cycles = extract64(cur_cycles, 32, 32) | cycles_lo;
+ hexagon_set_sys_pcycle_count(env, cycles);
}
void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
{
- g_assert_not_reached();
+ *(env->g_pcycle_base) = cycles;
+
+ CPUState *cs;
+ CPU_FOREACH(cs) {
+ CPUHexagonState *env_ = cpu_env(cs);
+ env_->t_cycle_count = 0;
+ }
}
static void set_wait_mode(CPUHexagonState *env)
--
2.34.1
^ permalink raw reply related [flat|nested] 112+ messages in thread
* Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-01 5:28 ` [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock Brian Cain
@ 2025-03-03 16:24 ` Brian Cain
2025-03-04 23:09 ` ltaylorsimpson
2025-03-19 17:01 ` ltaylorsimpson
1 sibling, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-03 16:24 UTC (permalink / raw)
To: qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
ltaylorsimpson, alex.bennee, quic_mburton, sidneym, Brian Cain
On 2/28/2025 11:28 PM, Brian Cain wrote:
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/sys_macros.h | 8 +--
> target/hexagon/op_helper.c | 104 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 108 insertions(+), 4 deletions(-)
>
> diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
> index 3c4c3c7aa5..e5dc1ce0ab 100644
> --- a/target/hexagon/sys_macros.h
> +++ b/target/hexagon/sys_macros.h
> @@ -143,11 +143,11 @@
> #define fDCINVIDX(REG)
> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in qemu */
>
> -#define fSET_TLB_LOCK() g_assert_not_reached()
> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
>
> -#define fSET_K0_LOCK() g_assert_not_reached()
> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
> +#define fSET_K0_LOCK() hex_k0_lock(env);
> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
>
> #define fTLB_IDXMASK(INDEX) \
> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)->num_tlbs)) - 1))
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 702c3dd3c6..f3b14fbf58 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState *env, uint32_t new, uint32_t old)
> BQL_LOCK_GUARD();
> hexagon_modify_ssr(env, new, old);
> }
> +
> +static void hex_k0_lock(CPUHexagonState *env)
> +{
> + BQL_LOCK_GUARD();
> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> +
> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> + if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) {
> + if (env->k0_lock_state == HEX_LOCK_QUEUED) {
> + env->next_PC += 4;
> + env->k0_lock_count++;
> + env->k0_lock_state = HEX_LOCK_OWNER;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> + return;
> + }
> + if (env->k0_lock_state == HEX_LOCK_OWNER) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "Double k0lock at PC: 0x%x, thread may hang\n",
> + env->next_PC);
> + env->next_PC += 4;
> + CPUState *cs = env_cpu(env);
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> + return;
> + }
> + env->k0_lock_state = HEX_LOCK_WAITING;
> + CPUState *cs = env_cpu(env);
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> + } else {
> + env->next_PC += 4;
> + env->k0_lock_count++;
> + env->k0_lock_state = HEX_LOCK_OWNER;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> + }
> +
> +}
This was discussed previously at
https://lore.kernel.org/qemu-devel/CH3PR02MB102479550F96F09E0C9D50BA7B87B2@CH3PR02MB10247.namprd02.prod.outlook.com/
We have taken some but not all of the suggestions from then. One of our
concerns is regarding an architectural requirement for "fairness" with
regards to picking the hardware thread to be selected to pass the lock
to. If we unleash the thundering herd, does this just mean that the
fairness is dependent on the host scheduler design / configuration?
Also - I note that we didn't take the suggestions regarding
cpu_loop_exit / cpu_loop_exit_restore. That was an oversight, the next
revision will include that update.
> +
> +static void hex_k0_unlock(CPUHexagonState *env)
> +{
> + BQL_LOCK_GUARD();
> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> +
> + /* Nothing to do if the k0 isn't locked by this thread */
> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> + if ((GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg) == 0) ||
> + (env->k0_lock_state != HEX_LOCK_OWNER)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "thread %d attempted to unlock k0 without having the "
> + "lock, k0_lock state = %d, syscfg:k0 = %d\n",
> + env->threadId, env->k0_lock_state,
> + GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg));
> + g_assert(env->k0_lock_state != HEX_LOCK_WAITING);
> + return;
> + }
> +
> + env->k0_lock_count--;
> + env->k0_lock_state = HEX_LOCK_UNLOCKED;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 0);
> +
> + /* Look for a thread to unlock */
> + unsigned int this_threadId = env->threadId;
> + CPUHexagonState *unlock_thread = NULL;
> + CPUState *cs;
> + CPU_FOREACH(cs) {
> + CPUHexagonState *thread = cpu_env(cs);
> +
> + /*
> + * The hardware implements round-robin fairness, so we look for threads
> + * starting at env->threadId + 1 and incrementing modulo the number of
> + * threads.
> + *
> + * To implement this, we check if thread is a earlier in the modulo
> + * sequence than unlock_thread.
> + * if unlock thread is higher than this thread
> + * thread must be between this thread and unlock_thread
> + * else
> + * thread higher than this thread is ahead of unlock_thread
> + * thread must be lower then unlock thread
> + */
> + if (thread->k0_lock_state == HEX_LOCK_WAITING) {
> + if (!unlock_thread) {
> + unlock_thread = thread;
> + } else if (unlock_thread->threadId > this_threadId) {
> + if (this_threadId < thread->threadId &&
> + thread->threadId < unlock_thread->threadId) {
> + unlock_thread = thread;
> + }
> + } else {
> + if (thread->threadId > this_threadId) {
> + unlock_thread = thread;
> + }
> + if (thread->threadId < unlock_thread->threadId) {
> + unlock_thread = thread;
> + }
> + }
> + }
> + }
> + if (unlock_thread) {
> + cs = env_cpu(unlock_thread);
> + unlock_thread->k0_lock_state = HEX_LOCK_QUEUED;
> + SET_SYSCFG_FIELD(unlock_thread, SYSCFG_K0LOCK, 1);
> + cpu_interrupt(cs, CPU_INTERRUPT_K0_UNLOCK);
> + }
> +
> +}
> #endif
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-03 16:24 ` Brian Cain
@ 2025-03-04 23:09 ` ltaylorsimpson
2025-03-04 23:57 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-04 23:09 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Monday, March 3, 2025 10:24 AM
> To: qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org;
> quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>
>
> On 2/28/2025 11:28 PM, Brian Cain wrote:
> > From: Brian Cain <bcain@quicinc.com>
> >
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/sys_macros.h | 8 +--
> > target/hexagon/op_helper.c | 104
> ++++++++++++++++++++++++++++++++++++
> > 2 files changed, 108 insertions(+), 4 deletions(-)
> >
> > diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
> > index 3c4c3c7aa5..e5dc1ce0ab 100644
> > --- a/target/hexagon/sys_macros.h
> > +++ b/target/hexagon/sys_macros.h
> > @@ -143,11 +143,11 @@
> > #define fDCINVIDX(REG)
> > #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in
> > qemu */
> >
> > -#define fSET_TLB_LOCK() g_assert_not_reached()
> > -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
> > +#define fSET_TLB_LOCK() hex_tlb_lock(env);
> > +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
> >
> > -#define fSET_K0_LOCK() g_assert_not_reached()
> > -#define fCLEAR_K0_LOCK() g_assert_not_reached()
> > +#define fSET_K0_LOCK() hex_k0_lock(env);
> > +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
> >
> > #define fTLB_IDXMASK(INDEX) \
> > ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)-
> >num_tlbs)) -
> > 1)) diff --git a/target/hexagon/op_helper.c
> > b/target/hexagon/op_helper.c index 702c3dd3c6..f3b14fbf58 100644
> > --- a/target/hexagon/op_helper.c
> > +++ b/target/hexagon/op_helper.c
> > @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState
> *env, uint32_t new, uint32_t old)
> > BQL_LOCK_GUARD();
> > hexagon_modify_ssr(env, new, old);
> > }
> > +
> > +static void hex_k0_lock(CPUHexagonState *env) {
> > + BQL_LOCK_GUARD();
> > + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> > +
> > + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
Minor nit - registers should be target_ulong type.
> > + if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) {
> > + if (env->k0_lock_state == HEX_LOCK_QUEUED) {
Are HEX_LOCK_* defined in an earlier patch in this series. Can we move the definitions here?
> > + env->next_PC += 4;
> > + env->k0_lock_count++;
> > + env->k0_lock_state = HEX_LOCK_OWNER;
> > + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> > + return;
> > + }
> > + if (env->k0_lock_state == HEX_LOCK_OWNER) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "Double k0lock at PC: 0x%x, thread may hang\n",
> > + env->next_PC);
> > + env->next_PC += 4;
> > + CPUState *cs = env_cpu(env);
> > + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> > + return;
> > + }
> > + env->k0_lock_state = HEX_LOCK_WAITING;
> > + CPUState *cs = env_cpu(env);
> > + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> > + } else {
> > + env->next_PC += 4;
> > + env->k0_lock_count++;
> > + env->k0_lock_state = HEX_LOCK_OWNER;
> > + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> > + }
> > +
> > +}
>
> This was discussed previously at
> https://lore.kernel.org/qemu-
> devel/CH3PR02MB102479550F96F09E0C9D50BA7B87B2@CH3PR02MB10247.n
> amprd02.prod.outlook.com/
>
> We have taken some but not all of the suggestions from then. One of our
> concerns is regarding an architectural requirement for "fairness" with regards
> to picking the hardware thread to be selected to pass the lock to. If we
> unleash the thundering herd, does this just mean that the fairness is
> dependent on the host scheduler design / configuration?
>
> Also - I note that we didn't take the suggestions regarding cpu_loop_exit /
> cpu_loop_exit_restore. That was an oversight, the next revision will include
> that update.
>
> > +
> > +static void hex_k0_unlock(CPUHexagonState *env) {
> > + BQL_LOCK_GUARD();
> > + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> > +
> > + /* Nothing to do if the k0 isn't locked by this thread */
> > + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
target_ulong
> > + if ((GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg) == 0) ||
> > + (env->k0_lock_state != HEX_LOCK_OWNER)) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "thread %d attempted to unlock k0 without having the "
> > + "lock, k0_lock state = %d, syscfg:k0 = %d\n",
> > + env->threadId, env->k0_lock_state,
> > + GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg));
> > + g_assert(env->k0_lock_state != HEX_LOCK_WAITING);
> > + return;
> > + }
> > +
> > + env->k0_lock_count--;
> > + env->k0_lock_state = HEX_LOCK_UNLOCKED;
> > + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 0);
> > +
> > + /* Look for a thread to unlock */
> > + unsigned int this_threadId = env->threadId;
> > + CPUHexagonState *unlock_thread = NULL;
> > + CPUState *cs;
> > + CPU_FOREACH(cs) {
> > + CPUHexagonState *thread = cpu_env(cs);
> > +
> > + /*
> > + * The hardware implements round-robin fairness, so we look for
> threads
> > + * starting at env->threadId + 1 and incrementing modulo the number
> of
> > + * threads.
> > + *
> > + * To implement this, we check if thread is a earlier in the modulo
> > + * sequence than unlock_thread.
> > + * if unlock thread is higher than this thread
> > + * thread must be between this thread and unlock_thread
> > + * else
> > + * thread higher than this thread is ahead of unlock_thread
> > + * thread must be lower then unlock thread
> > + */
> > + if (thread->k0_lock_state == HEX_LOCK_WAITING) {
> > + if (!unlock_thread) {
> > + unlock_thread = thread;
> > + } else if (unlock_thread->threadId > this_threadId) {
> > + if (this_threadId < thread->threadId &&
> > + thread->threadId < unlock_thread->threadId) {
> > + unlock_thread = thread;
> > + }
> > + } else {
> > + if (thread->threadId > this_threadId) {
> > + unlock_thread = thread;
> > + }
> > + if (thread->threadId < unlock_thread->threadId) {
> > + unlock_thread = thread;
> > + }
> > + }
> > + }
> > + }
> > + if (unlock_thread) {
> > + cs = env_cpu(unlock_thread);
> > + unlock_thread->k0_lock_state = HEX_LOCK_QUEUED;
> > + SET_SYSCFG_FIELD(unlock_thread, SYSCFG_K0LOCK, 1);
> > + cpu_interrupt(cs, CPU_INTERRUPT_K0_UNLOCK);
> > + }
> > +
> > +}
> > #endif
> >
> >
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-04 23:09 ` ltaylorsimpson
@ 2025-03-04 23:57 ` Philippe Mathieu-Daudé
2025-03-05 0:05 ` ltaylorsimpson
0 siblings, 1 reply; 112+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-04 23:57 UTC (permalink / raw)
To: richard.henderson, ltaylorsimpson, 'Brian Cain',
qemu-devel
Cc: quic_mathbern, ale, anjo, quic_mliebel, alex.bennee, quic_mburton,
sidneym, 'Brian Cain'
Hi Taylor,
On 5/3/25 00:09, ltaylorsimpson@gmail.com wrote:
>
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Monday, March 3, 2025 10:24 AM
>> To: qemu-devel@nongnu.org
>> Cc: richard.henderson@linaro.org; philmd@linaro.org;
>> quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>>
>>
>> On 2/28/2025 11:28 PM, Brian Cain wrote:
>>> From: Brian Cain <bcain@quicinc.com>
>>>
>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>>> ---
>>> target/hexagon/sys_macros.h | 8 +--
>>> target/hexagon/op_helper.c | 104
>> ++++++++++++++++++++++++++++++++++++
>>> 2 files changed, 108 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
>>> index 3c4c3c7aa5..e5dc1ce0ab 100644
>>> --- a/target/hexagon/sys_macros.h
>>> +++ b/target/hexagon/sys_macros.h
>>> @@ -143,11 +143,11 @@
>>> #define fDCINVIDX(REG)
>>> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in
>>> qemu */
>>>
>>> -#define fSET_TLB_LOCK() g_assert_not_reached()
>>> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
>>> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
>>> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
>>>
>>> -#define fSET_K0_LOCK() g_assert_not_reached()
>>> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
>>> +#define fSET_K0_LOCK() hex_k0_lock(env);
>>> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
>>>
>>> #define fTLB_IDXMASK(INDEX) \
>>> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)-
>>> num_tlbs)) -
>>> 1)) diff --git a/target/hexagon/op_helper.c
>>> b/target/hexagon/op_helper.c index 702c3dd3c6..f3b14fbf58 100644
>>> --- a/target/hexagon/op_helper.c
>>> +++ b/target/hexagon/op_helper.c
>>> @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState
>> *env, uint32_t new, uint32_t old)
>>> BQL_LOCK_GUARD();
>>> hexagon_modify_ssr(env, new, old);
>>> }
>>> +
>>> +static void hex_k0_lock(CPUHexagonState *env) {
>>> + BQL_LOCK_GUARD();
>>> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
>>> +
>>> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
>
> Minor nit - registers should be target_ulong type.
Since Hexagon is only implemented using 32-bit registers, is it worth
using target_ulong? (I'm trying to foresee heterogeneous emulation).
Richard, any thought on this (whether a target implementing only 32
*or* 64 bits should use target_[u]long).
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-04 23:57 ` Philippe Mathieu-Daudé
@ 2025-03-05 0:05 ` ltaylorsimpson
2025-03-05 0:19 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-05 0:05 UTC (permalink / raw)
To: 'Philippe Mathieu-Daudé', richard.henderson,
'Brian Cain', qemu-devel
Cc: quic_mathbern, ale, anjo, quic_mliebel, alex.bennee, quic_mburton,
sidneym, 'Brian Cain'
> -----Original Message-----
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
> Sent: Tuesday, March 4, 2025 5:58 PM
> To: richard.henderson@linaro.org; ltaylorsimpson@gmail.com; 'Brian Cain'
> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; alex.bennee@linaro.org;
> quic_mburton@quicinc.com; sidneym@quicinc.com; 'Brian Cain'
> <bcain@quicinc.com>
> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>
> Hi Taylor,
>
> On 5/3/25 00:09, ltaylorsimpson@gmail.com wrote:
> >
> >
> >> -----Original Message-----
> >> From: Brian Cain <brian.cain@oss.qualcomm.com>
> >> Sent: Monday, March 3, 2025 10:24 AM
> >> To: qemu-devel@nongnu.org
> >> Cc: richard.henderson@linaro.org; philmd@linaro.org;
> >> quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> >> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> >> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> >> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> >> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
> >>
> >>
> >> On 2/28/2025 11:28 PM, Brian Cain wrote:
> >>> From: Brian Cain <bcain@quicinc.com>
> >>>
> >>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> >>> ---
> >>> target/hexagon/sys_macros.h | 8 +--
> >>> target/hexagon/op_helper.c | 104
> >> ++++++++++++++++++++++++++++++++++++
> >>> 2 files changed, 108 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/target/hexagon/sys_macros.h
> >>> b/target/hexagon/sys_macros.h index 3c4c3c7aa5..e5dc1ce0ab 100644
> >>> --- a/target/hexagon/sys_macros.h
> >>> +++ b/target/hexagon/sys_macros.h
> >>> @@ -143,11 +143,11 @@
> >>> #define fDCINVIDX(REG)
> >>> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do
> >>> in qemu */
> >>>
> >>> -#define fSET_TLB_LOCK() g_assert_not_reached()
> >>> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
> >>> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
> >>> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
> >>>
> >>> -#define fSET_K0_LOCK() g_assert_not_reached()
> >>> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
> >>> +#define fSET_K0_LOCK() hex_k0_lock(env);
> >>> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
> >>>
> >>> #define fTLB_IDXMASK(INDEX) \
> >>> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)-
> >>> num_tlbs)) -
> >>> 1)) diff --git a/target/hexagon/op_helper.c
> >>> b/target/hexagon/op_helper.c index 702c3dd3c6..f3b14fbf58 100644
> >>> --- a/target/hexagon/op_helper.c
> >>> +++ b/target/hexagon/op_helper.c
> >>> @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState
> >> *env, uint32_t new, uint32_t old)
> >>> BQL_LOCK_GUARD();
> >>> hexagon_modify_ssr(env, new, old);
> >>> }
> >>> +
> >>> +static void hex_k0_lock(CPUHexagonState *env) {
> >>> + BQL_LOCK_GUARD();
> >>> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count ==
> >>> +1));
> >>> +
> >>> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> >
> > Minor nit - registers should be target_ulong type.
>
> Since Hexagon is only implemented using 32-bit registers, is it worth using
> target_ulong? (I'm trying to foresee heterogeneous emulation).
>
> Richard, any thought on this (whether a target implementing only 32
> *or* 64 bits should use target_[u]long).
It's just a hedge against the future in case Qualcomm ever builds a 64-bit Hexagon.
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-05 0:05 ` ltaylorsimpson
@ 2025-03-05 0:19 ` Philippe Mathieu-Daudé
2025-03-05 0:45 ` ltaylorsimpson
0 siblings, 1 reply; 112+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 0:19 UTC (permalink / raw)
To: ltaylorsimpson, richard.henderson, 'Brian Cain',
qemu-devel
Cc: quic_mathbern, ale, anjo, quic_mliebel, alex.bennee, quic_mburton,
sidneym, 'Brian Cain'
On 5/3/25 01:05, ltaylorsimpson@gmail.com wrote:
>
>
>> -----Original Message-----
>> From: Philippe Mathieu-Daudé <philmd@linaro.org>
>> Sent: Tuesday, March 4, 2025 5:58 PM
>> To: richard.henderson@linaro.org; ltaylorsimpson@gmail.com; 'Brian Cain'
>> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
>> Cc: quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; alex.bennee@linaro.org;
>> quic_mburton@quicinc.com; sidneym@quicinc.com; 'Brian Cain'
>> <bcain@quicinc.com>
>> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>>
>> Hi Taylor,
>>
>> On 5/3/25 00:09, ltaylorsimpson@gmail.com wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>>>> Sent: Monday, March 3, 2025 10:24 AM
>>>> To: qemu-devel@nongnu.org
>>>> Cc: richard.henderson@linaro.org; philmd@linaro.org;
>>>> quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>>>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>>>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>>>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>>>> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>>>>
>>>>
>>>> On 2/28/2025 11:28 PM, Brian Cain wrote:
>>>>> From: Brian Cain <bcain@quicinc.com>
>>>>>
>>>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>>>>> ---
>>>>> target/hexagon/sys_macros.h | 8 +--
>>>>> target/hexagon/op_helper.c | 104
>>>> ++++++++++++++++++++++++++++++++++++
>>>>> 2 files changed, 108 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/target/hexagon/sys_macros.h
>>>>> b/target/hexagon/sys_macros.h index 3c4c3c7aa5..e5dc1ce0ab 100644
>>>>> --- a/target/hexagon/sys_macros.h
>>>>> +++ b/target/hexagon/sys_macros.h
>>>>> @@ -143,11 +143,11 @@
>>>>> #define fDCINVIDX(REG)
>>>>> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do
>>>>> in qemu */
>>>>>
>>>>> -#define fSET_TLB_LOCK() g_assert_not_reached()
>>>>> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
>>>>> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
>>>>> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
>>>>>
>>>>> -#define fSET_K0_LOCK() g_assert_not_reached()
>>>>> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
>>>>> +#define fSET_K0_LOCK() hex_k0_lock(env);
>>>>> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
>>>>>
>>>>> #define fTLB_IDXMASK(INDEX) \
>>>>> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)-
>>>>> num_tlbs)) -
>>>>> 1)) diff --git a/target/hexagon/op_helper.c
>>>>> b/target/hexagon/op_helper.c index 702c3dd3c6..f3b14fbf58 100644
>>>>> --- a/target/hexagon/op_helper.c
>>>>> +++ b/target/hexagon/op_helper.c
>>>>> @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState
>>>> *env, uint32_t new, uint32_t old)
>>>>> BQL_LOCK_GUARD();
>>>>> hexagon_modify_ssr(env, new, old);
>>>>> }
>>>>> +
>>>>> +static void hex_k0_lock(CPUHexagonState *env) {
>>>>> + BQL_LOCK_GUARD();
>>>>> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count ==
>>>>> +1));
>>>>> +
>>>>> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
>>>
>>> Minor nit - registers should be target_ulong type.
>>
>> Since Hexagon is only implemented using 32-bit registers, is it worth using
>> target_ulong? (I'm trying to foresee heterogeneous emulation).
>>
>> Richard, any thought on this (whether a target implementing only 32
>> *or* 64 bits should use target_[u]long).
>
> It's just a hedge against the future in case Qualcomm ever builds a 64-bit Hexagon.
If there are plan for such future, then this is fine.
We are worried by maintenance burden, see for microblaze:
https://lore.kernel.org/qemu-devel/ad364fce-f73d-4dde-b890-0ea86d9c4674@linaro.org/
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-05 0:19 ` Philippe Mathieu-Daudé
@ 2025-03-05 0:45 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-05 0:45 UTC (permalink / raw)
To: 'Philippe Mathieu-Daudé', richard.henderson,
'Brian Cain', qemu-devel
Cc: quic_mathbern, ale, anjo, quic_mliebel, alex.bennee, quic_mburton,
sidneym, 'Brian Cain'
> -----Original Message-----
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
> Sent: Tuesday, March 4, 2025 6:19 PM
> To: ltaylorsimpson@gmail.com; richard.henderson@linaro.org; 'Brian Cain'
> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; alex.bennee@linaro.org;
> quic_mburton@quicinc.com; sidneym@quicinc.com; 'Brian Cain'
> <bcain@quicinc.com>
> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>
> On 5/3/25 01:05, ltaylorsimpson@gmail.com wrote:
> >
> >
> >> -----Original Message-----
> >> From: Philippe Mathieu-Daudé <philmd@linaro.org>
> >> Sent: Tuesday, March 4, 2025 5:58 PM
> >> To: richard.henderson@linaro.org; ltaylorsimpson@gmail.com; 'Brian Cain'
> >> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> >> Cc: quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> >> quic_mliebel@quicinc.com; alex.bennee@linaro.org;
> >> quic_mburton@quicinc.com; sidneym@quicinc.com; 'Brian Cain'
> >> <bcain@quicinc.com>
> >> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
> >>
> >> Hi Taylor,
> >>
> >> On 5/3/25 00:09, ltaylorsimpson@gmail.com wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Brian Cain <brian.cain@oss.qualcomm.com>
> >>>> Sent: Monday, March 3, 2025 10:24 AM
> >>>> To: qemu-devel@nongnu.org
> >>>> Cc: richard.henderson@linaro.org; philmd@linaro.org;
> >>>> quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> >>>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> >>>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> >>>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> >>>> Subject: Re: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
> >>>>
> >>>>
> >>>> On 2/28/2025 11:28 PM, Brian Cain wrote:
> >>>>> From: Brian Cain <bcain@quicinc.com>
> >>>>>
> >>>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> >>>>> ---
> >>>>> target/hexagon/sys_macros.h | 8 +--
> >>>>> target/hexagon/op_helper.c | 104
> >>>> ++++++++++++++++++++++++++++++++++++
> >>>>> 2 files changed, 108 insertions(+), 4 deletions(-)
> >>>>>
> >>>>> diff --git a/target/hexagon/sys_macros.h
> >>>>> b/target/hexagon/sys_macros.h index 3c4c3c7aa5..e5dc1ce0ab
> 100644
> >>>>> --- a/target/hexagon/sys_macros.h
> >>>>> +++ b/target/hexagon/sys_macros.h
> >>>>> @@ -143,11 +143,11 @@
> >>>>> #define fDCINVIDX(REG)
> >>>>> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to
> >>>>> do in qemu */
> >>>>>
> >>>>> -#define fSET_TLB_LOCK() g_assert_not_reached()
> >>>>> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
> >>>>> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
> >>>>> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
> >>>>>
> >>>>> -#define fSET_K0_LOCK() g_assert_not_reached()
> >>>>> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
> >>>>> +#define fSET_K0_LOCK() hex_k0_lock(env);
> >>>>> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
> >>>>>
> >>>>> #define fTLB_IDXMASK(INDEX) \
> >>>>> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)-
> >>>>> num_tlbs)) -
> >>>>> 1)) diff --git a/target/hexagon/op_helper.c
> >>>>> b/target/hexagon/op_helper.c index 702c3dd3c6..f3b14fbf58 100644
> >>>>> --- a/target/hexagon/op_helper.c
> >>>>> +++ b/target/hexagon/op_helper.c
> >>>>> @@ -1184,6 +1184,110 @@ void
> HELPER(modify_ssr)(CPUHexagonState
> >>>> *env, uint32_t new, uint32_t old)
> >>>>> BQL_LOCK_GUARD();
> >>>>> hexagon_modify_ssr(env, new, old);
> >>>>> }
> >>>>> +
> >>>>> +static void hex_k0_lock(CPUHexagonState *env) {
> >>>>> + BQL_LOCK_GUARD();
> >>>>> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count ==
> >>>>> +1));
> >>>>> +
> >>>>> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> >>>
> >>> Minor nit - registers should be target_ulong type.
> >>
> >> Since Hexagon is only implemented using 32-bit registers, is it worth
> >> using target_ulong? (I'm trying to foresee heterogeneous emulation).
> >>
> >> Richard, any thought on this (whether a target implementing only 32
> >> *or* 64 bits should use target_[u]long).
> >
> > It's just a hedge against the future in case Qualcomm ever builds a 64-bit
> Hexagon.
>
> If there are plan for such future, then this is fine.
> We are worried by maintenance burden, see for microblaze:
> https://lore.kernel.org/qemu-devel/ad364fce-f73d-4dde-b890-
> 0ea86d9c4674@linaro.org/
As I said "minor nit". I did a search through the code and the registers are declared in cpu.h as target_ulong but arch_get_system_reg is defined to return uint32_t. The users of this function have a mix of uint32_t and target_ulong.
From a quick read of the thread you pointed out, the problem for microblaze is changing the TARGET_LONG_BITS from 64 to 32. Hexagon wouldn't have this problem.
I'm not aware of any plans for a 64-bit Hexagon, so I'll leave it to Brian to decide if he thinks the change is worthwhile.
Taylor
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 01/39] target/hexagon: Implement ciad helper
2025-03-01 5:28 ` [PATCH 01/39] target/hexagon: Implement ciad helper Brian Cain
@ 2025-03-17 16:08 ` ltaylorsimpson
2025-03-18 14:44 ` Sid Manning
2025-09-02 1:32 ` Brian Cain
0 siblings, 2 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 16:08 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 01/39] target/hexagon: Implement ciad helper
>
> From: Brian Cain <bcain@quicinc.com>
>
> ciad is the clear interrupt auto disable instruction.
>
> This instruction is defined in the Qualcomm Hexagon V71 Programmer's
> Reference Manual - https://docs.qualcomm.com/bundle/publicresource/80-
> N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
> See §11.9.2 SYSTEM MONITOR.
Put this reference in somewhere easier to find. See prior discussion on this.
If it's only in the commit comment, it will be lost quickly.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/op_helper.c | 39 ++++++++++++++++++++++++++++++++-
> -----
> 1 file changed, 33 insertions(+), 6 deletions(-)
>
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index fd9caafefc..b28a18adf6 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -34,6 +34,11 @@
> #include "op_helper.h"
> #include "cpu_helper.h"
> #include "translate.h"
> +#ifndef CONFIG_USER_ONLY
> +#include "hex_mmu.h"
> +#include "hw/intc/l2vic.h"
> +#include "hex_interrupts.h"
> +#endif
>
> #define SF_BIAS 127
> #define SF_MANTBITS 23
> @@ -1338,9 +1343,36 @@ void HELPER(vwhist128qm)(CPUHexagonState
> *env, int32_t uiV) }
>
> #ifndef CONFIG_USER_ONLY
> +static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int
> +val) {
> + g_assert((offset == L2VIC_VID_0) || (offset == L2VIC_VID_1));
> + CPUState *cs = env_cpu(env);
> + HexagonCPU *cpu = HEXAGON_CPU(cs);
> + const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
> + cpu_physical_memory_write(pend_mem, &val, sizeof(val)); }
Careful here - an int is different sizes on 32-bit and 64-bit hosts. Change the type to int32_t or int64_t.
> +
> +static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t
> +offset) {
> + /*
> + * currently only l2vic is the only attached it uses vid0, remove
> + * the assert below if anther is added
What assert?
> + */
> + hexagon_set_vid(env, offset, L2VIC_CIAD_INSTRUCTION); }
> +
> void HELPER(ciad)(CPUHexagonState *env, uint32_t mask) {
> - g_assert_not_reached();
> + uint32_t ipendad;
> + uint32_t iad;
> +
> + BQL_LOCK_GUARD();
> + ipendad = READ_SREG(HEX_SREG_IPENDAD);
> + iad = fGET_FIELD(ipendad, IPENDAD_IAD);
> + fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask));
> + arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
> + hexagon_clear_last_irq(env, L2VIC_VID_0);
> + hex_interrupt_update(env);
> }
>
> void HELPER(siad)(CPUHexagonState *env, uint32_t mask) @@ -1416,11
> +1448,6 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t val)
> g_assert_not_reached();
> }
>
> -static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int
> val) -{
> - g_assert_not_reached();
> -}
> -
> static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
> {
> g_assert_not_reached();
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 02/39] target/hexagon: Implement {c,}swi helpers
2025-03-01 5:28 ` [PATCH 02/39] target/hexagon: Implement {c,}swi helpers Brian Cain
@ 2025-03-17 16:09 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 16:09 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 02/39] target/hexagon: Implement {c,}swi helpers
>
> From: Brian Cain <bcain@quicinc.com>
>
> {c,}swi are the "software interrupt"/"Cancel pending interrupts" instructions.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers
2025-03-01 5:28 ` [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers Brian Cain
@ 2025-03-17 16:20 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 16:20 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers
>
> From: Brian Cain <bcain@quicinc.com>
>
> iassign{r,w} are the "Interrupt to thread assignment {read,write}"
> instructions.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 04/39] target/hexagon: Implement start/stop helpers
2025-03-01 5:28 ` [PATCH 04/39] target/hexagon: Implement start/stop helpers Brian Cain
@ 2025-03-17 16:35 ` ltaylorsimpson
2025-09-02 1:33 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 16:35 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 04/39] target/hexagon: Implement start/stop helpers
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 3 ++
> target/hexagon/cpu_bits.h | 1 +
> target/hexagon/cpu_helper.h | 3 ++
> target/hexagon/cpu.c | 14 +++++-
> target/hexagon/cpu_helper.c | 94
> +++++++++++++++++++++++++++++++++++++
> target/hexagon/op_helper.c | 4 +-
> 6 files changed, 116 insertions(+), 3 deletions(-)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> 894219fd20..1549c4f1f0 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -41,6 +41,7 @@ typedef struct CPUHexagonTLBContext
> CPUHexagonTLBContext; #define REG_WRITES_MAX 32
> #define PRED_WRITES_MAX 5 /* 4 insns + endloop */
> #define VSTORES_MAX 2
> +#define VECTOR_UNIT_MAX 8
Not related to start/stop and not used in this patch.
>
> #ifndef CONFIG_USER_ONLY
> #define CPU_INTERRUPT_SWI CPU_INTERRUPT_TGT_INT_0
> @@ -178,6 +179,7 @@ struct ArchCPU {
> #ifndef CONFIG_USER_ONLY
> uint32_t num_tlbs;
> uint32_t l2vic_base_addr;
> + uint32_t hvx_contexts;
Not related to start/stop.
> #endif
> };
>
> @@ -194,6 +196,7 @@ G_NORETURN void
> hexagon_raise_exception_err(CPUHexagonState *env, uint32_t
> hexagon_greg_read(CPUHexagonState *env, uint32_t reg); uint32_t
> hexagon_sreg_read(CPUHexagonState *env, uint32_t reg); void
> hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t
> val);
> +void hexagon_cpu_soft_reset(CPUHexagonState *env);
> #endif
>
> #include "exec/cpu-all.h"
> diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h index
> b559a7ba88..610094a759 100644
> --- a/target/hexagon/cpu_bits.h
> +++ b/target/hexagon/cpu_bits.h
> @@ -52,6 +52,7 @@ enum hex_event {
>
> enum hex_cause {
> HEX_CAUSE_NONE = -1,
> + HEX_CAUSE_RESET = 0x000,
> HEX_CAUSE_TRAP0 = 0x172,
> HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
> HEX_CAUSE_INVALID_PACKET = 0x015,
> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
> index 6f0c6697ad..95a0cc0788 100644
> --- a/target/hexagon/cpu_helper.h
> +++ b/target/hexagon/cpu_helper.h
> @@ -17,6 +17,9 @@ void
> hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, uint32_t);
> void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t
> old); int get_exe_mode(CPUHexagonState *env); void
> clear_wait_mode(CPUHexagonState *env);
> +void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause); void
> +hexagon_start_threads(CPUHexagonState *env, uint32_t mask); void
> +hexagon_stop_thread(CPUHexagonState *env);
>
> static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
> uint32_t val) diff --git a/target/hexagon/cpu.c
> b/target/hexagon/cpu.c index cb56b929cf..84a96a194b 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -32,6 +32,7 @@
>
> #ifndef CONFIG_USER_ONLY
> #include "sys_macros.h"
> +#include "qemu/main-loop.h"
> #endif
>
> static void hexagon_v66_cpu_init(Object *obj) { } @@ -61,6 +62,7 @@ static
> const Property hexagon_cpu_properties[] = {
> DEFINE_PROP_UINT32("jtlb-entries", HexagonCPU, num_tlbs,
> MAX_TLB_ENTRIES),
> DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
> 0xffffffffULL),
> + DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
Not related to start/stop.
> #endif
> DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-01 5:28 ` [PATCH 05/39] target/hexagon: Implement modify SSR Brian Cain
@ 2025-03-17 17:37 ` ltaylorsimpson
2025-03-18 18:34 ` Sid Manning
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 17:37 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 05/39] target/hexagon: Implement modify SSR
>
> From: Brian Cain <bcain@quicinc.com>
>
> The per-vCPU System Status Register controls many modal behaviors of the
> system architecture. When the SSR is updated, we trigger the necessary
> effects for interrupts, privilege/MMU, and HVX context mapping.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu_helper.c | 100
> +++++++++++++++++++++++++++++++++++-
> 1 file changed, 99 insertions(+), 1 deletion(-)
>
> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
> index e151c6335a..3e2364a7b0 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -14,6 +14,8 @@
> #else
> #include "hw/boards.h"
> #include "hw/hexagon/hexagon.h"
> +#include "hex_interrupts.h"
> +#include "hex_mmu.h"
> #endif
> #include "exec/exec-all.h"
> #include "exec/cpu_ldst.h"
> @@ -69,9 +71,105 @@ void
> hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
> g_assert_not_reached();
> }
>
> +static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS];
> +static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS];
This won't scale for a system with multiple Hexagon instances. See discussion on how to handle shared resources.
> +
> +/*
> + * EXT_CONTEXTS
> + * SSR.XA 2 4 6 8
> + * 000 HVX Context 0 HVX Context 0 HVX Context 0 HVX Context 0
> + * 001 HVX Context 1 HVX Context 1 HVX Context 1 HVX Context 1
> + * 010 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 2
> + * 011 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 3
> + * 100 HVX Context 0 HVX Context 0 HVX Context 4 HVX Context 4
> + * 101 HVX Context 1 HVX Context 1 HVX Context 5 HVX Context 5
> + * 110 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 6
> + * 111 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 7
> + */
This is different from what the HVX PRM says. It only specifies what XA values 4, 5, 6, 7 mean.
Here is what it says:
The HVX scalar core can contain any number of hardware threads greater or equal to the number
of vector contexts. The scalar hardware thread is assignable to a vector context through per-
thread SSR:XA programming, as follows:
- SSR:XA = 4: HVX instructions use vector context 0.
- SSR:XA = 5: HVX instructions use vector context 1, if it is available.
- SSR:XA = 6: HVX instructions use vector context 2, if it is available.
- SSR:XA = 7: HVX instructions use vector context 3, if it is available.
> +static int parse_context_idx(CPUHexagonState *env, uint8_t XA) {
> + int ret;
> + HexagonCPU *cpu = env_archcpu(env);
You should assert that cpu->hvx_contexts is in { 2, 4, 6, 8 }. This will future proof against changes to the hardware as well as protect against bad command-line settings.
> + if (cpu->hvx_contexts == 6 && XA >= 6) {
> + ret = XA - 6 + 2;
> + } else {
> + ret = XA % cpu->hvx_contexts;
> + }
> + g_assert(ret >= 0 && ret < VECTOR_UNIT_MAX);
> + return ret;
> +}
> +
> +static void check_overcommitted_hvx(CPUHexagonState *env, uint32_t
> ssr)
> +{
> + if (!GET_FIELD(SSR_XE, ssr)) {
> + return;
> + }
What does SSR_XE indicate?
> +
> + uint8_t XA = GET_SSR_FIELD(SSR_XA, ssr);
> +
> + CPUState *cs;
> + CPU_FOREACH(cs) {
> + CPUHexagonState *env_ = cpu_env(cs);
This underscore is confusing. Use a full name such as thread_env.
> + if (env_ == env) {
> + continue;
> + }
> + /* Check if another thread has the XE bit set and same XA */
> + uint32_t ssr_ = arch_get_system_reg(env_, HEX_SREG_SSR);
Ditto
> + if (GET_SSR_FIELD(SSR_XE2, ssr_) && GET_FIELD(SSR_XA, ssr_) == XA) {
The comment says check the XE bit but the code checks XE2. Also, note the XE check on the current thread above.
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "setting SSR.XA '%d' on thread %d but thread"
> + " %d has same extension active\n", XA, env->threadId,
> + env_->threadId);
> + }
> + }
> +}
> +
> void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t
> old) {
> - g_assert_not_reached();
> + g_assert(bql_locked());
> +
> + bool old_EX = GET_SSR_FIELD(SSR_EX, old);
> + bool old_UM = GET_SSR_FIELD(SSR_UM, old);
> + bool old_GM = GET_SSR_FIELD(SSR_GM, old);
> + bool old_IE = GET_SSR_FIELD(SSR_IE, old);
> + uint8_t old_XA = GET_SSR_FIELD(SSR_XA, old);
> + bool new_EX = GET_SSR_FIELD(SSR_EX, new);
> + bool new_UM = GET_SSR_FIELD(SSR_UM, new);
> + bool new_GM = GET_SSR_FIELD(SSR_GM, new);
> + bool new_IE = GET_SSR_FIELD(SSR_IE, new);
> + uint8_t new_XA = GET_SSR_FIELD(SSR_XA, new);
> +
> + if ((old_EX != new_EX) ||
> + (old_UM != new_UM) ||
> + (old_GM != new_GM)) {
> + hex_mmu_mode_change(env);
> + }
> +
> + uint8_t old_asid = GET_SSR_FIELD(SSR_ASID, old);
> + uint8_t new_asid = GET_SSR_FIELD(SSR_ASID, new);
> + if (new_asid != old_asid) {
> + CPUState *cs = env_cpu(env);
> + tlb_flush(cs);
> + }
> +
> + if (old_XA != new_XA) {
> + int old_unit = parse_context_idx(env, old_XA);
> + int new_unit = parse_context_idx(env, new_XA);
Check that old_unit != new_unit. Per the table above, different XA values can point to the same unit. For example, if cpu->hvx_contexts is 2, the XA=0 and XA=2 both point to context 0.
> +
> + /* Ownership exchange */
> + memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
> + memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
> + memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
> + memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
What does the hardware do? Does it clear the context, or is that the OS'es job?
If the hardware leaves the context alone, the above should be
1) Copy env->{VQ}Regs to old_unit
2) Copy new_unit to env->{VQ}Regs
Should you check SSR_EX before doing these copies?
Do you need to do anything when SSR_EX changes?
> +
> + check_overcommitted_hvx(env, new);
> + }
> +
> + /* See if the interrupts have been enabled or we have exited EX mode */
> + if ((new_IE && !old_IE) ||
> + (!new_EX && old_EX)) {
> + hex_interrupt_update(env);
> + }
> }
>
> void clear_wait_mode(CPUHexagonState *env)
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
2025-03-01 5:28 ` [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers Brian Cain
@ 2025-03-17 17:44 ` ltaylorsimpson
2025-03-21 21:48 ` Sid Manning
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 17:44 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/op_helper.c | 31 +++++++++++++++++++++++++++++--
> 1 file changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 9f79b1a20c..83088cfaa3 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -1468,12 +1468,39 @@ void HELPER(resume)(CPUHexagonState *env,
> uint32_t mask)
>
> uint32_t HELPER(getimask)(CPUHexagonState *env, uint32_t tid) {
> - g_assert_not_reached();
> + CPUState *cs;
> + CPU_FOREACH(cs) {
> + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
> + CPUHexagonState *found_env = &found_cpu->env;
> + if (found_env->threadId == tid) {
> + target_ulong imask = arch_get_system_reg(found_env,
> HEX_SREG_IMASK);
> + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask = 0x%x\n",
> + __func__, env->threadId,
> + (unsigned)GET_FIELD(IMASK_MASK, imask));
> + return GET_FIELD(IMASK_MASK, imask);
> + }
> + }
> + return 0;
> }
>
> void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t
> imask) {
The name pred sounds like a predicate register. Use tid instead.
> - g_assert_not_reached();
> + CPUState *cs;
> +
> + BQL_LOCK_GUARD();
> + CPU_FOREACH(cs) {
> + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
> + CPUHexagonState *found_env = &found_cpu->env;
> +
> + if (pred == found_env->threadId) {
> + SET_SYSTEM_FIELD(found_env, HEX_SREG_IMASK, IMASK_MASK,
> imask);
> + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask 0x%x\n",
> + __func__, found_env->threadId, imask);
> + hex_interrupt_update(env);
Shouldn't this be found_env?
> + return;
> + }
> + }
> + hex_interrupt_update(env);
Do you need to update if the thread wasn't found?
> }
>
> static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 07/39] target/hexagon: Implement wait helper
2025-03-01 5:28 ` [PATCH 07/39] target/hexagon: Implement wait helper Brian Cain
@ 2025-03-17 18:37 ` ltaylorsimpson
2025-09-02 1:46 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 18:37 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 07/39] target/hexagon: Implement wait helper
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu_helper.h | 1 +
> target/hexagon/cpu_helper.c | 40
> +++++++++++++++++++++++++++++++++++++
> target/hexagon/op_helper.c | 6 +++++-
> 3 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
> index 95a0cc0788..e8d89d8526 100644
> --- a/target/hexagon/cpu_helper.h
> +++ b/target/hexagon/cpu_helper.h
> @@ -20,6 +20,7 @@ void clear_wait_mode(CPUHexagonState *env); void
> hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause); void
> hexagon_start_threads(CPUHexagonState *env, uint32_t mask); void
> hexagon_stop_thread(CPUHexagonState *env);
> +void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC);
>
> static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
> uint32_t val) diff --git a/target/hexagon/cpu_helper.c
> b/target/hexagon/cpu_helper.c index 3e2364a7b0..e64568b9fc 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -71,6 +71,46 @@ void
> hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
> g_assert_not_reached();
> }
>
> +static void set_wait_mode(CPUHexagonState *env) {
> + g_assert(bql_locked());
> +
> + const uint32_t modectl = arch_get_system_reg(env,
> HEX_SREG_MODECTL);
> + uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
> + thread_wait_mask |= 0x1 << env->threadId;
> + SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W,
> +thread_wait_mask); }
> +
> +void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC) {
> + g_assert(bql_locked());
> +
> + if (qemu_loglevel_mask(LOG_GUEST_ERROR) &&
> + (env->k0_lock_state != HEX_LOCK_UNLOCKED ||
> + env->tlb_lock_state != HEX_LOCK_UNLOCKED)) {
> + qemu_log("WARNING: executing wait() with acquired lock"
> + "may lead to deadlock\n");
> + }
> + g_assert(get_exe_mode(env) != HEX_EXE_MODE_WAIT);
> +
> + CPUState *cs = env_cpu(env);
> + /*
> + * The addtion of cpu_has_work is borrowed from arm's wfi helper
> + * and is critical for our stability
> + */
> + if ((cs->exception_index != HEX_EVENT_NONE) ||
> + (cpu_has_work(cs))) {
> + qemu_log_mask(CPU_LOG_INT,
> + "%s: thread %d skipping WAIT mode, have some work\n",
> + __func__, env->threadId);
> + return;
> + }
> + set_wait_mode(env);
> + env->wait_next_pc = PC + 4;
> +
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT); }
> +
Why not put this in op_helper.c?
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 08/39] target/hexagon: Implement get_exe_mode()
2025-03-01 5:28 ` [PATCH 08/39] target/hexagon: Implement get_exe_mode() Brian Cain
@ 2025-03-17 18:43 ` ltaylorsimpson
2025-04-02 2:03 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 18:43 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 08/39] target/hexagon: Implement get_exe_mode()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
> index e64568b9fc..e0dd120cd4 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -237,6 +237,30 @@ void hexagon_ssr_set_cause(CPUHexagonState
> *env, uint32_t cause)
>
> int get_exe_mode(CPUHexagonState *env)
> {
> + g_assert(bql_locked());
> +
> + target_ulong modectl = arch_get_system_reg(env,
> HEX_SREG_MODECTL);
> + uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
> + bool E_bit = thread_enabled_mask & (0x1 << env->threadId);
> + uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
> + bool W_bit = thread_wait_mask & (0x1 << env->threadId);
> + target_ulong isdbst = arch_get_system_reg(env, HEX_SREG_ISDBST);
> + uint32_t debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst);
> + bool D_bit = debugmode & (0x1 << env->threadId);
> +
> + /* Figure 4-2 */
Figure 4-2 in which document?
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 09/39] target/hexagon: Implement arch_get_system_reg()
2025-03-01 5:28 ` [PATCH 09/39] target/hexagon: Implement arch_get_system_reg() Brian Cain
@ 2025-03-17 18:46 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 18:46 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 09/39] target/hexagon: Implement arch_get_system_reg()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg()
2025-03-01 5:28 ` [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg() Brian Cain via
@ 2025-03-17 19:24 ` ltaylorsimpson
2025-09-02 1:50 ` [PATCH 10/39] target/hexagon: Implement arch_{s,g}et_{thread,system}_reg() Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:24 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 10/39] target/hexagon: Implement
> arch_{s,g}et_{thread,system}_reg()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu_helper.h | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
> index e8d89d8526..1cdf4f8dd0 100644
> --- a/target/hexagon/cpu_helper.h
> +++ b/target/hexagon/cpu_helper.h
> @@ -26,20 +26,27 @@ static inline void
> arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
> uint32_t val) {
> g_assert(reg < TOTAL_PER_THREAD_REGS);
> - g_assert_not_reached();
> + env->gpr[reg] = val;
Gotta be careful here. Not all registers can be assigned directly. Look at gen_write_ctrl_reg in genptr.c.
> }
>
> static inline uint32_t arch_get_thread_reg(CPUHexagonState *env, uint32_t
> reg) {
> g_assert(reg < TOTAL_PER_THREAD_REGS);
> - g_assert_not_reached();
> + return env->gpr[reg];
Ditto - look at gen_read_ctrl_reg in genptr.c
> }
>
> +#ifndef CONFIG_USER_ONLY
> static inline void arch_set_system_reg(CPUHexagonState *env, uint32_t
> reg,
> uint32_t val) {
> - g_assert_not_reached();
> + g_assert(reg < NUM_SREGS);
> + if (reg < HEX_SREG_GLB_START) {
> + env->t_sreg[reg] = val;
> + } else {
> + env->g_sreg[reg] = val;
> + }
Be careful here too. Look at gen_log_sreg_write.
> }
> +#endif
>
> uint32_t arch_get_system_reg(CPUHexagonState *env, uint32_t reg);
Honestly, consider getting rid of these. All the uses are a specific register number, so there's no benefit of things like g_assert(reg < TOTAL_PER_THREAD_REGS) or reg < HEX_SREG_GLB_START. Also, keeping them runs the risk of not having all the proper checks inside.
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 11/39] target/hexagon: Add representation to count cycles
2025-03-01 5:28 ` [PATCH 11/39] target/hexagon: Add representation to count cycles Brian Cain
@ 2025-03-17 19:33 ` ltaylorsimpson
2025-09-02 1:52 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:33 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 11/39] target/hexagon: Add representation to count cycles
>
> From: Brian Cain <bcain@quicinc.com>
>
> The PCYCLE register can be enabled to indicate accumulated clock cycles.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 3 ++-
> target/hexagon/cpu.c | 3 +++
> target/hexagon/machine.c | 25 ++++++++++++++++++++++++-
> 3 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> 1549c4f1f0..4b9c9873dc 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -113,7 +113,8 @@ typedef struct CPUArchState {
> target_ulong stack_start;
>
> uint8_t slot_cancelled;
> -
> + uint64_t t_cycle_count;
> + uint64_t *g_pcycle_base;
> #ifndef CONFIG_USER_ONLY
> /* Some system registers are per thread and some are global. */
> target_ulong t_sreg[NUM_SREGS];
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> 84a96a194b..89a051b41d 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -335,6 +335,7 @@ static void hexagon_cpu_reset_hold(Object *obj,
> ResetType type)
>
> if (cs->cpu_index == 0) {
> arch_set_system_reg(env, HEX_SREG_MODECTL, 0x1);
> + *(env->g_pcycle_base) = 0;
See discussion on shared resources.
> }
> mmu_reset(env);
> arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index); @@ -396,10
> +397,12 @@ static void hexagon_cpu_realize(DeviceState *dev, Error
> **errp) #ifndef CONFIG_USER_ONLY
> if (cs->cpu_index == 0) {
> env->g_sreg = g_new0(target_ulong, NUM_SREGS);
> + env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
Shared resource ...
> } else {
> CPUState *cpu0 = qemu_get_cpu(0);
> CPUHexagonState *env0 = cpu_env(cpu0);
> env->g_sreg = env0->g_sreg;
> + env->g_pcycle_base = env0->g_pcycle_base;
Shared resource ...
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm()
2025-03-01 5:28 ` [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm() Brian Cain
@ 2025-03-17 19:37 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:37 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 15/39] target/hexagon: Implement
> hex_tlb_entry_get_perm()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 14/39] target/hexagon: Add system event, cause codes
2025-03-01 5:28 ` [PATCH 14/39] target/hexagon: Add system event, cause codes Brian Cain
@ 2025-03-17 19:40 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:40 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 14/39] target/hexagon: Add system event, cause codes
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid()
2025-03-01 5:28 ` [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid() Brian Cain
@ 2025-03-17 19:42 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:42 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 16/39] target/hexagon: Implement
> hex_tlb_lookup_by_asid()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill()
2025-03-01 5:28 ` [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill() Brian Cain
@ 2025-03-17 19:55 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:55 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 20/39] target/hexagon: Implement siad inst
2025-03-01 5:28 ` [PATCH 20/39] target/hexagon: Implement siad inst Brian Cain
@ 2025-03-17 19:57 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 19:57 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 20/39] target/hexagon: Implement siad inst
>
> From: Brian Cain <bcain@quicinc.com>
>
> siad is the 'Set interrupt auto disable' instruction.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 24/39] target/hexagon: Add exec-start-addr prop
2025-03-01 5:28 ` [PATCH 24/39] target/hexagon: Add exec-start-addr prop Brian Cain
@ 2025-03-17 20:03 ` ltaylorsimpson
2025-09-02 2:12 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:03 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 24/39] target/hexagon: Add exec-start-addr prop
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 1 +
> target/hexagon/cpu.c | 7 ++-----
> 2 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> baa48ec051..4667a1f748 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -194,6 +194,7 @@ struct ArchCPU {
> uint32_t num_tlbs;
> uint32_t l2vic_base_addr;
> uint32_t hvx_contexts;
> + uint32_t boot_addr;
> #endif
> };
>
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> 9f4cfd03c4..7afdcbf9d0 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -66,6 +66,7 @@ static const Property hexagon_cpu_properties[] = {
> DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
> 0xffffffffULL),
> DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
> + DEFINE_PROP_UINT32("exec-start-addr", HexagonCPU, boot_addr,
> + 0xffffffffULL),
Don't put a ULL value for a UINT32 property.
Ditto for l2vic-base-addr above (must've missed it when it came in).
> #endif
> DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
> DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU,
> lldb_stack_adjust, 0, @@ -362,8 +363,6 @@ static void
> hexagon_cpu_reset_hold(Object *obj, ResetType type)
> mmu_reset(env);
> arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index);
> hexagon_cpu_soft_reset(env);
> - memset(env->t_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
> - memset(env->greg, 0, sizeof(target_ulong) * NUM_GREGS);
Why are you removing these here?
> env->threadId = cs->cpu_index;
> env->tlb_lock_state = HEX_LOCK_UNLOCKED;
> env->k0_lock_state = HEX_LOCK_UNLOCKED; @@ -372,6 +371,7 @@ static
> void hexagon_cpu_reset_hold(Object *obj, ResetType type)
> env->next_PC = 0;
> env->wait_next_pc = 0;
> env->cause_code = -1;
> + arch_set_thread_reg(env, HEX_REG_PC, cpu->boot_addr);
> #endif
> }
>
> @@ -414,9 +414,6 @@ static void hexagon_cpu_realize(DeviceState *dev,
> Error **errp) #ifndef CONFIG_USER_ONLY
> CPUHexagonState *env = cpu_env(cs);
> hex_mmu_realize(env);
> -#endif
> - cpu_reset(cs);
> -#ifndef CONFIG_USER_ONLY
Why are you removing these here?
> if (cs->cpu_index == 0) {
> env->g_sreg = g_new0(target_ulong, NUM_SREGS);
> env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index()
2025-03-01 5:28 ` [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index() Brian Cain
@ 2025-03-17 20:07 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:07 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 26/39] target/hexagon: Decode trap1, rte as COF
2025-03-01 5:28 ` [PATCH 26/39] target/hexagon: Decode trap1, rte as COF Brian Cain
@ 2025-03-17 20:08 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:08 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 26/39] target/hexagon: Decode trap1, rte as COF
>
> From: Brian Cain <bcain@quicinc.com>
>
> Also: handle rte instructions at the end of the packet.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq()
2025-03-01 5:28 ` [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq() Brian Cain
@ 2025-03-17 20:09 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:09 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt
2025-03-01 5:28 ` [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt Brian Cain
@ 2025-03-17 20:12 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:12 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 28/39] target/hexagon: Implement modify_ssr, resched,
> pending_interrupt
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation
2025-03-01 5:28 ` [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation Brian Cain
@ 2025-03-17 20:20 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-17 20:20 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/translate.h | 1 +
> target/hexagon/translate.c | 99
> +++++++++++++++++++++++++++++++++++++-
> 2 files changed, 99 insertions(+), 1 deletion(-)
>
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index
> 060df6e5eb..475726388a 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -259,6 +259,18 @@ static bool check_for_attrib(Packet *pkt, int attrib)
> return false;
> }
>
> +#ifndef CONFIG_USER_ONLY
> +static bool check_for_opcode(Packet *pkt, uint16_t opcode) {
> + for (int i = 0; i < pkt->num_insns; i++) {
> + if (pkt->insn[i].opcode == opcode) {
> + return true;
> + }
> + }
> + return false;
> +}
> +#endif
> +
> static bool need_slot_cancelled(Packet *pkt) {
> /* We only need slot_cancelled for conditional store instructions */ @@ -
> 272,6 +284,90 @@ static bool need_slot_cancelled(Packet *pkt)
> return false;
> }
>
> +#ifndef CONFIG_USER_ONLY
> +static bool sreg_write_to_global(int reg_num) {
> + return reg_num == HEX_SREG_SSR ||
> + reg_num == HEX_SREG_STID ||
> + reg_num == HEX_SREG_IMASK ||
The name of this function is misleading since SSR, STID, and IMASK are not global.
A better name would be sreg_write_ends_tb
> + reg_num == HEX_SREG_IPENDAD ||
> + reg_num == HEX_SREG_BESTWAIT ||
> + reg_num == HEX_SREG_SCHEDCFG; }
> +
> +static bool has_sreg_write_to_global(Packet const *pkt) {
Ditto
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 01/39] target/hexagon: Implement ciad helper
2025-03-17 16:08 ` ltaylorsimpson
@ 2025-03-18 14:44 ` Sid Manning
2025-09-02 1:32 ` Brian Cain
1 sibling, 0 replies; 112+ messages in thread
From: Sid Manning @ 2025-03-18 14:44 UTC (permalink / raw)
To: ltaylorsimpson@gmail.com, 'Brian Cain',
qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain
> -----Original Message-----
> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> Sent: Monday, March 17, 2025 11:08 AM
> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> Subject: RE: [PATCH 01/39] target/hexagon: Implement ciad helper
>
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> > -----Original Message-----
> > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > Sent: Friday, February 28, 2025 11:28 PM
> > To: qemu-devel@nongnu.org
> > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> anjo@rev.ng;
> > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com;
> > Brian Cain <bcain@quicinc.com>
> > Subject: [PATCH 01/39] target/hexagon: Implement ciad helper
> >
> > From: Brian Cain <bcain@quicinc.com>
> >
> > ciad is the clear interrupt auto disable instruction.
> >
> > This instruction is defined in the Qualcomm Hexagon V71 Programmer's
> > Reference Manual -
> https://docs.qualcomm.com/bundle/publicresource/80-
> > N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
> > See §11.9.2 SYSTEM MONITOR.
>
> Put this reference in somewhere easier to find. See prior discussion on this.
>
> If it's only in the commit comment, it will be lost quickly.
We can move this to op_helper.c and explain that ciad clears ipend.iad and handshakes with the l2vic.
>
> >
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/op_helper.c | 39
> ++++++++++++++++++++++++++++++++-
> > -----
> > 1 file changed, 33 insertions(+), 6 deletions(-)
> >
> > diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> > index fd9caafefc..b28a18adf6 100644
> > --- a/target/hexagon/op_helper.c
> > +++ b/target/hexagon/op_helper.c
> > @@ -34,6 +34,11 @@
> > #include "op_helper.h"
> > #include "cpu_helper.h"
> > #include "translate.h"
> > +#ifndef CONFIG_USER_ONLY
> > +#include "hex_mmu.h"
> > +#include "hw/intc/l2vic.h"
> > +#include "hex_interrupts.h"
> > +#endif
> >
> > #define SF_BIAS 127
> > #define SF_MANTBITS 23
> > @@ -1338,9 +1343,36 @@ void HELPER(vwhist128qm)(CPUHexagonState
> > *env, int32_t uiV) }
> >
> > #ifndef CONFIG_USER_ONLY
> > +static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset,
> > +int
> > +val) {
> > + g_assert((offset == L2VIC_VID_0) || (offset == L2VIC_VID_1));
> > + CPUState *cs = env_cpu(env);
> > + HexagonCPU *cpu = HEXAGON_CPU(cs);
> > + const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
> > + cpu_physical_memory_write(pend_mem, &val, sizeof(val)); }
>
> Careful here - an int is different sizes on 32-bit and 64-bit hosts. Change the
> type to int32_t or int64_t.
[Sid Manning]
Sure, will change this to be more precise.
>
> > +
> > +static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t
> > +offset) {
> > + /*
> > + * currently only l2vic is the only attached it uses vid0, remove
> > + * the assert below if anther is added
>
> What assert?
[Sid Manning]
Looks like a stale comment and can be removed.
>
> > + */
> > + hexagon_set_vid(env, offset, L2VIC_CIAD_INSTRUCTION); }
> > +
> > void HELPER(ciad)(CPUHexagonState *env, uint32_t mask) {
> > - g_assert_not_reached();
> > + uint32_t ipendad;
> > + uint32_t iad;
> > +
> > + BQL_LOCK_GUARD();
> > + ipendad = READ_SREG(HEX_SREG_IPENDAD);
> > + iad = fGET_FIELD(ipendad, IPENDAD_IAD);
> > + fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask));
> > + arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
> > + hexagon_clear_last_irq(env, L2VIC_VID_0);
> > + hex_interrupt_update(env);
> > }
> >
> > void HELPER(siad)(CPUHexagonState *env, uint32_t mask) @@ -1416,11
> > +1448,6 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t
> > +val)
> > g_assert_not_reached();
> > }
> >
> > -static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset,
> > int
> > val) -{
> > - g_assert_not_reached();
> > -}
> > -
> > static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t
> > vid) {
> > g_assert_not_reached();
> > --
> > 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-17 17:37 ` ltaylorsimpson
@ 2025-03-18 18:34 ` Sid Manning
2025-03-18 19:14 ` ltaylorsimpson
0 siblings, 1 reply; 112+ messages in thread
From: Sid Manning @ 2025-03-18 18:34 UTC (permalink / raw)
To: ltaylorsimpson@gmail.com, 'Brian Cain',
qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain
> -----Original Message-----
> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> Sent: Monday, March 17, 2025 12:37 PM
> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
>
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> > -----Original Message-----
> > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > Sent: Friday, February 28, 2025 11:28 PM
> > To: qemu-devel@nongnu.org
> > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> anjo@rev.ng;
> > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com;
> > Brian Cain <bcain@quicinc.com>
> > Subject: [PATCH 05/39] target/hexagon: Implement modify SSR
> >
> > From: Brian Cain <bcain@quicinc.com>
> >
> > The per-vCPU System Status Register controls many modal behaviors of
> > the system architecture. When the SSR is updated, we trigger the
> > necessary effects for interrupts, privilege/MMU, and HVX context
> mapping.
> >
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/cpu_helper.c | 100
> > +++++++++++++++++++++++++++++++++++-
> > 1 file changed, 99 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
> > index e151c6335a..3e2364a7b0 100644
> > --- a/target/hexagon/cpu_helper.c
> > +++ b/target/hexagon/cpu_helper.c
> > @@ -14,6 +14,8 @@
> > #else
> > #include "hw/boards.h"
> > #include "hw/hexagon/hexagon.h"
> > +#include "hex_interrupts.h"
> > +#include "hex_mmu.h"
> > #endif
> > #include "exec/exec-all.h"
> > #include "exec/cpu_ldst.h"
> > @@ -69,9 +71,105 @@ void
> > hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
> > g_assert_not_reached();
> > }
> >
> > +static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS];
> > +static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS];
>
> This won't scale for a system with multiple Hexagon instances. See
> discussion on how to handle shared resources.
I commented more below but yes I think we need to take a look at these and refactor because of what you point out and to avoid the copies we are doing when ownership changes.
>
> > +
> > +/*
> > + * EXT_CONTEXTS
> > + * SSR.XA 2 4 6 8
> > + * 000 HVX Context 0 HVX Context 0 HVX Context 0 HVX Context 0
> > + * 001 HVX Context 1 HVX Context 1 HVX Context 1 HVX Context 1
> > + * 010 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 2
> > + * 011 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 3
> > + * 100 HVX Context 0 HVX Context 0 HVX Context 4 HVX Context 4
> > + * 101 HVX Context 1 HVX Context 1 HVX Context 5 HVX Context 5
> > + * 110 HVX Context 0 HVX Context 2 HVX Context 2 HVX Context 6
> > + * 111 HVX Context 1 HVX Context 3 HVX Context 3 HVX Context 7
> > + */
>
> This is different from what the HVX PRM says. It only specifies what XA
> values 4, 5, 6, 7 mean.
[Sid Manning]
The comment is the generic case when ssr:xe bit 2 isn't always 1.
>
> Here is what it says:
> The HVX scalar core can contain any number of hardware threads greater or
> equal to the number of vector contexts. The scalar hardware thread is
> assignable to a vector context through per- thread SSR:XA programming, as
> follows:
> - SSR:XA = 4: HVX instructions use vector context 0.
> - SSR:XA = 5: HVX instructions use vector context 1, if it is available.
> - SSR:XA = 6: HVX instructions use vector context 2, if it is available.
> - SSR:XA = 7: HVX instructions use vector context 3, if it is available.
>
> > +static int parse_context_idx(CPUHexagonState *env, uint8_t XA) {
> > + int ret;
> > + HexagonCPU *cpu = env_archcpu(env);
>
> You should assert that cpu->hvx_contexts is in { 2, 4, 6, 8 }. This will future
> proof against changes to the hardware as well as protect against bad
> command-line settings.
[Sid Manning]
Looking at virt_init or hexagon_common_init the value of hvx-contexts will come from the config table regardless of what the user specifies via the command line. I think we have to trust the config space entries or we will have to add specific asserts for every entry.
>
> > + if (cpu->hvx_contexts == 6 && XA >= 6) {
> > + ret = XA - 6 + 2;
> > + } else {
> > + ret = XA % cpu->hvx_contexts;
> > + }
> > + g_assert(ret >= 0 && ret < VECTOR_UNIT_MAX);
> > + return ret;
> > +}
> > +
> > +static void check_overcommitted_hvx(CPUHexagonState *env, uint32_t
> > ssr)
> > +{
> > + if (!GET_FIELD(SSR_XE, ssr)) {
> > + return;
> > + }
>
> What does SSR_XE indicate?
[Sid Manning]
If SSR:XE isn't set this thread doesn't have the coproc enabled so discard additional checking. Any coproc insn issued when ssr:xe is 0 will trigger a, "Illegal execution of coprocessor instruction." error.
>
> > +
> > + uint8_t XA = GET_SSR_FIELD(SSR_XA, ssr);
> > +
> > + CPUState *cs;
> > + CPU_FOREACH(cs) {
> > + CPUHexagonState *env_ = cpu_env(cs);
>
> This underscore is confusing. Use a full name such as thread_env.
I see your point will update. Here and below.
>
> > + if (env_ == env) {
> > + continue;
> > + }
> > + /* Check if another thread has the XE bit set and same XA */
> > + uint32_t ssr_ = arch_get_system_reg(env_, HEX_SREG_SSR);
>
> Ditto
>
> > + if (GET_SSR_FIELD(SSR_XE2, ssr_) && GET_FIELD(SSR_XA, ssr_)
> > + == XA) {
>
> The comment says check the XE bit but the code checks XE2. Also, note the
> XE check on the current thread above.
This might be a type-o I think it should SSE_XE not XE2.
>
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "setting SSR.XA '%d' on thread %d but thread"
> > + " %d has same extension active\n", XA, env->threadId,
> > + env_->threadId);
> > + }
> > + }
> > +}
> > +
> > void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t
> > old) {
> > - g_assert_not_reached();
> > + g_assert(bql_locked());
> > +
> > + bool old_EX = GET_SSR_FIELD(SSR_EX, old);
> > + bool old_UM = GET_SSR_FIELD(SSR_UM, old);
> > + bool old_GM = GET_SSR_FIELD(SSR_GM, old);
> > + bool old_IE = GET_SSR_FIELD(SSR_IE, old);
> > + uint8_t old_XA = GET_SSR_FIELD(SSR_XA, old);
> > + bool new_EX = GET_SSR_FIELD(SSR_EX, new);
> > + bool new_UM = GET_SSR_FIELD(SSR_UM, new);
> > + bool new_GM = GET_SSR_FIELD(SSR_GM, new);
> > + bool new_IE = GET_SSR_FIELD(SSR_IE, new);
> > + uint8_t new_XA = GET_SSR_FIELD(SSR_XA, new);
> > +
> > + if ((old_EX != new_EX) ||
> > + (old_UM != new_UM) ||
> > + (old_GM != new_GM)) {
> > + hex_mmu_mode_change(env);
> > + }
> > +
> > + uint8_t old_asid = GET_SSR_FIELD(SSR_ASID, old);
> > + uint8_t new_asid = GET_SSR_FIELD(SSR_ASID, new);
> > + if (new_asid != old_asid) {
> > + CPUState *cs = env_cpu(env);
> > + tlb_flush(cs);
> > + }
> > +
> > + if (old_XA != new_XA) {
> > + int old_unit = parse_context_idx(env, old_XA);
> > + int new_unit = parse_context_idx(env, new_XA);
>
> Check that old_unit != new_unit. Per the table above, different XA values
> can point to the same unit. For example, if cpu->hvx_contexts is 2, the XA=0
> and XA=2 both point to context 0.
>
> > +
> > + /* Ownership exchange */
> > + memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
> > + memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
> > + memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
> > + memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
>
> What does the hardware do? Does it clear the context, or is that the OS'es
> job?
Nothing would keep a single htid from taking hvx unit 0, doing some hvx-ops , swapping to hvx unit 1 doing some more hvx-ops and so on. We are doing this because each thread has a private copy of the hvx register state. Since HVX units and threads are independent if one thread changes its ownership from HVX context 0 to HVX context 1 we have to do this copy. Instead of memcpy should create a new object that represents the HVX units available and change env->VRegs/QRegs to point to the one currently owned.
Refactoring this will be an improvement.
>
> If the hardware leaves the context alone, the above should be
> 1) Copy env->{VQ}Regs to old_unit
> 2) Copy new_unit to env->{VQ}Regs
>
> Should you check SSR_EX before doing these copies?
>
> Do you need to do anything when SSR_EX changes?
I think you mean SSR:XE before doing the copies. I think we have to do the copy here regardless of ssr:xe since a thread could swap ownership, update ssr:xa, without explicitly having ssr:xe set. Maybe the OS disables SSR:XE while changing hvx unit ownership?
>
> > +
> > + check_overcommitted_hvx(env, new);
> > + }
> > +
> > + /* See if the interrupts have been enabled or we have exited EX mode
> */
> > + if ((new_IE && !old_IE) ||
> > + (!new_EX && old_EX)) {
> > + hex_interrupt_update(env);
> > + }
> > }
> >
> > void clear_wait_mode(CPUHexagonState *env)
> > --
> > 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes
2025-03-01 5:28 ` [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes Brian Cain
@ 2025-03-18 18:50 ` ltaylorsimpson
2025-09-02 2:35 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-18 18:50 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 2 +-
> target/hexagon/translate.h | 2 +
> target/hexagon/genptr.c | 7 +-
> target/hexagon/translate.c | 142 ++++++++++++++++++++++++++++++++-
> ----
> 4 files changed, 132 insertions(+), 21 deletions(-)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> 4667a1f748..73c3bb34b0 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -142,9 +142,9 @@ typedef struct CPUArchState {
> hex_lock_state_t k0_lock_state;
> target_ulong tlb_lock_count;
> target_ulong k0_lock_count;
> - target_ulong next_PC;
> CPUHexagonTLBContext *hex_tlb;
> #endif
> + target_ulong next_PC;
You are moving this from system-mode only to unconditional. There must be an earlier patch in this series that put it in system-mode. Find that and remove it, so there is only a single addition.
Also, does this need to be part of the global state? The answer is no if it doesn't live across packets. If it is only used within the context of a single packet, you can just create a temporary TCGv in DisasContext. There are several examples already.
> target_ulong new_value_usr;
>
> MemLog mem_log_stores[STORES_MAX];
> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index
> c9533fee1f..ad1a2f4045 100644
> --- a/target/hexagon/translate.h
> +++ b/target/hexagon/translate.h
> @@ -85,6 +85,7 @@ typedef struct DisasContext {
> TCGv dczero_addr;
> bool pcycle_enabled;
> bool pkt_ends_tb;
> + bool need_next_pc;
> uint32_t num_cycles;
> } DisasContext;
>
> @@ -306,6 +307,7 @@ static inline void ctx_log_qreg_read(DisasContext
> *ctx, }
>
> extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
> +extern TCGv hex_next_PC;
> extern TCGv hex_pred[NUM_PREGS];
> extern TCGv hex_slot_cancelled;
> extern TCGv hex_new_value_usr;
> diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
> 5554c9515c..afc7e5f3a5 100644
> --- a/target/hexagon/genptr.c
> +++ b/target/hexagon/genptr.c
> @@ -634,14 +634,15 @@ static void gen_write_new_pc_addr(DisasContext
> *ctx, TCGv addr,
> tcg_gen_brcondi_tl(cond, pred, 0, pred_false);
> }
>
> + TCGv PC_wr = ctx->need_next_pc ? hex_next_PC :
> hex_gpr[HEX_REG_PC];
> if (ctx->pkt->pkt_has_multi_cof) {
> /* If there are multiple branches in a packet, ignore the second one */
> - tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
> + tcg_gen_movcond_tl(TCG_COND_NE, PC_wr,
> ctx->branch_taken, tcg_constant_tl(0),
> - hex_gpr[HEX_REG_PC], addr);
> + PC_wr, addr);
> tcg_gen_movi_tl(ctx->branch_taken, 1);
> } else {
> - tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
> + tcg_gen_mov_tl(PC_wr, addr);
> }
>
> if (cond != TCG_COND_ALWAYS) {
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index
> 475726388a..d4b22acb72 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -49,6 +49,7 @@ static const AnalyzeInsn
> opcode_analyze[XX_LAST_OPCODE] = { TCGv
> hex_gpr[TOTAL_PER_THREAD_REGS]; TCGv hex_pred[NUM_PREGS]; TCGv
> hex_slot_cancelled;
> +TCGv hex_next_PC;
> TCGv hex_new_value_usr;
> TCGv hex_store_addr[STORES_MAX];
> TCGv hex_store_width[STORES_MAX];
> @@ -61,12 +62,14 @@ TCGv_i64 hex_cycle_count; TCGv
> hex_vstore_addr[VSTORES_MAX]; TCGv hex_vstore_size[VSTORES_MAX];
> TCGv hex_vstore_pending[VSTORES_MAX];
> +static bool need_next_PC(DisasContext *ctx);
You don't need this. The function definition is before any reference to it.
>
> #ifndef CONFIG_USER_ONLY
> TCGv hex_greg[NUM_GREGS];
> TCGv hex_t_sreg[NUM_SREGS];
> TCGv_ptr hex_g_sreg_ptr;
> TCGv hex_g_sreg[NUM_SREGS];
> +TCGv hex_cause_code;
This doesn't belong in this patch.
> #endif
>
> static const char * const hexagon_prednames[] = { @@ -184,6 +187,9 @@
> static void gen_end_tb(DisasContext *ctx)
>
> gen_exec_counters(ctx);
>
> + if (ctx->need_next_pc) {
> + tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
> + }
> if (ctx->branch_cond != TCG_COND_NEVER) {
> if (ctx->branch_cond != TCG_COND_ALWAYS) {
> TCGLabel *skip = gen_new_label(); @@ -371,18 +377,24 @@ static
> bool pkt_ends_tb(Packet *pkt) static bool need_next_PC(DisasContext
> *ctx) {
> Packet *pkt = ctx->pkt;
> -
> - /* Check for conditional control flow or HW loop end */
> - for (int i = 0; i < pkt->num_insns; i++) {
> - uint16_t opcode = pkt->insn[i].opcode;
> - if (GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode,
> A_COF)) {
> - return true;
> - }
> - if (GET_ATTRIB(opcode, A_HWLOOP0_END) ||
> - GET_ATTRIB(opcode, A_HWLOOP1_END)) {
> - return true;
Was this inserted by an earlier patch in this series? If so, don't insert it before. Just put the below code in this patch.
> + if (pkt->pkt_has_cof || ctx->pkt_ends_tb) {
> + for (int i = 0; i < pkt->num_insns; i++) {
> + uint16_t opcode = pkt->insn[i].opcode;
> + if ((GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode,
> A_COF)) ||
> + GET_ATTRIB(opcode, A_HWLOOP0_END) ||
> + GET_ATTRIB(opcode, A_HWLOOP1_END)) {
> + return true;
> + }
> }
> }
> + /*
> + * We end the TB on some instructions that do not change the flow (for
> + * other reasons). In these cases, we must set pc too, as the insn won't
> + * do it themselves.
> + */
> + if (ctx->pkt_ends_tb && !check_for_attrib(pkt, A_COF)) {
> + return true;
> + }
> return false;
> }
>
> @@ -523,7 +535,14 @@ static void analyze_packet(DisasContext *ctx) static
> void gen_start_packet(DisasContext *ctx) {
> Packet *pkt = ctx->pkt;
> +#ifndef CONFIG_USER_ONLY
> + target_ulong next_PC = (check_for_opcode(pkt, Y2_k0lock) ||
> + check_for_opcode(pkt, Y2_tlblock)) ?
Should we also check for Y2_wait?
> + ctx->base.pc_next :
> + ctx->base.pc_next +
> +pkt->encod_pkt_size_in_bytes; #else
> target_ulong next_PC = ctx->base.pc_next + pkt-
> >encod_pkt_size_in_bytes;
> +#endif
You don't need the #ifndef CONFIG_USER_ONLY here. Note that the opcodes exist in linux-user mode as well as system mode. So, you can just keep the first version.
Note that check_for_opcode is currently guarded by #ifndef CONFIG_USER_ONLY, but you can remove that.
> int i;
>
> /* Clear out the disassembly context */ @@ -531,6 +550,10 @@ static void
> gen_start_packet(DisasContext *ctx)
> ctx->reg_log_idx = 0;
> bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
> bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
> +#ifndef CONFIG_USER_ONLY
> + ctx->greg_log_idx = 0;
> + ctx->sreg_log_idx = 0;
> +#endif
> ctx->preg_log_idx = 0;
> bitmap_zero(ctx->pregs_written, NUM_PREGS);
> ctx->future_vregs_idx = 0;
> @@ -563,21 +586,41 @@ static void gen_start_packet(DisasContext *ctx)
> * gen phase, so clear it again.
> */
> bitmap_zero(ctx->pregs_written, NUM_PREGS);
> +#ifndef CONFIG_USER_ONLY
> + for (i = 0; i < NUM_SREGS; i++) {
> + ctx->t_sreg_new_value[i] = NULL;
> + }
> + for (i = 0; i < ctx->sreg_log_idx; i++) {
> + int reg_num = ctx->sreg_log[i];
> + if (reg_num < HEX_SREG_GLB_START) {
> + ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
> + tcg_gen_mov_tl(ctx->t_sreg_new_value[reg_num],
> hex_t_sreg[reg_num]);
> + }
> + }
> + for (i = 0; i < NUM_GREGS; i++) {
> + ctx->greg_new_value[i] = NULL;
> + }
> + for (i = 0; i < ctx->greg_log_idx; i++) {
> + int reg_num = ctx->greg_log[i];
> + ctx->greg_new_value[reg_num] = tcg_temp_new();
> + }
> +#endif
>
> /* Initialize the runtime state for packet semantics */
> if (need_slot_cancelled(pkt)) {
> tcg_gen_movi_tl(hex_slot_cancelled, 0);
> }
> ctx->branch_taken = NULL;
> - ctx->pkt_ends_tb = pkt_ends_tb(pkt);
> if (pkt->pkt_has_cof) {
> ctx->branch_taken = tcg_temp_new();
> - if (pkt->pkt_has_multi_cof) {
> - tcg_gen_movi_tl(ctx->branch_taken, 0);
> - }
> - if (need_next_PC(ctx)) {
> - tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC);
> - }
> + }
> + if (pkt->pkt_has_multi_cof) {
> + tcg_gen_movi_tl(ctx->branch_taken, 0);
> + }
> + ctx->pkt_ends_tb = pkt_ends_tb(pkt);
> + ctx->need_next_pc = need_next_PC(ctx);
> + if (ctx->need_next_pc) {
> + tcg_gen_movi_tl(hex_next_PC, next_PC);
> }
>
> /* Preload the predicated registers into get_result_gpr(ctx, i) */ @@ -
> 713,6 +756,59 @@ static void gen_reg_writes(DisasContext *ctx)
> }
> }
>
> +#ifndef CONFIG_USER_ONLY
> +static void gen_greg_writes(DisasContext *ctx) {
> + int i;
> +
> + for (i = 0; i < ctx->greg_log_idx; i++) {
> + int reg_num = ctx->greg_log[i];
> +
> + tcg_gen_mov_tl(hex_greg[reg_num], ctx-
> >greg_new_value[reg_num]);
> + }
> +}
> +
> +
> +static void gen_sreg_writes(DisasContext *ctx) {
> + int i;
> +
> + TCGv old_reg = tcg_temp_new();
> + for (i = 0; i < ctx->sreg_log_idx; i++) {
> + int reg_num = ctx->sreg_log[i];
> +
> + if (reg_num == HEX_SREG_SSR) {
> + tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
> + tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx-
> >t_sreg_new_value[reg_num]);
> + gen_helper_modify_ssr(tcg_env, ctx->t_sreg_new_value[reg_num],
> + old_reg);
> + /* This can change processor state, so end the TB */
> + ctx->base.is_jmp = DISAS_NORETURN;
> + } else if ((reg_num == HEX_SREG_STID) ||
> + (reg_num == HEX_SREG_IMASK) ||
> + (reg_num == HEX_SREG_IPENDAD)) {
> + if (reg_num < HEX_SREG_GLB_START) {
> + tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
> + tcg_gen_mov_tl(hex_t_sreg[reg_num],
> + ctx->t_sreg_new_value[reg_num]);
> + }
> + /* This can change the interrupt state, so end the TB */
> + gen_helper_pending_interrupt(tcg_env);
> + ctx->base.is_jmp = DISAS_NORETURN;
> + } else if ((reg_num == HEX_SREG_BESTWAIT) ||
> + (reg_num == HEX_SREG_SCHEDCFG)) {
> + /* This can trigger resched interrupt, so end the TB */
> + gen_helper_resched(tcg_env);
> + ctx->base.is_jmp = DISAS_NORETURN;
> + }
> +
> + if (reg_num < HEX_SREG_GLB_START) {
> + tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx-
> >t_sreg_new_value[reg_num]);
> + }
> + }
> +}
> +#endif
> +
> static void gen_pred_writes(DisasContext *ctx) {
> /* Early exit if not needed or the log is empty */ @@ -1012,6 +1108,10 @@
> static void gen_commit_packet(DisasContext *ctx)
> process_store_log(ctx);
>
> gen_reg_writes(ctx);
> +#if !defined(CONFIG_USER_ONLY)
> + gen_greg_writes(ctx);
> + gen_sreg_writes(ctx);
> +#endif
> gen_pred_writes(ctx);
> if (pkt->pkt_has_hvx) {
> gen_commit_hvx(ctx);
> @@ -1073,6 +1173,7 @@ static void
> hexagon_tr_init_disas_context(DisasContextBase *dcbase,
> ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
> ctx->short_circuit = hex_cpu->short_circuit;
> ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS,
> PCYCLE_ENABLED);
> + ctx->need_next_pc = false;
Don't need this because it is initialized in gen_start_packet.
> }
>
> static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) @@
> -1201,6 +1302,13 @@ void hexagon_translate_init(void)
> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
> hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
> offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
> +#ifndef CONFIG_USER_ONLY
> + hex_cause_code = tcg_global_mem_new(tcg_env,
> + offsetof(CPUHexagonState, cause_code), "cause_code"); #endif
Doesn’t' belong in this patch
> + hex_next_PC = tcg_global_mem_new(tcg_env,
> + offsetof(CPUHexagonState, next_PC), "next_PC");
> +
> for (i = 0; i < STORES_MAX; i++) {
> snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
> hex_store_addr[i] = tcg_global_mem_new(tcg_env,
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-18 18:34 ` Sid Manning
@ 2025-03-18 19:14 ` ltaylorsimpson
2025-03-18 23:47 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-18 19:14 UTC (permalink / raw)
To: 'Sid Manning', 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, 'Matheus Bernardino (QUIC)',
ale, anjo, 'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
> -----Original Message-----
> From: Sid Manning <sidneym@quicinc.com>
> Sent: Tuesday, March 18, 2025 1:34 PM
> To: ltaylorsimpson@gmail.com; 'Brian Cain'
> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Brian Cain
> <bcain@quicinc.com>
> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
>
>
>
> > -----Original Message-----
> > From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> > Sent: Monday, March 17, 2025 12:37 PM
> > To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-
> devel@nongnu.org
> > Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus
> > Bernardino
> > (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> > Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> > Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> > <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> > Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
> >
> > > -----Original Message-----
> > > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > > Sent: Friday, February 28, 2025 11:28 PM
> > > To: qemu-devel@nongnu.org
> > > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> > anjo@rev.ng;
> > > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> > sidneym@quicinc.com;
> > > Brian Cain <bcain@quicinc.com>
> > > Subject: [PATCH 05/39] target/hexagon: Implement modify SSR
> > >
> > > From: Brian Cain <bcain@quicinc.com>
> > >
> > > The per-vCPU System Status Register controls many modal behaviors of
> > > the system architecture. When the SSR is updated, we trigger the
> > > necessary effects for interrupts, privilege/MMU, and HVX context
> > mapping.
> > >
> > > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > > ---
> >
> > What does SSR_XE indicate?
> [Sid Manning]
> If SSR:XE isn't set this thread doesn't have the coproc enabled so discard
> additional checking. Any coproc insn issued when ssr:xe is 0 will trigger a,
> "Illegal execution of coprocessor instruction." error.
> > > + if (old_XA != new_XA) {
> > > + int old_unit = parse_context_idx(env, old_XA);
> > > + int new_unit = parse_context_idx(env, new_XA);
> >
> > Check that old_unit != new_unit. Per the table above, different XA values
> > can point to the same unit. For example, if cpu->hvx_contexts is 2, the
> XA=0
> > and XA=2 both point to context 0.
> >
> > > +
> > > + /* Ownership exchange */
> > > + memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
> > > + memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
> > > + memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
> > > + memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
> >
> > What does the hardware do? Does it clear the context, or is that the OS'es
> > job?
> Nothing would keep a single htid from taking hvx unit 0, doing some hvx-ops
> , swapping to hvx unit 1 doing some more hvx-ops and so on. We are doing
> this because each thread has a private copy of the hvx register state. Since
> HVX units and threads are independent if one thread changes its ownership
> from HVX context 0 to HVX context 1 we have to do this copy. Instead of
> memcpy should create a new object that represents the HVX units available
> and change env->VRegs/QRegs to point to the one currently owned.
>
> Refactoring this will be an improvement.
>
>
> >
> > If the hardware leaves the context alone, the above should be
> > 1) Copy env->{VQ}Regs to old_unit
> > 2) Copy new_unit to env->{VQ}Regs
> >
> > Should you check SSR_EX before doing these copies?
> >
> > Do you need to do anything when SSR_EX changes?
>
> I think you mean SSR:XE before doing the copies. I think we have to do the
> copy here regardless of ssr:xe since a thread could swap ownership, update
> ssr:xa, without explicitly having ssr:xe set. Maybe the OS disables SSR:XE
> while changing hvx unit ownership?
Correct. I meant SSR:XE.
Some refactoring is in order but need to understand the HW behavior more specifically.
- What will the HW do if more than one thread claims ownership of the same HVX context?
- What happens if a thread claims ownership without setting SSR:XE and then sets SSR:XE later?
- What about this example?
1) Thread 0 claims context 1 and sets SSR:XE
2) Thread 0 does some HVX computation
3) Thread 0 is done with HVX for now so clears SSR:XE
4) Thread 1 claims context 1 and sets SSR:XE, does some work, then clears SSR:XE
5) Thread 0 wants to do more HVX, so it sets SSR:XE (still pointing to HVX context 1)
We should keep the copies for the contexts and local copies inside CPUHexagonState. This makes TCG generation easier as well as having common code between system mode and linux-user mode.
Also, since check_overcommitted_hvx only prints a log message, add an early exit if LOG_GUEST_ERROR is off.
Thanks,
Taylor
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 31/39] target/hexagon: Add implicit sysreg writes
2025-03-01 5:28 ` [PATCH 31/39] target/hexagon: Add implicit sysreg writes Brian Cain
@ 2025-03-18 19:18 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-18 19:18 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 31/39] target/hexagon: Add implicit sysreg writes
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-18 19:14 ` ltaylorsimpson
@ 2025-03-18 23:47 ` Brian Cain
2025-03-19 16:39 ` ltaylorsimpson
0 siblings, 1 reply; 112+ messages in thread
From: Brian Cain @ 2025-03-18 23:47 UTC (permalink / raw)
To: ltaylorsimpson, 'Sid Manning', qemu-devel
Cc: richard.henderson, philmd, 'Matheus Bernardino (QUIC)',
ale, anjo, 'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
On 3/18/2025 2:14 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Sid Manning <sidneym@quicinc.com>
>> Sent: Tuesday, March 18, 2025 1:34 PM
>> To: ltaylorsimpson@gmail.com; 'Brian Cain'
>> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
>> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
>> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
>> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
>> Burton (QUIC) <quic_mburton@quicinc.com>; Brian Cain
>> <bcain@quicinc.com>
>> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
>>
>>
>>
>>> -----Original Message-----
>>> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
>>> Sent: Monday, March 17, 2025 12:37 PM
>>> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-
>> devel@nongnu.org
>>> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus
>>> Bernardino
>>> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
>>> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
>>> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
>>> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
>>> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
>>>
>>>> -----Original Message-----
>>>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>>>> Sent: Friday, February 28, 2025 11:28 PM
>>>> To: qemu-devel@nongnu.org
>>>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>>>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
>>> anjo@rev.ng;
>>>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>>>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>>> sidneym@quicinc.com;
>>>> Brian Cain <bcain@quicinc.com>
>>>> Subject: [PATCH 05/39] target/hexagon: Implement modify SSR
>>>>
>>>> From: Brian Cain <bcain@quicinc.com>
>>>>
>>>> The per-vCPU System Status Register controls many modal behaviors of
>>>> the system architecture. When the SSR is updated, we trigger the
>>>> necessary effects for interrupts, privilege/MMU, and HVX context
>>> mapping.
>>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>>>> ---
>>> What does SSR_XE indicate?
>> [Sid Manning]
>> If SSR:XE isn't set this thread doesn't have the coproc enabled so discard
>> additional checking. Any coproc insn issued when ssr:xe is 0 will trigger a,
>> "Illegal execution of coprocessor instruction." error.
>
>
>>>> + if (old_XA != new_XA) {
>>>> + int old_unit = parse_context_idx(env, old_XA);
>>>> + int new_unit = parse_context_idx(env, new_XA);
>>> Check that old_unit != new_unit. Per the table above, different XA values
>>> can point to the same unit. For example, if cpu->hvx_contexts is 2, the
>> XA=0
>>> and XA=2 both point to context 0.
>>>
>>>> +
>>>> + /* Ownership exchange */
>>>> + memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
>>>> + memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
>>>> + memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
>>>> + memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
>>> What does the hardware do? Does it clear the context, or is that the OS'es
>>> job?
>> Nothing would keep a single htid from taking hvx unit 0, doing some hvx-ops
>> , swapping to hvx unit 1 doing some more hvx-ops and so on. We are doing
>> this because each thread has a private copy of the hvx register state. Since
>> HVX units and threads are independent if one thread changes its ownership
>> from HVX context 0 to HVX context 1 we have to do this copy. Instead of
>> memcpy should create a new object that represents the HVX units available
>> and change env->VRegs/QRegs to point to the one currently owned.
>>
>> Refactoring this will be an improvement.
>>
>>
>>> If the hardware leaves the context alone, the above should be
>>> 1) Copy env->{VQ}Regs to old_unit
>>> 2) Copy new_unit to env->{VQ}Regs
>>>
>>> Should you check SSR_EX before doing these copies?
>>>
>>> Do you need to do anything when SSR_EX changes?
>> I think you mean SSR:XE before doing the copies. I think we have to do the
>> copy here regardless of ssr:xe since a thread could swap ownership, update
>> ssr:xa, without explicitly having ssr:xe set. Maybe the OS disables SSR:XE
>> while changing hvx unit ownership?
> Correct. I meant SSR:XE.
>
> Some refactoring is in order but need to understand the HW behavior more specifically.
> - What will the HW do if more than one thread claims ownership of the same HVX context?
> - What happens if a thread claims ownership without setting SSR:XE and then sets SSR:XE later?
> - What about this example?
> 1) Thread 0 claims context 1 and sets SSR:XE
> 2) Thread 0 does some HVX computation
> 3) Thread 0 is done with HVX for now so clears SSR:XE
> 4) Thread 1 claims context 1 and sets SSR:XE, does some work, then clears SSR:XE
> 5) Thread 0 wants to do more HVX, so it sets SSR:XE (still pointing to HVX context 1)
>
> We should keep the copies for the contexts and local copies inside CPUHexagonState. This makes TCG generation easier as well as having common code between system mode and linux-user mode.
Good point that linux-user will need their own exclusive HVX context.
But it doesn't sound right to me to have CPU state store both the system
contexts *and* a local context for system emulation. Our current design
under review is better than that IMO. Once we have some experience
modeling the system registers as an independent QEMU Object, I think
we'll be better prepared to model the HVX contexts similarly. Ideally
we can remap these via something along the lines of
"object_property_set_link()" when the contexts change, without requiring
any copies. And ideally the existing TCG should work as-is, despite the
remappable register files.
"What happens when ... " - multiple threads picking the same context is
almost certainly explicitly or implicitly undefined architectural
behavior, so whatever QEMU does should be appropriate. However, we'll
talk to the architecture team and get a definitive answer.
>
> Also, since check_overcommitted_hvx only prints a log message, add an early exit if LOG_GUEST_ERROR is off.
>
> Thanks,
> Taylor
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-18 23:47 ` Brian Cain
@ 2025-03-19 16:39 ` ltaylorsimpson
2025-03-19 16:58 ` Richard Henderson
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 16:39 UTC (permalink / raw)
To: 'Brian Cain', 'Sid Manning', qemu-devel
Cc: richard.henderson, philmd, 'Matheus Bernardino (QUIC)',
ale, anjo, 'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Tuesday, March 18, 2025 6:47 PM
> To: ltaylorsimpson@gmail.com; 'Sid Manning' <sidneym@quicinc.com>;
> qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; 'Matheus Bernardino
> (QUIC)' <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; 'Marco
> Liebel (QUIC)' <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; 'Mark
> Burton (QUIC)' <quic_mburton@quicinc.com>; 'Brian Cain'
> <bcain@quicinc.com>
> Subject: Re: [PATCH 05/39] target/hexagon: Implement modify SSR
>
>
> On 3/18/2025 2:14 PM, ltaylorsimpson@gmail.com wrote:
> >
> >> -----Original Message-----
> >> From: Sid Manning <sidneym@quicinc.com>
> >> Sent: Tuesday, March 18, 2025 1:34 PM
> >> To: ltaylorsimpson@gmail.com; 'Brian Cain'
> >> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> >> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus
> >> Bernardino
> >> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> >> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org;
> >> Mark Burton (QUIC) <quic_mburton@quicinc.com>; Brian Cain
> >> <bcain@quicinc.com>
> >> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
> >>
> >>
> >>
> >>> -----Original Message-----
> >>> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> >>> Sent: Monday, March 17, 2025 12:37 PM
> >>> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-
> >> devel@nongnu.org
> >>> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus
> >>> Bernardino
> >>> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng;
> Marco
> >>> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org;
> >>> Mark Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> >>> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> >>> Subject: RE: [PATCH 05/39] target/hexagon: Implement modify SSR
> >>>
> >>>> -----Original Message-----
> >>>> From: Brian Cain <brian.cain@oss.qualcomm.com>
> >>>> Sent: Friday, February 28, 2025 11:28 PM
> >>>> To: qemu-devel@nongnu.org
> >>>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> >>>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> >>> anjo@rev.ng;
> >>>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> >>>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> >>> sidneym@quicinc.com;
> >>>> Brian Cain <bcain@quicinc.com>
> >>>> Subject: [PATCH 05/39] target/hexagon: Implement modify SSR
> >>>>
> >>>> From: Brian Cain <bcain@quicinc.com>
> >>>>
> >>>> The per-vCPU System Status Register controls many modal behaviors
> >>>> of the system architecture. When the SSR is updated, we trigger
> >>>> the necessary effects for interrupts, privilege/MMU, and HVX
> >>>> context
> >>> mapping.
> >>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> >>>> ---
> >>> What does SSR_XE indicate?
> >> [Sid Manning]
> >> If SSR:XE isn't set this thread doesn't have the coproc enabled so
> >> discard additional checking. Any coproc insn issued when ssr:xe is 0
> >> will trigger a, "Illegal execution of coprocessor instruction." error.
> >
> >
> >>>> + if (old_XA != new_XA) {
> >>>> + int old_unit = parse_context_idx(env, old_XA);
> >>>> + int new_unit = parse_context_idx(env, new_XA);
> >>> Check that old_unit != new_unit. Per the table above, different XA
> >>> values can point to the same unit. For example, if
> >>> cpu->hvx_contexts is 2, the
> >> XA=0
> >>> and XA=2 both point to context 0.
> >>>
> >>>> +
> >>>> + /* Ownership exchange */
> >>>> + memcpy(VRegs[old_unit], env->VRegs, sizeof(env->VRegs));
> >>>> + memcpy(QRegs[old_unit], env->QRegs, sizeof(env->QRegs));
> >>>> + memcpy(env->VRegs, VRegs[new_unit], sizeof(env->VRegs));
> >>>> + memcpy(env->QRegs, QRegs[new_unit], sizeof(env->QRegs));
> >>> What does the hardware do? Does it clear the context, or is that
> >>> the OS'es job?
> >> Nothing would keep a single htid from taking hvx unit 0, doing some hvx-
> ops
> >> , swapping to hvx unit 1 doing some more hvx-ops and so on. We are
> doing
> >> this because each thread has a private copy of the hvx register
> >> state. Since HVX units and threads are independent if one thread
> >> changes its ownership from HVX context 0 to HVX context 1 we have to
> >> do this copy. Instead of memcpy should create a new object that
> >> represents the HVX units available and change env->VRegs/QRegs to
> point to the one currently owned.
> >>
> >> Refactoring this will be an improvement.
> >>
> >>
> >>> If the hardware leaves the context alone, the above should be
> >>> 1) Copy env->{VQ}Regs to old_unit
> >>> 2) Copy new_unit to env->{VQ}Regs
> >>>
> >>> Should you check SSR_EX before doing these copies?
> >>>
> >>> Do you need to do anything when SSR_EX changes?
> >> I think you mean SSR:XE before doing the copies. I think we have to
> >> do the copy here regardless of ssr:xe since a thread could swap
> >> ownership, update ssr:xa, without explicitly having ssr:xe set.
> >> Maybe the OS disables SSR:XE while changing hvx unit ownership?
> > Correct. I meant SSR:XE.
> >
> > Some refactoring is in order but need to understand the HW behavior more
> specifically.
> > - What will the HW do if more than one thread claims ownership of the
> same HVX context?
> > - What happens if a thread claims ownership without setting SSR:XE and
> then sets SSR:XE later?
> > - What about this example?
> > 1) Thread 0 claims context 1 and sets SSR:XE
> > 2) Thread 0 does some HVX computation
> > 3) Thread 0 is done with HVX for now so clears SSR:XE
> > 4) Thread 1 claims context 1 and sets SSR:XE, does some work, then
> clears SSR:XE
> > 5) Thread 0 wants to do more HVX, so it sets SSR:XE (still
> > pointing to HVX context 1)
> >
> > We should keep the copies for the contexts and local copies inside
> CPUHexagonState. This makes TCG generation easier as well as having
> common code between system mode and linux-user mode.
>
> Good point that linux-user will need their own exclusive HVX context. But it
> doesn't sound right to me to have CPU state store both the system contexts
> *and* a local context for system emulation. Our current design under
> review is better than that IMO. Once we have some experience modeling
> the system registers as an independent QEMU Object, I think we'll be better
> prepared to model the HVX contexts similarly. Ideally we can remap these
> via something along the lines of "object_property_set_link()" when the
> contexts change, without requiring any copies. And ideally the existing TCG
> should work as-is, despite the remappable register files.
>
> "What happens when ... " - multiple threads picking the same context is
> almost certainly explicitly or implicitly undefined architectural behavior, so
> whatever QEMU does should be appropriate. However, we'll talk to the
> architecture team and get a definitive answer.
I caution against putting a level of indirection into CPUHexagonState for the HVX registers. The HVX TCG implementation relies on an offset from the start of CPUHexagonState to identify the operands. This would be a very significant rewrite if it's even possible. I don't know if TCG's gvec code generation can handle random pointers or a level of indirection.
If the behavior is undefined, we can avoid the copies. Then we just need some bookkeeping to check if multiple threads try to claim the same context (if that behavior is defined). If copies are needed, we could keep the hardware contexts as shared a shared resource. Another alternative would be to track the current owner of a context and copy from the previous owner's {VQ}Regs to the new owners {VQ}Regs.
Thanks,
Taylor
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 32/39] target/hexagon: Define system, guest reg names
2025-03-01 5:28 ` [PATCH 32/39] target/hexagon: Define system, guest reg names Brian Cain
@ 2025-03-19 16:48 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 16:48 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 32/39] target/hexagon: Define system, guest reg names
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/internal.h | 2 ++
> target/hexagon/cpu.c | 29 +++++++++++++++++++++++++++++
> 2 files changed, 31 insertions(+)
>
> diff --git a/target/hexagon/internal.h b/target/hexagon/internal.h index
> 120cfde7b9..fd2397b9ef 100644
> --- a/target/hexagon/internal.h
> +++ b/target/hexagon/internal.h
> @@ -34,6 +34,8 @@ void hexagon_debug_qreg(CPUHexagonState *env, int
> regnum); void hexagon_debug(CPUHexagonState *env);
>
> extern const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS];
> +extern const char * const hexagon_sregnames[]; extern const char *
> +const hexagon_gregnames[];
Guard these with #ifndef CONFIG_USER_ONLY
>
> void G_NORETURN do_raise_exception(CPUHexagonState *env,
> uint32_t exception,
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> c7c470b099..3c4776232e 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -85,6 +85,35 @@ const char * const
> hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
> "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", };
>
> +#ifndef CONFIG_USER_ONLY
> +const char * const hexagon_sregnames[] = {
> + "sgp0", "sgp1", "stid", "elr", "badva0",
> + "badva1", "ssr", "ccr", "htid", "badva",
> + "imask", "gevb", "vwctrl", "s13", "s14",
> + "s15", "evb", "modectl", "syscfg", "segment",
> + "ipendad", "vid", "vid1", "bestwait", "s24",
> + "schedcfg", "s26", "cfgbase", "diag", "rev",
> + "pcyclelo", "pcyclehi", "isdbst", "isdbcfg0", "isdbcfg1",
> + "livelock", "brkptpc0", "brkptcfg0", "brkptpc1", "brkptcfg1",
> + "isdbmbxin", "isdbmbxout", "isdben", "isdbgpr", "pmucnt4",
> + "pmucnt5", "pmucnt6", "pmucnt7", "pmucnt0", "pmucnt1",
> + "pmucnt2", "pmucnt3", "pmuevtcfg", "pmustid0", "pmuevtcfg1",
> + "pmustid1", "timerlo", "timerhi", "pmucfg", "rgdr2",
> + "rgdr", "turkey", "duck", "chicken",
The last 5 names look strange and don't match what's in hex_regs.h.
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs
2025-03-01 5:28 ` [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs Brian Cain
@ 2025-03-19 16:53 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 16:53 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/translate.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index
> ff881d1060..248ed60f29 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -1295,6 +1295,26 @@ void hexagon_translate_init(void)
>
> opcode_init();
>
> +#ifndef CONFIG_USER_ONLY
> + for (i = 0; i < NUM_GREGS; i++) {
> + hex_greg[i] = tcg_global_mem_new(tcg_env,
> + offsetof(CPUHexagonState, greg[i]),
> + hexagon_gregnames[i]);
> + }
> + hex_g_sreg_ptr = tcg_global_mem_new_ptr(tcg_env,
> + offsetof(CPUHexagonState, g_sreg), "hex_g_sreg_ptr");
> + for (i = 0; i < NUM_SREGS; i++) {
> + if (i < HEX_SREG_GLB_START) {
> + hex_t_sreg[i] = tcg_global_mem_new(tcg_env,
> + offsetof(CPUHexagonState, t_sreg[i]),
> + hexagon_sregnames[i]);
> + } else {
> + hex_g_sreg[i] = tcg_global_mem_new(hex_g_sreg_ptr,
> + i * sizeof(target_ulong),
> + hexagon_sregnames[i]);
I assume this will be changed with the redo of global resource handling
> + }
> + }
> +#endif
> for (i = 0; i < TOTAL_PER_THREAD_REGS; i++) {
> hex_gpr[i] = tcg_global_mem_new(tcg_env,
> offsetof(CPUHexagonState, gpr[i]),
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-19 16:39 ` ltaylorsimpson
@ 2025-03-19 16:58 ` Richard Henderson
2025-09-02 1:39 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: Richard Henderson @ 2025-03-19 16:58 UTC (permalink / raw)
To: ltaylorsimpson, 'Brian Cain', 'Sid Manning',
qemu-devel
Cc: philmd, 'Matheus Bernardino (QUIC)', ale, anjo,
'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
On 3/19/25 09:39, ltaylorsimpson@gmail.com wrote:
> I caution against putting a level of indirection into CPUHexagonState for the HVX registers. The HVX TCG implementation relies on an offset from the start of CPUHexagonState to identify the operands. This would be a very significant rewrite if it's even possible. I don't know if TCG's gvec code generation can handle random pointers or a level of indirection.
Not yet, it can't, no.
I've been extending it for random pointers because of Arm FEAT_SME2, wherein we have
indirect addressing of matrix slices. So we wind up with a pointer like
&env->zarray + (env->xregs[reg] + offset) % size
> If the behavior is undefined, we can avoid the copies. Then we just need some bookkeeping to check if multiple threads try to claim the same context (if that behavior is defined). If copies are needed, we could keep the hardware contexts as shared a shared resource. Another alternative would be to track the current owner of a context and copy from the previous owner's {VQ}Regs to the new owners {VQ}Regs.
Depending on how you answer these questions, I could split out the TCG work.
But in the short term, copying context data might well be easier.
r~
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
2025-03-01 5:28 ` [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock Brian Cain
2025-03-03 16:24 ` Brian Cain
@ 2025-03-19 17:01 ` ltaylorsimpson
1 sibling, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 17:01 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/sys_macros.h | 8 +--
> target/hexagon/op_helper.c | 104
> ++++++++++++++++++++++++++++++++++++
> 2 files changed, 108 insertions(+), 4 deletions(-)
>
> diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
> index 3c4c3c7aa5..e5dc1ce0ab 100644
> --- a/target/hexagon/sys_macros.h
> +++ b/target/hexagon/sys_macros.h
> @@ -143,11 +143,11 @@
> #define fDCINVIDX(REG)
> #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in qemu
> */
>
> -#define fSET_TLB_LOCK() g_assert_not_reached()
> -#define fCLEAR_TLB_LOCK() g_assert_not_reached()
> +#define fSET_TLB_LOCK() hex_tlb_lock(env);
> +#define fCLEAR_TLB_LOCK() hex_tlb_unlock(env);
Move these to the patch that implements TLB lock/unlock.
>
> -#define fSET_K0_LOCK() g_assert_not_reached()
> -#define fCLEAR_K0_LOCK() g_assert_not_reached()
> +#define fSET_K0_LOCK() hex_k0_lock(env);
> +#define fCLEAR_K0_LOCK() hex_k0_unlock(env);
>
> #define fTLB_IDXMASK(INDEX) \
> ((INDEX) & (fPOW2_ROUNDUP(fCAST4u(env_archcpu(env)->num_tlbs)) -
> 1)) diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 702c3dd3c6..f3b14fbf58 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -1184,6 +1184,110 @@ void HELPER(modify_ssr)(CPUHexagonState
> *env, uint32_t new, uint32_t old)
> BQL_LOCK_GUARD();
> hexagon_modify_ssr(env, new, old);
> }
> +
> +static void hex_k0_lock(CPUHexagonState *env) {
> + BQL_LOCK_GUARD();
> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> +
> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> + if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) {
> + if (env->k0_lock_state == HEX_LOCK_QUEUED) {
> + env->next_PC += 4;
> + env->k0_lock_count++;
> + env->k0_lock_state = HEX_LOCK_OWNER;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> + return;
> + }
> + if (env->k0_lock_state == HEX_LOCK_OWNER) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "Double k0lock at PC: 0x%x, thread may hang\n",
> + env->next_PC);
> + env->next_PC += 4;
> + CPUState *cs = env_cpu(env);
QEMU coding standards prefer to put declarations at the beginning of the code block (just after the open curly brace).
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> + return;
> + }
> + env->k0_lock_state = HEX_LOCK_WAITING;
> + CPUState *cs = env_cpu(env);
Ditto
> + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
> + } else {
> + env->next_PC += 4;
> + env->k0_lock_count++;
> + env->k0_lock_state = HEX_LOCK_OWNER;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
> + }
> +
> +}
> +
> +static void hex_k0_unlock(CPUHexagonState *env) {
> + BQL_LOCK_GUARD();
> + g_assert((env->k0_lock_count == 0) || (env->k0_lock_count == 1));
> +
> + /* Nothing to do if the k0 isn't locked by this thread */
> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> + if ((GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg) == 0) ||
> + (env->k0_lock_state != HEX_LOCK_OWNER)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "thread %d attempted to unlock k0 without having the "
> + "lock, k0_lock state = %d, syscfg:k0 = %d\n",
> + env->threadId, env->k0_lock_state,
> + GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg));
> + g_assert(env->k0_lock_state != HEX_LOCK_WAITING);
> + return;
> + }
> +
> + env->k0_lock_count--;
> + env->k0_lock_state = HEX_LOCK_UNLOCKED;
> + SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 0);
> +
> + /* Look for a thread to unlock */
> + unsigned int this_threadId = env->threadId;
> + CPUHexagonState *unlock_thread = NULL;
> + CPUState *cs;
Ditto
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 35/39] target/hexagon: Define gen_precise_exception()
2025-03-01 5:28 ` [PATCH 35/39] target/hexagon: Define gen_precise_exception() Brian Cain
@ 2025-03-19 17:20 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 17:20 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 35/39] target/hexagon: Define gen_precise_exception()
The definition of gen_precise_exception is not in this patch.
There is a use but no definition.
>
> From: Brian Cain <bcain@quicinc.com>
>
> Add PC to raise_exception helper
>
> Replace the fGEN_TCG_J2_trap0 macro override with the fTRAP()-generated
> system helper instead.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts
2025-03-01 5:28 ` [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts Brian Cain
@ 2025-03-19 17:22 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 17:22 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 38/39] target/hexagon: Add guest reg reading functionality
2025-03-01 5:28 ` [PATCH 38/39] target/hexagon: Add guest reg reading functionality Brian Cain
@ 2025-03-19 18:36 ` ltaylorsimpson
2025-09-02 2:40 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 18:36 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com
> Subject: [PATCH 38/39] target/hexagon: Add guest reg reading functionality
>
> From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
>
> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
> ---
> target/hexagon/cpu.c | 19 ++++++++++++++++++-
> target/hexagon/op_helper.c | 19 +++++++++++++++++--
> 2 files changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> 3c4776232e..80f5e23794 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -739,7 +739,24 @@ static void hexagon_cpu_class_init(ObjectClass *c,
> void *data) #ifndef CONFIG_USER_ONLY uint32_t
> hexagon_greg_read(CPUHexagonState *env, uint32_t reg) {
> - g_assert_not_reached();
> + target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
> + int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
Consider moving this check into hexagon_get_sys_pcycle_count*
Otherwise
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 39/39] target/hexagon: Add pcycle setting functionality
2025-03-01 5:28 ` [PATCH 39/39] target/hexagon: Add pcycle setting functionality Brian Cain
@ 2025-03-19 18:49 ` ltaylorsimpson
2025-09-02 2:42 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 18:49 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com
> Subject: [PATCH 39/39] target/hexagon: Add pcycle setting functionality
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
> ---
> target/hexagon/cpu.c | 10 +++++++---
> target/hexagon/cpu_helper.c | 17 ++++++++++++++---
> 2 files changed, 21 insertions(+), 6 deletions(-)
>
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> 80f5e23794..4ca6add834 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -440,19 +440,23 @@ static void hexagon_cpu_realize(DeviceState *dev,
> Error **errp) #endif
>
> qemu_init_vcpu(cs);
> -#ifndef CONFIG_USER_ONLY
> 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);
> - env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
> } else {
> CPUState *cpu0 = qemu_get_cpu(0);
> CPUHexagonState *env0 = cpu_env(cpu0);
> env->g_sreg = env0->g_sreg;
> - env->g_pcycle_base = env0->g_pcycle_base;
> }
> #endif
> + if (cs->cpu_index == 0) {
> + env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
Another shared resource ...
> + } else {
> + CPUState *cpu0 = qemu_get_cpu(0);
> + env->g_pcycle_base = cpu_env(cpu0)->g_pcycle_base;
> + }
>
> mcc->parent_realize(dev, errp);
> }
> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
> index 9c44cb7950..08c749e9fa 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -70,18 +70,29 @@ uint32_t
> hexagon_get_sys_pcycle_count_low(CPUHexagonState *env) void
> hexagon_set_sys_pcycle_count_high(CPUHexagonState *env,
> uint32_t cycles_hi)
> {
> - g_assert_not_reached();
> + uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
> + uint64_t cycles =
> + ((uint64_t)cycles_hi << 32) | extract64(cur_cycles, 0, 32);
> + hexagon_set_sys_pcycle_count(env, cycles);
> }
>
> void hexagon_set_sys_pcycle_count_low(CPUHexagonState *env,
> uint32_t cycles_lo)
> {
> - g_assert_not_reached();
> + uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
> + uint64_t cycles = extract64(cur_cycles, 32, 32) | cycles_lo;
> + hexagon_set_sys_pcycle_count(env, cycles);
> }
>
> void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t
> cycles) {
> - g_assert_not_reached();
Do we need a lock here?
> + *(env->g_pcycle_base) = cycles;
> +
> + CPUState *cs;
> + CPU_FOREACH(cs) {
> + CPUHexagonState *env_ = cpu_env(cs);
This underscore is easy to miss. Just
cpu_env(cs)->t_cycle_count = 0;
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 12/39] target/hexagon: Add implementation of cycle counters
2025-03-01 5:28 ` [PATCH 12/39] target/hexagon: Add implementation of cycle counters Brian Cain
@ 2025-03-19 19:50 ` ltaylorsimpson
2025-04-02 2:44 ` Brian Cain
[not found] ` <7274cd69-f4e7-40b5-b850-cbd9099ed8ac@oss.qualcomm.com>
0 siblings, 2 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 19:50 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 12/39] target/hexagon: Add implementation of cycle
> counters
>
> From: Brian Cain <bcain@quicinc.com>
>
> Co-authored-by: Sid Manning <sidneym@quicinc.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 25 ++++++++++++++++++++++---
> target/hexagon/translate.h | 2 ++
> target/hexagon/cpu_helper.c | 12 +++++++++---
> target/hexagon/translate.c | 27 +++++++++++++++++++++++++++
> 4 files changed, 60 insertions(+), 6 deletions(-)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> 4b9c9873dc..7e2ea838c5 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -27,11 +27,15 @@
>
> #include "cpu-qom.h"
> #include "exec/cpu-defs.h"
> +#include "exec/cpu-common.h"
> #include "hex_regs.h"
> #include "mmvec/mmvec.h"
> #include "hw/registerfields.h"
>
> +#ifndef CONFIG_USER_ONLY
> +#include "reg_fields.h"
> typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
> +#endif
Why is reg_fields.h guarded by #ifndef CONFIG_USER_ONLY?
Also, why wasn't the CPUHexagonTLBContext guarded when it was first inserted?
>
> #define NUM_PREGS 4
> #define TOTAL_PER_THREAD_REGS 64
> @@ -188,6 +192,7 @@ struct ArchCPU {
>
> FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
> FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
> +FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1)
>
> G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
> uint32_t exception, @@ -201,6 +206,11 @@ void
> hexagon_cpu_soft_reset(CPUHexagonState *env); #endif
>
> #include "exec/cpu-all.h"
> +
> +#ifndef CONFIG_USER_ONLY
> +#include "cpu_helper.h"
> +#endif
> +
> static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
> uint64_t *cs_base, uint32_t *flags) { @@ -210,16
> +220,27 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState
> *env, vaddr *pc,
> if (*pc == env->gpr[HEX_REG_SA0]) {
> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
> }
> - *flags = hex_flags;
> if (*pc & PCALIGN_MASK) {
> hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0);
> }
> #ifndef CONFIG_USER_ONLY
> + target_ulong syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> +
> + bool pcycle_enabled = extract32(syscfg,
> + reg_field_info[SYSCFG_PCYCLEEN].offset,
> +
> + reg_field_info[SYSCFG_PCYCLEEN].width);
> +
> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
> cpu_mmu_index(env_cpu(env), false));
> +
> + if (pcycle_enabled) {
> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, 1);
> + }
> #else
> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, true);
Are pcycles exposed in linux-user mode? If not, make this flag system-mode only.
> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
> MMU_USER_IDX); #endif
> + *flags = hex_flags;
> }
>
> typedef HexagonCPU ArchCPU;
> @@ -228,6 +249,4 @@ void hexagon_translate_init(void); void
> hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
> int *max_insns, vaddr pc, void *host_pc);
>
> -#include "exec/cpu-all.h"
> -
> #endif /* HEXAGON_CPU_H */
> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index
> 0eaa3db03e..9bc4b3ce8b 100644
> --- a/target/hexagon/translate.h
> +++ b/target/hexagon/translate.h
> @@ -83,6 +83,8 @@ typedef struct DisasContext {
> TCGv new_pred_value[NUM_PREGS];
> TCGv branch_taken;
> TCGv dczero_addr;
> + bool pcycle_enabled;
Guard with #ifndef CONFIG_USER_ONLY
> + uint32_t num_cycles;
> } DisasContext;
>
> bool is_gather_store_insn(DisasContext *ctx); diff --git
> a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c index
> 0b0802bfb9..1d9b9f8bef 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -48,17 +48,23 @@ uint32_t arch_get_system_reg(CPUHexagonState
> *env, uint32_t reg)
>
> uint64_t hexagon_get_sys_pcycle_count(CPUHexagonState *env) {
> - g_assert_not_reached();
Do we need a lock here?
> + uint64_t cycles = 0;
> + CPUState *cs;
> + CPU_FOREACH(cs) {
> + CPUHexagonState *env_ = cpu_env(cs);
> + cycles += env_->t_cycle_count;
> + }
> + return *(env->g_pcycle_base) + cycles;
> }
>
> uint32_t hexagon_get_sys_pcycle_count_high(CPUHexagonState *env) {
> - g_assert_not_reached();
> + return hexagon_get_sys_pcycle_count(env) >> 32;
> }
>
> uint32_t hexagon_get_sys_pcycle_count_low(CPUHexagonState *env) {
> - g_assert_not_reached();
> + return extract64(hexagon_get_sys_pcycle_count(env), 0, 32);
> }
>
> void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, diff --git
> a/target/hexagon/translate.c b/target/hexagon/translate.c index
> 9119e42ff7..060df6e5eb 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -57,6 +57,7 @@ TCGv_i64 hex_store_val64[STORES_MAX]; TCGv
> hex_llsc_addr; TCGv hex_llsc_val;
> TCGv_i64 hex_llsc_val_i64;
> +TCGv_i64 hex_cycle_count;
Guard with #ifndef CONFIG_USER_ONLY
> TCGv hex_vstore_addr[VSTORES_MAX];
> TCGv hex_vstore_size[VSTORES_MAX];
> TCGv hex_vstore_pending[VSTORES_MAX];
> @@ -125,6 +126,22 @@ static void gen_exception_raw(int excp)
> gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); }
>
> +#ifndef CONFIG_USER_ONLY
> +static inline void gen_precise_exception(int excp, target_ulong PC) {
> + tcg_gen_movi_tl(hex_cause_code, excp);
> + gen_exception(HEX_EVENT_PRECISE, PC); }
Belongs in a different patch.
> +
> +static inline void gen_pcycle_counters(DisasContext *ctx) {
> + if (ctx->pcycle_enabled) {
> + tcg_gen_addi_i64(hex_cycle_count, hex_cycle_count, ctx-
> >num_cycles);
> + ctx->num_cycles = 0;
> + }
> +}
> +#endif
> +
> static void gen_exec_counters(DisasContext *ctx) {
> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT],
> @@ -133,6 +150,10 @@ static void gen_exec_counters(DisasContext *ctx)
> hex_gpr[HEX_REG_QEMU_INSN_CNT], ctx->num_insns);
> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_HVX_CNT],
> hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
> +
> +#ifndef CONFIG_USER_ONLY
> + gen_pcycle_counters(ctx);
> +#endif
> }
>
> static bool use_goto_tb(DisasContext *ctx, target_ulong dest) @@ -785,6
> +806,7 @@ static void gen_commit_hvx(DisasContext *ctx)
> }
> }
>
> +static const int PCYCLES_PER_PACKET = 3;
> static void update_exec_counters(DisasContext *ctx) {
> Packet *pkt = ctx->pkt;
> @@ -804,6 +826,7 @@ static void update_exec_counters(DisasContext *ctx)
> }
>
> ctx->num_packets++;
> + ctx->num_cycles += PCYCLES_PER_PACKET;
Guard
> ctx->num_insns += num_real_insns;
> ctx->num_hvx_insns += num_hvx_insns; } @@ -946,11 +969,13 @@ static
> void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>
> ctx->mem_idx = FIELD_EX32(hex_flags, TB_FLAGS, MMU_INDEX);
> ctx->num_packets = 0;
> + ctx->num_cycles = 0;
Guard
> ctx->num_insns = 0;
> ctx->num_hvx_insns = 0;
> ctx->branch_cond = TCG_COND_NEVER;
> ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
> ctx->short_circuit = hex_cpu->short_circuit;
> + ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS,
> + PCYCLE_ENABLED);
Guard
> }
>
> static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) @@
> -1077,6 +1102,8 @@ void hexagon_translate_init(void)
> offsetof(CPUHexagonState, llsc_val), "llsc_val");
> hex_llsc_val_i64 = tcg_global_mem_new_i64(tcg_env,
> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
> + hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
> + offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
Guard
> for (i = 0; i < STORES_MAX; i++) {
> snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
> hex_store_addr[i] = tcg_global_mem_new(tcg_env,
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 13/39] target/hexagon: Implement modify_syscfg()
2025-03-01 5:28 ` [PATCH 13/39] target/hexagon: Implement modify_syscfg() Brian Cain
@ 2025-03-19 21:12 ` ltaylorsimpson
2025-09-02 1:58 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 21:12 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 13/39] target/hexagon: Implement modify_syscfg()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/op_helper.c | 51
> +++++++++++++++++++++++++++++++++++++-
> 1 file changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 03bed11f6e..42805d0f1d 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -1522,7 +1522,56 @@ static bool
> handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
>
> static void modify_syscfg(CPUHexagonState *env, uint32_t val) {
> - g_assert_not_reached();
> + g_assert(bql_locked());
> +
> + uint32_t old;
> + uint32_t syscfg_read_only_mask = 0x80001c00;
> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> +
> + /* clear read-only bits if they are set in the new value. */
> + val &= ~syscfg_read_only_mask;
> + /* if read-only are currently set in syscfg keep them set. */
> + val |= (syscfg & syscfg_read_only_mask);
> +
> + uint32_t tmp = val;
> + old = arch_get_system_reg(env, HEX_SREG_SYSCFG);
This is the same as syscfg declared above
> + arch_set_system_reg(env, HEX_SREG_SYSCFG, tmp);
Why is tmp needed? Just use val here.
> +
> + /* Check for change in MMU enable */
> + target_ulong old_mmu_enable = GET_SYSCFG_FIELD(SYSCFG_MMUEN,
> old);
> + uint8_t old_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, old);
> + uint8_t old_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, old);
> + target_ulong new_mmu_enable =
> + GET_SYSCFG_FIELD(SYSCFG_MMUEN, val);
Move these declarations to the beginning of the function.
> + if (new_mmu_enable && !old_mmu_enable) {
> + hex_mmu_on(env);
> + } else if (!new_mmu_enable && old_mmu_enable) {
> + hex_mmu_off(env);
> + }
> +
> + /* Changing pcycle enable from 0 to 1 resets the counters */
> + uint8_t new_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, val);
> + CPUState *cs;
Move the declarations to the beginning of the function
> + if (old_en == 0 && new_en == 1) {
You could put declaration of cs here if you prefer
> + CPU_FOREACH(cs) {
> + CPUHexagonState *_env = cpu_env(cs);
> + _env->t_cycle_count = 0;
I'm not a fan of _env as a variable name. Just do
cpu_env(cs)->t_cycle_count = 0
> + }
> + }
> +
> + /* See if global interrupts are turned on */
> + uint8_t new_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, val);
Move the declaration to the beginning
> + if (!old_gie && new_gie) {
> + qemu_log_mask(CPU_LOG_INT, "%s: global interrupts enabled\n",
> __func__);
> + hex_interrupt_update(env);
> + }
> +
> + if (qemu_loglevel_mask(LOG_UNIMP)) {
> + int new_v2x = GET_SYSCFG_FIELD(SYSCFG_V2X, val);
> + if (!new_v2x) {
> + qemu_log("HVX: 64 byte vector length is unsupported\n");
> + }
> + }
> }
>
> static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 17/39] target/hexagon: Implement software interrupt
2025-03-01 5:28 ` [PATCH 17/39] target/hexagon: Implement software interrupt Brian Cain
@ 2025-03-19 21:28 ` ltaylorsimpson
2025-03-24 15:51 ` Sid Manning
2025-09-02 2:03 ` Brian Cain
0 siblings, 2 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 21:28 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain',
'Mike Lambert'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>; Mike Lambert
> <mlambert@quicinc.com>
> Subject: [PATCH 17/39] target/hexagon: Implement software interrupt
>
> From: Brian Cain <bcain@quicinc.com>
>
> Co-authored-by: Mike Lambert <mlambert@quicinc.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/cpu.h | 1 -
> target/hexagon/hexswi.h | 17 +++
> target/hexagon/cpu.c | 2 +
> target/hexagon/hexswi.c | 258
> +++++++++++++++++++++++++++++++++++++
> target/hexagon/op_helper.c | 1 +
> 5 files changed, 278 insertions(+), 1 deletion(-) create mode 100644
> target/hexagon/hexswi.h create mode 100644 target/hexagon/hexswi.c
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> dabee310c5..045581d7be 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -256,5 +256,4 @@ typedef HexagonCPU ArchCPU; void
> hexagon_translate_init(void); void hexagon_translate_code(CPUState *cs,
> TranslationBlock *tb,
> int *max_insns, vaddr pc, void *host_pc);
> -
Gratuitous change
> #endif /* HEXAGON_CPU_H */
> diff --git a/target/hexagon/hexswi.h b/target/hexagon/hexswi.h new file
> mode 100644 index 0000000000..5d232cb06c
> --- /dev/null
> +++ b/target/hexagon/hexswi.h
> @@ -0,0 +1,17 @@
> +/*
> + * Copyright(c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#ifndef HEXSWI_H
> +#define HEXSWI_H
> +
> +
> +#include "cpu.h"
> +
> +void hexagon_cpu_do_interrupt(CPUState *cpu); void
> +register_trap_exception(CPUHexagonState *env, int type, int imm,
> + target_ulong PC);
> +
> +#endif /* HEXSWI_H */
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> 89a051b41d..843be8221f 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -33,6 +33,8 @@
> #ifndef CONFIG_USER_ONLY
> #include "sys_macros.h"
> #include "qemu/main-loop.h"
> +#include "hex_interrupts.h"
> +#include "hexswi.h"
Move these added include to a different patch where the contents are needed.
> #endif
>
> static void hexagon_v66_cpu_init(Object *obj) { } diff --git
> a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c new file mode
> 100644 index 0000000000..5fcf9b2be9
> --- /dev/null
> +++ b/target/hexagon/hexswi.c
> @@ -0,0 +1,258 @@
> +/*
> + * Copyright(c) 2019-2025 Qualcomm Innovation Center, Inc. All Rights
> Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#ifdef CONFIG_USER_ONLY
This file is only included in the system-mode build, so we don't need these guards. Several in this file.
> +#include "exec/helper-proto.h"
> +#include "qemu.h"
> +#endif
> +#include "exec/cpu_ldst.h"
> +#include "exec/exec-all.h"
> +#include "qemu/log.h"
> +#include "qemu/main-loop.h"
> +#include "arch.h"
> +#include "internal.h"
> +#include "macros.h"
> +#include "sys_macros.h"
> +#include "tcg/tcg-op.h"
> +#ifndef CONFIG_USER_ONLY
> +#include "hex_mmu.h"
> +#include "hexswi.h"
> +#endif
> +
> +#ifndef CONFIG_USER_ONLY
> +
> +
> +static void set_addresses(CPUHexagonState *env, target_ulong pc_offset,
> + target_ulong exception_index)
> +
> +{
> + arch_set_system_reg(env, HEX_SREG_ELR,
> + arch_get_thread_reg(env, HEX_REG_PC) + pc_offset);
> + arch_set_thread_reg(env, HEX_REG_PC,
> + arch_get_system_reg(env, HEX_SREG_EVB) |
> + (exception_index << 2)); }
> +
> +static const char *event_name[] = {
> + [HEX_EVENT_RESET] = "HEX_EVENT_RESET",
> + [HEX_EVENT_IMPRECISE] = "HEX_EVENT_IMPRECISE",
> + [HEX_EVENT_TLB_MISS_X] = "HEX_EVENT_TLB_MISS_X",
> + [HEX_EVENT_TLB_MISS_RW] = "HEX_EVENT_TLB_MISS_RW",
> + [HEX_EVENT_TRAP0] = "HEX_EVENT_TRAP0",
> + [HEX_EVENT_TRAP1] = "HEX_EVENT_TRAP1",
> + [HEX_EVENT_FPTRAP] = "HEX_EVENT_FPTRAP",
> + [HEX_EVENT_DEBUG] = "HEX_EVENT_DEBUG",
> + [HEX_EVENT_INT0] = "HEX_EVENT_INT0",
> + [HEX_EVENT_INT1] = "HEX_EVENT_INT1",
> + [HEX_EVENT_INT2] = "HEX_EVENT_INT2",
> + [HEX_EVENT_INT3] = "HEX_EVENT_INT3",
> + [HEX_EVENT_INT4] = "HEX_EVENT_INT4",
> + [HEX_EVENT_INT5] = "HEX_EVENT_INT5",
> + [HEX_EVENT_INT6] = "HEX_EVENT_INT6",
> + [HEX_EVENT_INT7] = "HEX_EVENT_INT7",
> + [HEX_EVENT_INT8] = "HEX_EVENT_INT8",
> + [HEX_EVENT_INT9] = "HEX_EVENT_INT9",
> + [HEX_EVENT_INTA] = "HEX_EVENT_INTA",
> + [HEX_EVENT_INTB] = "HEX_EVENT_INTB",
> + [HEX_EVENT_INTC] = "HEX_EVENT_INTC",
> + [HEX_EVENT_INTD] = "HEX_EVENT_INTD",
> + [HEX_EVENT_INTE] = "HEX_EVENT_INTE",
> + [HEX_EVENT_INTF] = "HEX_EVENT_INTF"
> +};
> +
> +void hexagon_cpu_do_interrupt(CPUState *cs)
> +
> +{
> + CPUHexagonState *env = cpu_env(cs);
> + BQL_LOCK_GUARD();
> +
> + qemu_log_mask(CPU_LOG_INT, "\t%s: event 0x%x:%s, cause
> 0x%x(%d)\n",
> + __func__, cs->exception_index,
> + event_name[cs->exception_index], env->cause_code,
> + env->cause_code);
> +
> + env->llsc_addr = ~0;
> +
> + uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
Declarations at the beginning of the function.
> + if (GET_SSR_FIELD(SSR_EX, ssr) == 1) {
> + arch_set_system_reg(env, HEX_SREG_DIAG, env->cause_code);
> + env->cause_code = HEX_CAUSE_DOUBLE_EXCEPT;
> + cs->exception_index = HEX_EVENT_PRECISE;
> + }
> +
> + switch (cs->exception_index) {
> + case HEX_EVENT_TRAP0:
> + if (env->cause_code == 0) {
> + qemu_log_mask(LOG_UNIMP,
> + "trap0 is unhandled, no semihosting available\n");
> + }
> +
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 4, cs->exception_index);
> + break;
> +
> + case HEX_EVENT_TRAP1:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 4, cs->exception_index);
> + break;
> +
> + case HEX_EVENT_TLB_MISS_X:
> + switch (env->cause_code) {
> + case HEX_CAUSE_TLBMISSX_CAUSE_NORMAL:
> + case HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE:
> + qemu_log_mask(CPU_LOG_MMU,
> + "TLB miss EX exception (0x%x) caught: "
> + "Cause code (0x%x) "
> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> + ", BADVA = 0x%" PRIx32 "\n",
> + cs->exception_index, env->cause_code, env->threadId,
> + arch_get_thread_reg(env, HEX_REG_PC),
> + arch_get_system_reg(env, HEX_SREG_BADVA));
> +
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + break;
> +
> + default:
> + cpu_abort(cs,
> + "1:Hexagon exception %d/0x%x: "
> + "Unknown cause code %d/0x%x\n",
> + cs->exception_index, cs->exception_index, env->cause_code,
> + env->cause_code);
> + break;
> + }
> + break;
> +
> + case HEX_EVENT_TLB_MISS_RW:
> + switch (env->cause_code) {
> + case HEX_CAUSE_TLBMISSRW_CAUSE_READ:
> + case HEX_CAUSE_TLBMISSRW_CAUSE_WRITE:
> + qemu_log_mask(CPU_LOG_MMU,
> + "TLB miss RW exception (0x%x) caught: "
> + "Cause code (0x%x) "
> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> + ", BADVA = 0x%" PRIx32 "\n",
> + cs->exception_index, env->cause_code, env->threadId,
> + env->gpr[HEX_REG_PC],
> + arch_get_system_reg(env, HEX_SREG_BADVA));
> +
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised
> */
> + break;
> +
> + default:
> + cpu_abort(cs,
> + "2:Hexagon exception %d/0x%x: "
> + "Unknown cause code %d/0x%x\n",
> + cs->exception_index, cs->exception_index, env->cause_code,
> + env->cause_code);
> + break;
> + }
> + break;
> +
> + case HEX_EVENT_FPTRAP:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + arch_set_thread_reg(env, HEX_REG_PC,
> + arch_get_system_reg(env, HEX_SREG_EVB) |
> + (cs->exception_index << 2));
Why not use set_addresses here? How is ELR set?
> + break;
> +
> + case HEX_EVENT_DEBUG:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + qemu_log_mask(LOG_UNIMP, "single-step exception is not
> handled\n");
> + break;
> +
> + case HEX_EVENT_PRECISE:
> + switch (env->cause_code) {
> + case HEX_CAUSE_FETCH_NO_XPAGE:
> + case HEX_CAUSE_FETCH_NO_UPAGE:
> + case HEX_CAUSE_PRIV_NO_READ:
> + case HEX_CAUSE_PRIV_NO_UREAD:
> + case HEX_CAUSE_PRIV_NO_WRITE:
> + case HEX_CAUSE_PRIV_NO_UWRITE:
> + case HEX_CAUSE_MISALIGNED_LOAD:
> + case HEX_CAUSE_MISALIGNED_STORE:
> + case HEX_CAUSE_PC_NOT_ALIGNED:
> + qemu_log_mask(CPU_LOG_MMU,
> + "MMU permission exception (0x%x) caught: "
> + "Cause code (0x%x) "
> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> + ", BADVA = 0x%" PRIx32 "\n",
> + cs->exception_index, env->cause_code, env->threadId,
> + env->gpr[HEX_REG_PC],
> + arch_get_system_reg(env, HEX_SREG_BADVA));
> +
> +
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised
> */
> + break;
> +
> + case HEX_CAUSE_DOUBLE_EXCEPT:
> + case HEX_CAUSE_PRIV_USER_NO_SINSN:
> + case HEX_CAUSE_PRIV_USER_NO_GINSN:
> + case HEX_CAUSE_INVALID_OPCODE:
> + case HEX_CAUSE_NO_COPROC_ENABLE:
> + case HEX_CAUSE_NO_COPROC2_ENABLE:
> + case HEX_CAUSE_UNSUPORTED_HVX_64B:
> + case HEX_CAUSE_REG_WRITE_CONFLICT:
> + case HEX_CAUSE_VWCTRL_WINDOW_MISS:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + break;
> +
> + case HEX_CAUSE_COPROC_LDST:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + break;
> +
> + case HEX_CAUSE_STACK_LIMIT:
> + hexagon_ssr_set_cause(env, env->cause_code);
> + set_addresses(env, 0, cs->exception_index);
> + break;
> +
> + default:
> + cpu_abort(cs,
> + "3:Hexagon exception %d/0x%x: "
> + "Unknown cause code %d/0x%x\n",
> + cs->exception_index, cs->exception_index, env->cause_code,
> + env->cause_code);
> + break;
> + }
> + break;
> +
> + case HEX_EVENT_IMPRECISE:
> + qemu_log_mask(LOG_UNIMP,
> + "Imprecise exception: this case is not yet handled");
> + break;
> +
> + default:
> + qemu_log_mask(LOG_UNIMP,
> + "Hexagon Unsupported exception 0x%x/0x%x\n",
> + cs->exception_index, env->cause_code);
> + break;
> + }
> +
> + cs->exception_index = HEX_EVENT_NONE; }
> +
> +void register_trap_exception(CPUHexagonState *env, int traptype, int
> imm,
> + target_ulong PC) {
> + CPUState *cs = env_cpu(env);
> +
> + cs->exception_index = (traptype == 0) ? HEX_EVENT_TRAP0 :
> HEX_EVENT_TRAP1;
> + ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
> +
> + env->cause_code = imm;
> + env->gpr[HEX_REG_PC] = PC;
> + cpu_loop_exit(cs);
> +}
> +#endif
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 42805d0f1d..687e7f45c2 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -38,6 +38,7 @@
> #include "hex_mmu.h"
> #include "hw/intc/l2vic.h"
> #include "hex_interrupts.h"
> +#include "hexswi.h"
Move this do a different patch where the contents are needed
> #endif
>
> #define SF_BIAS 127
> --
> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq
2025-03-01 5:28 ` [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq Brian Cain
@ 2025-03-19 21:33 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 21:33 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads()
2025-03-01 5:28 ` [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads() Brian Cain
@ 2025-03-19 21:36 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-19 21:36 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 21/39] target/hexagon: Implement
> hexagon_resume_threads()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
2025-03-01 5:28 ` [PATCH 22/39] target/hexagon: Implement setprio, resched Brian Cain
@ 2025-03-20 19:44 ` ltaylorsimpson
2025-03-20 20:25 ` Sid Manning
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-20 19:44 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 22/39] target/hexagon: Implement setprio, resched
>
> From: Brian Cain <bcain@quicinc.com>
>
> The hardware-assisted scheduler helps manage tasks on the run queue and
> interrupt steering.
>
> This instruction is defined in the Qualcomm Hexagon V71 Programmer's
> Reference Manual - https://docs.qualcomm.com/bundle/publicresource/80-
> N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
> See §11.9.2 SYSTEM MONITOR.
See earlier discussion on references to documents.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/op_helper.c | 65
> ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 65 insertions(+)
>
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index 0dce133d3a..d0dc4afac7 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -1465,6 +1465,57 @@ void HELPER(stop)(CPUHexagonState *env)
> hexagon_stop_thread(env);
> }
>
> +static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env)
> {
> + uint32_t schedcfg;
> + uint32_t schedcfg_en;
> + int int_number;
> + CPUState *cs;
> + uint32_t lowest_th_prio = 0; /* 0 is highest prio */
> + uint32_t bestwait_reg;
> + uint32_t best_prio;
> +
> + BQL_LOCK_GUARD();
> + qemu_log_mask(CPU_LOG_INT, "%s: check resched\n", __func__);
> + schedcfg = arch_get_system_reg(env, HEX_SREG_SCHEDCFG);
> + schedcfg_en = GET_FIELD(SCHEDCFG_EN, schedcfg);
> + int_number = GET_FIELD(SCHEDCFG_INTNO, schedcfg);
> +
> + if (!schedcfg_en) {
> + return;
> + }
> +
> + CPU_FOREACH(cs) {
> + HexagonCPU *thread = HEXAGON_CPU(cs);
> + CPUHexagonState *thread_env = &(thread->env);
> + uint32_t th_prio = GET_FIELD(
> + STID_PRIO, arch_get_system_reg(thread_env, HEX_SREG_STID));
> + if (!hexagon_thread_is_enabled(thread_env)) {
> + continue;
> + }
> +
> + lowest_th_prio = (lowest_th_prio > th_prio)
> + ? lowest_th_prio
> + : th_prio;
> + }
> +
> + bestwait_reg = arch_get_system_reg(env, HEX_SREG_BESTWAIT);
> + best_prio = GET_FIELD(BESTWAIT_PRIO, bestwait_reg);
> +
> + /*
> + * If the lowest priority thread is lower priority than the
> + * value in the BESTWAIT register, we must raise the reschedule
> + * interrupt on the lowest priority thread.
> + */
> + if (lowest_th_prio > best_prio) {
> + qemu_log_mask(CPU_LOG_INT,
> + "%s: raising resched int %d, cur PC 0x" TARGET_FMT_lx "\n",
> + __func__, int_number, arch_get_thread_reg(env, HEX_REG_PC));
> + SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO,
> 0x1ff);
What is the significance of 0x1ff? The field is 10 bits, so this isn't setting all the bits.
Should this be lowest_th_prio?
> + hex_raise_interrupts(env, 1 << int_number, CPU_INTERRUPT_SWI);
> + }
> +}
> +
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug()
2025-03-01 5:28 ` [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug() Brian Cain
@ 2025-03-20 20:02 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-20 20:02 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:28 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 23/39] target/hexagon: Add sysemu_ops,
> cpu_get_phys_page_debug()
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 37/39] target/hexagon: Add support for loadw_phys
2025-03-01 5:28 ` [PATCH 37/39] target/hexagon: Add support for loadw_phys Brian Cain
@ 2025-03-20 20:04 ` ltaylorsimpson
0 siblings, 0 replies; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-20 20:04 UTC (permalink / raw)
To: 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
> -----Original Message-----
> From: Brian Cain <brian.cain@oss.qualcomm.com>
> Sent: Friday, February 28, 2025 11:29 PM
> To: qemu-devel@nongnu.org
> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
> Subject: [PATCH 37/39] target/hexagon: Add support for loadw_phys
>
> From: Brian Cain <bcain@quicinc.com>
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
2025-03-20 19:44 ` ltaylorsimpson
@ 2025-03-20 20:25 ` Sid Manning
2025-03-20 22:28 ` ltaylorsimpson
0 siblings, 1 reply; 112+ messages in thread
From: Sid Manning @ 2025-03-20 20:25 UTC (permalink / raw)
To: ltaylorsimpson@gmail.com, 'Brian Cain',
qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain
> -----Original Message-----
> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> Sent: Thursday, March 20, 2025 2:45 PM
> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> Subject: RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
>
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> > -----Original Message-----
> > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > Sent: Friday, February 28, 2025 11:28 PM
> > To: qemu-devel@nongnu.org
> > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> anjo@rev.ng;
> > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com;
> > Brian Cain <bcain@quicinc.com>
> > Subject: [PATCH 22/39] target/hexagon: Implement setprio, resched
> >
> > From: Brian Cain <bcain@quicinc.com>
> >
> > The hardware-assisted scheduler helps manage tasks on the run queue
> > and interrupt steering.
> >
> > This instruction is defined in the Qualcomm Hexagon V71 Programmer's
> > Reference Manual -
> https://docs.qualcomm.com/bundle/publicresource/80-
> > N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
> > See §11.9.2 SYSTEM MONITOR.
>
> See earlier discussion on references to documents.
>
> >
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/op_helper.c | 65
> > ++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 65 insertions(+)
> >
> > diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> > index 0dce133d3a..d0dc4afac7 100644
> > --- a/target/hexagon/op_helper.c
> > +++ b/target/hexagon/op_helper.c
> > @@ -1465,6 +1465,57 @@ void HELPER(stop)(CPUHexagonState *env)
> > hexagon_stop_thread(env);
> > }
> >
> > +static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState
> *env)
> > {
> > + uint32_t schedcfg;
> > + uint32_t schedcfg_en;
> > + int int_number;
> > + CPUState *cs;
> > + uint32_t lowest_th_prio = 0; /* 0 is highest prio */
> > + uint32_t bestwait_reg;
> > + uint32_t best_prio;
> > +
> > + BQL_LOCK_GUARD();
> > + qemu_log_mask(CPU_LOG_INT, "%s: check resched\n", __func__);
> > + schedcfg = arch_get_system_reg(env, HEX_SREG_SCHEDCFG);
> > + schedcfg_en = GET_FIELD(SCHEDCFG_EN, schedcfg);
> > + int_number = GET_FIELD(SCHEDCFG_INTNO, schedcfg);
> > +
> > + if (!schedcfg_en) {
> > + return;
> > + }
> > +
> > + CPU_FOREACH(cs) {
> > + HexagonCPU *thread = HEXAGON_CPU(cs);
> > + CPUHexagonState *thread_env = &(thread->env);
> > + uint32_t th_prio = GET_FIELD(
> > + STID_PRIO, arch_get_system_reg(thread_env, HEX_SREG_STID));
> > + if (!hexagon_thread_is_enabled(thread_env)) {
> > + continue;
> > + }
> > +
> > + lowest_th_prio = (lowest_th_prio > th_prio)
> > + ? lowest_th_prio
> > + : th_prio;
> > + }
> > +
> > + bestwait_reg = arch_get_system_reg(env, HEX_SREG_BESTWAIT);
> > + best_prio = GET_FIELD(BESTWAIT_PRIO, bestwait_reg);
> > +
> > + /*
> > + * If the lowest priority thread is lower priority than the
> > + * value in the BESTWAIT register, we must raise the reschedule
> > + * interrupt on the lowest priority thread.
> > + */
> > + if (lowest_th_prio > best_prio) {
> > + qemu_log_mask(CPU_LOG_INT,
> > + "%s: raising resched int %d, cur PC 0x" TARGET_FMT_lx "\n",
> > + __func__, int_number, arch_get_thread_reg(env,
> HEX_REG_PC));
> > + SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO,
> > 0x1ff);
>
> What is the significance of 0x1ff? The field is 10 bits, so this isn't setting all
> the bits.
> Should this be lowest_th_prio?
[Sid Manning]
Hi Taylor,
The value 0x1ff is correct but it does look like BESTWAIT_PRIO is not, it should be 9 not 10
target/hexagon/reg_fields_def.h.inc
It looks like it was added in "PATCH 19/38 target/hexagon: Define register fields for system regs"
I will make a fixup to that patch and correct the value.
>
> > + hex_raise_interrupts(env, 1 << int_number, CPU_INTERRUPT_SWI);
> > + }
> > +}
> > +
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
2025-03-20 20:25 ` Sid Manning
@ 2025-03-20 22:28 ` ltaylorsimpson
2025-09-02 2:08 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: ltaylorsimpson @ 2025-03-20 22:28 UTC (permalink / raw)
To: 'Sid Manning', 'Brian Cain', qemu-devel
Cc: richard.henderson, philmd, 'Matheus Bernardino (QUIC)',
ale, anjo, 'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
> -----Original Message-----
> From: Sid Manning <sidneym@quicinc.com>
> Sent: Thursday, March 20, 2025 3:26 PM
> To: ltaylorsimpson@gmail.com; 'Brian Cain'
> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Brian Cain
> <bcain@quicinc.com>
> Subject: RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
> > > + if (lowest_th_prio > best_prio) {
> > > + qemu_log_mask(CPU_LOG_INT,
> > > + "%s: raising resched int %d, cur PC 0x" TARGET_FMT_lx "\n",
> > > + __func__, int_number, arch_get_thread_reg(env,
> > HEX_REG_PC));
> > > + SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO,
> > > 0x1ff);
> >
> > What is the significance of 0x1ff? The field is 10 bits, so this
> > isn't setting all the bits.
> > Should this be lowest_th_prio?
> [Sid Manning]
>
> Hi Taylor,
>
> The value 0x1ff is correct but it does look like BESTWAIT_PRIO is not, it should
> be 9 not 10 target/hexagon/reg_fields_def.h.inc
>
> It looks like it was added in "PATCH 19/38 target/hexagon: Define register
> fields for system regs"
> I will make a fixup to that patch and correct the value.
I see.
If the intent is to set all the bits in the field, then use ~0.
Taylor
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
2025-03-17 17:44 ` ltaylorsimpson
@ 2025-03-21 21:48 ` Sid Manning
2025-09-02 1:44 ` Brian Cain
0 siblings, 1 reply; 112+ messages in thread
From: Sid Manning @ 2025-03-21 21:48 UTC (permalink / raw)
To: ltaylorsimpson@gmail.com, 'Brian Cain',
qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain
> -----Original Message-----
> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> Sent: Monday, March 17, 2025 12:44 PM
> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
> Subject: RE: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
>
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> > -----Original Message-----
> > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > Sent: Friday, February 28, 2025 11:28 PM
> > To: qemu-devel@nongnu.org
> > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> anjo@rev.ng;
> > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com;
> > Brian Cain <bcain@quicinc.com>
> > Subject: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
> >
> > From: Brian Cain <bcain@quicinc.com>
> >
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/op_helper.c | 31 +++++++++++++++++++++++++++++--
> > 1 file changed, 29 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> > index 9f79b1a20c..83088cfaa3 100644
> > --- a/target/hexagon/op_helper.c
> > +++ b/target/hexagon/op_helper.c
> > @@ -1468,12 +1468,39 @@ void HELPER(resume)(CPUHexagonState *env,
> > uint32_t mask)
> >
> > uint32_t HELPER(getimask)(CPUHexagonState *env, uint32_t tid) {
> > - g_assert_not_reached();
> > + CPUState *cs;
> > + CPU_FOREACH(cs) {
> > + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
> > + CPUHexagonState *found_env = &found_cpu->env;
> > + if (found_env->threadId == tid) {
> > + target_ulong imask = arch_get_system_reg(found_env,
> > HEX_SREG_IMASK);
> > + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask = 0x%x\n",
> > + __func__, env->threadId,
> > + (unsigned)GET_FIELD(IMASK_MASK, imask));
> > + return GET_FIELD(IMASK_MASK, imask);
> > + }
> > + }
> > + return 0;
> > }
> >
> > void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t
> > imask) {
>
> The name pred sounds like a predicate register. Use tid instead.
[Sid Manning]
In this case pred is referring to the predicate register.
setimask(Pt,Rs)
The setimask instruction writes the IMASK for the thread indicated by the low bits of
predicate Pt. Register Rs contains the 32-bit mask value to be written. For Pt values outside of
[0-NUM_THREADS-1], the results are undefined.
>
> > - g_assert_not_reached();
> > + CPUState *cs;
> > +
> > + BQL_LOCK_GUARD();
> > + CPU_FOREACH(cs) {
> > + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
> > + CPUHexagonState *found_env = &found_cpu->env;
> > +
> > + if (pred == found_env->threadId) {
> > + SET_SYSTEM_FIELD(found_env, HEX_SREG_IMASK, IMASK_MASK,
> > imask);
> > + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask 0x%x\n",
> > + __func__, found_env->threadId, imask);
> > + hex_interrupt_update(env);
>
> Shouldn't this be found_env?
[Sid Manning]
It could be either, hex_interrupt_update is just using env to get the global ipend register.
>
> > + return;
> > + }
> > + }
> > + hex_interrupt_update(env);
>
> Do you need to update if the thread wasn't found?
[Sid Manning]
This may not be strictly needed since the only way to reach this line is for setimask to pass a predicate that is outside the range of valid htids. We can remove this and add a guest error.
>
> > }
> >
> > static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
> > --
> > 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* RE: [PATCH 17/39] target/hexagon: Implement software interrupt
2025-03-19 21:28 ` ltaylorsimpson
@ 2025-03-24 15:51 ` Sid Manning
2025-09-02 2:03 ` Brian Cain
1 sibling, 0 replies; 112+ messages in thread
From: Sid Manning @ 2025-03-24 15:51 UTC (permalink / raw)
To: ltaylorsimpson@gmail.com, 'Brian Cain',
qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain, 'Mike Lambert'
> -----Original Message-----
> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
> Sent: Wednesday, March 19, 2025 4:28 PM
> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>; 'Mike Lambert'
> <mlambert@quicinc.com>
> Subject: RE: [PATCH 17/39] target/hexagon: Implement software interrupt
>
> WARNING: This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> > -----Original Message-----
> > From: Brian Cain <brian.cain@oss.qualcomm.com>
> > Sent: Friday, February 28, 2025 11:28 PM
> > To: qemu-devel@nongnu.org
> > Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
> > philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
> anjo@rev.ng;
> > quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
> > alex.bennee@linaro.org; quic_mburton@quicinc.com;
> sidneym@quicinc.com;
> > Brian Cain <bcain@quicinc.com>; Mike Lambert <mlambert@quicinc.com>
> > Subject: [PATCH 17/39] target/hexagon: Implement software interrupt
> >
> > From: Brian Cain <bcain@quicinc.com>
> >
> > Co-authored-by: Mike Lambert <mlambert@quicinc.com>
> > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> > ---
> > target/hexagon/cpu.h | 1 -
> > target/hexagon/hexswi.h | 17 +++
> > target/hexagon/cpu.c | 2 +
> > target/hexagon/hexswi.c | 258
> > +++++++++++++++++++++++++++++++++++++
> > target/hexagon/op_helper.c | 1 +
> > 5 files changed, 278 insertions(+), 1 deletion(-) create mode 100644
> > target/hexagon/hexswi.h create mode 100644 target/hexagon/hexswi.c
> >
> > diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
> > dabee310c5..045581d7be 100644
> > --- a/target/hexagon/cpu.h
> > +++ b/target/hexagon/cpu.h
> > @@ -256,5 +256,4 @@ typedef HexagonCPU ArchCPU; void
> > hexagon_translate_init(void); void hexagon_translate_code(CPUState
> > *cs, TranslationBlock *tb,
> > int *max_insns, vaddr pc, void *host_pc);
> > -
>
> Gratuitous change
>
> > #endif /* HEXAGON_CPU_H */
> > diff --git a/target/hexagon/hexswi.h b/target/hexagon/hexswi.h new
> > file mode 100644 index 0000000000..5d232cb06c
> > --- /dev/null
> > +++ b/target/hexagon/hexswi.h
> > @@ -0,0 +1,17 @@
> > +/*
> > + * Copyright(c) 2025 Qualcomm Innovation Center, Inc. All Rights
> Reserved.
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +#ifndef HEXSWI_H
> > +#define HEXSWI_H
> > +
> > +
> > +#include "cpu.h"
> > +
> > +void hexagon_cpu_do_interrupt(CPUState *cpu); void
> > +register_trap_exception(CPUHexagonState *env, int type, int imm,
> > + target_ulong PC);
> > +
> > +#endif /* HEXSWI_H */
> > diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
> > 89a051b41d..843be8221f 100644
> > --- a/target/hexagon/cpu.c
> > +++ b/target/hexagon/cpu.c
> > @@ -33,6 +33,8 @@
> > #ifndef CONFIG_USER_ONLY
> > #include "sys_macros.h"
> > #include "qemu/main-loop.h"
> > +#include "hex_interrupts.h"
> > +#include "hexswi.h"
>
> Move these added include to a different patch where the contents are
> needed.
>
> > #endif
> >
> > static void hexagon_v66_cpu_init(Object *obj) { } diff --git
> > a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c new file mode
> > 100644 index 0000000000..5fcf9b2be9
> > --- /dev/null
> > +++ b/target/hexagon/hexswi.c
> > @@ -0,0 +1,258 @@
> > +/*
> > + * Copyright(c) 2019-2025 Qualcomm Innovation Center, Inc. All Rights
> > Reserved.
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +#include "qemu/osdep.h"
> > +#include "cpu.h"
> > +#ifdef CONFIG_USER_ONLY
>
> This file is only included in the system-mode build, so we don't need these
> guards. Several in this file.
>
> > +#include "exec/helper-proto.h"
> > +#include "qemu.h"
> > +#endif
> > +#include "exec/cpu_ldst.h"
> > +#include "exec/exec-all.h"
> > +#include "qemu/log.h"
> > +#include "qemu/main-loop.h"
> > +#include "arch.h"
> > +#include "internal.h"
> > +#include "macros.h"
> > +#include "sys_macros.h"
> > +#include "tcg/tcg-op.h"
> > +#ifndef CONFIG_USER_ONLY
> > +#include "hex_mmu.h"
> > +#include "hexswi.h"
> > +#endif
> > +
> > +#ifndef CONFIG_USER_ONLY
> > +
> > +
> > +static void set_addresses(CPUHexagonState *env, target_ulong
> pc_offset,
> > + target_ulong exception_index)
> > +
> > +{
> > + arch_set_system_reg(env, HEX_SREG_ELR,
> > + arch_get_thread_reg(env, HEX_REG_PC) + pc_offset);
> > + arch_set_thread_reg(env, HEX_REG_PC,
> > + arch_get_system_reg(env, HEX_SREG_EVB) |
> > + (exception_index << 2)); }
> > +
> > +static const char *event_name[] = {
> > + [HEX_EVENT_RESET] = "HEX_EVENT_RESET",
> > + [HEX_EVENT_IMPRECISE] = "HEX_EVENT_IMPRECISE",
> > + [HEX_EVENT_TLB_MISS_X] = "HEX_EVENT_TLB_MISS_X",
> > + [HEX_EVENT_TLB_MISS_RW] = "HEX_EVENT_TLB_MISS_RW",
> > + [HEX_EVENT_TRAP0] = "HEX_EVENT_TRAP0",
> > + [HEX_EVENT_TRAP1] = "HEX_EVENT_TRAP1",
> > + [HEX_EVENT_FPTRAP] = "HEX_EVENT_FPTRAP",
> > + [HEX_EVENT_DEBUG] = "HEX_EVENT_DEBUG",
> > + [HEX_EVENT_INT0] = "HEX_EVENT_INT0",
> > + [HEX_EVENT_INT1] = "HEX_EVENT_INT1",
> > + [HEX_EVENT_INT2] = "HEX_EVENT_INT2",
> > + [HEX_EVENT_INT3] = "HEX_EVENT_INT3",
> > + [HEX_EVENT_INT4] = "HEX_EVENT_INT4",
> > + [HEX_EVENT_INT5] = "HEX_EVENT_INT5",
> > + [HEX_EVENT_INT6] = "HEX_EVENT_INT6",
> > + [HEX_EVENT_INT7] = "HEX_EVENT_INT7",
> > + [HEX_EVENT_INT8] = "HEX_EVENT_INT8",
> > + [HEX_EVENT_INT9] = "HEX_EVENT_INT9",
> > + [HEX_EVENT_INTA] = "HEX_EVENT_INTA",
> > + [HEX_EVENT_INTB] = "HEX_EVENT_INTB",
> > + [HEX_EVENT_INTC] = "HEX_EVENT_INTC",
> > + [HEX_EVENT_INTD] = "HEX_EVENT_INTD",
> > + [HEX_EVENT_INTE] = "HEX_EVENT_INTE",
> > + [HEX_EVENT_INTF] = "HEX_EVENT_INTF"
> > +};
> > +
> > +void hexagon_cpu_do_interrupt(CPUState *cs)
> > +
> > +{
> > + CPUHexagonState *env = cpu_env(cs);
> > + BQL_LOCK_GUARD();
> > +
> > + qemu_log_mask(CPU_LOG_INT, "\t%s: event 0x%x:%s, cause
> > 0x%x(%d)\n",
> > + __func__, cs->exception_index,
> > + event_name[cs->exception_index], env->cause_code,
> > + env->cause_code);
> > +
> > + env->llsc_addr = ~0;
> > +
> > + uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
>
> Declarations at the beginning of the function.
[Sid Manning]
Will fix
>
> > + if (GET_SSR_FIELD(SSR_EX, ssr) == 1) {
> > + arch_set_system_reg(env, HEX_SREG_DIAG, env->cause_code);
> > + env->cause_code = HEX_CAUSE_DOUBLE_EXCEPT;
> > + cs->exception_index = HEX_EVENT_PRECISE;
> > + }
> > +
> > + switch (cs->exception_index) {
> > + case HEX_EVENT_TRAP0:
> > + if (env->cause_code == 0) {
> > + qemu_log_mask(LOG_UNIMP,
> > + "trap0 is unhandled, no semihosting available\n");
> > + }
> > +
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 4, cs->exception_index);
> > + break;
> > +
> > + case HEX_EVENT_TRAP1:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 4, cs->exception_index);
> > + break;
> > +
> > + case HEX_EVENT_TLB_MISS_X:
> > + switch (env->cause_code) {
> > + case HEX_CAUSE_TLBMISSX_CAUSE_NORMAL:
> > + case HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE:
> > + qemu_log_mask(CPU_LOG_MMU,
> > + "TLB miss EX exception (0x%x) caught: "
> > + "Cause code (0x%x) "
> > + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> > + ", BADVA = 0x%" PRIx32 "\n",
> > + cs->exception_index, env->cause_code, env->threadId,
> > + arch_get_thread_reg(env, HEX_REG_PC),
> > + arch_get_system_reg(env, HEX_SREG_BADVA));
> > +
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + break;
> > +
> > + default:
> > + cpu_abort(cs,
> > + "1:Hexagon exception %d/0x%x: "
> > + "Unknown cause code %d/0x%x\n",
> > + cs->exception_index, cs->exception_index, env->cause_code,
> > + env->cause_code);
> > + break;
> > + }
> > + break;
> > +
> > + case HEX_EVENT_TLB_MISS_RW:
> > + switch (env->cause_code) {
> > + case HEX_CAUSE_TLBMISSRW_CAUSE_READ:
> > + case HEX_CAUSE_TLBMISSRW_CAUSE_WRITE:
> > + qemu_log_mask(CPU_LOG_MMU,
> > + "TLB miss RW exception (0x%x) caught: "
> > + "Cause code (0x%x) "
> > + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> > + ", BADVA = 0x%" PRIx32 "\n",
> > + cs->exception_index, env->cause_code, env->threadId,
> > + env->gpr[HEX_REG_PC],
> > + arch_get_system_reg(env, HEX_SREG_BADVA));
> > +
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + /* env->sreg[HEX_SREG_BADVA] is set when the exception is
> > + raised
> > */
> > + break;
> > +
> > + default:
> > + cpu_abort(cs,
> > + "2:Hexagon exception %d/0x%x: "
> > + "Unknown cause code %d/0x%x\n",
> > + cs->exception_index, cs->exception_index, env->cause_code,
> > + env->cause_code);
> > + break;
> > + }
> > + break;
> > +
> > + case HEX_EVENT_FPTRAP:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + arch_set_thread_reg(env, HEX_REG_PC,
> > + arch_get_system_reg(env, HEX_SREG_EVB) |
> > + (cs->exception_index << 2));
>
> Why not use set_addresses here? How is ELR set?
[Sid Manning]
I think at this level the FP traps are not complete. ELR is supposed to point to the next instruction, next_PC, that is why set_addresses isn't used. We will have to add some checks of usr:fp's to know if instructions with FPOPS attribute need next_PC or not.
>
> > + break;
> > +
> > + case HEX_EVENT_DEBUG:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + qemu_log_mask(LOG_UNIMP, "single-step exception is not
> > handled\n");
> > + break;
> > +
> > + case HEX_EVENT_PRECISE:
> > + switch (env->cause_code) {
> > + case HEX_CAUSE_FETCH_NO_XPAGE:
> > + case HEX_CAUSE_FETCH_NO_UPAGE:
> > + case HEX_CAUSE_PRIV_NO_READ:
> > + case HEX_CAUSE_PRIV_NO_UREAD:
> > + case HEX_CAUSE_PRIV_NO_WRITE:
> > + case HEX_CAUSE_PRIV_NO_UWRITE:
> > + case HEX_CAUSE_MISALIGNED_LOAD:
> > + case HEX_CAUSE_MISALIGNED_STORE:
> > + case HEX_CAUSE_PC_NOT_ALIGNED:
> > + qemu_log_mask(CPU_LOG_MMU,
> > + "MMU permission exception (0x%x) caught: "
> > + "Cause code (0x%x) "
> > + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
> > + ", BADVA = 0x%" PRIx32 "\n",
> > + cs->exception_index, env->cause_code, env->threadId,
> > + env->gpr[HEX_REG_PC],
> > + arch_get_system_reg(env, HEX_SREG_BADVA));
> > +
> > +
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + /* env->sreg[HEX_SREG_BADVA] is set when the exception is
> > + raised
> > */
> > + break;
> > +
> > + case HEX_CAUSE_DOUBLE_EXCEPT:
> > + case HEX_CAUSE_PRIV_USER_NO_SINSN:
> > + case HEX_CAUSE_PRIV_USER_NO_GINSN:
> > + case HEX_CAUSE_INVALID_OPCODE:
> > + case HEX_CAUSE_NO_COPROC_ENABLE:
> > + case HEX_CAUSE_NO_COPROC2_ENABLE:
> > + case HEX_CAUSE_UNSUPORTED_HVX_64B:
> > + case HEX_CAUSE_REG_WRITE_CONFLICT:
> > + case HEX_CAUSE_VWCTRL_WINDOW_MISS:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + break;
> > +
> > + case HEX_CAUSE_COPROC_LDST:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + break;
> > +
> > + case HEX_CAUSE_STACK_LIMIT:
> > + hexagon_ssr_set_cause(env, env->cause_code);
> > + set_addresses(env, 0, cs->exception_index);
> > + break;
> > +
> > + default:
> > + cpu_abort(cs,
> > + "3:Hexagon exception %d/0x%x: "
> > + "Unknown cause code %d/0x%x\n",
> > + cs->exception_index, cs->exception_index, env->cause_code,
> > + env->cause_code);
> > + break;
> > + }
> > + break;
> > +
> > + case HEX_EVENT_IMPRECISE:
> > + qemu_log_mask(LOG_UNIMP,
> > + "Imprecise exception: this case is not yet handled");
> > + break;
> > +
> > + default:
> > + qemu_log_mask(LOG_UNIMP,
> > + "Hexagon Unsupported exception 0x%x/0x%x\n",
> > + cs->exception_index, env->cause_code);
> > + break;
> > + }
> > +
> > + cs->exception_index = HEX_EVENT_NONE; }
> > +
> > +void register_trap_exception(CPUHexagonState *env, int traptype, int
> > imm,
> > + target_ulong PC) {
> > + CPUState *cs = env_cpu(env);
> > +
> > + cs->exception_index = (traptype == 0) ? HEX_EVENT_TRAP0 :
> > HEX_EVENT_TRAP1;
> > + ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
> > +
> > + env->cause_code = imm;
> > + env->gpr[HEX_REG_PC] = PC;
> > + cpu_loop_exit(cs);
> > +}
> > +#endif
> > diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> > index 42805d0f1d..687e7f45c2 100644
> > --- a/target/hexagon/op_helper.c
> > +++ b/target/hexagon/op_helper.c
> > @@ -38,6 +38,7 @@
> > #include "hex_mmu.h"
> > #include "hw/intc/l2vic.h"
> > #include "hex_interrupts.h"
> > +#include "hexswi.h"
>
> Move this do a different patch where the contents are needed
>
> > #endif
> >
> > #define SF_BIAS 127
> > --
> > 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 08/39] target/hexagon: Implement get_exe_mode()
2025-03-17 18:43 ` ltaylorsimpson
@ 2025-04-02 2:03 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-04-02 2:03 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 1:43 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 08/39] target/hexagon: Implement get_exe_mode()
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>
>> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
>> index e64568b9fc..e0dd120cd4 100644
>> --- a/target/hexagon/cpu_helper.c
>> +++ b/target/hexagon/cpu_helper.c
>> @@ -237,6 +237,30 @@ void hexagon_ssr_set_cause(CPUHexagonState
>> *env, uint32_t cause)
>>
>> int get_exe_mode(CPUHexagonState *env)
>> {
>> + g_assert(bql_locked());
>> +
>> + target_ulong modectl = arch_get_system_reg(env,
>> HEX_SREG_MODECTL);
>> + uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
>> + bool E_bit = thread_enabled_mask & (0x1 << env->threadId);
>> + uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
>> + bool W_bit = thread_wait_mask & (0x1 << env->threadId);
>> + target_ulong isdbst = arch_get_system_reg(env, HEX_SREG_ISDBST);
>> + uint32_t debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst);
>> + bool D_bit = debugmode & (0x1 << env->threadId);
>> +
>> + /* Figure 4-2 */
> Figure 4-2 in which document?
I don't think that document with this figure is published.
I'll just remove the reference instead.
>
> Otherwise
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 12/39] target/hexagon: Add implementation of cycle counters
2025-03-19 19:50 ` ltaylorsimpson
@ 2025-04-02 2:44 ` Brian Cain
[not found] ` <7274cd69-f4e7-40b5-b850-cbd9099ed8ac@oss.qualcomm.com>
1 sibling, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-04-02 2:44 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/19/2025 2:50 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 12/39] target/hexagon: Add implementation of cycle
>> counters
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Co-authored-by: Sid Manning <sidneym@quicinc.com>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 25 ++++++++++++++++++++++---
>> target/hexagon/translate.h | 2 ++
>> target/hexagon/cpu_helper.c | 12 +++++++++---
>> target/hexagon/translate.c | 27 +++++++++++++++++++++++++++
>> 4 files changed, 60 insertions(+), 6 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> 4b9c9873dc..7e2ea838c5 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -27,11 +27,15 @@
>>
>> #include "cpu-qom.h"
>> #include "exec/cpu-defs.h"
>> +#include "exec/cpu-common.h"
>> #include "hex_regs.h"
>> #include "mmvec/mmvec.h"
>> #include "hw/registerfields.h"
>>
>> +#ifndef CONFIG_USER_ONLY
>> +#include "reg_fields.h"
>> typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
>> +#endif
> Why is reg_fields.h guarded by #ifndef CONFIG_USER_ONLY?
It's to get syscfg field definitions like "SYSCFG_PCYCLEEN". We can
move it to a more general place, though.
> Also, why wasn't the CPUHexagonTLBContext guarded when it was first inserted?
It should have been. I will fix this.
>> #define NUM_PREGS 4
>> #define TOTAL_PER_THREAD_REGS 64
>> @@ -188,6 +192,7 @@ struct ArchCPU {
>>
>> FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
>> FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
>> +FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1)
>>
>> G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
>> uint32_t exception, @@ -201,6 +206,11 @@ void
>> hexagon_cpu_soft_reset(CPUHexagonState *env); #endif
>>
>> #include "exec/cpu-all.h"
>> +
>> +#ifndef CONFIG_USER_ONLY
>> +#include "cpu_helper.h"
>> +#endif
>> +
>> static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
>> uint64_t *cs_base, uint32_t *flags) { @@ -210,16
>> +220,27 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState
>> *env, vaddr *pc,
>> if (*pc == env->gpr[HEX_REG_SA0]) {
>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
>> }
>> - *flags = hex_flags;
>> if (*pc & PCALIGN_MASK) {
>> hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0);
>> }
>> #ifndef CONFIG_USER_ONLY
>> + target_ulong syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
>> +
>> + bool pcycle_enabled = extract32(syscfg,
>> + reg_field_info[SYSCFG_PCYCLEEN].offset,
>> +
>> + reg_field_info[SYSCFG_PCYCLEEN].width);
>> +
>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
>> cpu_mmu_index(env_cpu(env), false));
>> +
>> + if (pcycle_enabled) {
>> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, 1);
>> + }
>> #else
>> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, true);
> Are pcycles exposed in linux-user mode? If not, make this flag system-mode only.
Yes, they are (for the "upcycle" registers).
>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
>> MMU_USER_IDX); #endif
>> + *flags = hex_flags;
>> }
>>
>> typedef HexagonCPU ArchCPU;
>> @@ -228,6 +249,4 @@ void hexagon_translate_init(void); void
>> hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
>> int *max_insns, vaddr pc, void *host_pc);
>>
>> -#include "exec/cpu-all.h"
>> -
>> #endif /* HEXAGON_CPU_H */
>> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index
>> 0eaa3db03e..9bc4b3ce8b 100644
>> --- a/target/hexagon/translate.h
>> +++ b/target/hexagon/translate.h
>> @@ -83,6 +83,8 @@ typedef struct DisasContext {
>> TCGv new_pred_value[NUM_PREGS];
>> TCGv branch_taken;
>> TCGv dczero_addr;
>> + bool pcycle_enabled;
> Guard with #ifndef CONFIG_USER_ONLY
>
>> + uint32_t num_cycles;
>> } DisasContext;
>>
>> bool is_gather_store_insn(DisasContext *ctx); diff --git
>> a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c index
>> 0b0802bfb9..1d9b9f8bef 100644
>> --- a/target/hexagon/cpu_helper.c
>> +++ b/target/hexagon/cpu_helper.c
>> @@ -48,17 +48,23 @@ uint32_t arch_get_system_reg(CPUHexagonState
>> *env, uint32_t reg)
>>
>> uint64_t hexagon_get_sys_pcycle_count(CPUHexagonState *env) {
>> - g_assert_not_reached();
> Do we need a lock here?
I didn't think we did. But now that you mention it, we may indeed.
>> + uint64_t cycles = 0;
>> + CPUState *cs;
>> + CPU_FOREACH(cs) {
>> + CPUHexagonState *env_ = cpu_env(cs);
>> + cycles += env_->t_cycle_count;
>> + }
>> + return *(env->g_pcycle_base) + cycles;
>> }
>>
>> uint32_t hexagon_get_sys_pcycle_count_high(CPUHexagonState *env) {
>> - g_assert_not_reached();
>> + return hexagon_get_sys_pcycle_count(env) >> 32;
>> }
>>
>> uint32_t hexagon_get_sys_pcycle_count_low(CPUHexagonState *env) {
>> - g_assert_not_reached();
>> + return extract64(hexagon_get_sys_pcycle_count(env), 0, 32);
>> }
>>
>> void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, diff --git
>> a/target/hexagon/translate.c b/target/hexagon/translate.c index
>> 9119e42ff7..060df6e5eb 100644
>> --- a/target/hexagon/translate.c
>> +++ b/target/hexagon/translate.c
>> @@ -57,6 +57,7 @@ TCGv_i64 hex_store_val64[STORES_MAX]; TCGv
>> hex_llsc_addr; TCGv hex_llsc_val;
>> TCGv_i64 hex_llsc_val_i64;
>> +TCGv_i64 hex_cycle_count;
> Guard with #ifndef CONFIG_USER_ONLY
This feature belongs to both usermode and system emulation.
>> TCGv hex_vstore_addr[VSTORES_MAX];
>> TCGv hex_vstore_size[VSTORES_MAX];
>> TCGv hex_vstore_pending[VSTORES_MAX];
>> @@ -125,6 +126,22 @@ static void gen_exception_raw(int excp)
>> gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); }
>>
>> +#ifndef CONFIG_USER_ONLY
>> +static inline void gen_precise_exception(int excp, target_ulong PC) {
>> + tcg_gen_movi_tl(hex_cause_code, excp);
>> + gen_exception(HEX_EVENT_PRECISE, PC); }
> Belongs in a different patch.
I will fix this.
>> +
>> +static inline void gen_pcycle_counters(DisasContext *ctx) {
>> + if (ctx->pcycle_enabled) {
>> + tcg_gen_addi_i64(hex_cycle_count, hex_cycle_count, ctx-
>>> num_cycles);
>> + ctx->num_cycles = 0;
>> + }
>> +}
>> +#endif
>> +
>> static void gen_exec_counters(DisasContext *ctx) {
>> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT],
>> @@ -133,6 +150,10 @@ static void gen_exec_counters(DisasContext *ctx)
>> hex_gpr[HEX_REG_QEMU_INSN_CNT], ctx->num_insns);
>> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_HVX_CNT],
>> hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
>> +
>> +#ifndef CONFIG_USER_ONLY
>> + gen_pcycle_counters(ctx);
>> +#endif
>> }
>>
>> static bool use_goto_tb(DisasContext *ctx, target_ulong dest) @@ -785,6
>> +806,7 @@ static void gen_commit_hvx(DisasContext *ctx)
>> }
>> }
>>
>> +static const int PCYCLES_PER_PACKET = 3;
>> static void update_exec_counters(DisasContext *ctx) {
>> Packet *pkt = ctx->pkt;
>> @@ -804,6 +826,7 @@ static void update_exec_counters(DisasContext *ctx)
>> }
>>
>> ctx->num_packets++;
>> + ctx->num_cycles += PCYCLES_PER_PACKET;
> Guard
>
>> ctx->num_insns += num_real_insns;
>> ctx->num_hvx_insns += num_hvx_insns; } @@ -946,11 +969,13 @@ static
>> void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>>
>> ctx->mem_idx = FIELD_EX32(hex_flags, TB_FLAGS, MMU_INDEX);
>> ctx->num_packets = 0;
>> + ctx->num_cycles = 0;
> Guard
>
>> ctx->num_insns = 0;
>> ctx->num_hvx_insns = 0;
>> ctx->branch_cond = TCG_COND_NEVER;
>> ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
>> ctx->short_circuit = hex_cpu->short_circuit;
>> + ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS,
>> + PCYCLE_ENABLED);
> Guard
>
>> }
>>
>> static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) @@
>> -1077,6 +1102,8 @@ void hexagon_translate_init(void)
>> offsetof(CPUHexagonState, llsc_val), "llsc_val");
>> hex_llsc_val_i64 = tcg_global_mem_new_i64(tcg_env,
>> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
>> + hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
>> + offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
> Guard
These will remain unguarded as referenced above - it's a general feature.
>> for (i = 0; i < STORES_MAX; i++) {
>> snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
>> hex_store_addr[i] = tcg_global_mem_new(tcg_env,
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 01/39] target/hexagon: Implement ciad helper
2025-03-17 16:08 ` ltaylorsimpson
2025-03-18 14:44 ` Sid Manning
@ 2025-09-02 1:32 ` Brian Cain
1 sibling, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:32 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 11:08 AM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 01/39] target/hexagon: Implement ciad helper
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> ciad is the clear interrupt auto disable instruction.
>>
>> This instruction is defined in the Qualcomm Hexagon V71 Programmer's
>> Reference Manual - https://docs.qualcomm.com/bundle/publicresource/80-
>> N2040-51_REV_AB_Hexagon_V71_ProgrammerS_Reference_Manual.pdf
>> See §11.9.2 SYSTEM MONITOR.
> Put this reference in somewhere easier to find. See prior discussion on this.
>
> If it's only in the commit comment, it will be lost quickly.
Fixed in v2.
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/op_helper.c | 39 ++++++++++++++++++++++++++++++++-
>> -----
>> 1 file changed, 33 insertions(+), 6 deletions(-)
>>
>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>> index fd9caafefc..b28a18adf6 100644
>> --- a/target/hexagon/op_helper.c
>> +++ b/target/hexagon/op_helper.c
>> @@ -34,6 +34,11 @@
>> #include "op_helper.h"
>> #include "cpu_helper.h"
>> #include "translate.h"
>> +#ifndef CONFIG_USER_ONLY
>> +#include "hex_mmu.h"
>> +#include "hw/intc/l2vic.h"
>> +#include "hex_interrupts.h"
>> +#endif
>>
>> #define SF_BIAS 127
>> #define SF_MANTBITS 23
>> @@ -1338,9 +1343,36 @@ void HELPER(vwhist128qm)(CPUHexagonState
>> *env, int32_t uiV) }
>>
>> #ifndef CONFIG_USER_ONLY
>> +static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int
>> +val) {
>> + g_assert((offset == L2VIC_VID_0) || (offset == L2VIC_VID_1));
>> + CPUState *cs = env_cpu(env);
>> + HexagonCPU *cpu = HEXAGON_CPU(cs);
>> + const hwaddr pend_mem = cpu->l2vic_base_addr + offset;
>> + cpu_physical_memory_write(pend_mem, &val, sizeof(val)); }
> Careful here - an int is different sizes on 32-bit and 64-bit hosts. Change the type to int32_t or int64_t.
Not fixed in v2, will work on this for v3.
>> +
>> +static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t
>> +offset) {
>> + /*
>> + * currently only l2vic is the only attached it uses vid0, remove
>> + * the assert below if anther is added
> What assert?
Fixed in v2.
>> + */
>> + hexagon_set_vid(env, offset, L2VIC_CIAD_INSTRUCTION); }
>> +
>> void HELPER(ciad)(CPUHexagonState *env, uint32_t mask) {
>> - g_assert_not_reached();
>> + uint32_t ipendad;
>> + uint32_t iad;
>> +
>> + BQL_LOCK_GUARD();
>> + ipendad = READ_SREG(HEX_SREG_IPENDAD);
>> + iad = fGET_FIELD(ipendad, IPENDAD_IAD);
>> + fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask));
>> + arch_set_system_reg(env, HEX_SREG_IPENDAD, ipendad);
>> + hexagon_clear_last_irq(env, L2VIC_VID_0);
>> + hex_interrupt_update(env);
>> }
>>
>> void HELPER(siad)(CPUHexagonState *env, uint32_t mask) @@ -1416,11
>> +1448,6 @@ static void modify_syscfg(CPUHexagonState *env, uint32_t val)
>> g_assert_not_reached();
>> }
>>
>> -static void hexagon_set_vid(CPUHexagonState *env, uint32_t offset, int
>> val) -{
>> - g_assert_not_reached();
>> -}
>> -
>> static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
>> {
>> g_assert_not_reached();
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 04/39] target/hexagon: Implement start/stop helpers
2025-03-17 16:35 ` ltaylorsimpson
@ 2025-09-02 1:33 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:33 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 11:35 AM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 04/39] target/hexagon: Implement start/stop helpers
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 3 ++
>> target/hexagon/cpu_bits.h | 1 +
>> target/hexagon/cpu_helper.h | 3 ++
>> target/hexagon/cpu.c | 14 +++++-
>> target/hexagon/cpu_helper.c | 94
>> +++++++++++++++++++++++++++++++++++++
>> target/hexagon/op_helper.c | 4 +-
>> 6 files changed, 116 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> 894219fd20..1549c4f1f0 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -41,6 +41,7 @@ typedef struct CPUHexagonTLBContext
>> CPUHexagonTLBContext; #define REG_WRITES_MAX 32
>> #define PRED_WRITES_MAX 5 /* 4 insns + endloop */
>> #define VSTORES_MAX 2
>> +#define VECTOR_UNIT_MAX 8
> Not related to start/stop and not used in this patch.
HVX contexts moved out of this series, they'll return in a new series
after we land parts 1,2,3.
>
>> #ifndef CONFIG_USER_ONLY
>> #define CPU_INTERRUPT_SWI CPU_INTERRUPT_TGT_INT_0
>> @@ -178,6 +179,7 @@ struct ArchCPU {
>> #ifndef CONFIG_USER_ONLY
>> uint32_t num_tlbs;
>> uint32_t l2vic_base_addr;
>> + uint32_t hvx_contexts;
> Not related to start/stop.
>
>> #endif
>> };
>>
>> @@ -194,6 +196,7 @@ G_NORETURN void
>> hexagon_raise_exception_err(CPUHexagonState *env, uint32_t
>> hexagon_greg_read(CPUHexagonState *env, uint32_t reg); uint32_t
>> hexagon_sreg_read(CPUHexagonState *env, uint32_t reg); void
>> hexagon_gdb_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t
>> val);
>> +void hexagon_cpu_soft_reset(CPUHexagonState *env);
>> #endif
>>
>> #include "exec/cpu-all.h"
>> diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h index
>> b559a7ba88..610094a759 100644
>> --- a/target/hexagon/cpu_bits.h
>> +++ b/target/hexagon/cpu_bits.h
>> @@ -52,6 +52,7 @@ enum hex_event {
>>
>> enum hex_cause {
>> HEX_CAUSE_NONE = -1,
>> + HEX_CAUSE_RESET = 0x000,
>> HEX_CAUSE_TRAP0 = 0x172,
>> HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
>> HEX_CAUSE_INVALID_PACKET = 0x015,
>> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
>> index 6f0c6697ad..95a0cc0788 100644
>> --- a/target/hexagon/cpu_helper.h
>> +++ b/target/hexagon/cpu_helper.h
>> @@ -17,6 +17,9 @@ void
>> hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, uint32_t);
>> void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t
>> old); int get_exe_mode(CPUHexagonState *env); void
>> clear_wait_mode(CPUHexagonState *env);
>> +void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause); void
>> +hexagon_start_threads(CPUHexagonState *env, uint32_t mask); void
>> +hexagon_stop_thread(CPUHexagonState *env);
>>
>> static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
>> uint32_t val) diff --git a/target/hexagon/cpu.c
>> b/target/hexagon/cpu.c index cb56b929cf..84a96a194b 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -32,6 +32,7 @@
>>
>> #ifndef CONFIG_USER_ONLY
>> #include "sys_macros.h"
>> +#include "qemu/main-loop.h"
>> #endif
>>
>> static void hexagon_v66_cpu_init(Object *obj) { } @@ -61,6 +62,7 @@ static
>> const Property hexagon_cpu_properties[] = {
>> DEFINE_PROP_UINT32("jtlb-entries", HexagonCPU, num_tlbs,
>> MAX_TLB_ENTRIES),
>> DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
>> 0xffffffffULL),
>> + DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
> Not related to start/stop.
>
>> #endif
>> DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 05/39] target/hexagon: Implement modify SSR
2025-03-19 16:58 ` Richard Henderson
@ 2025-09-02 1:39 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:39 UTC (permalink / raw)
To: Richard Henderson, ltaylorsimpson, 'Sid Manning',
qemu-devel
Cc: philmd, 'Matheus Bernardino (QUIC)', ale, anjo,
'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
On 3/19/2025 11:58 AM, Richard Henderson wrote:
> On 3/19/25 09:39, ltaylorsimpson@gmail.com wrote:
>> I caution against putting a level of indirection into CPUHexagonState
>> for the HVX registers. The HVX TCG implementation relies on an
>> offset from the start of CPUHexagonState to identify the operands.
>> This would be a very significant rewrite if it's even possible. I
>> don't know if TCG's gvec code generation can handle random pointers
>> or a level of indirection.
>
>
> Not yet, it can't, no.
>
> I've been extending it for random pointers because of Arm FEAT_SME2,
> wherein we have indirect addressing of matrix slices. So we wind up
> with a pointer like
>
> &env->zarray + (env->xregs[reg] + offset) % size
>
>
>> If the behavior is undefined, we can avoid the copies. Then we just
>> need some bookkeeping to check if multiple threads try to claim the
>> same context (if that behavior is defined). If copies are needed, we
>> could keep the hardware contexts as shared a shared resource.
>> Another alternative would be to track the current owner of a context
>> and copy from the previous owner's {VQ}Regs to the new owners {VQ}Regs.
>
> Depending on how you answer these questions, I could split out the TCG
> work.
> But in the short term, copying context data might well be easier.
>
I've removed HVX context management from this series and will propose it
in a future one. Indeed the behavior is undefined when multiple
hardware threads try to access the same context. If the TCG changes for
indirection show up at some point (or have already shown up) that would
be great for us to take advantage of. But the copies seem adequate for now.
>
> r~
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
2025-03-21 21:48 ` Sid Manning
@ 2025-09-02 1:44 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:44 UTC (permalink / raw)
To: Sid Manning, ltaylorsimpson@gmail.com, qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
Matheus Bernardino (QUIC), ale@rev.ng, anjo@rev.ng,
Marco Liebel (QUIC), alex.bennee@linaro.org, Mark Burton (QUIC),
Brian Cain
On 3/21/2025 4:48 PM, Sid Manning wrote:
>
>> -----Original Message-----
>> From: ltaylorsimpson@gmail.com <ltaylorsimpson@gmail.com>
>> Sent: Monday, March 17, 2025 12:44 PM
>> To: 'Brian Cain' <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
>> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
>> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
>> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
>> Burton (QUIC) <quic_mburton@quicinc.com>; Sid Manning
>> <sidneym@quicinc.com>; Brian Cain <bcain@quicinc.com>
>> Subject: RE: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
>>
>> WARNING: This email originated from outside of Qualcomm. Please be wary
>> of any links or attachments, and do not enable macros.
>>
>>> -----Original Message-----
>>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>>> Sent: Friday, February 28, 2025 11:28 PM
>>> To: qemu-devel@nongnu.org
>>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng;
>> anjo@rev.ng;
>>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com;
>>> Brian Cain <bcain@quicinc.com>
>>> Subject: [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers
>>>
>>> From: Brian Cain <bcain@quicinc.com>
>>>
>>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>>> ---
>>> target/hexagon/op_helper.c | 31 +++++++++++++++++++++++++++++--
>>> 1 file changed, 29 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>>> index 9f79b1a20c..83088cfaa3 100644
>>> --- a/target/hexagon/op_helper.c
>>> +++ b/target/hexagon/op_helper.c
>>> @@ -1468,12 +1468,39 @@ void HELPER(resume)(CPUHexagonState *env,
>>> uint32_t mask)
>>>
>>> uint32_t HELPER(getimask)(CPUHexagonState *env, uint32_t tid) {
>>> - g_assert_not_reached();
>>> + CPUState *cs;
>>> + CPU_FOREACH(cs) {
>>> + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
>>> + CPUHexagonState *found_env = &found_cpu->env;
>>> + if (found_env->threadId == tid) {
>>> + target_ulong imask = arch_get_system_reg(found_env,
>>> HEX_SREG_IMASK);
>>> + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask = 0x%x\n",
>>> + __func__, env->threadId,
>>> + (unsigned)GET_FIELD(IMASK_MASK, imask));
>>> + return GET_FIELD(IMASK_MASK, imask);
>>> + }
>>> + }
>>> + return 0;
>>> }
>>>
>>> void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t
>>> imask) {
>> The name pred sounds like a predicate register. Use tid instead.
> [Sid Manning]
> In this case pred is referring to the predicate register.
>
> setimask(Pt,Rs)
> The setimask instruction writes the IMASK for the thread indicated by the low bits of
> predicate Pt. Register Rs contains the 32-bit mask value to be written. For Pt values outside of
> [0-NUM_THREADS-1], the results are undefined.
>
>>> - g_assert_not_reached();
>>> + CPUState *cs;
>>> +
>>> + BQL_LOCK_GUARD();
>>> + CPU_FOREACH(cs) {
>>> + HexagonCPU *found_cpu = HEXAGON_CPU(cs);
>>> + CPUHexagonState *found_env = &found_cpu->env;
>>> +
>>> + if (pred == found_env->threadId) {
>>> + SET_SYSTEM_FIELD(found_env, HEX_SREG_IMASK, IMASK_MASK,
>>> imask);
>>> + qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask 0x%x\n",
>>> + __func__, found_env->threadId, imask);
>>> + hex_interrupt_update(env);
>> Shouldn't this be found_env?
> [Sid Manning]
> It could be either, hex_interrupt_update is just using env to get the global ipend register.
>>> + return;
>>> + }
>>> + }
>>> + hex_interrupt_update(env);
>> Do you need to update if the thread wasn't found?
> [Sid Manning]
> This may not be strictly needed since the only way to reach this line is for setimask to pass a predicate that is outside the range of valid htids. We can remove this and add a guest error.
>
Fixed in v2 but I see now that we used the wrong format specifier - will
fix it for v3.
>>> }
>>>
>>> static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
>>> --
>>> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 07/39] target/hexagon: Implement wait helper
2025-03-17 18:37 ` ltaylorsimpson
@ 2025-09-02 1:46 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:46 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 1:37 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 07/39] target/hexagon: Implement wait helper
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu_helper.h | 1 +
>> target/hexagon/cpu_helper.c | 40
>> +++++++++++++++++++++++++++++++++++++
>> target/hexagon/op_helper.c | 6 +++++-
>> 3 files changed, 46 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
>> index 95a0cc0788..e8d89d8526 100644
>> --- a/target/hexagon/cpu_helper.h
>> +++ b/target/hexagon/cpu_helper.h
>> @@ -20,6 +20,7 @@ void clear_wait_mode(CPUHexagonState *env); void
>> hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause); void
>> hexagon_start_threads(CPUHexagonState *env, uint32_t mask); void
>> hexagon_stop_thread(CPUHexagonState *env);
>> +void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC);
>>
>> static inline void arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
>> uint32_t val) diff --git a/target/hexagon/cpu_helper.c
>> b/target/hexagon/cpu_helper.c index 3e2364a7b0..e64568b9fc 100644
>> --- a/target/hexagon/cpu_helper.c
>> +++ b/target/hexagon/cpu_helper.c
>> @@ -71,6 +71,46 @@ void
>> hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t cycles)
>> g_assert_not_reached();
>> }
>>
>> +static void set_wait_mode(CPUHexagonState *env) {
>> + g_assert(bql_locked());
>> +
>> + const uint32_t modectl = arch_get_system_reg(env,
>> HEX_SREG_MODECTL);
>> + uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
>> + thread_wait_mask |= 0x1 << env->threadId;
>> + SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W,
>> +thread_wait_mask); }
>> +
>> +void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC) {
>> + g_assert(bql_locked());
>> +
>> + if (qemu_loglevel_mask(LOG_GUEST_ERROR) &&
>> + (env->k0_lock_state != HEX_LOCK_UNLOCKED ||
>> + env->tlb_lock_state != HEX_LOCK_UNLOCKED)) {
>> + qemu_log("WARNING: executing wait() with acquired lock"
>> + "may lead to deadlock\n");
>> + }
>> + g_assert(get_exe_mode(env) != HEX_EXE_MODE_WAIT);
>> +
>> + CPUState *cs = env_cpu(env);
>> + /*
>> + * The addtion of cpu_has_work is borrowed from arm's wfi helper
>> + * and is critical for our stability
>> + */
>> + if ((cs->exception_index != HEX_EVENT_NONE) ||
>> + (cpu_has_work(cs))) {
>> + qemu_log_mask(CPU_LOG_INT,
>> + "%s: thread %d skipping WAIT mode, have some work\n",
>> + __func__, env->threadId);
>> + return;
>> + }
>> + set_wait_mode(env);
>> + env->wait_next_pc = PC + 4;
>> +
>> + cpu_interrupt(cs, CPU_INTERRUPT_HALT); }
>> +
> Why not put this in op_helper.c?
I'm not quite certain what the rationale was but if it shouldn't be in
cpu_helper.c we can move it. Is it just hexagon_wait_thread() or should
all of these functions be there instead?
>
> Otherwise
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 10/39] target/hexagon: Implement arch_{s,g}et_{thread,system}_reg()
2025-03-17 19:24 ` ltaylorsimpson
@ 2025-09-02 1:50 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:50 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 2:24 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 10/39] target/hexagon: Implement
>> arch_{s,g}et_{thread,system}_reg()
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu_helper.h | 13 ++++++++++---
>> 1 file changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
>> index e8d89d8526..1cdf4f8dd0 100644
>> --- a/target/hexagon/cpu_helper.h
>> +++ b/target/hexagon/cpu_helper.h
>> @@ -26,20 +26,27 @@ static inline void
>> arch_set_thread_reg(CPUHexagonState *env, uint32_t reg,
>> uint32_t val) {
>> g_assert(reg < TOTAL_PER_THREAD_REGS);
>> - g_assert_not_reached();
>> + env->gpr[reg] = val;
> Gotta be careful here. Not all registers can be assigned directly. Look at gen_write_ctrl_reg in genptr.c.
>
>> }
>>
>> static inline uint32_t arch_get_thread_reg(CPUHexagonState *env, uint32_t
>> reg) {
>> g_assert(reg < TOTAL_PER_THREAD_REGS);
>> - g_assert_not_reached();
>> + return env->gpr[reg];
> Ditto - look at gen_read_ctrl_reg in genptr.c
>
>> }
>>
>> +#ifndef CONFIG_USER_ONLY
>> static inline void arch_set_system_reg(CPUHexagonState *env, uint32_t
>> reg,
>> uint32_t val) {
>> - g_assert_not_reached();
>> + g_assert(reg < NUM_SREGS);
>> + if (reg < HEX_SREG_GLB_START) {
>> + env->t_sreg[reg] = val;
>> + } else {
>> + env->g_sreg[reg] = val;
>> + }
> Be careful here too. Look at gen_log_sreg_write.
>
>> }
>> +#endif
>>
>> uint32_t arch_get_system_reg(CPUHexagonState *env, uint32_t reg);
> Honestly, consider getting rid of these. All the uses are a specific register number, so there's no benefit of things like g_assert(reg < TOTAL_PER_THREAD_REGS) or reg < HEX_SREG_GLB_START. Also, keeping them runs the risk of not having all the proper checks inside.
I see your point. We will take a look at this for v3.
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 11/39] target/hexagon: Add representation to count cycles
2025-03-17 19:33 ` ltaylorsimpson
@ 2025-09-02 1:52 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:52 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 2:33 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 11/39] target/hexagon: Add representation to count cycles
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> The PCYCLE register can be enabled to indicate accumulated clock cycles.
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 3 ++-
>> target/hexagon/cpu.c | 3 +++
>> target/hexagon/machine.c | 25 ++++++++++++++++++++++++-
>> 3 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> 1549c4f1f0..4b9c9873dc 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -113,7 +113,8 @@ typedef struct CPUArchState {
>> target_ulong stack_start;
>>
>> uint8_t slot_cancelled;
>> -
>> + uint64_t t_cycle_count;
>> + uint64_t *g_pcycle_base;
>> #ifndef CONFIG_USER_ONLY
>> /* Some system registers are per thread and some are global. */
>> target_ulong t_sreg[NUM_SREGS];
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
>> 84a96a194b..89a051b41d 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -335,6 +335,7 @@ static void hexagon_cpu_reset_hold(Object *obj,
>> ResetType type)
>>
>> if (cs->cpu_index == 0) {
>> arch_set_system_reg(env, HEX_SREG_MODECTL, 0x1);
>> + *(env->g_pcycle_base) = 0;
> See discussion on shared resources.
>
>> }
>> mmu_reset(env);
>> arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index); @@ -396,10
>> +397,12 @@ static void hexagon_cpu_realize(DeviceState *dev, Error
>> **errp) #ifndef CONFIG_USER_ONLY
>> if (cs->cpu_index == 0) {
>> env->g_sreg = g_new0(target_ulong, NUM_SREGS);
>> + env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
> Shared resource ...
>
>> } else {
>> CPUState *cpu0 = qemu_get_cpu(0);
>> CPUHexagonState *env0 = cpu_env(cpu0);
>> env->g_sreg = env0->g_sreg;
>> + env->g_pcycle_base = env0->g_pcycle_base;
> Shared resource ...
>
This is captured by the global registers object in v2 and only the
thread-local count is introduced here.
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 12/39] target/hexagon: Add implementation of cycle counters
[not found] ` <7274cd69-f4e7-40b5-b850-cbd9099ed8ac@oss.qualcomm.com>
@ 2025-09-02 1:56 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:56 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 4/1/2025 9:42 PM, Brian Cain wrote:
>
>
> On 3/19/2025 2:50 PM, ltaylorsimpson@gmail.com wrote:
>>> -----Original Message-----
>>> From: Brian Cain<brian.cain@oss.qualcomm.com>
>>> Sent: Friday, February 28, 2025 11:28 PM
>>> To:qemu-devel@nongnu.org
>>> Cc:brian.cain@oss.qualcomm.com;richard.henderson@linaro.org;
>>> philmd@linaro.org;quic_mathbern@quicinc.com;ale@rev.ng;anjo@rev.ng;
>>> quic_mliebel@quicinc.com;ltaylorsimpson@gmail.com;
>>> alex.bennee@linaro.org;quic_mburton@quicinc.com;
>>> sidneym@quicinc.com; Brian Cain<bcain@quicinc.com>
>>> Subject: [PATCH 12/39] target/hexagon: Add implementation of cycle
>>> counters
>>>
>>> From: Brian Cain<bcain@quicinc.com>
>>>
>>> Co-authored-by: Sid Manning<sidneym@quicinc.com>
>>> Signed-off-by: Brian Cain<brian.cain@oss.qualcomm.com>
>>> ---
>>> target/hexagon/cpu.h | 25 ++++++++++++++++++++++---
>>> target/hexagon/translate.h | 2 ++
>>> target/hexagon/cpu_helper.c | 12 +++++++++---
>>> target/hexagon/translate.c | 27 +++++++++++++++++++++++++++
>>> 4 files changed, 60 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>>> 4b9c9873dc..7e2ea838c5 100644
>>> --- a/target/hexagon/cpu.h
>>> +++ b/target/hexagon/cpu.h
>>> @@ -27,11 +27,15 @@
>>>
>>> #include "cpu-qom.h"
>>> #include "exec/cpu-defs.h"
>>> +#include "exec/cpu-common.h"
>>> #include "hex_regs.h"
>>> #include "mmvec/mmvec.h"
>>> #include "hw/registerfields.h"
>>>
>>> +#ifndef CONFIG_USER_ONLY
>>> +#include "reg_fields.h"
>>> typedef struct CPUHexagonTLBContext CPUHexagonTLBContext;
>>> +#endif
>> Why is reg_fields.h guarded by #ifndef CONFIG_USER_ONLY?
>
>
> It's to get syscfg field definitions like "SYSCFG_PCYCLEEN". We can
> move it to a more general place, though.
>
>
>> Also, why wasn't the CPUHexagonTLBContext guarded when it was first inserted?
>
>
> It should have been. I will fix this.
>
>
Fixed in v2.
>>> #define NUM_PREGS 4
>>> #define TOTAL_PER_THREAD_REGS 64
>>> @@ -188,6 +192,7 @@ struct ArchCPU {
>>>
>>> FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
>>> FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
>>> +FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1)
>>>
>>> G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
>>> uint32_t exception, @@ -201,6 +206,11 @@ void
>>> hexagon_cpu_soft_reset(CPUHexagonState *env); #endif
>>>
>>> #include "exec/cpu-all.h"
>>> +
>>> +#ifndef CONFIG_USER_ONLY
>>> +#include "cpu_helper.h"
>>> +#endif
>>> +
>>> static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
>>> uint64_t *cs_base, uint32_t *flags) { @@ -210,16
>>> +220,27 @@ static inline void cpu_get_tb_cpu_state(CPUHexagonState
>>> *env, vaddr *pc,
>>> if (*pc == env->gpr[HEX_REG_SA0]) {
>>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
>>> }
>>> - *flags = hex_flags;
>>> if (*pc & PCALIGN_MASK) {
>>> hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0);
>>> }
>>> #ifndef CONFIG_USER_ONLY
>>> + target_ulong syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
>>> +
>>> + bool pcycle_enabled = extract32(syscfg,
>>> + reg_field_info[SYSCFG_PCYCLEEN].offset,
>>> +
>>> + reg_field_info[SYSCFG_PCYCLEEN].width);
>>> +
>>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
>>> cpu_mmu_index(env_cpu(env), false));
>>> +
>>> + if (pcycle_enabled) {
>>> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, 1);
>>> + }
>>> #else
>>> + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, true);
>> Are pcycles exposed in linux-user mode? If not, make this flag system-mode only.
>
>
> Yes, they are (for the "upcycle" registers).
>
>
>>> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX,
>>> MMU_USER_IDX); #endif
>>> + *flags = hex_flags;
>>> }
>>>
>>> typedef HexagonCPU ArchCPU;
>>> @@ -228,6 +249,4 @@ void hexagon_translate_init(void); void
>>> hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
>>> int *max_insns, vaddr pc, void *host_pc);
>>>
>>> -#include "exec/cpu-all.h"
>>> -
>>> #endif /* HEXAGON_CPU_H */
>>> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index
>>> 0eaa3db03e..9bc4b3ce8b 100644
>>> --- a/target/hexagon/translate.h
>>> +++ b/target/hexagon/translate.h
>>> @@ -83,6 +83,8 @@ typedef struct DisasContext {
>>> TCGv new_pred_value[NUM_PREGS];
>>> TCGv branch_taken;
>>> TCGv dczero_addr;
>>> + bool pcycle_enabled;
>> Guard with #ifndef CONFIG_USER_ONLY
>>
>>> + uint32_t num_cycles;
>>> } DisasContext;
>>>
>>> bool is_gather_store_insn(DisasContext *ctx); diff --git
>>> a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c index
>>> 0b0802bfb9..1d9b9f8bef 100644
>>> --- a/target/hexagon/cpu_helper.c
>>> +++ b/target/hexagon/cpu_helper.c
>>> @@ -48,17 +48,23 @@ uint32_t arch_get_system_reg(CPUHexagonState
>>> *env, uint32_t reg)
>>>
>>> uint64_t hexagon_get_sys_pcycle_count(CPUHexagonState *env) {
>>> - g_assert_not_reached();
>> Do we need a lock here?
>>
>>> + uint64_t cycles = 0;
>>> + CPUState *cs;
>>> + CPU_FOREACH(cs) {
>>> + CPUHexagonState *env_ = cpu_env(cs);
>>> + cycles += env_->t_cycle_count;
>>> + }
>>> + return *(env->g_pcycle_base) + cycles;
>>> }
>>>
>>> uint32_t hexagon_get_sys_pcycle_count_high(CPUHexagonState *env) {
>>> - g_assert_not_reached();
>>> + return hexagon_get_sys_pcycle_count(env) >> 32;
>>> }
>>>
>>> uint32_t hexagon_get_sys_pcycle_count_low(CPUHexagonState *env) {
>>> - g_assert_not_reached();
>>> + return extract64(hexagon_get_sys_pcycle_count(env), 0, 32);
>>> }
>>>
>>> void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, diff --git
>>> a/target/hexagon/translate.c b/target/hexagon/translate.c index
>>> 9119e42ff7..060df6e5eb 100644
>>> --- a/target/hexagon/translate.c
>>> +++ b/target/hexagon/translate.c
>>> @@ -57,6 +57,7 @@ TCGv_i64 hex_store_val64[STORES_MAX]; TCGv
>>> hex_llsc_addr; TCGv hex_llsc_val;
>>> TCGv_i64 hex_llsc_val_i64;
>>> +TCGv_i64 hex_cycle_count;
>> Guard with #ifndef CONFIG_USER_ONLY
>
>
> This feature belongs to both usermode and system emulation.
>
>
>>> TCGv hex_vstore_addr[VSTORES_MAX];
>>> TCGv hex_vstore_size[VSTORES_MAX];
>>> TCGv hex_vstore_pending[VSTORES_MAX];
>>> @@ -125,6 +126,22 @@ static void gen_exception_raw(int excp)
>>> gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); }
>>>
>>> +#ifndef CONFIG_USER_ONLY
>>> +static inline void gen_precise_exception(int excp, target_ulong PC) {
>>> + tcg_gen_movi_tl(hex_cause_code, excp);
>>> + gen_exception(HEX_EVENT_PRECISE, PC); }
>> Belongs in a different patch.
>
>
> I will fix this.
>
Tsk! I did *not* fix it in v2. Sorry, will address it in v3.
>
>>> +
>>> +static inline void gen_pcycle_counters(DisasContext *ctx) {
>>> + if (ctx->pcycle_enabled) {
>>> + tcg_gen_addi_i64(hex_cycle_count, hex_cycle_count, ctx-
>>>> num_cycles);
>>> + ctx->num_cycles = 0;
>>> + }
>>> +}
>>> +#endif
>>> +
>>> static void gen_exec_counters(DisasContext *ctx) {
>>> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT],
>>> @@ -133,6 +150,10 @@ static void gen_exec_counters(DisasContext *ctx)
>>> hex_gpr[HEX_REG_QEMU_INSN_CNT], ctx->num_insns);
>>> tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_HVX_CNT],
>>> hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
>>> +
>>> +#ifndef CONFIG_USER_ONLY
>>> + gen_pcycle_counters(ctx);
>>> +#endif
>>> }
>>>
>>> static bool use_goto_tb(DisasContext *ctx, target_ulong dest) @@ -785,6
>>> +806,7 @@ static void gen_commit_hvx(DisasContext *ctx)
>>> }
>>> }
>>>
>>> +static const int PCYCLES_PER_PACKET = 3;
>>> static void update_exec_counters(DisasContext *ctx) {
>>> Packet *pkt = ctx->pkt;
>>> @@ -804,6 +826,7 @@ static void update_exec_counters(DisasContext *ctx)
>>> }
>>>
>>> ctx->num_packets++;
>>> + ctx->num_cycles += PCYCLES_PER_PACKET;
>> Guard
>>
>>> ctx->num_insns += num_real_insns;
>>> ctx->num_hvx_insns += num_hvx_insns; } @@ -946,11 +969,13 @@ static
>>> void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>>>
>>> ctx->mem_idx = FIELD_EX32(hex_flags, TB_FLAGS, MMU_INDEX);
>>> ctx->num_packets = 0;
>>> + ctx->num_cycles = 0;
>> Guard
>>
>>> ctx->num_insns = 0;
>>> ctx->num_hvx_insns = 0;
>>> ctx->branch_cond = TCG_COND_NEVER;
>>> ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
>>> ctx->short_circuit = hex_cpu->short_circuit;
>>> + ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS,
>>> + PCYCLE_ENABLED);
>> Guard
>>
>>> }
>>>
>>> static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) @@
>>> -1077,6 +1102,8 @@ void hexagon_translate_init(void)
>>> offsetof(CPUHexagonState, llsc_val), "llsc_val");
>>> hex_llsc_val_i64 = tcg_global_mem_new_i64(tcg_env,
>>> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
>>> + hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
>>> + offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
>> Guard
>
>
> These will remain unguarded as referenced above.
>
>
>>> for (i = 0; i < STORES_MAX; i++) {
>>> snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
>>> hex_store_addr[i] = tcg_global_mem_new(tcg_env,
>>> --
>>> 2.34.1
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 13/39] target/hexagon: Implement modify_syscfg()
2025-03-19 21:12 ` ltaylorsimpson
@ 2025-09-02 1:58 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 1:58 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/19/2025 4:12 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 13/39] target/hexagon: Implement modify_syscfg()
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/op_helper.c | 51
>> +++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 50 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>> index 03bed11f6e..42805d0f1d 100644
>> --- a/target/hexagon/op_helper.c
>> +++ b/target/hexagon/op_helper.c
>> @@ -1522,7 +1522,56 @@ static bool
>> handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg,
>>
>> static void modify_syscfg(CPUHexagonState *env, uint32_t val) {
>> - g_assert_not_reached();
>> + g_assert(bql_locked());
>> +
>> + uint32_t old;
>> + uint32_t syscfg_read_only_mask = 0x80001c00;
>> + uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
>> +
>> + /* clear read-only bits if they are set in the new value. */
>> + val &= ~syscfg_read_only_mask;
>> + /* if read-only are currently set in syscfg keep them set. */
>> + val |= (syscfg & syscfg_read_only_mask);
>> +
>> + uint32_t tmp = val;
>> + old = arch_get_system_reg(env, HEX_SREG_SYSCFG);
> This is the same as syscfg declared above
>
>> + arch_set_system_reg(env, HEX_SREG_SYSCFG, tmp);
> Why is tmp needed? Just use val here.
>
>> +
>> + /* Check for change in MMU enable */
>> + target_ulong old_mmu_enable = GET_SYSCFG_FIELD(SYSCFG_MMUEN,
>> old);
>> + uint8_t old_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, old);
>> + uint8_t old_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, old);
>> + target_ulong new_mmu_enable =
>> + GET_SYSCFG_FIELD(SYSCFG_MMUEN, val);
> Move these declarations to the beginning of the function.
>
>> + if (new_mmu_enable && !old_mmu_enable) {
>> + hex_mmu_on(env);
>> + } else if (!new_mmu_enable && old_mmu_enable) {
>> + hex_mmu_off(env);
>> + }
>> +
>> + /* Changing pcycle enable from 0 to 1 resets the counters */
>> + uint8_t new_en = GET_SYSCFG_FIELD(SYSCFG_PCYCLEEN, val);
>> + CPUState *cs;
> Move the declarations to the beginning of the function
>
>> + if (old_en == 0 && new_en == 1) {
> You could put declaration of cs here if you prefer
>
>> + CPU_FOREACH(cs) {
>> + CPUHexagonState *_env = cpu_env(cs);
>> + _env->t_cycle_count = 0;
> I'm not a fan of _env as a variable name. Just do
> cpu_env(cs)->t_cycle_count = 0
>
>> + }
>> + }
>> +
>> + /* See if global interrupts are turned on */
>> + uint8_t new_gie = GET_SYSCFG_FIELD(SYSCFG_GIE, val);
> Move the declaration to the beginning
>
>> + if (!old_gie && new_gie) {
>> + qemu_log_mask(CPU_LOG_INT, "%s: global interrupts enabled\n",
>> __func__);
>> + hex_interrupt_update(env);
>> + }
>> +
>> + if (qemu_loglevel_mask(LOG_UNIMP)) {
>> + int new_v2x = GET_SYSCFG_FIELD(SYSCFG_V2X, val);
>> + if (!new_v2x) {
>> + qemu_log("HVX: 64 byte vector length is unsupported\n");
>> + }
>> + }
>> }
>>
>> static uint32_t hexagon_find_last_irq(CPUHexagonState *env, uint32_t vid)
>> --
>> 2.34.1
Fixed in v2.
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 17/39] target/hexagon: Implement software interrupt
2025-03-19 21:28 ` ltaylorsimpson
2025-03-24 15:51 ` Sid Manning
@ 2025-09-02 2:03 ` Brian Cain
1 sibling, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:03 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain',
'Mike Lambert'
On 3/19/2025 4:28 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:28 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>; Mike Lambert
>> <mlambert@quicinc.com>
>> Subject: [PATCH 17/39] target/hexagon: Implement software interrupt
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Co-authored-by: Mike Lambert <mlambert@quicinc.com>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 1 -
>> target/hexagon/hexswi.h | 17 +++
>> target/hexagon/cpu.c | 2 +
>> target/hexagon/hexswi.c | 258
>> +++++++++++++++++++++++++++++++++++++
>> target/hexagon/op_helper.c | 1 +
>> 5 files changed, 278 insertions(+), 1 deletion(-) create mode 100644
>> target/hexagon/hexswi.h create mode 100644 target/hexagon/hexswi.c
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> dabee310c5..045581d7be 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -256,5 +256,4 @@ typedef HexagonCPU ArchCPU; void
>> hexagon_translate_init(void); void hexagon_translate_code(CPUState *cs,
>> TranslationBlock *tb,
>> int *max_insns, vaddr pc, void *host_pc);
>> -
> Gratuitous change
Fixed in v2.
>> #endif /* HEXAGON_CPU_H */
>> diff --git a/target/hexagon/hexswi.h b/target/hexagon/hexswi.h new file
>> mode 100644 index 0000000000..5d232cb06c
>> --- /dev/null
>> +++ b/target/hexagon/hexswi.h
>> @@ -0,0 +1,17 @@
>> +/*
>> + * Copyright(c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later */
>> +
>> +#ifndef HEXSWI_H
>> +#define HEXSWI_H
>> +
>> +
>> +#include "cpu.h"
>> +
>> +void hexagon_cpu_do_interrupt(CPUState *cpu); void
>> +register_trap_exception(CPUHexagonState *env, int type, int imm,
>> + target_ulong PC);
>> +
>> +#endif /* HEXSWI_H */
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
>> 89a051b41d..843be8221f 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -33,6 +33,8 @@
>> #ifndef CONFIG_USER_ONLY
>> #include "sys_macros.h"
>> #include "qemu/main-loop.h"
>> +#include "hex_interrupts.h"
>> +#include "hexswi.h"
> Move these added include to a different patch where the contents are needed.
I didn't fix this in v2 because I convinced myself that these were
appropriate as-is. But on reconsideration I think I'm mistaken and will
try to fix this for v3.
>> #endif
>>
>> static void hexagon_v66_cpu_init(Object *obj) { } diff --git
>> a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c new file mode
>> 100644 index 0000000000..5fcf9b2be9
>> --- /dev/null
>> +++ b/target/hexagon/hexswi.c
>> @@ -0,0 +1,258 @@
>> +/*
>> + * Copyright(c) 2019-2025 Qualcomm Innovation Center, Inc. All Rights
>> Reserved.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later */
>> +
>> +#include "qemu/osdep.h"
>> +#include "cpu.h"
>> +#ifdef CONFIG_USER_ONLY
> This file is only included in the system-mode build, so we don't need these guards. Several in this file.
Fixed in v2.
>> +#include "exec/helper-proto.h"
>> +#include "qemu.h"
>> +#endif
>> +#include "exec/cpu_ldst.h"
>> +#include "exec/exec-all.h"
>> +#include "qemu/log.h"
>> +#include "qemu/main-loop.h"
>> +#include "arch.h"
>> +#include "internal.h"
>> +#include "macros.h"
>> +#include "sys_macros.h"
>> +#include "tcg/tcg-op.h"
>> +#ifndef CONFIG_USER_ONLY
>> +#include "hex_mmu.h"
>> +#include "hexswi.h"
>> +#endif
>> +
>> +#ifndef CONFIG_USER_ONLY
>> +
>> +
>> +static void set_addresses(CPUHexagonState *env, target_ulong pc_offset,
>> + target_ulong exception_index)
>> +
>> +{
>> + arch_set_system_reg(env, HEX_SREG_ELR,
>> + arch_get_thread_reg(env, HEX_REG_PC) + pc_offset);
>> + arch_set_thread_reg(env, HEX_REG_PC,
>> + arch_get_system_reg(env, HEX_SREG_EVB) |
>> + (exception_index << 2)); }
>> +
>> +static const char *event_name[] = {
>> + [HEX_EVENT_RESET] = "HEX_EVENT_RESET",
>> + [HEX_EVENT_IMPRECISE] = "HEX_EVENT_IMPRECISE",
>> + [HEX_EVENT_TLB_MISS_X] = "HEX_EVENT_TLB_MISS_X",
>> + [HEX_EVENT_TLB_MISS_RW] = "HEX_EVENT_TLB_MISS_RW",
>> + [HEX_EVENT_TRAP0] = "HEX_EVENT_TRAP0",
>> + [HEX_EVENT_TRAP1] = "HEX_EVENT_TRAP1",
>> + [HEX_EVENT_FPTRAP] = "HEX_EVENT_FPTRAP",
>> + [HEX_EVENT_DEBUG] = "HEX_EVENT_DEBUG",
>> + [HEX_EVENT_INT0] = "HEX_EVENT_INT0",
>> + [HEX_EVENT_INT1] = "HEX_EVENT_INT1",
>> + [HEX_EVENT_INT2] = "HEX_EVENT_INT2",
>> + [HEX_EVENT_INT3] = "HEX_EVENT_INT3",
>> + [HEX_EVENT_INT4] = "HEX_EVENT_INT4",
>> + [HEX_EVENT_INT5] = "HEX_EVENT_INT5",
>> + [HEX_EVENT_INT6] = "HEX_EVENT_INT6",
>> + [HEX_EVENT_INT7] = "HEX_EVENT_INT7",
>> + [HEX_EVENT_INT8] = "HEX_EVENT_INT8",
>> + [HEX_EVENT_INT9] = "HEX_EVENT_INT9",
>> + [HEX_EVENT_INTA] = "HEX_EVENT_INTA",
>> + [HEX_EVENT_INTB] = "HEX_EVENT_INTB",
>> + [HEX_EVENT_INTC] = "HEX_EVENT_INTC",
>> + [HEX_EVENT_INTD] = "HEX_EVENT_INTD",
>> + [HEX_EVENT_INTE] = "HEX_EVENT_INTE",
>> + [HEX_EVENT_INTF] = "HEX_EVENT_INTF"
>> +};
>> +
>> +void hexagon_cpu_do_interrupt(CPUState *cs)
>> +
>> +{
>> + CPUHexagonState *env = cpu_env(cs);
>> + BQL_LOCK_GUARD();
>> +
>> + qemu_log_mask(CPU_LOG_INT, "\t%s: event 0x%x:%s, cause
>> 0x%x(%d)\n",
>> + __func__, cs->exception_index,
>> + event_name[cs->exception_index], env->cause_code,
>> + env->cause_code);
>> +
>> + env->llsc_addr = ~0;
>> +
>> + uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
> Declarations at the beginning of the function.
Fixed in v2.
>> + if (GET_SSR_FIELD(SSR_EX, ssr) == 1) {
>> + arch_set_system_reg(env, HEX_SREG_DIAG, env->cause_code);
>> + env->cause_code = HEX_CAUSE_DOUBLE_EXCEPT;
>> + cs->exception_index = HEX_EVENT_PRECISE;
>> + }
>> +
>> + switch (cs->exception_index) {
>> + case HEX_EVENT_TRAP0:
>> + if (env->cause_code == 0) {
>> + qemu_log_mask(LOG_UNIMP,
>> + "trap0 is unhandled, no semihosting available\n");
>> + }
>> +
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 4, cs->exception_index);
>> + break;
>> +
>> + case HEX_EVENT_TRAP1:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 4, cs->exception_index);
>> + break;
>> +
>> + case HEX_EVENT_TLB_MISS_X:
>> + switch (env->cause_code) {
>> + case HEX_CAUSE_TLBMISSX_CAUSE_NORMAL:
>> + case HEX_CAUSE_TLBMISSX_CAUSE_NEXTPAGE:
>> + qemu_log_mask(CPU_LOG_MMU,
>> + "TLB miss EX exception (0x%x) caught: "
>> + "Cause code (0x%x) "
>> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
>> + ", BADVA = 0x%" PRIx32 "\n",
>> + cs->exception_index, env->cause_code, env->threadId,
>> + arch_get_thread_reg(env, HEX_REG_PC),
>> + arch_get_system_reg(env, HEX_SREG_BADVA));
>> +
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + break;
>> +
>> + default:
>> + cpu_abort(cs,
>> + "1:Hexagon exception %d/0x%x: "
>> + "Unknown cause code %d/0x%x\n",
>> + cs->exception_index, cs->exception_index, env->cause_code,
>> + env->cause_code);
>> + break;
>> + }
>> + break;
>> +
>> + case HEX_EVENT_TLB_MISS_RW:
>> + switch (env->cause_code) {
>> + case HEX_CAUSE_TLBMISSRW_CAUSE_READ:
>> + case HEX_CAUSE_TLBMISSRW_CAUSE_WRITE:
>> + qemu_log_mask(CPU_LOG_MMU,
>> + "TLB miss RW exception (0x%x) caught: "
>> + "Cause code (0x%x) "
>> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
>> + ", BADVA = 0x%" PRIx32 "\n",
>> + cs->exception_index, env->cause_code, env->threadId,
>> + env->gpr[HEX_REG_PC],
>> + arch_get_system_reg(env, HEX_SREG_BADVA));
>> +
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised
>> */
>> + break;
>> +
>> + default:
>> + cpu_abort(cs,
>> + "2:Hexagon exception %d/0x%x: "
>> + "Unknown cause code %d/0x%x\n",
>> + cs->exception_index, cs->exception_index, env->cause_code,
>> + env->cause_code);
>> + break;
>> + }
>> + break;
>> +
>> + case HEX_EVENT_FPTRAP:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + arch_set_thread_reg(env, HEX_REG_PC,
>> + arch_get_system_reg(env, HEX_SREG_EVB) |
>> + (cs->exception_index << 2));
> Why not use set_addresses here? How is ELR set?
>
>> + break;
>> +
>> + case HEX_EVENT_DEBUG:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + qemu_log_mask(LOG_UNIMP, "single-step exception is not
>> handled\n");
>> + break;
>> +
>> + case HEX_EVENT_PRECISE:
>> + switch (env->cause_code) {
>> + case HEX_CAUSE_FETCH_NO_XPAGE:
>> + case HEX_CAUSE_FETCH_NO_UPAGE:
>> + case HEX_CAUSE_PRIV_NO_READ:
>> + case HEX_CAUSE_PRIV_NO_UREAD:
>> + case HEX_CAUSE_PRIV_NO_WRITE:
>> + case HEX_CAUSE_PRIV_NO_UWRITE:
>> + case HEX_CAUSE_MISALIGNED_LOAD:
>> + case HEX_CAUSE_MISALIGNED_STORE:
>> + case HEX_CAUSE_PC_NOT_ALIGNED:
>> + qemu_log_mask(CPU_LOG_MMU,
>> + "MMU permission exception (0x%x) caught: "
>> + "Cause code (0x%x) "
>> + "TID = 0x%" PRIx32 ", PC = 0x%" PRIx32
>> + ", BADVA = 0x%" PRIx32 "\n",
>> + cs->exception_index, env->cause_code, env->threadId,
>> + env->gpr[HEX_REG_PC],
>> + arch_get_system_reg(env, HEX_SREG_BADVA));
>> +
>> +
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + /* env->sreg[HEX_SREG_BADVA] is set when the exception is raised
>> */
>> + break;
>> +
>> + case HEX_CAUSE_DOUBLE_EXCEPT:
>> + case HEX_CAUSE_PRIV_USER_NO_SINSN:
>> + case HEX_CAUSE_PRIV_USER_NO_GINSN:
>> + case HEX_CAUSE_INVALID_OPCODE:
>> + case HEX_CAUSE_NO_COPROC_ENABLE:
>> + case HEX_CAUSE_NO_COPROC2_ENABLE:
>> + case HEX_CAUSE_UNSUPORTED_HVX_64B:
>> + case HEX_CAUSE_REG_WRITE_CONFLICT:
>> + case HEX_CAUSE_VWCTRL_WINDOW_MISS:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + break;
>> +
>> + case HEX_CAUSE_COPROC_LDST:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + break;
>> +
>> + case HEX_CAUSE_STACK_LIMIT:
>> + hexagon_ssr_set_cause(env, env->cause_code);
>> + set_addresses(env, 0, cs->exception_index);
>> + break;
>> +
>> + default:
>> + cpu_abort(cs,
>> + "3:Hexagon exception %d/0x%x: "
>> + "Unknown cause code %d/0x%x\n",
>> + cs->exception_index, cs->exception_index, env->cause_code,
>> + env->cause_code);
>> + break;
>> + }
>> + break;
>> +
>> + case HEX_EVENT_IMPRECISE:
>> + qemu_log_mask(LOG_UNIMP,
>> + "Imprecise exception: this case is not yet handled");
>> + break;
>> +
>> + default:
>> + qemu_log_mask(LOG_UNIMP,
>> + "Hexagon Unsupported exception 0x%x/0x%x\n",
>> + cs->exception_index, env->cause_code);
>> + break;
>> + }
>> +
>> + cs->exception_index = HEX_EVENT_NONE; }
>> +
>> +void register_trap_exception(CPUHexagonState *env, int traptype, int
>> imm,
>> + target_ulong PC) {
>> + CPUState *cs = env_cpu(env);
>> +
>> + cs->exception_index = (traptype == 0) ? HEX_EVENT_TRAP0 :
>> HEX_EVENT_TRAP1;
>> + ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
>> +
>> + env->cause_code = imm;
>> + env->gpr[HEX_REG_PC] = PC;
>> + cpu_loop_exit(cs);
>> +}
>> +#endif
>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>> index 42805d0f1d..687e7f45c2 100644
>> --- a/target/hexagon/op_helper.c
>> +++ b/target/hexagon/op_helper.c
>> @@ -38,6 +38,7 @@
>> #include "hex_mmu.h"
>> #include "hw/intc/l2vic.h"
>> #include "hex_interrupts.h"
>> +#include "hexswi.h"
> Move this do a different patch where the contents are needed
I didn't fix this in v2 because I convinced myself that these were
appropriate as-is. But on reconsideration I think I'm mistaken and will
try to fix this for v3.
>> #endif
>>
>> #define SF_BIAS 127
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 22/39] target/hexagon: Implement setprio, resched
2025-03-20 22:28 ` ltaylorsimpson
@ 2025-09-02 2:08 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:08 UTC (permalink / raw)
To: ltaylorsimpson, 'Sid Manning', qemu-devel
Cc: richard.henderson, philmd, 'Matheus Bernardino (QUIC)',
ale, anjo, 'Marco Liebel (QUIC)', alex.bennee,
'Mark Burton (QUIC)', 'Brian Cain'
On 3/20/2025 5:28 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Sid Manning <sidneym@quicinc.com>
>> Sent: Thursday, March 20, 2025 3:26 PM
>> To: ltaylorsimpson@gmail.com; 'Brian Cain'
>> <brian.cain@oss.qualcomm.com>; qemu-devel@nongnu.org
>> Cc: richard.henderson@linaro.org; philmd@linaro.org; Matheus Bernardino
>> (QUIC) <quic_mathbern@quicinc.com>; ale@rev.ng; anjo@rev.ng; Marco
>> Liebel (QUIC) <quic_mliebel@quicinc.com>; alex.bennee@linaro.org; Mark
>> Burton (QUIC) <quic_mburton@quicinc.com>; Brian Cain
>> <bcain@quicinc.com>
>> Subject: RE: [PATCH 22/39] target/hexagon: Implement setprio, resched
>>>> + if (lowest_th_prio > best_prio) {
>>>> + qemu_log_mask(CPU_LOG_INT,
>>>> + "%s: raising resched int %d, cur PC 0x" TARGET_FMT_lx "\n",
>>>> + __func__, int_number, arch_get_thread_reg(env,
>>> HEX_REG_PC));
>>>> + SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO,
>>>> 0x1ff);
>>> What is the significance of 0x1ff? The field is 10 bits, so this
>>> isn't setting all the bits.
>>> Should this be lowest_th_prio?
>> [Sid Manning]
>>
>> Hi Taylor,
>>
>> The value 0x1ff is correct but it does look like BESTWAIT_PRIO is not, it should
>> be 9 not 10 target/hexagon/reg_fields_def.h.inc
>>
>> It looks like it was added in "PATCH 19/38 target/hexagon: Define register
>> fields for system regs"
>> I will make a fixup to that patch and correct the value.
> I see.
> If the intent is to set all the bits in the field, then use ~0.
This didn't make it into v2 but it's a simple fix - will add it for v3.
> Taylor
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 24/39] target/hexagon: Add exec-start-addr prop
2025-03-17 20:03 ` ltaylorsimpson
@ 2025-09-02 2:12 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:12 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/17/2025 3:03 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:29 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 24/39] target/hexagon: Add exec-start-addr prop
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 1 +
>> target/hexagon/cpu.c | 7 ++-----
>> 2 files changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> baa48ec051..4667a1f748 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -194,6 +194,7 @@ struct ArchCPU {
>> uint32_t num_tlbs;
>> uint32_t l2vic_base_addr;
>> uint32_t hvx_contexts;
>> + uint32_t boot_addr;
>> #endif
>> };
>>
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
>> 9f4cfd03c4..7afdcbf9d0 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -66,6 +66,7 @@ static const Property hexagon_cpu_properties[] = {
>> DEFINE_PROP_UINT32("l2vic-base-addr", HexagonCPU, l2vic_base_addr,
>> 0xffffffffULL),
>> DEFINE_PROP_UINT32("hvx-contexts", HexagonCPU, hvx_contexts, 0),
>> + DEFINE_PROP_UINT32("exec-start-addr", HexagonCPU, boot_addr,
>> + 0xffffffffULL),
> Don't put a ULL value for a UINT32 property.
Happy to fix this for v3.
> Ditto for l2vic-base-addr above (must've missed it when it came in).
>
>> #endif
>> DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
>> DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU,
>> lldb_stack_adjust, 0, @@ -362,8 +363,6 @@ static void
>> hexagon_cpu_reset_hold(Object *obj, ResetType type)
>> mmu_reset(env);
>> arch_set_system_reg(env, HEX_SREG_HTID, cs->cpu_index);
>> hexagon_cpu_soft_reset(env);
>> - memset(env->t_sreg, 0, sizeof(target_ulong) * NUM_SREGS);
>> - memset(env->greg, 0, sizeof(target_ulong) * NUM_GREGS);
> Why are you removing these here?
>
>> env->threadId = cs->cpu_index;
>> env->tlb_lock_state = HEX_LOCK_UNLOCKED;
>> env->k0_lock_state = HEX_LOCK_UNLOCKED; @@ -372,6 +371,7 @@ static
>> void hexagon_cpu_reset_hold(Object *obj, ResetType type)
>> env->next_PC = 0;
>> env->wait_next_pc = 0;
>> env->cause_code = -1;
>> + arch_set_thread_reg(env, HEX_REG_PC, cpu->boot_addr);
>> #endif
>> }
>>
>> @@ -414,9 +414,6 @@ static void hexagon_cpu_realize(DeviceState *dev,
>> Error **errp) #ifndef CONFIG_USER_ONLY
>> CPUHexagonState *env = cpu_env(cs);
>> hex_mmu_realize(env);
>> -#endif
>> - cpu_reset(cs);
>> -#ifndef CONFIG_USER_ONLY
> Why are you removing these here?
Fixed in v2.
>> if (cs->cpu_index == 0) {
>> env->g_sreg = g_new0(target_ulong, NUM_SREGS);
>> env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes
2025-03-18 18:50 ` ltaylorsimpson
@ 2025-09-02 2:35 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:35 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym, 'Brian Cain'
On 3/18/2025 1:50 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:29 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com; Brian Cain <bcain@quicinc.com>
>> Subject: [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes
>>
>> From: Brian Cain <bcain@quicinc.com>
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> target/hexagon/cpu.h | 2 +-
>> target/hexagon/translate.h | 2 +
>> target/hexagon/genptr.c | 7 +-
>> target/hexagon/translate.c | 142 ++++++++++++++++++++++++++++++++-
>> ----
>> 4 files changed, 132 insertions(+), 21 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index
>> 4667a1f748..73c3bb34b0 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -142,9 +142,9 @@ typedef struct CPUArchState {
>> hex_lock_state_t k0_lock_state;
>> target_ulong tlb_lock_count;
>> target_ulong k0_lock_count;
>> - target_ulong next_PC;
>> CPUHexagonTLBContext *hex_tlb;
>> #endif
>> + target_ulong next_PC;
> You are moving this from system-mode only to unconditional. There must be an earlier patch in this series that put it in system-mode. Find that and remove it, so there is only a single addition.
>
> Also, does this need to be part of the global state? The answer is no if it doesn't live across packets. If it is only used within the context of a single packet, you can just create a temporary TCGv in DisasContext. There are several examples already.
>
We were not eager to re-introduce next_PC but there were some features
that wouldn't work without it - in particular the wait instruction IIRC.
If this is objectionable, I can try and share the illustrating test case(s).
>> target_ulong new_value_usr;
>>
>> MemLog mem_log_stores[STORES_MAX];
>> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index
>> c9533fee1f..ad1a2f4045 100644
>> --- a/target/hexagon/translate.h
>> +++ b/target/hexagon/translate.h
>> @@ -85,6 +85,7 @@ typedef struct DisasContext {
>> TCGv dczero_addr;
>> bool pcycle_enabled;
>> bool pkt_ends_tb;
>> + bool need_next_pc;
>> uint32_t num_cycles;
>> } DisasContext;
>>
>> @@ -306,6 +307,7 @@ static inline void ctx_log_qreg_read(DisasContext
>> *ctx, }
>>
>> extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
>> +extern TCGv hex_next_PC;
>> extern TCGv hex_pred[NUM_PREGS];
>> extern TCGv hex_slot_cancelled;
>> extern TCGv hex_new_value_usr;
>> diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
>> 5554c9515c..afc7e5f3a5 100644
>> --- a/target/hexagon/genptr.c
>> +++ b/target/hexagon/genptr.c
>> @@ -634,14 +634,15 @@ static void gen_write_new_pc_addr(DisasContext
>> *ctx, TCGv addr,
>> tcg_gen_brcondi_tl(cond, pred, 0, pred_false);
>> }
>>
>> + TCGv PC_wr = ctx->need_next_pc ? hex_next_PC :
>> hex_gpr[HEX_REG_PC];
>> if (ctx->pkt->pkt_has_multi_cof) {
>> /* If there are multiple branches in a packet, ignore the second one */
>> - tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
>> + tcg_gen_movcond_tl(TCG_COND_NE, PC_wr,
>> ctx->branch_taken, tcg_constant_tl(0),
>> - hex_gpr[HEX_REG_PC], addr);
>> + PC_wr, addr);
>> tcg_gen_movi_tl(ctx->branch_taken, 1);
>> } else {
>> - tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
>> + tcg_gen_mov_tl(PC_wr, addr);
>> }
>>
>> if (cond != TCG_COND_ALWAYS) {
>> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index
>> 475726388a..d4b22acb72 100644
>> --- a/target/hexagon/translate.c
>> +++ b/target/hexagon/translate.c
>> @@ -49,6 +49,7 @@ static const AnalyzeInsn
>> opcode_analyze[XX_LAST_OPCODE] = { TCGv
>> hex_gpr[TOTAL_PER_THREAD_REGS]; TCGv hex_pred[NUM_PREGS]; TCGv
>> hex_slot_cancelled;
>> +TCGv hex_next_PC;
>> TCGv hex_new_value_usr;
>> TCGv hex_store_addr[STORES_MAX];
>> TCGv hex_store_width[STORES_MAX];
>> @@ -61,12 +62,14 @@ TCGv_i64 hex_cycle_count; TCGv
>> hex_vstore_addr[VSTORES_MAX]; TCGv hex_vstore_size[VSTORES_MAX];
>> TCGv hex_vstore_pending[VSTORES_MAX];
>> +static bool need_next_PC(DisasContext *ctx);
> You don't need this. The function definition is before any reference to it.
I'll remove this declaration in v3.
>> #ifndef CONFIG_USER_ONLY
>> TCGv hex_greg[NUM_GREGS];
>> TCGv hex_t_sreg[NUM_SREGS];
>> TCGv_ptr hex_g_sreg_ptr;
>> TCGv hex_g_sreg[NUM_SREGS];
>> +TCGv hex_cause_code;
> This doesn't belong in this patch.
Fixed in v2.
>> #endif
>>
>> static const char * const hexagon_prednames[] = { @@ -184,6 +187,9 @@
>> static void gen_end_tb(DisasContext *ctx)
>>
>> gen_exec_counters(ctx);
>>
>> + if (ctx->need_next_pc) {
>> + tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
>> + }
>> if (ctx->branch_cond != TCG_COND_NEVER) {
>> if (ctx->branch_cond != TCG_COND_ALWAYS) {
>> TCGLabel *skip = gen_new_label(); @@ -371,18 +377,24 @@ static
>> bool pkt_ends_tb(Packet *pkt) static bool need_next_PC(DisasContext
>> *ctx) {
>> Packet *pkt = ctx->pkt;
>> -
>> - /* Check for conditional control flow or HW loop end */
>> - for (int i = 0; i < pkt->num_insns; i++) {
>> - uint16_t opcode = pkt->insn[i].opcode;
>> - if (GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode,
>> A_COF)) {
>> - return true;
>> - }
>> - if (GET_ATTRIB(opcode, A_HWLOOP0_END) ||
>> - GET_ATTRIB(opcode, A_HWLOOP1_END)) {
>> - return true;
> Was this inserted by an earlier patch in this series? If so, don't insert it before. Just put the below code in this patch.
>
>> + if (pkt->pkt_has_cof || ctx->pkt_ends_tb) {
>> + for (int i = 0; i < pkt->num_insns; i++) {
>> + uint16_t opcode = pkt->insn[i].opcode;
>> + if ((GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode,
>> A_COF)) ||
>> + GET_ATTRIB(opcode, A_HWLOOP0_END) ||
>> + GET_ATTRIB(opcode, A_HWLOOP1_END)) {
>> + return true;
>> + }
>> }
>> }
>> + /*
>> + * We end the TB on some instructions that do not change the flow (for
>> + * other reasons). In these cases, we must set pc too, as the insn won't
>> + * do it themselves.
>> + */
>> + if (ctx->pkt_ends_tb && !check_for_attrib(pkt, A_COF)) {
>> + return true;
>> + }
>> return false;
>> }
>>
>> @@ -523,7 +535,14 @@ static void analyze_packet(DisasContext *ctx) static
>> void gen_start_packet(DisasContext *ctx) {
>> Packet *pkt = ctx->pkt;
>> +#ifndef CONFIG_USER_ONLY
>> + target_ulong next_PC = (check_for_opcode(pkt, Y2_k0lock) ||
>> + check_for_opcode(pkt, Y2_tlblock)) ?
> Should we also check for Y2_wait?
Let me review why we didn't include Y2_wait here - the behavior is
similar but not identical between these instructions.
>> + ctx->base.pc_next :
>> + ctx->base.pc_next +
>> +pkt->encod_pkt_size_in_bytes; #else
>> target_ulong next_PC = ctx->base.pc_next + pkt-
>>> encod_pkt_size_in_bytes;
>> +#endif
> You don't need the #ifndef CONFIG_USER_ONLY here. Note that the opcodes exist in linux-user mode as well as system mode. So, you can just keep the first version.
>
> Note that check_for_opcode is currently guarded by #ifndef CONFIG_USER_ONLY, but you can remove that.
>
>> int i;
>>
>> /* Clear out the disassembly context */ @@ -531,6 +550,10 @@ static void
>> gen_start_packet(DisasContext *ctx)
>> ctx->reg_log_idx = 0;
>> bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
>> bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
>> +#ifndef CONFIG_USER_ONLY
>> + ctx->greg_log_idx = 0;
>> + ctx->sreg_log_idx = 0;
>> +#endif
>> ctx->preg_log_idx = 0;
>> bitmap_zero(ctx->pregs_written, NUM_PREGS);
>> ctx->future_vregs_idx = 0;
>> @@ -563,21 +586,41 @@ static void gen_start_packet(DisasContext *ctx)
>> * gen phase, so clear it again.
>> */
>> bitmap_zero(ctx->pregs_written, NUM_PREGS);
>> +#ifndef CONFIG_USER_ONLY
>> + for (i = 0; i < NUM_SREGS; i++) {
>> + ctx->t_sreg_new_value[i] = NULL;
>> + }
>> + for (i = 0; i < ctx->sreg_log_idx; i++) {
>> + int reg_num = ctx->sreg_log[i];
>> + if (reg_num < HEX_SREG_GLB_START) {
>> + ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
>> + tcg_gen_mov_tl(ctx->t_sreg_new_value[reg_num],
>> hex_t_sreg[reg_num]);
>> + }
>> + }
>> + for (i = 0; i < NUM_GREGS; i++) {
>> + ctx->greg_new_value[i] = NULL;
>> + }
>> + for (i = 0; i < ctx->greg_log_idx; i++) {
>> + int reg_num = ctx->greg_log[i];
>> + ctx->greg_new_value[reg_num] = tcg_temp_new();
>> + }
>> +#endif
>>
>> /* Initialize the runtime state for packet semantics */
>> if (need_slot_cancelled(pkt)) {
>> tcg_gen_movi_tl(hex_slot_cancelled, 0);
>> }
>> ctx->branch_taken = NULL;
>> - ctx->pkt_ends_tb = pkt_ends_tb(pkt);
>> if (pkt->pkt_has_cof) {
>> ctx->branch_taken = tcg_temp_new();
>> - if (pkt->pkt_has_multi_cof) {
>> - tcg_gen_movi_tl(ctx->branch_taken, 0);
>> - }
>> - if (need_next_PC(ctx)) {
>> - tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC);
>> - }
>> + }
>> + if (pkt->pkt_has_multi_cof) {
>> + tcg_gen_movi_tl(ctx->branch_taken, 0);
>> + }
>> + ctx->pkt_ends_tb = pkt_ends_tb(pkt);
>> + ctx->need_next_pc = need_next_PC(ctx);
>> + if (ctx->need_next_pc) {
>> + tcg_gen_movi_tl(hex_next_PC, next_PC);
>> }
>>
>> /* Preload the predicated registers into get_result_gpr(ctx, i) */ @@ -
>> 713,6 +756,59 @@ static void gen_reg_writes(DisasContext *ctx)
>> }
>> }
>>
>> +#ifndef CONFIG_USER_ONLY
>> +static void gen_greg_writes(DisasContext *ctx) {
>> + int i;
>> +
>> + for (i = 0; i < ctx->greg_log_idx; i++) {
>> + int reg_num = ctx->greg_log[i];
>> +
>> + tcg_gen_mov_tl(hex_greg[reg_num], ctx-
>>> greg_new_value[reg_num]);
>> + }
>> +}
>> +
>> +
>> +static void gen_sreg_writes(DisasContext *ctx) {
>> + int i;
>> +
>> + TCGv old_reg = tcg_temp_new();
>> + for (i = 0; i < ctx->sreg_log_idx; i++) {
>> + int reg_num = ctx->sreg_log[i];
>> +
>> + if (reg_num == HEX_SREG_SSR) {
>> + tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
>> + tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx-
>>> t_sreg_new_value[reg_num]);
>> + gen_helper_modify_ssr(tcg_env, ctx->t_sreg_new_value[reg_num],
>> + old_reg);
>> + /* This can change processor state, so end the TB */
>> + ctx->base.is_jmp = DISAS_NORETURN;
>> + } else if ((reg_num == HEX_SREG_STID) ||
>> + (reg_num == HEX_SREG_IMASK) ||
>> + (reg_num == HEX_SREG_IPENDAD)) {
>> + if (reg_num < HEX_SREG_GLB_START) {
>> + tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
>> + tcg_gen_mov_tl(hex_t_sreg[reg_num],
>> + ctx->t_sreg_new_value[reg_num]);
>> + }
>> + /* This can change the interrupt state, so end the TB */
>> + gen_helper_pending_interrupt(tcg_env);
>> + ctx->base.is_jmp = DISAS_NORETURN;
>> + } else if ((reg_num == HEX_SREG_BESTWAIT) ||
>> + (reg_num == HEX_SREG_SCHEDCFG)) {
>> + /* This can trigger resched interrupt, so end the TB */
>> + gen_helper_resched(tcg_env);
>> + ctx->base.is_jmp = DISAS_NORETURN;
>> + }
>> +
>> + if (reg_num < HEX_SREG_GLB_START) {
>> + tcg_gen_mov_tl(hex_t_sreg[reg_num], ctx-
>>> t_sreg_new_value[reg_num]);
>> + }
>> + }
>> +}
>> +#endif
>> +
>> static void gen_pred_writes(DisasContext *ctx) {
>> /* Early exit if not needed or the log is empty */ @@ -1012,6 +1108,10 @@
>> static void gen_commit_packet(DisasContext *ctx)
>> process_store_log(ctx);
>>
>> gen_reg_writes(ctx);
>> +#if !defined(CONFIG_USER_ONLY)
>> + gen_greg_writes(ctx);
>> + gen_sreg_writes(ctx);
>> +#endif
>> gen_pred_writes(ctx);
>> if (pkt->pkt_has_hvx) {
>> gen_commit_hvx(ctx);
>> @@ -1073,6 +1173,7 @@ static void
>> hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>> ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
>> ctx->short_circuit = hex_cpu->short_circuit;
>> ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS,
>> PCYCLE_ENABLED);
>> + ctx->need_next_pc = false;
> Don't need this because it is initialized in gen_start_packet.
>
>> }
>>
>> static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu) @@
>> -1201,6 +1302,13 @@ void hexagon_translate_init(void)
>> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
>> hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
>> offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
>> +#ifndef CONFIG_USER_ONLY
>> + hex_cause_code = tcg_global_mem_new(tcg_env,
>> + offsetof(CPUHexagonState, cause_code), "cause_code"); #endif
> Doesn’t' belong in this patch
Not fixed in v2, will address it in v3.
>
>> + hex_next_PC = tcg_global_mem_new(tcg_env,
>> + offsetof(CPUHexagonState, next_PC), "next_PC");
>> +
>> for (i = 0; i < STORES_MAX; i++) {
>> snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
>> hex_store_addr[i] = tcg_global_mem_new(tcg_env,
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 38/39] target/hexagon: Add guest reg reading functionality
2025-03-19 18:36 ` ltaylorsimpson
@ 2025-09-02 2:40 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:40 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym
On 3/19/2025 1:36 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:29 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com
>> Subject: [PATCH 38/39] target/hexagon: Add guest reg reading functionality
>>
>> From: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
>>
>> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
>> ---
>> target/hexagon/cpu.c | 19 ++++++++++++++++++-
>> target/hexagon/op_helper.c | 19 +++++++++++++++++--
>> 2 files changed, 35 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
>> 3c4776232e..80f5e23794 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -739,7 +739,24 @@ static void hexagon_cpu_class_init(ObjectClass *c,
>> void *data) #ifndef CONFIG_USER_ONLY uint32_t
>> hexagon_greg_read(CPUHexagonState *env, uint32_t reg) {
>> - g_assert_not_reached();
>> + target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
>> + int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
> Consider moving this check into hexagon_get_sys_pcycle_count*
Ok, will fix this in v3.
> Otherwise
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
* Re: [PATCH 39/39] target/hexagon: Add pcycle setting functionality
2025-03-19 18:49 ` ltaylorsimpson
@ 2025-09-02 2:42 ` Brian Cain
0 siblings, 0 replies; 112+ messages in thread
From: Brian Cain @ 2025-09-02 2:42 UTC (permalink / raw)
To: ltaylorsimpson, qemu-devel
Cc: richard.henderson, philmd, quic_mathbern, ale, anjo, quic_mliebel,
alex.bennee, quic_mburton, sidneym
On 3/19/2025 1:49 PM, ltaylorsimpson@gmail.com wrote:
>
>> -----Original Message-----
>> From: Brian Cain <brian.cain@oss.qualcomm.com>
>> Sent: Friday, February 28, 2025 11:29 PM
>> To: qemu-devel@nongnu.org
>> Cc: brian.cain@oss.qualcomm.com; richard.henderson@linaro.org;
>> philmd@linaro.org; quic_mathbern@quicinc.com; ale@rev.ng; anjo@rev.ng;
>> quic_mliebel@quicinc.com; ltaylorsimpson@gmail.com;
>> alex.bennee@linaro.org; quic_mburton@quicinc.com;
>> sidneym@quicinc.com
>> Subject: [PATCH 39/39] target/hexagon: Add pcycle setting functionality
>>
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
>> ---
>> target/hexagon/cpu.c | 10 +++++++---
>> target/hexagon/cpu_helper.c | 17 ++++++++++++++---
>> 2 files changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index
>> 80f5e23794..4ca6add834 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -440,19 +440,23 @@ static void hexagon_cpu_realize(DeviceState *dev,
>> Error **errp) #endif
>>
>> qemu_init_vcpu(cs);
>> -#ifndef CONFIG_USER_ONLY
>> 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);
>> - env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
>> } else {
>> CPUState *cpu0 = qemu_get_cpu(0);
>> CPUHexagonState *env0 = cpu_env(cpu0);
>> env->g_sreg = env0->g_sreg;
>> - env->g_pcycle_base = env0->g_pcycle_base;
>> }
>> #endif
>> + if (cs->cpu_index == 0) {
>> + env->g_pcycle_base = g_malloc0(sizeof(*env->g_pcycle_base));
> Another shared resource ...
>
>> + } else {
>> + CPUState *cpu0 = qemu_get_cpu(0);
>> + env->g_pcycle_base = cpu_env(cpu0)->g_pcycle_base;
>> + }
>>
>> mcc->parent_realize(dev, errp);
>> }
>> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
>> index 9c44cb7950..08c749e9fa 100644
>> --- a/target/hexagon/cpu_helper.c
>> +++ b/target/hexagon/cpu_helper.c
>> @@ -70,18 +70,29 @@ uint32_t
>> hexagon_get_sys_pcycle_count_low(CPUHexagonState *env) void
>> hexagon_set_sys_pcycle_count_high(CPUHexagonState *env,
>> uint32_t cycles_hi)
>> {
>> - g_assert_not_reached();
>> + uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
>> + uint64_t cycles =
>> + ((uint64_t)cycles_hi << 32) | extract64(cur_cycles, 0, 32);
>> + hexagon_set_sys_pcycle_count(env, cycles);
>> }
>>
>> void hexagon_set_sys_pcycle_count_low(CPUHexagonState *env,
>> uint32_t cycles_lo)
>> {
>> - g_assert_not_reached();
>> + uint64_t cur_cycles = hexagon_get_sys_pcycle_count(env);
>> + uint64_t cycles = extract64(cur_cycles, 32, 32) | cycles_lo;
>> + hexagon_set_sys_pcycle_count(env, cycles);
>> }
>>
>> void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t
>> cycles) {
>> - g_assert_not_reached();
> Do we need a lock here?
I will address the lack of locking here in v3, seems like an appropriate
change.
>> + *(env->g_pcycle_base) = cycles;
>> +
>> + CPUState *cs;
>> + CPU_FOREACH(cs) {
>> + CPUHexagonState *env_ = cpu_env(cs);
> This underscore is easy to miss. Just
> cpu_env(cs)->t_cycle_count = 0;
>
>
>
^ permalink raw reply [flat|nested] 112+ messages in thread
end of thread, other threads:[~2025-09-02 4:26 UTC | newest]
Thread overview: 112+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-01 5:28 [PATCH 00/39] hexagon system emu, part 2/3 Brian Cain
2025-03-01 5:28 ` [PATCH 01/39] target/hexagon: Implement ciad helper Brian Cain
2025-03-17 16:08 ` ltaylorsimpson
2025-03-18 14:44 ` Sid Manning
2025-09-02 1:32 ` Brian Cain
2025-03-01 5:28 ` [PATCH 02/39] target/hexagon: Implement {c,}swi helpers Brian Cain
2025-03-17 16:09 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 03/39] target/hexagon: Implement iassign{r,w} helpers Brian Cain
2025-03-17 16:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 04/39] target/hexagon: Implement start/stop helpers Brian Cain
2025-03-17 16:35 ` ltaylorsimpson
2025-09-02 1:33 ` Brian Cain
2025-03-01 5:28 ` [PATCH 05/39] target/hexagon: Implement modify SSR Brian Cain
2025-03-17 17:37 ` ltaylorsimpson
2025-03-18 18:34 ` Sid Manning
2025-03-18 19:14 ` ltaylorsimpson
2025-03-18 23:47 ` Brian Cain
2025-03-19 16:39 ` ltaylorsimpson
2025-03-19 16:58 ` Richard Henderson
2025-09-02 1:39 ` Brian Cain
2025-03-01 5:28 ` [PATCH 06/39] target/hexagon: Implement {g,s}etimask helpers Brian Cain
2025-03-17 17:44 ` ltaylorsimpson
2025-03-21 21:48 ` Sid Manning
2025-09-02 1:44 ` Brian Cain
2025-03-01 5:28 ` [PATCH 07/39] target/hexagon: Implement wait helper Brian Cain
2025-03-17 18:37 ` ltaylorsimpson
2025-09-02 1:46 ` Brian Cain
2025-03-01 5:28 ` [PATCH 08/39] target/hexagon: Implement get_exe_mode() Brian Cain
2025-03-17 18:43 ` ltaylorsimpson
2025-04-02 2:03 ` Brian Cain
2025-03-01 5:28 ` [PATCH 09/39] target/hexagon: Implement arch_get_system_reg() Brian Cain
2025-03-17 18:46 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 10/39] target/hexagon: Implement arch_{s, g}et_{thread, system}_reg() Brian Cain via
2025-03-17 19:24 ` ltaylorsimpson
2025-09-02 1:50 ` [PATCH 10/39] target/hexagon: Implement arch_{s,g}et_{thread,system}_reg() Brian Cain
2025-03-01 5:28 ` [PATCH 11/39] target/hexagon: Add representation to count cycles Brian Cain
2025-03-17 19:33 ` ltaylorsimpson
2025-09-02 1:52 ` Brian Cain
2025-03-01 5:28 ` [PATCH 12/39] target/hexagon: Add implementation of cycle counters Brian Cain
2025-03-19 19:50 ` ltaylorsimpson
2025-04-02 2:44 ` Brian Cain
[not found] ` <7274cd69-f4e7-40b5-b850-cbd9099ed8ac@oss.qualcomm.com>
2025-09-02 1:56 ` Brian Cain
2025-03-01 5:28 ` [PATCH 13/39] target/hexagon: Implement modify_syscfg() Brian Cain
2025-03-19 21:12 ` ltaylorsimpson
2025-09-02 1:58 ` Brian Cain
2025-03-01 5:28 ` [PATCH 14/39] target/hexagon: Add system event, cause codes Brian Cain
2025-03-17 19:40 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 15/39] target/hexagon: Implement hex_tlb_entry_get_perm() Brian Cain
2025-03-17 19:37 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 16/39] target/hexagon: Implement hex_tlb_lookup_by_asid() Brian Cain
2025-03-17 19:42 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 17/39] target/hexagon: Implement software interrupt Brian Cain
2025-03-19 21:28 ` ltaylorsimpson
2025-03-24 15:51 ` Sid Manning
2025-09-02 2:03 ` Brian Cain
2025-03-01 5:28 ` [PATCH 18/39] target/hexagon: Implement exec_interrupt, set_irq Brian Cain
2025-03-19 21:33 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 19/39] target/hexagon: Implement hexagon_tlb_fill() Brian Cain
2025-03-17 19:55 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 20/39] target/hexagon: Implement siad inst Brian Cain
2025-03-17 19:57 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 21/39] target/hexagon: Implement hexagon_resume_threads() Brian Cain
2025-03-19 21:36 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 22/39] target/hexagon: Implement setprio, resched Brian Cain
2025-03-20 19:44 ` ltaylorsimpson
2025-03-20 20:25 ` Sid Manning
2025-03-20 22:28 ` ltaylorsimpson
2025-09-02 2:08 ` Brian Cain
2025-03-01 5:28 ` [PATCH 23/39] target/hexagon: Add sysemu_ops, cpu_get_phys_page_debug() Brian Cain
2025-03-20 20:02 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 24/39] target/hexagon: Add exec-start-addr prop Brian Cain
2025-03-17 20:03 ` ltaylorsimpson
2025-09-02 2:12 ` Brian Cain
2025-03-01 5:28 ` [PATCH 25/39] target/hexagon: Add hexagon_cpu_mmu_index() Brian Cain
2025-03-17 20:07 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 26/39] target/hexagon: Decode trap1, rte as COF Brian Cain
2025-03-17 20:08 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 27/39] target/hexagon: Implement hexagon_find_last_irq() Brian Cain
2025-03-17 20:09 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 28/39] target/hexagon: Implement modify_ssr, resched, pending_interrupt Brian Cain
2025-03-17 20:12 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 29/39] target/hexagon: Add pkt_ends_tb to translation Brian Cain
2025-03-17 20:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 30/39] target/hexagon: Add next_PC, {s,g}reg writes Brian Cain
2025-03-18 18:50 ` ltaylorsimpson
2025-09-02 2:35 ` Brian Cain
2025-03-01 5:28 ` [PATCH 31/39] target/hexagon: Add implicit sysreg writes Brian Cain
2025-03-18 19:18 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 32/39] target/hexagon: Define system, guest reg names Brian Cain
2025-03-19 16:48 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 33/39] target/hexagon: initialize sys/guest reg TCGvs Brian Cain
2025-03-19 16:53 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 34/39] target/hexagon: Add TLB, k0 {un,}lock Brian Cain
2025-03-03 16:24 ` Brian Cain
2025-03-04 23:09 ` ltaylorsimpson
2025-03-04 23:57 ` Philippe Mathieu-Daudé
2025-03-05 0:05 ` ltaylorsimpson
2025-03-05 0:19 ` Philippe Mathieu-Daudé
2025-03-05 0:45 ` ltaylorsimpson
2025-03-19 17:01 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 35/39] target/hexagon: Define gen_precise_exception() Brian Cain
2025-03-19 17:20 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 36/39] target/hexagon: Add TCG overrides for transfer insts Brian Cain
2025-03-19 17:22 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 37/39] target/hexagon: Add support for loadw_phys Brian Cain
2025-03-20 20:04 ` ltaylorsimpson
2025-03-01 5:28 ` [PATCH 38/39] target/hexagon: Add guest reg reading functionality Brian Cain
2025-03-19 18:36 ` ltaylorsimpson
2025-09-02 2:40 ` Brian Cain
2025-03-01 5:28 ` [PATCH 39/39] target/hexagon: Add pcycle setting functionality Brian Cain
2025-03-19 18:49 ` ltaylorsimpson
2025-09-02 2:42 ` Brian Cain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).