Commit Graph

4116 Commits

Author SHA1 Message Date
Smail AIDER
842918ee3c target/arm: Trap PMCR when MDCR_EL2.TPMCR is set
Trap PMCR_EL0 or PMCR accesses to EL2 when MDCR_EL2.TPMCR is set.
Similar to MDCR_EL2.TPM, MDCR_EL2.TPMCR allows trapping EL0 and EL1
accesses to the PMCR register to EL2.

Cc: qemu-stable@nongnu.org
Signed-off-by: Smail AIDER <smail.aider@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250811112143.1577055-2-smail.aider@huawei.com
Message-Id: <20250722131925.2119169-1-smail.aider@huawei.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 186db6a73b)
(Mjt: adjust for 10.0, before target/arm/helper.c split)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 07:57:47 +03:00
Alex Richardson
5c535004b9 target/arm: add support for 64-bit PMCCNTR in AArch32 mode
In the PMUv3, a new AArch32 64-bit (MCRR/MRRC) accessor for the
PMCCNTR was added. In QEMU we forgot to implement this, so only
provide the 32-bit accessor. Since we have a 64-bit PMCCNTR
sysreg for AArch64, adding the 64-bit AArch32 version is easy.

We add the PMCCNTR to the v8_cp_reginfo because PMUv3 was added
in the ARMv8 architecture. This is consistent with how we
handle the existing PMCCNTR support, where we always implement
it for all v7 CPUs. This is arguably something we should
clean up so it is gated on ARM_FEATURE_PMU and/or an ID
register check for the relevant PMU version, but we should
do that as its own tidyup rather than being inconsistent between
this PMCCNTR accessor and the others.

Since the register name is the same as the 32-bit PMCCNTR, we set
ARM_CP_NO_GDB on the 32-bit one to avoid generating an invalid GDB XML.

See https://developer.arm.com/documentation/ddi0601/2024-06/AArch32-Registers/PMCCNTR--Performance-Monitors-Cycle-Count-Register?lang=en

Note for potential backporting:
 * this code in cpregs-pmu.c will be in helper.c on stable
   branches that don't have commit ae2086426d

Cc: qemu-stable@nongnu.org
Signed-off-by: Alex Richardson <alexrichardson@google.com>
Message-id: 20250725170136.145116-1-alexrichardson@google.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit cd9f752fee)
(Mjt: moved code to target/arm/helper.c and modified it for 10.0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-06 10:02:36 +03:00
Vacha Bhavsar
e62a4440ef target/arm: Fix handling of setting SVE registers from gdb
The code to handle setting SVE registers via the gdbstub is broken:
 * it sets each pair of elements in the zregs[].d[] array in the
   wrong order for the most common (little endian) case: the least
   significant 64-bit value comes first
 * it makes no attempt to handle target_endian()
 * it does a simple copy out of the (target endian) gdbstub buffer
   into the (host endan) zregs data structure, which is wrong on
   big endian hosts

Fix all these problems:
 * use ldq_p() to read from the gdbstub buffer
 * check target_big_endian() to see if we need to handle the
   128-bit values the opposite way around

Cc: qemu-stable@nongnu.org
Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
Message-id: 20250722173736.2332529-3-vacha.bhavsar@oss.qualcomm.com
[PMM: adjusted commit message, fixed spacing]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 97b3d732af)
(Mjt: s/target_big_endian/target_words_bigendian/ due to missing
 v10.0.0-277-gb939b8e42a "exec: Rename target_words_bigendian() -> target_big_endian()")
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-06 10:02:36 +03:00
Vacha Bhavsar
8d7488649b target/arm: Fix big-endian handling of NEON gdb remote debugging
In the code for allowing the gdbstub to set the value of an AArch64
FP/SIMD register, we weren't accounting for target_big_endian()
being true. This meant that for aarch64_be-linux-user we would
set the two halves of the FP register the wrong way around.
The much more common case of a little-endian guest is not affected;
nor are big-endian hosts.

Correct the handling of this case.

Cc: qemu-stable@nongnu.org
Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
Message-id: 20250722173736.2332529-2-vacha.bhavsar@oss.qualcomm.com
[PMM: added comment, expanded commit message, fixed missing space]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 35cca0f95f)
(Mjt: s/target_big_endian/target_words_bigendian/ due to missing
 v10.0.0-277-gb939b8e42a "exec: Rename target_words_bigendian() -> target_big_endian()")
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-06 10:02:36 +03:00
Zenghui Yu
a5ac9803d5 hvf: arm: Emulate ICC_RPR_EL1 accesses properly
Commit a2260983c6 ("hvf: arm: Add support for GICv3") added GICv3 support
by implementing emulation for a few system registers. ICC_RPR_EL1 was
defined but not plugged in the sysreg handlers (for no good reason).

Fix it.

Fixes: a2260983c6 ("hvf: arm: Add support for GICv3")
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20250714160139.10404-3-zenghui.yu@linux.dev
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit e6da704b71)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-21 22:11:49 +03:00
Peter Maydell
3341f5cd5c target/arm: Correct encoding of Debug Communications Channel registers
We don't implement the Debug Communications Channel (DCC), but
we do attempt to provide dummy versions of its system registers
so that software that tries to access them doesn't fall over.

However, we got the tx/rx register definitions wrong. These
should be:

AArch32:
  DBGDTRTX   p14 0 c0 c5 0  (on writes)
  DBGDTRRX   p14 0 c0 c5 0  (on reads)

AArch64:
  DBGDTRTX_EL0  2 3 0 5 0 (on writes)
  DBGDTRRX_EL0  2 3 0 5 0 (on reads)
  DBGDTR_EL0    2 3 0 4 0 (reads and writes)

where DBGDTRTX and DBGDTRRX are effectively different names for the
same 32-bit register, which has tx behaviour on writes and rx
behaviour on reads.  The AArch64-only DBGDTR_EL0 is a 64-bit wide
register whose top and bottom halves map to the DBGDTRRX and DBGDTRTX
registers.

Currently we have just one cpreg struct, which:
 * calls itself DBGDTR_EL0
 * uses the DBGDTRTX_EL0/DBGDTRRX_EL0 encoding
 * is marked as ARM_CP_STATE_BOTH but has the wrong opc1
   value for AArch32
 * is implemented as RAZ/WI

Correct the encoding so:
 * we name the DBGDTRTX/DBGDTRRX register correctly
 * we split it into AA64 and AA32 versions so we can get the
   AA32 encoding right
 * we implement DBGDTR_EL0 at its correct encoding

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2986
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250708141049.778361-1-peter.maydell@linaro.org
(cherry picked from commit 655659a74a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-21 22:02:51 +03:00
Peter Maydell
fe000c4648 target/arm: Don't enforce NSE,NS check for EL3->EL3 returns
In the Arm ARM, rule R_TYTWB that defines illegal exception return cases
includes the case:
 If FEAT_RME is implemented, then if SCR_EL3.{NSE, NS} is {1, 0}, an
 exception return from EL3 to a lower Exception level

Our implementation of this check fails to check that the
return is to a lower exception level, so it will incorrectly fire on
EL3->EL3 exception returns.

Fix the check condition. This requires us to move it further
down in the function to a point where we know the new_el value.

Fixes: 35aa6715dd ("target/arm: Catch illegal-exception-return from EL3 with bad NSE/NS")
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3016
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704165636.261888-1-peter.maydell@linaro.org
(cherry picked from commit c563cd7e61)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-13 11:16:20 +03:00
Richard Henderson
005184da9d target/arm: Fix bfdotadd_ebf vs nan selection
Implement FPProcessNaNs4 within bfdotadd_ebf, rather than
simply letting NaNs propagate through the function.

Cc: qemu-stable@nongnu.org
Fixes: 0e1850182a ("target/arm: Implement FPCR.EBF=1 semantics for bfdotadd()")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20250704142112.1018902-10-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit bf020eaa67)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-09 05:08:40 +03:00
Richard Henderson
9a98db505f target/arm: Fix f16_dotadd vs nan selection
Implement FPProcessNaNs4 within f16_dotadd, rather than
simply letting NaNs propagate through the function.

Cc: qemu-stable@nongnu.org
Fixes: 3916841ac7 ("target/arm: Implement FMOPA, FMOPS (widening)")
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-9-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit cfc688c00a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-09 05:07:49 +03:00
Richard Henderson
9af1de0c4b target/arm: Fix PSEL size operands to tcg_gen_gvec_ands
Gvec only operates on size 8 and multiples of 16.
Predicates may be any multiple of 2.
Round up the size using the appropriate function.

Cc: qemu-stable@nongnu.org
Fixes: 598ab0b24c ("target/arm: Implement PSEL")
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-8-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3801c5b75f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-09 05:07:31 +03:00
Richard Henderson
c76ec8d575 target/arm: Fix 128-bit element ZIP, UZP, TRN
We missed the instructions UDEF when the vector size is too small.
We missed marking the instructions non-streaming with SME.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit e6ffd009c7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-09 05:04:25 +03:00
Richard Henderson
0e5f0d87f8 target/arm: Fix sve_access_check for SME
Do not assume SME implies SVE.  Ensure that the non-streaming
check is present along the SME path, since it is not implied
by sme_*_enabled_check.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-3-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit b4b2e070f4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-09 04:59:21 +03:00
Richard Henderson
83b48a500f target/arm: Fix SME vs AdvSIMD exception priority
We failed to raise an exception when
sme_excp_el == 0 and fp_excp_el == 1.

Cc: qemu-stable@nongnu.org
Fixes: 3d74825f4d ("target/arm: Add SME enablement checks")
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit f9b0f69304)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-08 22:54:34 +03:00
Philippe Mathieu-Daudé
5df7910a23 target/arm: Correct KVM & HVF dtb_compatible value
Linux kernel knows how to parse "arm,armv8", not "arm,arm-v8".

See arch/arm64/boot/dts/foundation-v8.dts:

  https://github.com/torvalds/linux/commit/90556ca1ebdd

Cc: qemu-stable@nongnu.org
Fixes: 26861c7ce0 ("target-arm: Add minimal KVM AArch64 support")
Fixes: 585df85efe ("hvf: arm: Implement -cpu host")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250623121845.7214-10-philmd@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a412575837)
(Mjt: context fix in target/arm/kvm.c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-02 23:23:29 +03:00
Solomon Tan
ed4bad29e7 target/arm: Make RETA[AB] UNDEF when pauth is not implemented
According to the Arm A-profile A64 Instruction Set Architecture,
RETA[AB] should be decoded as UNDEF if the pauth feature is not
implemented.

We got this right in the initial implementation, but accidentally
dropped the feature-check when we converted these insns to
decodetree.

Cc: qemu-stable@nongnu.org
Fixes: 0ebbe90212 ("target/arm: Convert BRA[AB]Z, BLR[AB]Z, RETA[AB] to decodetree")
Signed-off-by: Solomon Tan <root@wjsota.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250616171549.59190-1-root@wjsota.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9a3bf0e0ab)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-07-02 23:21:10 +03:00
Peter Maydell
ac32612b93 target/arm: Don't assert() for ISB/SB inside IT block
If the guest code has an ISB or SB insn inside an IT block, we
generate incorrect code which trips a TCG assertion:

qemu-system-arm: ../tcg/tcg-op.c:3343: void tcg_gen_goto_tb(unsigned int): Assertion `(tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0' failed.

This is because we call gen_goto_tb(dc, 1, ...) twice:

 brcond_i32 ZF,$0x0,ne,$L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x73d948001b81
 set_label $L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x73d948001b81

Both calls are in arm_tr_tb_stop(), one for the
DISAS_NEXT/DISAS_TOO_MANY handling, and one for the dc->condjump
condition-failed codepath.  The DISAS_NEXT handling doesn't have this
problem because arm_post_translate_insn() does the handling of "emit
the label for the condition-failed conditional execution" and so
arm_tr_tb_stop() doesn't have dc->condjump set.  But for
DISAS_TOO_MANY we don't do that.

Fix the bug by making arm_post_translate_insn() handle the
DISAS_TOO_MANY case.  This only affects the SB and ISB insns when
used in Thumb mode inside an IT block: only these insns specifically
set is_jmp to TOO_MANY, and their A32 encodings are unconditional.

For the major TOO_MANY case (breaking the TB because it would cross a
page boundary) we do that check and set is_jmp to TOO_MANY only after
the call to arm_post_translate_insn(); so arm_post_translate_insn()
sees is_jmp == DISAS_NEXT, and  we emit the correct code for that
situation.

With this fix we generate the somewhat more sensible set of TCG ops:
 brcond_i32 ZF,$0x0,ne,$L1
 set_label $L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x7c5434001b81

(NB: the TCG optimizer doesn't optimize out the jump-to-next, but
we can't really avoid emitting it because we don't know at the
point we're emitting the handling for the condexec check whether
this insn is going to happen to be a nop for us or not.)

Cc: qemu-stable@nongnu.org
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2942
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250501125544.727038-1-peter.maydell@linaro.org
(cherry picked from commit 8ed7c0b648)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-05-08 10:22:21 +03:00
Richard Henderson
cc7abc35df target/arm: Simplify pstate_sm check in sve_access_check
In StreamingMode, fp_access_checked is handled already.
We cannot fall through to fp_access_check lest we fall
foul of the double-check assertion.

Cc: qemu-stable@nongnu.org
Fixes: 285b1d5fce ("target/arm: Handle SME in sve_access_check")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250307190415.982049-3-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: move declaration of 'ret' to top of block]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-03-14 12:54:33 +00:00
Richard Henderson
298a04998f target/arm: Make DisasContext.{fp, sve}_access_checked tristate
The check for fp_excp_el in assert_fp_access_checked is
incorrect.  For SME, with StreamingMode enabled, the access
is really against the streaming mode vectors, and access
to the normal fp registers is allowed to be disabled.
C.f. sme_enabled_check.

Convert sve_access_checked to match, even though we don't
currently check the exception state.

Cc: qemu-stable@nongnu.org
Fixes: 3d74825f4d ("target/arm: Add SME enablement checks")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250307190415.982049-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-03-14 12:54:33 +00:00
Peter Maydell
097d68ac2f target/arm: Forbid return to AArch32 when CPU is AArch64-only
In the Arm ARM, rule R_TYTWB states that returning to AArch32
is an illegal exception return if:
 * AArch32 is not supported at any exception level
 * the target EL is configured for AArch64 via SCR_EL3.RW
   or HCR_EL2.RW or via CPU state at reset

We check the second of these, but not the first (which can only be
relevant for the case of a return to EL0, because if AArch32 is not
supported at one of the higher ELs then the RW bits will have an
effective value of 1 and the the "configured for AArch64" condition
will hold also).

Add the missing condition. Although this is technically a bug
(because we have one AArch64-only CPU: a64fx) it isn't worth
backporting to stable because no sensible guest code will
deliberately try to return to a nonexistent execution state
to check that it gets an illegal exception return.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 12:54:33 +00:00
Peter Maydell
44ab8c248d target/arm: Add cpu local variable to exception_return helper
We already call env_archcpu() multiple times within the
exception_return helper function, and we're about to want to
add another use of the ARMCPU pointer. Add a local variable
cpu so we can call env_archcpu() just once.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 12:54:33 +00:00
Peter Maydell
39ec3fc030 target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32
When EL1 doesn't support AArch32, the HCR_EL2.RW bit is supposed to
be RAO/WI. Enforce the RAO/WI behaviour.

Note that we handle "reset value should honour RES1 bits" in the same
way that SCR_EL3 does, via a reset function.

We do already have some CPU types which don't implement AArch32
above EL0, so this is technically a bug; it doesn't seem worth
backporting to stable because no sensible guest code will be
deliberately attempting to set the RW bit to a value corresponding
to an unimplemented execution state and then checking that we
did the right thing.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 12:54:33 +00:00
Peter Maydell
5d71c6820f target/arm: SCR_EL3.RW should be treated as 1 if EL2 doesn't support AArch32
The definition of SCR_EL3.RW says that its effective value is 1 if:
 - EL2 is implemented and does not support AArch32, and SCR_EL3.NS is 1
 - the effective value of SCR_EL3.{EEL2,NS} is {1,0} (i.e. we are
   Secure and Secure EL2 is disabled)

We implement the second of these in arm_el_is_aa64(), but forgot the
first.

Provide a new function arm_scr_rw_eff() to return the effective
value of SCR_EL3.RW, and use it in arm_el_is_aa64() and the other
places that currently look directly at the bit value.

(scr_write() enforces that the RW bit is RAO/WI if neither EL1 nor
EL2 have AArch32 support, but if EL1 does but EL2 does not then the
bit must still be writeable.)

This will mean that if code at EL3 attempts to perform an exception
return to AArch32 EL2 when EL2 is AArch64-only we will correctly
handle this as an illegal exception return: it will be caught by the
"return to an EL which is configured for a different register width"
check in HELPER(exception_return).

We do already have some CPU types which don't implement AArch32
above EL0, so this is technically a bug; it doesn't seem worth
backporting to stable because no sensible guest code will be
deliberately attempting to set the RW bit to a value corresponding
to an unimplemented execution state and then checking that we
did the right thing.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 10:49:20 +00:00
Peter Maydell
2beb051191 target/arm: Move arm_current_el() and arm_el_is_aa64() to internals.h
The functions arm_current_el() and arm_el_is_aa64() are used only in
target/arm and in hw/intc/arm_gicv3_cpuif.c.  They're functions that
query internal state of the CPU.  Move them out of cpu.h and into
internals.h.

This means we need to include internals.h in arm_gicv3_cpuif.c, but
this is justifiable because that file is implementing the GICv3 CPU
interface, which really is part of the CPU proper; we just ended up
implementing it in code in hw/intc/ for historical reasons.

The motivation for this move is that we'd like to change
arm_el_is_aa64() to add a condition that uses cpu_isar_feature();
but we don't want to include cpu-features.h in cpu.h.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 10:49:20 +00:00
Peter Maydell
fefc1220ad target/arm: Move arm_cpu_data_is_big_endian() etc to internals.h
The arm_cpu_data_is_big_endian() and related functions are now used
only in target/arm; they can be moved to internals.h.

The motivation here is that we would like to move arm_current_el()
to internals.h.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 10:49:20 +00:00
Peter Maydell
23560ada94 target/arm: Un-inline access_secure_reg()
We would like to move arm_el_is_aa64() to internals.h; however, it is
used by access_secure_reg().  Make that function not be inline, so
that it can stay in cpu.h.

access_secure_reg() is used only in two places:
 * in hflags.c
 * in the user-mode arm emulators, to decide whether to store
   the TLS value in the secure or non-secure banked field

The second of these is not on a super-hot path that would care about
the inlining (and incidentally will always use the NS banked field
because our user-mode CPUs never set ARM_FEATURE_EL3); put the
definition of access_secure_reg() in hflags.c, near its only use
inside target/arm.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 10:49:20 +00:00
Peter Maydell
eae0c3b659 target/arm: Move A32_BANKED_REG_{GET,SET} macros to cpregs.h
The A32_BANKED_REG_{GET,SET} macros are only used inside target/arm;
move their definitions to cpregs.h. There's no need to have them
defined in all the code that includes cpu.h.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-14 10:49:20 +00:00
Philippe Mathieu-Daudé
f5e67b6dda target/arm: Move has_work() from CPUClass to SysemuCPUOps
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250125170125.32855-6-philmd@linaro.org>
2025-03-09 17:00:47 +01:00
Philippe Mathieu-Daudé
0ebdf989c3 target/arm: Prefer cached CpuClass over CPU_GET_CLASS() macro
CpuState caches its CPUClass since commit 6fbdff8706
("cpu: cache CPUClass in CPUState for hot code paths"),
use it.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250122093028.52416-11-philmd@linaro.org>
2025-03-09 17:00:47 +01:00
Stefan Hajnoczi
d9a4282c4b include/qemu: Tidy atomic128 headers.
include/exec: Split out cpu-interrupt.h
 include/exec: Split many tlb_* declarations to cputlb.h
 include/accel/tcg: Split out getpc.h
 accel/tcg: system: Compile some files once
 linux-user/main: Allow setting tb-size
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmfMyz8dHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV9D/Af/Vh5PMtYjL+Mw2NQn
 Vmqbv+joiqswAxI8PmZZzEBJ06j4pCLXn+r/2nr+sEwLmrI4BI40Vxx5c5puftoZ
 GDGGclskF/pId5TE96TCEr8AoJgeNSSv4WxbINFTZRsRP4voZFHpU6mTz6B0Nnq5
 GS/k6c7+VcYbHIPD0RcIWwBlQv11uUAcnaygkNSsy+theUseOzTPTN/XGfTprf/6
 1sxlmtt6QcQ88bBJJbiNwqbjWGxANcSUspRo0sstpVr8ApkXNl7WSkWYRBhBa5oc
 iu0tixdCIoqqcCJy9/YVyIkmmwWeRUkbQqBeKf0o5xPnhmO3kfeezvERSDvDViAH
 K9BVBw==
 =7vra
 -----END PGP SIGNATURE-----

Merge tag 'pull-tcg-20250308' of https://gitlab.com/rth7680/qemu into staging

include/qemu: Tidy atomic128 headers.
include/exec: Split out cpu-interrupt.h
include/exec: Split many tlb_* declarations to cputlb.h
include/accel/tcg: Split out getpc.h
accel/tcg: system: Compile some files once
linux-user/main: Allow setting tb-size

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmfMyz8dHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV9D/Af/Vh5PMtYjL+Mw2NQn
# Vmqbv+joiqswAxI8PmZZzEBJ06j4pCLXn+r/2nr+sEwLmrI4BI40Vxx5c5puftoZ
# GDGGclskF/pId5TE96TCEr8AoJgeNSSv4WxbINFTZRsRP4voZFHpU6mTz6B0Nnq5
# GS/k6c7+VcYbHIPD0RcIWwBlQv11uUAcnaygkNSsy+theUseOzTPTN/XGfTprf/6
# 1sxlmtt6QcQ88bBJJbiNwqbjWGxANcSUspRo0sstpVr8ApkXNl7WSkWYRBhBa5oc
# iu0tixdCIoqqcCJy9/YVyIkmmwWeRUkbQqBeKf0o5xPnhmO3kfeezvERSDvDViAH
# K9BVBw==
# =7vra
# -----END PGP SIGNATURE-----
# gpg: Signature made Sun 09 Mar 2025 06:57:03 HKT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-tcg-20250308' of https://gitlab.com/rth7680/qemu: (23 commits)
  accel/tcg: Build tcg-runtime-gvec.c once
  accel/tcg: Build tcg-runtime.c once
  qemu/atomic128: Include missing 'qemu/atomic.h' header
  qemu/atomic: Rename atomic128-ldst.h headers using .h.inc suffix
  qemu/atomic: Rename atomic128-cas.h headers using .h.inc suffix
  accel/tcg: Split out getpc.h
  accel/tcg: Restrict GETPC_ADJ to 'tb-internal.h'
  accel/tcg: Build tcg-accel-ops-mttcg.c once
  accel/tcg: Build tcg-accel-ops-rr.c once
  accel/tcg: Build tcg-accel-ops-icount.c once
  accel/tcg: Build tcg-accel-ops.c once
  system: Build watchpoint.c once
  exec: Declare tlb_flush*() in 'exec/cputlb.h'
  exec: Declare tlb_hit*() in 'exec/cputlb.h'
  exec: Declare tlb_set_page() in 'exec/cputlb.h'
  exec: Declare tlb_set_page_with_attrs() in 'exec/cputlb.h'
  exec: Declare tlb_set_page_full() in 'exec/cputlb.h'
  exec: Declare tlb_reset_dirty*() in 'exec/cputlb.h'
  accel/tcg: Compile watchpoint.c once
  include/exec: Split out exec/cpu-interrupt.h
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2025-03-09 11:45:00 +08:00
Philippe Mathieu-Daudé
6ff5da1600 exec: Declare tlb_flush*() in 'exec/cputlb.h'
Move CPU TLB related methods to "exec/cputlb.h".

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-ID: <20241114011310.3615-19-philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2025-03-08 07:56:14 -08:00
Peter Maydell
cc503abf4b target/arm: Make dummy debug registers RAZ, not NOP
In debug_helper.c we provide a few dummy versions of
debug registers:
 * DBGVCR (AArch32 only): enable bits for vector-catch
   debug events
 * MDCCINT_EL1: interrupt enable bits for the DCC
   debug communications channel
 * DBGVCR32_EL2: the AArch64 accessor for the state in
   DBGVCR

We implemented these only to stop Linux crashing on startup,
but we chose to implement them as ARM_CP_NOP. This worked
for Linux where it only cares about trying to write to these
registers, but is very confusing behaviour for anything that
wants to read the registers (perhaps for context state switches),
because the destination register will be left with whatever
random value it happened to have before the read.

Model these registers instead as RAZ.

Fixes: 5e8b12ffbb ("target-arm: Implement minimal DBGVCR, OSDLR_EL1, MDCCSR_EL0")
Fixes: 5dbdc4342f ("target-arm: Implement dummy MDCCINT_EL1")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2708
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250228162424.1917269-1-peter.maydell@linaro.org
2025-03-07 10:33:41 +00:00
Peter Maydell
5be4419c57 target/arm: Drop unused address_offset from op_addr_{rr, ri}_post()
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
zero for the address_offset, so we can remove that argument.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20250227142746.1698904-4-peter.maydell@linaro.org
2025-03-07 10:08:22 +00:00
Peter Maydell
ee786ca115 target/arm: Correct STRD atomicity
Our STRD implementation doesn't correctly implement the requirement:
 * if the address is 8-aligned the access must be a 64-bit
   single-copy atomic access, not two 32-bit accesses

Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64()
of a value produced by concatenating the two 32 bit source registers.
This allows us to get the atomicity right.

As with the LDRD change, now that we don't update 'addr' in the
course of performing the store we need to adjust the offset
we pass to op_addr_ri_post() and op_addr_rr_post().

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250227142746.1698904-3-peter.maydell@linaro.org
2025-03-07 10:08:21 +00:00
Peter Maydell
cde3247651 target/arm: Correct LDRD atomicity and fault behaviour
Our LDRD implementation is wrong in two respects:

 * if the address is 4-aligned and the load crosses a page boundary
   and the second load faults and the first load was to the
   base register (as in cases like "ldrd r2, r3, [r2]", then we
   must not update the base register before taking the fault
 * if the address is 8-aligned the access must be a 64-bit
   single-copy atomic access, not two 32-bit accesses

Rewrite the handling of the loads in LDRD to use a single
tcg_gen_qemu_ld_i64() and split the result into the destination
registers. This allows us to get the atomicity requirements
right, and also implicitly means that we won't update the
base register too early for the page-crossing case.

Note that because we no longer increment 'addr' by 4 in the course of
performing the LDRD we must change the adjustment value we pass to
op_addr_ri_post() and op_addr_rr_post(): it no longer needs to
subtract 4 to get the correct value to use if doing base register
writeback.

STRD has the same problem with not getting the atomicity right;
we will deal with that in the following commit.

Cc: qemu-stable@nongnu.org
Reported-by: Stu Grossman <stu.grossman@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250227142746.1698904-2-peter.maydell@linaro.org
2025-03-07 10:08:21 +00:00
Alex Bennée
47e2c5510f target/arm: Document the architectural names of our GTIMERs
As we are about to add more physical and virtual timers let's make it
clear what each timer does.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20250204125009.2281315-8-peter.maydell@linaro.org
[PMM: Add timer register name prefix to each comment]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-03-07 10:08:21 +00:00
Alex Bennée
f9f99d7ca5 target/arm: Implement SEL2 physical and virtual timers
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
actual implementation utilises the same logic as the rest of the
timers so all we need to do is:

  - define the timers and their access functions
  - conditionally add the correct system registers
  - create a new accessfn as the rules are subtly different to the
    existing secure timer

Fixes: e9152ee91c (target/arm: add ARMv8.4-SEL2 system registers)
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20250204125009.2281315-7-peter.maydell@linaro.org
Cc: qemu-stable@nongnu.org
Cc: Andrei Homescu <ahomescu@google.com>
Cc: Arve Hjønnevåg <arve@google.com>
Cc: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
[PMM: CP_ACCESS_TRAP_UNCATEGORIZED -> CP_ACCESS_UNDEFINED;
 offset logic now in gt_{indirect,direct}_access_timer_offset() ]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-03-07 10:08:21 +00:00
Peter Maydell
02c648a0a1 target/arm: Refactor handling of timer offset for direct register accesses
When reading or writing the timer registers, sometimes we need to
apply one of the timer offsets.  Specifically, this happens for
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0).  It
also applies for direct reads and writes of the CNT*_TVAL_EL*
registers that provide the 32-bit downcounting view of each timer.

We currently do this with duplicated code in gt_tval_read() and
gt_tval_write() and a special-case in gt_virt_cnt_read() and
gt_cnt_read().  Refactor this so that we handle it all in a single
function gt_direct_access_timer_offset(), to parallel how we handle
the offset for indirect accesses.

The call in the WFIT helper previously to gt_virt_cnt_offset() is
now to gt_direct_access_timer_offset(); this is the correct
behaviour, but it's not immediately obvious that it shouldn't be
considered an indirect access, so we add an explanatory comment.

This commit should make no behavioural changes.

(Cc to stable because the following bugfix commit will
depend on this one.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20250204125009.2281315-6-peter.maydell@linaro.org
2025-03-07 10:08:21 +00:00
Peter Maydell
4aecd4b442 target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
Currently we handle CNTV_TVAL_EL02 by calling gt_tval_read() for the
EL1 virt timer.  This is almost correct, but the underlying
CNTV_TVAL_EL0 register behaves slightly differently.  CNTV_TVAL_EL02
always applies the CNTVOFF_EL2 offset; CNTV_TVAL_EL0 doesn't do so if
we're at EL2 and HCR_EL2.E2H is 1.

We were getting this wrong, because we ended up in
gt_virt_cnt_offset() and did the E2H check.

Factor out the tval read/write calculation from the selection of the
offset, so that we can special case gt_virt_tval_read() and
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20250204125009.2281315-5-peter.maydell@linaro.org
2025-03-07 10:08:20 +00:00
Peter Maydell
bdd641541f target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
When we added Secure EL2 support, we missed that this needs an update
to the access code for the EL3 physical timer registers.  These are
supposed to UNDEF from Secure EL1 when Secure EL2 is enabled.

(Note for stable backporting: for backports to branches where
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
is CP_ACCESS_TRAP_UNCATEGORIZED.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
2025-03-07 10:08:20 +00:00
Peter Maydell
5709038aa8 target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
The CNTVOFF_EL2 offset register should only be applied for accessses
to CNTVCT_EL0 and for the EL1 virtual timer (CNTV_*).  We were
incorrectly applying it for the EL2 virtual timer (CNTHV_*).

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20250204125009.2281315-3-peter.maydell@linaro.org
2025-03-07 10:08:20 +00:00
Peter Maydell
db6c219283 target/arm: Apply correct timer offset when calculating deadlines
When we are calculating timer deadlines, the correct definition of
whether or not to apply an offset to the physical count is described
in the Arm ARM DDI4087 rev L.a section D12.2.4.1.  This is different
from when the offset should be applied for a direct read of the
counter sysreg.

We got this right for the EL1 physical timer and for the EL1 virtual
timer, but got all the rest wrong: they should be using a zero offset
always.

Factor the offset calculation out into a function that has a comment
documenting exactly which offset it is calculating and which gets the
HYP, SEC, and HYPVIRT cases right.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
2025-03-07 10:08:19 +00:00
Philippe Mathieu-Daudé
4b7d6557ef target/arm: Set disassemble_info::endian value in disas_set_info()
Have the CPUClass::disas_set_info() callback set the
disassemble_info::endian field.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250210212931.62401-4-philmd@linaro.org>
2025-03-06 15:46:18 +01:00
Philippe Mathieu-Daudé
1501743654 accel/tcg: Rename 'hw/core/tcg-cpu-ops.h' -> 'accel/tcg/cpu-ops.h'
TCGCPUOps structure makes more sense in the accelerator context
rather than hardware emulation. Move it under the accel/tcg/ scope.

Mechanical change doing:

 $  sed -i -e 's,hw/core/tcg-cpu-ops.h,accel/tcg/cpu-ops.h,g' \
   $(git grep -l hw/core/tcg-cpu-ops.h)

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250123234415.59850-11-philmd@linaro.org>
2025-03-06 15:46:17 +01:00
Joelle van Dyne
12c365315a target/arm/hvf: sign extend the data for a load operation when SSE=1
In the syndrome value for a data abort, bit 21 is SSE, which is
set to indicate that the abort was on a sign-extending load. When
we handle the data abort from the guest via address_space_read(),
we forgot to handle this and so would return the wrong value if
the guest did a sign-extending load to an MMIO region. Add the
sign-extension of the returned data.

Cc: qemu-stable@nongnu.org
Signed-off-by: Joelle van Dyne <j@getutm.app>
Message-id: 20250224184123.50780-1-j@getutm.app
[PMM: Drop an unnecessary check on 'len'; expand commit message]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-02-25 15:32:58 +00:00
Joelle van Dyne
fd207677a8 target/arm/hvf: Disable SME feature
macOS 15.2's Hypervisor.framework exposes SME feature on M4 Macs.
However, QEMU's hvf accelerator code does not properly support it
yet, causing QEMU to fail to start when hvf accelerator is used on
these systems, with the error message:

  qemu-aarch64-softmmu: cannot disable sme4224
  All SME vector lengths are disabled.
  With SME enabled, at least one vector length must be enabled.

Ideally we would have SME support on these hosts; however, until that
point, we must suppress the SME feature in the ID registers, so that
users can at least run non-SME guests.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2665
Signed-off-by: Joelle van Dyne <j@getutm.app>
Message-id: 20250224165735.36792-1-j@getutm.app
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: expanded commit message, comment]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-02-25 15:32:58 +00:00
Peter Maydell
cb8bb8472e target/arm: Rename vfp_helper.c to vfp_fpscr.c
The vfp_helper.c in the target/arm directory now only has
code for handling FPSCR/FPCR/FPSR in it, and no helper
functions. Rename it to vfp_fpscr.c; this helps keep it
distinct from tcg/vfp_helper.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250221190957.811948-5-peter.maydell@linaro.org
2025-02-25 15:32:58 +00:00
Peter Maydell
b9d3dc4553 target/arm: Move softfloat specific FPCR/FPSR handling to tcg/
The softfloat (i.e. TCG) specific handling for the FPCR
and FPSR is abstracted behind five functions:
 arm_set_default_fp_behaviours
 arm_set_ah_fp_behaviours
 vfp_get_fpsr_from_host
 vfp_clear_float_status_exc_flags
 vfp_set_fpsr_to_host

Currently we rely on the first two calling softfloat functions that
work even in a KVM-only compile because they're defined as inline in
the softfloat header file, and we provide stub versions of the last
three in arm/vfp_helper.c if CONFIG_TCG isn't defined.

Move the softfloat-specific versions of these functions to
tcg/vfp_helper.c, and provide the non-TCG stub versions in
tcg-stubs.c.

This lets us drop the softfloat header include and the last
set of CONFIG_TCG ifdefs from arm/vfp_helper.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250221190957.811948-4-peter.maydell@linaro.org
2025-02-25 15:32:58 +00:00
Peter Maydell
e34cfba5e8 target/arm: Move FPSCR get/set helpers to tcg/vfp_helper.c
Currently the helper_vfp_get_fpscr() and helper_vfp_set_fpscr()
functions do the actual work of updating the FPSCR, and we have
wrappers vfp_get_fpscr() and vfp_set_fpscr() which we use for calls
from other QEMU C code.

Flip these around so that it is vfp_get_fpscr() and vfp_set_fpscr()
which do the actual work, and helper_vfp_get_fpscr() and
helper_vfp_set_fpscr() which are the wrappers; this allows us to move
them to tcg/vfp_helper.c.

Since this is the last HELPER() we had in arm/vfp_helper.c, we can
drop the include of helper-proto.h.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250221190957.811948-3-peter.maydell@linaro.org
2025-02-25 15:32:58 +00:00
Peter Maydell
1deb15c88a target/arm: Move TCG-only VFP code into tcg/ subdir
Most of the target/arm/vfp_helper.c file is purely TCG helper code,
guarded by #ifdef CONFIG_TCG.  Move this into a new file in
target/arm/tcg/.

This leaves only the code relating to getting and setting the
FPCR/FPSR/FPSCR in the original file. (Some of this also is
TCG-only, but that needs more careful disentangling.)

Having two vfp_helper.c files might seem a bit confusing,
but once we've finished moving all the helper code out
of the old file we are going to rename it to vfp_fpscr.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250221190957.811948-2-peter.maydell@linaro.org
2025-02-25 15:32:58 +00:00
Stephen Longfield
b2ba5ff272 target/arm: Use uint32_t in t32_expandimm_imm()
In t32_expandimm_imm(), we take an 8 bit value XY and construct a
32-bit value which might be of the form XY, 00XY00XY, XY00XY00, or
XYXYXYXY.  We do this with multiplications, and we use an 'int' type.
For the cases where we're setting the high byte of the 32-bit value
to XY, this means that we do an integer multiplication that might
overflow, and rely on the -fwrapv semantics to keep this from being
undefined behaviour.

It's clearer to use an unsigned type here, because we're really
doing operations on the value considered as a set of bits. The
result is the same.

The return value from the function remains 'int', because this
is a decodetree !function function, and follows the API for those
functions.

Signed-off-by: Stephen Longfield <slongfield@google.com>
Signed-off-by: Roque Arcudia Hernandez <roqueh@google.com>
Message-id: 20250219165534.3387376-1-slongfield@google.com
[PMM: Rewrote the commit message]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2025-02-20 14:20:29 +00:00