From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Cc: brian.cain@oss.qualcomm.com, matheus.bernardino@oss.qualcomm.com,
pierrick.bouvier@oss.qualcomm.com, ltaylorsimpson@gmail.com,
philmd@mailo.org, philmd@oss.qualcomm.com,
Brian Cain <bcain@quicinc.com>
Subject: [PATCH v8] target/hexagon: Add new macro definitions for sysemu
Date: Wed, 10 Jun 2026 22:28:36 -0700 [thread overview]
Message-ID: <20260611052857.3911981-16-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20260611052857.3911981-1-brian.cain@oss.qualcomm.com>
From: Brian Cain <bcain@quicinc.com>
Also: add nop TCG overrides for break, unpause, fetchbo; add TCG
override for dczeroa_nt (non-temporal variant of dczeroa).
break: this hardware breakpoint instruction is used with the in-silicon
debugger feature, this is not modeled.
unpause: this instruction is used to resume hardware threads that are
stalled by pause instructions. pause is modeled as a nop, or in RR
mode as an EXCP_YIELD. This instruction is safe to ignore.
Since prefetch functions are not modeled, fetchbo is safe to ignore.
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/gen_tcg.h | 9 ++
target/hexagon/macros.h | 25 +++-
target/hexagon/sys_macros.h | 237 ++++++++++++++++++++++++++++++++++++
target/hexagon/op_helper.c | 4 +
4 files changed, 274 insertions(+), 1 deletion(-)
create mode 100644 target/hexagon/sys_macros.h
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 0159e5c2d5f..4a58ead877b 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -488,6 +488,7 @@
/* dczeroa clears the 32 byte cache line at the address given */
#define fGEN_TCG_Y2_dczeroa(SHORTCODE) SHORTCODE
+#define fGEN_TCG_Y2_dczeroa_nt(SHORTCODE) SHORTCODE
/* In linux-user mode, these are not modelled, suppress compiler warning */
#define fGEN_TCG_Y2_dcinva(SHORTCODE) \
@@ -1112,6 +1113,9 @@
RdV, tcg_constant_tl(0)); \
} while (0)
+#define fGEN_TCG_Y2_break(SHORTCODE)
+#define fGEN_TCG_J2_unpause(SHORTCODE)
+
#define fGEN_TCG_J2_pause(SHORTCODE) \
do { \
uiV = uiV; \
@@ -1321,6 +1325,11 @@
RsV = RsV; \
uiV = uiV; \
} while (0)
+#define fGEN_TCG_Y2_dcfetchbo_nt(SHORTCODE) \
+ do { \
+ RsV = RsV; \
+ uiV = uiV; \
+ } while (0)
#define fGEN_TCG_L2_loadw_aq(SHORTCODE) SHORTCODE
#define fGEN_TCG_L4_loadd_aq(SHORTCODE) SHORTCODE
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index eebfe1e5ed9..38a43647dd9 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -631,8 +631,18 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
#define fCONSTLL(A) A##LL
#define fECHO(A) (A)
-#define fTRAP(TRAPTYPE, IMM) helper_raise_exception(env, HEX_EXCP_TRAP0)
+#ifdef CONFIG_USER_ONLY
+#define fTRAP(TRAPTYPE, IMM) \
+ do { \
+ hexagon_raise_exception_err(env, HEX_EVENT_TRAP0, PC); \
+ } while (0)
+#endif
+
+#define fDO_TRACE(SREG)
+#define fBREAK()
+#define fUNPAUSE()
#define fPAUSE(IMM)
+#define fDCFETCH(REG)
#define fALIGN_REG_FIELD_VALUE(FIELD, VAL) \
((VAL) << reg_field_info[FIELD].offset)
@@ -654,5 +664,18 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
#define fBRANCH_SPECULATE_STALL(DOTNEWVAL, JUMP_COND, SPEC_DIR, HINTBITNUM, \
STRBITNUM) /* Nothing */
+#ifdef CONFIG_USER_ONLY
+/*
+ * This macro can only be true in guest mode.
+ * In user mode, the 4 VIRTINSN's can't be reached
+ */
+#define fTRAP1_VIRTINSN(IMM) (false)
+#define fVIRTINSN_SPSWAP(IMM, REG) g_assert_not_reached()
+#define fVIRTINSN_GETIE(IMM, REG) g_assert_not_reached()
+#define fVIRTINSN_SETIE(IMM, REG) g_assert_not_reached()
+#define fVIRTINSN_RTE(IMM, REG) g_assert_not_reached()
+#endif
+
+#define fPREDUSE_TIMING()
#endif
diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
new file mode 100644
index 00000000000..f497d55bb81
--- /dev/null
+++ b/target/hexagon/sys_macros.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HEXAGON_SYS_MACROS_H
+#define HEXAGON_SYS_MACROS_H
+
+/*
+ * Macro definitions for Hexagon system mode
+ */
+
+#ifndef CONFIG_USER_ONLY
+
+#ifdef QEMU_GENERATE
+#define GET_SSR_FIELD(RES, FIELD) \
+ GET_FIELD(RES, FIELD, hex_t_sreg[HEX_SREG_SSR])
+#else
+
+#define GET_SSR_FIELD(FIELD, REGIN) \
+ (uint32_t)GET_FIELD(FIELD, REGIN)
+#define GET_SYSCFG_FIELD(FIELD, REGIN) \
+ (uint32_t)GET_FIELD(FIELD, REGIN)
+#define SET_SYSTEM_FIELD(ENV, REG, FIELD, VAL) \
+ do { \
+ HexagonCPU *_sf_cpu = env_archcpu(ENV); \
+ uint32_t regval; \
+ if ((REG) < HEX_SREG_GLB_START) { \
+ regval = (ENV)->t_sreg[(REG)]; \
+ } else { \
+ regval = _sf_cpu->globalregs ? \
+ hexagon_globalreg_read(_sf_cpu->globalregs, (REG), \
+ (ENV)->threadId) : 0; \
+ } \
+ fINSERT_BITS(regval, reg_field_info[FIELD].width, \
+ reg_field_info[FIELD].offset, (VAL)); \
+ if ((REG) < HEX_SREG_GLB_START) { \
+ (ENV)->t_sreg[(REG)] = regval; \
+ } else if (_sf_cpu->globalregs) { \
+ hexagon_globalreg_write(_sf_cpu->globalregs, (REG), regval, \
+ (ENV)->threadId); \
+ } \
+ } while (0)
+#define SET_SSR_FIELD(ENV, FIELD, VAL) \
+ SET_SYSTEM_FIELD(ENV, HEX_SREG_SSR, FIELD, VAL)
+#define SET_SYSCFG_FIELD(ENV, FIELD, VAL) \
+ SET_SYSTEM_FIELD(ENV, HEX_SREG_SYSCFG, FIELD, VAL)
+
+#define CCR_FIELD_SET(ENV, FIELD) \
+ (!!GET_FIELD(FIELD, (ENV)->t_sreg[HEX_SREG_CCR]))
+
+/*
+ * Direct-to-guest is not implemented yet, continuing would cause unexpected
+ * behavior, so we abort.
+ */
+#define ASSERT_DIRECT_TO_GUEST_UNSET(ENV, EXCP) \
+ do { \
+ switch (EXCP) { \
+ case HEX_EVENT_TRAP0: \
+ g_assert(!CCR_FIELD_SET(ENV, CCR_GTE)); \
+ break; \
+ case HEX_EVENT_IMPRECISE: \
+ case HEX_EVENT_PRECISE: \
+ case HEX_EVENT_FPTRAP: \
+ g_assert(!CCR_FIELD_SET(ENV, CCR_GEE)); \
+ break; \
+ default: \
+ if ((EXCP) >= HEX_EVENT_INT0) { \
+ g_assert(!CCR_FIELD_SET(ENV, CCR_GIE)); \
+ } \
+ break; \
+ } \
+ } while (0)
+#endif
+
+#define fREAD_ELR() (env->t_sreg[HEX_SREG_ELR])
+
+#define fLOAD_PHYS(NUM, SIZE, SIGN, SRC1, SRC2, DST) { \
+ const uintptr_t rs = ((unsigned long)(unsigned)(SRC1)) & 0x7ff; \
+ const uintptr_t rt = ((unsigned long)(unsigned)(SRC2)) << 11; \
+ const uintptr_t addr = rs + rt; \
+ cpu_physical_memory_read(addr, &DST, sizeof(uint32_t)); \
+}
+
+#define fPOW2_HELP_ROUNDUP(VAL) \
+ ((VAL) | \
+ ((VAL) >> 1) | \
+ ((VAL) >> 2) | \
+ ((VAL) >> 4) | \
+ ((VAL) >> 8) | \
+ ((VAL) >> 16))
+#define fPOW2_ROUNDUP(VAL) (fPOW2_HELP_ROUNDUP((VAL) - 1) + 1)
+
+#define fTRAP(TRAPTYPE, IMM) \
+ register_trap_exception(env, TRAPTYPE, IMM, PC)
+
+#define fVIRTINSN_SPSWAP(IMM, REG)
+#define fVIRTINSN_GETIE(IMM, REG) { REG = 0xdeafbeef; }
+#define fVIRTINSN_SETIE(IMM, REG)
+#define fVIRTINSN_RTE(IMM, REG)
+#define fGRE_ENABLED() \
+ GET_FIELD(CCR_GRE, env->t_sreg[HEX_SREG_CCR])
+#define fTRAP1_VIRTINSN(IMM) \
+ (fGRE_ENABLED() && \
+ (((IMM) == 1) || ((IMM) == 3) || ((IMM) == 4) || ((IMM) == 6)))
+
+/* Not modeled in qemu */
+
+#define MARK_LATE_PRED_WRITE(RNUM)
+#define fICINVIDX(REG)
+#define fICKILL()
+#define fDCKILL()
+#define fL2KILL()
+#define fL2UNLOCK()
+#define fL2CLEAN()
+#define fL2CLEANINV()
+#define fL2CLEANPA(REG)
+#define fL2CLEANINVPA(REG)
+#define fL2CLEANINVIDX(REG)
+#define fL2CLEANIDX(REG)
+#define fL2INVIDX(REG)
+#define fL2TAGR(INDEX, DST, DSTREG)
+#define fL2UNLOCKA(VA) ((void) VA)
+#define fL2TAGW(INDEX, PART2)
+#define fDCCLEANIDX(REG)
+#define fDCCLEANINVIDX(REG)
+
+/* Always succeed: */
+#define fL2LOCKA(EA, PDV, PDN) ((void) EA, PDV = 0xFF)
+#define fCLEAR_RTE_EX() \
+ do { \
+ uint32_t tmp = env->t_sreg[HEX_SREG_SSR]; \
+ fINSERT_BITS(tmp, reg_field_info[SSR_EX].width, \
+ reg_field_info[SSR_EX].offset, 0); \
+ log_sreg_write(env, HEX_SREG_SSR, tmp, slot); \
+ } while (0)
+
+#define fDCINVIDX(REG)
+#define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do in qemu */
+
+#define fTLB_IDXMASK(INDEX) \
+ ((INDEX) & (fPOW2_ROUNDUP( \
+ fCAST4u(hexagon_tlb_get_num_entries(env_archcpu(env)->tlb))) - 1))
+
+#define fTLB_NONPOW2WRAP(INDEX) \
+ (((INDEX) >= hexagon_tlb_get_num_entries(env_archcpu(env)->tlb)) ? \
+ ((INDEX) - hexagon_tlb_get_num_entries(env_archcpu(env)->tlb)) : \
+ (INDEX))
+
+
+#define fTLBW(INDEX, VALUE) \
+ hex_tlbw(env, (INDEX), (VALUE))
+#define fTLBW_EXTENDED(INDEX, VALUE) \
+ hex_tlbw(env, (INDEX), (VALUE))
+#define fTLB_ENTRY_OVERLAP(VALUE) \
+ (hex_tlb_check_overlap(env, VALUE, -1) != -2)
+#define fTLB_ENTRY_OVERLAP_IDX(VALUE) \
+ hex_tlb_check_overlap(env, VALUE, -1)
+#define fTLBR(INDEX) \
+ hexagon_tlb_read(env_archcpu(env)->tlb, \
+ fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX)))
+#define fTLBR_EXTENDED(INDEX) \
+ hexagon_tlb_read(env_archcpu(env)->tlb, \
+ fTLB_NONPOW2WRAP(fTLB_IDXMASK(INDEX)))
+#define fTLBP(TLBHI) \
+ hex_tlb_lookup(env, ((TLBHI) >> 12), ((TLBHI) << 12))
+#define iic_flush_cache(p)
+
+#define fIN_DEBUG_MODE(TNUM) ({ \
+ HexagonCPU *_cpu = env_archcpu(env); \
+ uint32_t _isdbst = _cpu->globalregs ? \
+ hexagon_globalreg_read(_cpu->globalregs, \
+ HEX_SREG_ISDBST, env->threadId) : 0; \
+ (GET_FIELD(ISDBST_DEBUGMODE, _isdbst) \
+ & (0x1 << (TNUM))) != 0; })
+
+#define fIN_DEBUG_MODE_NO_ISDB(TNUM) false
+#define fIN_DEBUG_MODE_WARN(TNUM) false
+
+#ifdef QEMU_GENERATE
+
+/*
+ * Read tags back as zero for now:
+ *
+ * tag value in RD[31:10] for 32k, RD[31:9] for 16k
+ */
+#define fICTAGR(RS, RD, RD2) \
+ do { \
+ RD = ctx->zero; \
+ } while (0)
+#define fICTAGW(RS, RD)
+#define fICDATAR(RS, RD) \
+ do { \
+ RD = ctx->zero; \
+ } while (0)
+#define fICDATAW(RS, RD)
+
+#define fDCTAGW(RS, RT)
+/* tag: RD[23:0], state: RD[30:29] */
+#define fDCTAGR(INDEX, DST, DST_REG_NUM) \
+ do { \
+ DST = ctx->zero; \
+ } while (0)
+#else
+
+/*
+ * Read tags back as zero for now:
+ *
+ * tag value in RD[31:10] for 32k, RD[31:9] for 16k
+ */
+#define fICTAGR(RS, RD, RD2) \
+ do { \
+ RD = 0x00; \
+ } while (0)
+#define fICTAGW(RS, RD)
+#define fICDATAR(RS, RD) \
+ do { \
+ RD = 0x00; \
+ } while (0)
+#define fICDATAW(RS, RD)
+
+#define fDCTAGW(RS, RT)
+/* tag: RD[23:0], state: RD[30:29] */
+#define fDCTAGR(INDEX, DST, DST_REG_NUM) \
+ do { \
+ DST = 0; \
+ } while (0)
+#endif
+
+#else
+#define ASSERT_DIRECT_TO_GUEST_UNSET(ENV, EXCP) do { } while (0)
+#endif
+
+#define NUM_TLB_REGS(x) (hexagon_tlb_get_num_entries(env_archcpu(env)->tlb))
+
+#endif
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 368391bb846..53898db815b 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -24,6 +24,7 @@
#include "cpu.h"
#include "internal.h"
#include "macros.h"
+#include "sys_macros.h"
#include "arch.h"
#include "hex_arch_types.h"
#include "fma_emu.h"
@@ -31,6 +32,9 @@
#include "mmvec/macros.h"
#include "op_helper.h"
#include "translate.h"
+#ifndef CONFIG_USER_ONLY
+#include "hexswi.h"
+#endif
#define SF_BIAS 127
#define SF_MANTBITS 23
--
2.34.1
next prev parent reply other threads:[~2026-06-11 5:30 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-11 5:28 [PATCH v8 00/36] Hexagon system emulation - Part 1/3 Brian Cain
2026-06-11 5:28 ` [PATCH v8] docs: Add hexagon sysemu docs Brian Cain
2026-06-11 5:28 ` [PATCH v8] docs/system: Add hexagon CPU emulation Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Fix badva reference, delete CAUSE Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add missing A_CALL attr, hintjumpr to multi_cof Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Handle system/guest registers in gen_analyze_funcs.py and hex_common.py Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Suppress unused-variable warnings for sysemu source regs Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Switch to tag_ignore(), generate via get_{user, sys}_tags() Brian Cain via qemu development
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add privilege check, use tag_ignore() Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add a placeholder fp exception Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add guest, system reg number defs Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add guest, system reg number state Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add TCG values for sreg, greg Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add guest/sys reg writes to DisasContext Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add imported macro, attr defs for sysemu Brian Cain
2026-06-11 5:28 ` Brian Cain [this message]
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add handlers for guest/sysreg r/w Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add placeholder greg/sreg r/w helpers Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add vmstate representation Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Make A_PRIV, "J2_trap*" insts need_env() Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Define register fields for system regs Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Implement do_raise_exception() Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add system reg insns Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add sysemu TCG overrides Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add implicit attributes to sysemu macros Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add TCG overrides for int handler insts Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add TCG overrides for thread ctl Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add TCG overrides for rte, nmi Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add sreg_{read,write} helpers Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add representation to count cycles Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add implementation of cycle counters Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add pcycle setting functionality Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add cpu modes, mmu indices, next_PC to state Brian Cain
2026-06-11 5:28 ` [PATCH v8] hw/hexagon: Declare hexagon TLB device interface Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Update TARGET_PAGE_BITS, stubs for modify_ssr/get_exe_mode Brian Cain
2026-06-17 15:03 ` Pierrick Bouvier
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Define f{S,G}ET_FIELD macros Brian Cain
2026-06-11 5:28 ` [PATCH v8] target/hexagon: Add hex_interrupts support Brian Cain
2026-06-17 19:34 ` Pierrick Bouvier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260611052857.3911981-16-brian.cain@oss.qualcomm.com \
--to=brian.cain@oss.qualcomm.com \
--cc=bcain@quicinc.com \
--cc=ltaylorsimpson@gmail.com \
--cc=matheus.bernardino@oss.qualcomm.com \
--cc=philmd@mailo.org \
--cc=philmd@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.