Support disabling TCG on ARM
PATCH 4/13 target: arm: Move all interrupt and exception handlers into their own file
In reply to Samuel OrtizMost of them are TCG dependent so we want to be able to not build them in order to support TCG disablement with ARM.
--- target/arm/excp_helper.c | 550 +++++++++++++++++++++++++++++++++++++++ target/arm/helper.c | 531 ------------------------------------- target/arm/Makefile.objs | 2 +- 3 files changed, 551 insertions(+), 532 deletions(-) create mode 100644 target/arm/excp_helper.c
target/arm/excp_helper.c new file +550 -0
@@ -0,0 +1,550 @@ +/* +* Exception and interrupt helpers. +* +* This code is licensed under the GNU GPL v2 and later. +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "qemu/osdep.h" +#include "trace.h" +#include "cpu.h" +#include "internals.h" +#include "sysemu/sysemu.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "arm_ldst.h" +#include "exec/semihost.h" +#include "sysemu/kvm.h" + +static void take_aarch32_exception (CPUARMState *env,int new_mode, +uint32_t mask,uint32_t offset, +uint32_t newpc) +{ +/* Change the CPU state so as to actually take the exception. */ +switch_mode (env, new_mode); +/* +* For exceptions taken to AArch32 we must clear the SS bit in both +* PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now. +*/ + env->uncached_cpsr &= ~PSTATE_SS ; + env->spsr =cpsr_read (env); +/* Clear IT bits. */ + env->condexec_bits =0 ; +/* Switch to the new mode, and to the correct instruction set. */ + env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M ) | new_mode; +/* Set new mode endianness */ + env->uncached_cpsr &= ~CPSR_E ; +if (env->cp15.sctlr_el[arm_current_el (env)] &SCTLR_EE ) { + env->uncached_cpsr |=CPSR_E ; + } +/* J and IL must always be cleared for exception entry */ + env->uncached_cpsr &= ~(CPSR_IL |CPSR_J ); + env->daif |= mask; + +if (new_mode ==ARM_CPU_MODE_HYP ) { + env->thumb = (env->cp15.sctlr_el[2 ] &SCTLR_TE ) !=0 ; + env->elr_el[2 ] = env->regs[15 ]; + }else { +/* +* this is a lie, as there was no c1_sys on V4T/V5, but who cares +* and we should just guard the thumb mode on V4 +*/ +if (arm_feature (env,ARM_FEATURE_V4T )) { + env->thumb = + (A32_BANKED_CURRENT_REG_GET (env, sctlr) &SCTLR_TE ) !=0 ; + } + env->regs[14 ] = env->regs[15 ] + offset; + } + env->regs[15 ] = newpc; +} + +static void arm_cpu_do_interrupt_aarch32_hyp (CPUState *cs) +{ +/* +* Handle exception entry to Hyp mode; this is sufficiently +* different to entry to other AArch32 modes that we handle it +* separately here. +* +* The vector table entry used is always the 0x14 Hyp mode entry point, +* unless this is an UNDEF/HVC/abort taken from Hyp to Hyp. +* The offset applied to the preferred return address is always zero +* (see DDI0487C.a section G1.12.3). +* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values. +*/ +uint32_t addr, mask; +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; + +switch (cs->exception_index) { +case EXCP_UDEF : + addr =0x04 ; +break ; +case EXCP_SWI : + addr =0x14 ; +break ; +case EXCP_BKPT : +/* Fall through to prefetch abort. */ +case EXCP_PREFETCH_ABORT : + env->cp15.ifar_s = env->exception.vaddress; +qemu_log_mask (CPU_LOG_INT ,"...with HIFAR 0x%x\n" , + (uint32_t )env->exception.vaddress); + addr =0x0c ; +break ; +case EXCP_DATA_ABORT : + env->cp15.dfar_s = env->exception.vaddress; +qemu_log_mask (CPU_LOG_INT ,"...with HDFAR 0x%x\n" , + (uint32_t )env->exception.vaddress); + addr =0x10 ; +break ; +case EXCP_IRQ : + addr =0x18 ; +break ; +case EXCP_FIQ : + addr =0x1c ; +break ; +case EXCP_HVC : + addr =0x08 ; +break ; +case EXCP_HYP_TRAP : + addr =0x14 ; +default : +cpu_abort (cs,"Unhandled exception 0x%x\n" , cs->exception_index); + } + +if (cs->exception_index !=EXCP_IRQ && cs->exception_index !=EXCP_FIQ ) { +if (!arm_feature (env,ARM_FEATURE_V8 )) { +/* +* QEMU syndrome values are v8-style. v7 has the IL bit +* UNK/SBZP for "field not valid" cases, where v8 uses RES1. +* If this is a v7 CPU, squash the IL bit in those cases. +*/ +if (cs->exception_index ==EXCP_PREFETCH_ABORT || + (cs->exception_index ==EXCP_DATA_ABORT && + !(env->exception.syndrome &ARM_EL_ISV )) || +syn_get_ec (env->exception.syndrome) ==EC_UNCATEGORIZED ) { + env->exception.syndrome &= ~ARM_EL_IL ; + } + } + env->cp15.esr_el[2 ] = env->exception.syndrome; + } + +if (arm_current_el (env) !=2 && addr <0x14 ) { + addr =0x14 ; + } + + mask =0 ; +if (!(env->cp15.scr_el3 &SCR_EA )) { + mask |=CPSR_A ; + } +if (!(env->cp15.scr_el3 &SCR_IRQ )) { + mask |=CPSR_I ; + } +if (!(env->cp15.scr_el3 &SCR_FIQ )) { + mask |=CPSR_F ; + } + + addr += env->cp15.hvbar; + +take_aarch32_exception (env,ARM_CPU_MODE_HYP , mask,0 , addr); +} + +static void arm_cpu_do_interrupt_aarch32 (CPUState *cs) +{ +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; +uint32_t addr; +uint32_t mask; +int new_mode; +uint32_t offset; +uint32_t moe; + +/* If this is a debug exception we must update the DBGDSCR.MOE bits */ +switch (syn_get_ec (env->exception.syndrome)) { +case EC_BREAKPOINT : +case EC_BREAKPOINT_SAME_EL : + moe =1 ; +break ; +case EC_WATCHPOINT : +case EC_WATCHPOINT_SAME_EL : + moe =10 ; +break ; +case EC_AA32_BKPT : + moe =3 ; +break ; +case EC_VECTORCATCH : + moe =5 ; +break ; +default : + moe =0 ; +break ; + } + +if (moe) { + env->cp15.mdscr_el1 =deposit64 (env->cp15.mdscr_el1,2 ,4 , moe); + } + +if (env->exception.target_el ==2 ) { +arm_cpu_do_interrupt_aarch32_hyp (cs); +return ; + } + +/* TODO: Vectored interrupt controller. */ +switch (cs->exception_index) { +case EXCP_UDEF : + new_mode =ARM_CPU_MODE_UND ; + addr =0x04 ; + mask =CPSR_I ; +if (env->thumb) { + offset =2 ; + }else { + offset =4 ; + } +break ; +case EXCP_SWI : + new_mode =ARM_CPU_MODE_SVC ; + addr =0x08 ; + mask =CPSR_I ; +/* The PC already points to the next instruction. */ + offset =0 ; +break ; +case EXCP_BKPT : +/* Fall through to prefetch abort. */ +case EXCP_PREFETCH_ABORT : +A32_BANKED_CURRENT_REG_SET (env, ifsr, env->exception.fsr); +A32_BANKED_CURRENT_REG_SET (env, ifar, env->exception.vaddress); +qemu_log_mask (CPU_LOG_INT ,"...with IFSR 0x%x IFAR 0x%x\n" , + env->exception.fsr, (uint32_t )env->exception.vaddress); + new_mode =ARM_CPU_MODE_ABT ; + addr =0x0c ; + mask =CPSR_A |CPSR_I ; + offset =4 ; +break ; +case EXCP_DATA_ABORT : +A32_BANKED_CURRENT_REG_SET (env, dfsr, env->exception.fsr); +A32_BANKED_CURRENT_REG_SET (env, dfar, env->exception.vaddress); +qemu_log_mask (CPU_LOG_INT ,"...with DFSR 0x%x DFAR 0x%x\n" , + env->exception.fsr, + (uint32_t )env->exception.vaddress); + new_mode =ARM_CPU_MODE_ABT ; + addr =0x10 ; + mask =CPSR_A |CPSR_I ; + offset =8 ; +break ; +case EXCP_IRQ : + new_mode =ARM_CPU_MODE_IRQ ; + addr =0x18 ; +/* Disable IRQ and imprecise data aborts. */ + mask =CPSR_A |CPSR_I ; + offset =4 ; +if (env->cp15.scr_el3 &SCR_IRQ ) { +/* IRQ routed to monitor mode */ + new_mode =ARM_CPU_MODE_MON ; + mask |=CPSR_F ; + } +break ; +case EXCP_FIQ : + new_mode =ARM_CPU_MODE_FIQ ; + addr =0x1c ; +/* Disable FIQ, IRQ and imprecise data aborts. */ + mask =CPSR_A |CPSR_I |CPSR_F ; +if (env->cp15.scr_el3 &SCR_FIQ ) { +/* FIQ routed to monitor mode */ + new_mode =ARM_CPU_MODE_MON ; + } + offset =4 ; +break ; +case EXCP_VIRQ : + new_mode =ARM_CPU_MODE_IRQ ; + addr =0x18 ; +/* Disable IRQ and imprecise data aborts. */ + mask =CPSR_A |CPSR_I ; + offset =4 ; +break ; +case EXCP_VFIQ : + new_mode =ARM_CPU_MODE_FIQ ; + addr =0x1c ; +/* Disable FIQ, IRQ and imprecise data aborts. */ + mask =CPSR_A |CPSR_I |CPSR_F ; + offset =4 ; +break ; +case EXCP_SMC : + new_mode =ARM_CPU_MODE_MON ; + addr =0x08 ; + mask =CPSR_A |CPSR_I |CPSR_F ; + offset =0 ; +break ; +default : +cpu_abort (cs,"Unhandled exception 0x%x\n" , cs->exception_index); +return ;/* Never happens. Keep compiler happy. */ + } + +if (new_mode ==ARM_CPU_MODE_MON ) { + addr += env->cp15.mvbar; + }else if (A32_BANKED_CURRENT_REG_GET (env, sctlr) &SCTLR_V ) { +/* High vectors. When enabled, base address cannot be remapped. */ + addr +=0xffff0000 ; + }else { +/* ARM v7 architectures provide a vector base address register to remap +* the interrupt vector table. +* This register is only followed in non-monitor mode, and is banked. +* Note: only bits 31:5 are valid. +*/ + addr +=A32_BANKED_CURRENT_REG_GET (env, vbar); + } + +if ((env->uncached_cpsr &CPSR_M ) ==ARM_CPU_MODE_MON ) { + env->cp15.scr_el3 &= ~SCR_NS ; + } + +take_aarch32_exception (env, new_mode, mask, offset, addr); +} + +/* Handle exception entry to a target EL which is using AArch64 */ +static void arm_cpu_do_interrupt_aarch64 (CPUState *cs) +{ +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; +unsigned int new_el = env->exception.target_el; +target_ulong addr = env->cp15.vbar_el[new_el]; +unsigned int new_mode =aarch64_pstate_mode (new_el, true); +unsigned int cur_el =arm_current_el (env); + +/* +* Note that new_el can never be 0. If cur_el is 0, then +* el0_a64 is is_a64(), else el0_a64 is ignored. +*/ +aarch64_sve_change_el (env, cur_el, new_el,is_a64 (env)); + +if (cur_el < new_el) { +/* Entry vector offset depends on whether the implemented EL +* immediately lower than the target level is using AArch32 or AArch64 +*/ +bool is_aa64; + +switch (new_el) { +case 3 : + is_aa64 = (env->cp15.scr_el3 &SCR_RW ) !=0 ; +break ; +case 2 : + is_aa64 = (env->cp15.hcr_el2 &HCR_RW ) !=0 ; +break ; +case 1 : + is_aa64 =is_a64 (env); +break ; +default : +g_assert_not_reached (); + } + +if (is_aa64) { + addr +=0x400 ; + }else { + addr +=0x600 ; + } + }else if (pstate_read (env) &PSTATE_SP ) { + addr +=0x200 ; + } + +switch (cs->exception_index) { +case EXCP_PREFETCH_ABORT : +case EXCP_DATA_ABORT : + env->cp15.far_el[new_el] = env->exception.vaddress; +qemu_log_mask (CPU_LOG_INT ,"...with FAR 0x%" PRIx64"\n" , + env->cp15.far_el[new_el]); +/* fall through */ +case EXCP_BKPT : +case EXCP_UDEF : +case EXCP_SWI : +case EXCP_HVC : +case EXCP_HYP_TRAP : +case EXCP_SMC : +if (syn_get_ec (env->exception.syndrome) ==EC_ADVSIMDFPACCESSTRAP ) { +/* +* QEMU internal FP/SIMD syndromes from AArch32 include the +* TA and coproc fields which are only exposed if the exception +* is taken to AArch32 Hyp mode. Mask them out to get a valid +* AArch64 format syndrome. +*/ + env->exception.syndrome &= ~MAKE_64BIT_MASK (0 ,20 ); + } + env->cp15.esr_el[new_el] = env->exception.syndrome; +break ; +case EXCP_IRQ : +case EXCP_VIRQ : + addr +=0x80 ; +break ; +case EXCP_FIQ : +case EXCP_VFIQ : + addr +=0x100 ; +break ; +case EXCP_SEMIHOST : +qemu_log_mask (CPU_LOG_INT , +"...handling as semihosting call 0x%" PRIx64"\n" , + env->xregs[0 ]); + env->xregs[0 ] =do_arm_semihosting (env); +return ; +default : +cpu_abort (cs,"Unhandled exception 0x%x\n" , cs->exception_index); + } + +if (is_a64 (env)) { + env->banked_spsr[aarch64_banked_spsr_index (new_el)] =pstate_read (env); +aarch64_save_sp (env,arm_current_el (env)); + env->elr_el[new_el] = env->pc; + }else { + env->banked_spsr[aarch64_banked_spsr_index (new_el)] =cpsr_read (env); + env->elr_el[new_el] = env->regs[15 ]; + +aarch64_sync_32_to_64 (env); + + env->condexec_bits =0 ; + } +qemu_log_mask (CPU_LOG_INT ,"...with ELR 0x%" PRIx64"\n" , + env->elr_el[new_el]); + +pstate_write (env,PSTATE_DAIF | new_mode); + env->aarch64 =1 ; +aarch64_restore_sp (env, new_el); + + env->pc = addr; + +qemu_log_mask (CPU_LOG_INT ,"...to EL%d PC 0x%" PRIx64" PSTATE 0x%x\n" , + new_el, env->pc,pstate_read (env)); +} + +static inline bool check_for_semihosting (CPUState *cs) +{ +/* Check whether this exception is a semihosting call; if so +* then handle it and return true; otherwise return false. +*/ +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; + +if (is_a64 (env)) { +if (cs->exception_index ==EXCP_SEMIHOST ) { +/* This is always the 64-bit semihosting exception. +* The "is this usermode" and "is semihosting enabled" +* checks have been done at translate time. +*/ +qemu_log_mask (CPU_LOG_INT , +"...handling as semihosting call 0x%" PRIx64"\n" , + env->xregs[0 ]); + env->xregs[0 ] =do_arm_semihosting (env); +return true; + } +return false; + }else { +uint32_t imm; + +/* Only intercept calls from privileged modes, to provide some +* semblance of security. +*/ +if (cs->exception_index !=EXCP_SEMIHOST && + (!semihosting_enabled () || + ((env->uncached_cpsr &CPSR_M ) ==ARM_CPU_MODE_USR ))) { +return false; + } + +switch (cs->exception_index) { +case EXCP_SEMIHOST : +/* This is always a semihosting call; the "is this usermode" +* and "is semihosting enabled" checks have been done at +* translate time. +*/ +break ; +case EXCP_SWI : +/* Check for semihosting interrupt. */ +if (env->thumb) { + imm =arm_lduw_code (env, env->regs[15 ] -2 ,arm_sctlr_b (env)) + &0xff ; +if (imm ==0xab ) { +break ; + } + }else { + imm =arm_ldl_code (env, env->regs[15 ] -4 ,arm_sctlr_b (env)) + &0xffffff ; +if (imm ==0x123456 ) { +break ; + } + } +return false; +case EXCP_BKPT : +/* See if this is a semihosting syscall. */ +if (env->thumb) { + imm =arm_lduw_code (env, env->regs[15 ],arm_sctlr_b (env)) + &0xff ; +if (imm ==0xab ) { + env->regs[15 ] +=2 ; +break ; + } + } +return false; +default : +return false; + } + +qemu_log_mask (CPU_LOG_INT , +"...handling as semihosting call 0x%x\n" , + env->regs[0 ]); + env->regs[0 ] =do_arm_semihosting (env); +return true; + } +} + +/* Handle a CPU exception for A and R profile CPUs. +* Do any appropriate logging, handle PSCI calls, and then hand off +* to the AArch64-entry or AArch32-entry function depending on the +* target exception level's register width. +*/ +void arm_cpu_do_interrupt (CPUState *cs) +{ +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; +unsigned int new_el = env->exception.target_el; + +assert (!arm_feature (env,ARM_FEATURE_M )); + +arm_log_exception (cs->exception_index); +qemu_log_mask (CPU_LOG_INT ,"...from EL%d to EL%d\n" ,arm_current_el (env), + new_el); +if (qemu_loglevel_mask (CPU_LOG_INT ) + && !excp_is_internal (cs->exception_index)) { +qemu_log_mask (CPU_LOG_INT ,"...with ESR 0x%x/0x%" PRIx32"\n" , +syn_get_ec (env->exception.syndrome), + env->exception.syndrome); + } + +if (arm_is_psci_call (cpu, cs->exception_index)) { +arm_handle_psci_call (cpu); +qemu_log_mask (CPU_LOG_INT ,"...handled as PSCI call\n" ); +return ; + } + +/* Semihosting semantics depend on the register width of the +* code that caused the exception, not the target exception level, +* so must be handled here. +*/ +if (check_for_semihosting (cs)) { +return ; + } + +/* Hooks may change global state so BQL should be held, also the +* BQL needs to be held for any modification of +* cs->interrupt_request. +*/ +g_assert (qemu_mutex_iothread_locked ()); + +arm_call_pre_el_change_hook (cpu); + +assert (!excp_is_internal (cs->exception_index)); +if (arm_el_is_aa64 (env, new_el)) { +arm_cpu_do_interrupt_aarch64 (cs); + }else { +arm_cpu_do_interrupt_aarch32 (cs); + } + +arm_call_el_change_hook (cpu); + +if (!kvm_enabled ()) { + cs->interrupt_request |=CPU_INTERRUPT_EXITTB ; + } +}
target/arm/helper.c +0 -531
537 lines not on this page · raw message
target/arm/Makefile.objs +1 -1
@@ -6,7 +6,7 @@ obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o -obj-y += gdbstub.o m_helper.o +obj-y += gdbstub.o m_helper.o excp_helper.o obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o obj-y += crypto_helper.o obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
Signature · 1 line
2.19.1
Re: [Qemu-arm] [PATCH 02/13] target: arm: Remove unused headers
In reply to Samuel OrtizQuoted 14 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 3 --- 1 file changed, 3 deletions(-)target/arm/helper.c +0
-0
target/arm/helper.c line 15
Quoted 4 lines
target/arm/helper.c +0
-1@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h"
This is for muldiv64().
target/arm/helper.c line 18
Quoted 3 lines
target/arm/helper.c +0
-1#include "sysemu/arch_init.h" #include "sysemu/sysemu.h" -#include "qemu/bitops.h"
This is for extract32() and friends.
target/arm/helper.c line 21
Quoted 3 lines
target/arm/helper.c +0
-1#include "qemu/crc32c.h" #include "exec/exec-all.h" -#include "exec/cpu_ldst.h"
This is for cpu_stl_data().
target/arm/helper.c line 21
Quoted 3 lines
target/arm/helper.c +0
-0#include "arm_ldst.h" #include <zlib.h> /* For crc32 */ #include "exec/semihost.h"
thanks
-- PMM
Re: [Qemu-devel] [PATCH 01/13] target: arm: Add copyright boilerplate
In reply to Peter MaydellQuoted 10 lines · Peter Maydell
Quoted 9 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 7 +++++++ 1 file changed, 7 insertions(+)
Quoted 16 lines
target/arm/helper.c line 7
Quoted 12 lines
target/arm/helper.c +7
-0@@ -1,3 +1,10 @@ +/* +* ARM generic helpers. +* +* This code is licensed under the GNU GPL v2. +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ The human readable text says "v2", but the SPDX tag says "v2 or later". Which is right? (The top level LICENSE file says source files with no specific license are 2-or-later).
Sorry, the human failed, the machine is right.
Re: [Qemu-arm] [PATCH 01/13] target: arm: Add copyright boilerplate
In reply to Samuel OrtizQuoted 14 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 7 +++++++ 1 file changed, 7 insertions(+)target/arm/helper.c +0
-0
target/arm/helper.c line 7
Quoted 7 lines
target/arm/helper.c +7
-0@@ -1,3 +1,10 @@ +/* +* ARM generic helpers. +* +* This code is licensed under the GNU GPL v2. +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/
The human readable text says "v2", but the SPDX tag says "v2 or later". Which is right? (The top level LICENSE file says source files with no specific license are 2-or-later).
thanks
-- PMM
PATCH 13/13 target: arm: Do not build TCG objects when TCG is off
In reply to Samuel OrtizWe can now safely turn all TCG dependent build off when CONFIG_TCG is off. This allows building ARM binaries with --disable-tcg.
--- target/arm/Makefile.objs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
target/arm/Makefile.objs +8 -6
@@ -1,9 +1,10 @@ obj-y += arm-semi.o crypto_helper.o gdbstub.o helper.o cpu.o -obj-y += translate.o op_helper.o neon_helper.o -obj-y += iwmmxt_helper.o vec_helper.o m_helper.o -obj-y += excp_helper.o vfp_helper.o +obj-$(CONFIG_TCG) += translate.o op_helper.o neon_helper.o +obj-$(CONFIG_TCG) += iwmmxt_helper.o vec_helper.o m_helper.o +obj-$(CONFIG_TCG) += excp_helper.o vfp_helper.o -obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o arm-powerctl.o +obj-$(CONFIG_SOFTMMU) += machine.o arch_dump.o monitor.o arm-powerctl.o +obj-$(call land,$(CONFIG_TCG),$(CONFIG_SOFTMMU)) += psci.o obj-$(CONFIG_KVM) += kvm.o obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
@@ -17,5 +18,6 @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE) "GEN", $(TARGET_DIR)$@) target/arm/translate-sve.o: target/arm/decode-sve.inc.c -obj-$(TARGET_AARCH64) += translate-sve.o sve_helper.o -obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o +obj-$(call land,$(CONFIG_TCG),$(TARGET_AARCH64)) += translate-sve.o sve_helper.o +obj-$(call land,$(CONFIG_TCG),$(TARGET_AARCH64)) += translate-a64.o helper-a64.o +obj-$(TARGET_AARCH64) += cpu64.o gdbstub64.o
Signature · 1 line
2.19.1
PATCH 12/13 target: arm: Makefile cleanup
In reply to Samuel OrtizGroup objects with the same build dependencies together.
--- target/arm/Makefile.objs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
target/arm/Makefile.objs +7 -8
@@ -1,15 +1,13 @@ -obj-y += arm-semi.o -obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o +obj-y += arm-semi.o crypto_helper.o gdbstub.o helper.o cpu.o +obj-y += translate.o op_helper.o neon_helper.o +obj-y += iwmmxt_helper.o vec_helper.o m_helper.o +obj-y += excp_helper.o vfp_helper.o + +obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o arm-powerctl.o obj-$(CONFIG_KVM) += kvm.o obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o -obj-y += translate.o op_helper.o helper.o cpu.o -obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o -obj-y += gdbstub.o m_helper.o excp_helper.o vfp_helper.o -obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o -obj-y += crypto_helper.o -obj-$(CONFIG_SOFTMMU) += arm-powerctl.o DECODETREE = $(SRC_PATH)/scripts/decodetree.py
@@ -20,3 +18,4 @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE) target/arm/translate-sve.o: target/arm/decode-sve.inc.c obj-$(TARGET_AARCH64) += translate-sve.o sve_helper.o +obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
Signature · 1 line
2.19.1
PATCH 10/13 target: arm: Move watchpoints APIs to helper.c
In reply to Samuel OrtizHere again, those APIs are not TCG dependent and can move to the always built helper.c.
--- target/arm/internals.h | 6 ++ target/arm/helper.c | 204 +++++++++++++++++++++++++++++++++++++++++ target/arm/op_helper.c | 204 ----------------------------------------- 3 files changed, 210 insertions(+), 204 deletions(-)
target/arm/internals.h +6 -0
@@ -937,6 +937,12 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, int *prot, bool *is_subpage, ARMMMUFaultInfo *fi, uint32_t *mregion); +/* +* Returns true when the current CPU execution context matches +* the watchpoint or the breakpoint pointed at by n. +*/ +bool bp_wp_matches (ARMCPU *cpu,int n,bool is_wp); +#ifdef TARGET_AARCH64 void aarch64_cpu_dump_state (CPUState *cs,FILE *f,fprintf_function cpu_fprintf,int flags);
target/arm/helper.c +204 -0
207 lines not on this page · raw message
target/arm/op_helper.c +0 -204
216 lines not on this page · raw message
Signature · 1 line
2.19.1
PATCH 8/13 target: arm: Move all VFP helpers into their own file
In reply to Samuel OrtizSince softfloat is only relevant with TCG, we move all ARM VFP helpers into their own file (vfp_helper.c), in order to support TCG disablement on ARM.
--- target/arm/helper.c | 871 -------------------------------------- target/arm/vfp_helper.c | 893 +++++++++++++++++++++++++++++++++++++++ target/arm/Makefile.objs | 2 +- 3 files changed, 894 insertions(+), 872 deletions(-) create mode 100644 target/arm/vfp_helper.c
target/arm/helper.c +0 -871
@@ -9257,877 +9257,6 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val)HELPER (vfp_set_fpscr)(env, val); } -#define VFP_HELPER (name, p) HELPER(glue(glue(vfp_,name),p)) - -#define VFP_BINOP (name) \ -float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return float32_ ## name(a, b, fpst); \ -} \ -float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return float64_ ## name(a, b, fpst); \ -} -VFP_BINOP (add) -VFP_BINOP (sub ) -VFP_BINOP (mul) -VFP_BINOP (div) -VFP_BINOP (min) -VFP_BINOP (max) -VFP_BINOP (minnum) -VFP_BINOP (maxnum) -#undef VFP_BINOP - -float32VFP_HELPER (neg, s)(float32 a) -{ -return float32_chs (a); -} - -float64 VFP_HELPER (neg ,d )(float64 a) -{ -return float64_chs (a); -} - -float32 VFP_HELPER (abs ,s )(float32 a) -{ -return float32_abs (a); -} - -float64 VFP_HELPER (abs ,d )(float64 a) -{ -return float64_abs (a); -} - -float32 VFP_HELPER (sqrt ,s )(float32 a,CPUARMState *env) -{ -return float32_sqrt (a, &env->vfp.fp_status); -} - -float64 VFP_HELPER (sqrt ,d )(float64 a,CPUARMState *env) -{ -return float64_sqrt (a, &env->vfp.fp_status); -} - -/* XXX: check quiet/signaling case */ -#define DO_VFP_cmp (p, type) \ -void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ -{ \ - uint32_t flags; \ - switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \ - case 0: flags = 0x6; break; \ - case -1: flags = 0x8; break; \ - case 1: flags = 0x2; break; \ - default: case 2: flags = 0x3; break; \ - } \ - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ -} \ -void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ -{ \ - uint32_t flags; \ - switch(type ## _compare(a, b, &env->vfp.fp_status)) { \ - case 0: flags = 0x6; break; \ - case -1: flags = 0x8; break; \ - case 1: flags = 0x2; break; \ - default: case 2: flags = 0x3; break; \ - } \ - env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ - | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ -} -DO_VFP_cmp(s, float32) -DO_VFP_cmp(d, float64) -#undef DO_VFP_cmp - -/* Integer to float and float to integer conversions */ - -#define CONV_ITOF (name, ftype, fsz, sign) \ -ftype HELPER(name)(uint32_t x, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \ -} - -#define CONV_FTOI (name, ftype, fsz, sign, round) \ -sign##int32_t HELPER(name)(ftype x, void *fpstp) \ -{ \ - float_status *fpst = fpstp; \ - if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - return float##fsz##_to_##sign##int32##round(x, fpst); \ -} - -#define FLOAT_CONVS (name, p, ftype, fsz, sign) \ - CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \ - CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \ - CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero) - -FLOAT_CONVS(si, h, uint32_t, 16, ) -FLOAT_CONVS(si, s, float32, 32, ) -FLOAT_CONVS(si, d, float64, 64, ) -FLOAT_CONVS(ui, h, uint32_t, 16, u) -FLOAT_CONVS(ui, s, float32, 32, u) -FLOAT_CONVS(ui, d, float64, 64, u) - -#undef CONV_ITOF -#undef CONV_FTOI -#undef FLOAT_CONVS - -/* floating point conversion */ -float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env) -{ - return float32_to_float64(x, &env->vfp.fp_status); -} - -float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) -{ - return float64_to_float32(x, &env->vfp.fp_status); -} - -/* VFP3 fixed point conversion. */ -#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ - void *fpstp) \ -{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } - -#define VFP_CONV_FLOAT_FIX_ROUND (name, p, fsz, isz, itype,ROUND , suff) \ -uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \ - void *fpst) \ -{ \ - if (unlikely(float##fsz##_is_any_nan(x))) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, fpst); \ -} - -#define VFP_CONV_FIX (name, p, fsz, isz, itype) \ -VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ - float_round_to_zero, _round_to_zero) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ - get_float_rounding_mode(fpst), ) - -#define VFP_CONV_FIX_A64 (name, p, fsz, isz, itype) \ -VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ - get_float_rounding_mode(fpst), ) - -VFP_CONV_FIX(sh, d, 64, 64, int16) -VFP_CONV_FIX(sl, d, 64, 64, int32) -VFP_CONV_FIX_A64(sq, d, 64, 64, int64) -VFP_CONV_FIX(uh, d, 64, 64, uint16) -VFP_CONV_FIX(ul, d, 64, 64, uint32) -VFP_CONV_FIX_A64(uq, d, 64, 64, uint64) -VFP_CONV_FIX(sh, s, 32, 32, int16) -VFP_CONV_FIX(sl, s, 32, 32, int32) -VFP_CONV_FIX_A64(sq, s, 32, 64, int64) -VFP_CONV_FIX(uh, s, 32, 32, uint16) -VFP_CONV_FIX(ul, s, 32, 32, uint32) -VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) - -#undef VFP_CONV_FIX -#undef VFP_CONV_FIX_FLOAT -#undef VFP_CONV_FLOAT_FIX_ROUND -#undef VFP_CONV_FIX_A64 - -uint32_t HELPER (vfp_sltoh )(uint32_t x,uint32_t shift,void *fpst) -{ -return int32_to_float16_scalbn (x, -shift, fpst); -} - -uint32_t HELPER (vfp_ultoh )(uint32_t x,uint32_t shift,void *fpst) -{ -return uint32_to_float16_scalbn (x, -shift, fpst); -} - -uint32_t HELPER (vfp_sqtoh )(uint64_t x,uint32_t shift,void *fpst) -{ -return int64_to_float16_scalbn (x, -shift, fpst); -} - -uint32_t HELPER (vfp_uqtoh )(uint64_t x,uint32_t shift,void *fpst) -{ -return uint64_to_float16_scalbn (x, -shift, fpst); -} - -uint32_t HELPER (vfp_toshh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_int16_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -uint32_t HELPER (vfp_touhh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_uint16_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -uint32_t HELPER (vfp_toslh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_int32_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -uint32_t HELPER (vfp_toulh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_uint32_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -uint64_t HELPER (vfp_tosqh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_int64_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -uint64_t HELPER (vfp_touqh )(uint32_t x,uint32_t shift,void *fpst) -{ -if (unlikely (float16_is_any_nan (x))) { -float_raise (float_flag_invalid, fpst); -return 0 ; - } -return float16_to_uint64_scalbn (x,get_float_rounding_mode (fpst), - shift, fpst); -} - -/* Set the current fp rounding mode and return the old one. -* The argument is a softfloat float_round_ value. -*/ -uint32_t HELPER (set_rmode )(uint32_t rmode,void *fpstp) -{ -float_status *fp_status = fpstp; - -uint32_t prev_rmode =get_float_rounding_mode (fp_status); -set_float_rounding_mode (rmode, fp_status); - -return prev_rmode; -} - -/* Set the current fp rounding mode in the standard fp status and return -* the old one. This is for NEON instructions that need to change the -* rounding mode but wish to use the standard FPSCR values for everything -* else. Always set the rounding mode back to the correct value after -* modifying it. -* The argument is a softfloat float_round_ value. -*/ -uint32_t HELPER (set_neon_rmode )(uint32_t rmode,CPUARMState *env) -{ -float_status *fp_status = &env->vfp.standard_fp_status; - -uint32_t prev_rmode =get_float_rounding_mode (fp_status); -set_float_rounding_mode (rmode, fp_status); - -return prev_rmode; -} - -/* Half precision conversions. */ -float32 HELPER (vfp_fcvt_f16_to_f32 )(uint32_t a,void *fpstp,uint32_t ahp_mode) -{ -/* Squash FZ16 to 0 for the duration of conversion. In this case, -* it would affect flushing input denormals. -*/ -float_status *fpst = fpstp; -flag save =get_flush_inputs_to_zero (fpst); -set_flush_inputs_to_zero (false, fpst); -float32 r =float16_to_float32 (a, !ahp_mode, fpst); -set_flush_inputs_to_zero (save, fpst); -return r; -} - -uint32_t HELPER (vfp_fcvt_f32_to_f16 )(float32 a,void *fpstp,uint32_t ahp_mode) -{ -/* Squash FZ16 to 0 for the duration of conversion. In this case, -* it would affect flushing output denormals. -*/ -float_status *fpst = fpstp; -flag save =get_flush_to_zero (fpst); -set_flush_to_zero (false, fpst); -float16 r =float32_to_float16 (a, !ahp_mode, fpst); -set_flush_to_zero (save, fpst); -return r; -} - -float64 HELPER (vfp_fcvt_f16_to_f64 )(uint32_t a,void *fpstp,uint32_t ahp_mode) -{ -/* Squash FZ16 to 0 for the duration of conversion. In this case, -* it would affect flushing input denormals. -*/ -float_status *fpst = fpstp; -flag save =get_flush_inputs_to_zero (fpst); -set_flush_inputs_to_zero (false, fpst); -float64 r =float16_to_float64 (a, !ahp_mode, fpst); -set_flush_inputs_to_zero (save, fpst); -return r; -} - -uint32_t HELPER (vfp_fcvt_f64_to_f16 )(float64 a,void *fpstp,uint32_t ahp_mode) -{ -/* Squash FZ16 to 0 for the duration of conversion. In this case, -* it would affect flushing output denormals. -*/ -float_status *fpst = fpstp; -flag save =get_flush_to_zero (fpst); -set_flush_to_zero (false, fpst); -float16 r =float64_to_float16 (a, !ahp_mode, fpst); -set_flush_to_zero (save, fpst); -return r; -} - -#define float32_two make_float32(0x40000000) -#define float32_three make_float32(0x40400000) -#define float32_one_point_five make_float32(0x3fc00000) - -float32 HELPER (recps_f32 )(float32 a,float32 b,CPUARMState *env) -{ -float_status *s = &env->vfp.standard_fp_status; -if ((float32_is_infinity (a) &&float32_is_zero_or_denormal (b)) || - (float32_is_infinity (b) &&float32_is_zero_or_denormal (a))) { -if (!(float32_is_zero (a) ||float32_is_zero (b))) { -float_raise (float_flag_input_denormal, s); - } -return float32_two; - } -return float32_sub (float32_two,float32_mul (a, b, s), s); -} - -float32 HELPER (rsqrts_f32 )(float32 a,float32 b,CPUARMState *env) -{ -float_status *s = &env->vfp.standard_fp_status; -float32 product; -if ((float32_is_infinity (a) &&float32_is_zero_or_denormal (b)) || - (float32_is_infinity (b) &&float32_is_zero_or_denormal (a))) { -if (!(float32_is_zero (a) ||float32_is_zero (b))) { -float_raise (float_flag_input_denormal, s); - } -return float32_one_point_five; - } - product =float32_mul (a, b, s); -return float32_div (float32_sub (float32_three, product, s), float32_two, s); -} - -/* NEON helpers. */ - -/* Constants 256 and 512 are used in some helpers; we avoid relying on -* int->float conversions at run-time. */ -#define float64_256 make_float64(0x4070000000000000LL) -#define float64_512 make_float64(0x4080000000000000LL) -#define float16_maxnorm make_float16(0x7bff) -#define float32_maxnorm make_float32(0x7f7fffff) -#define float64_maxnorm make_float64(0x7fefffffffffffffLL) - -/* Reciprocal functions -* -* The algorithm that must be used to calculate the estimate -* is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate -*/ - -/* See RecipEstimate() -* -* input is a 9 bit fixed point number -* input range 256 .. 511 for a number from 0.5 <= x < 1.0. -* result range 256 .. 511 for a number from 1.0 to 511/256. -*/ - -static int recip_estimate (int input) -{ -int a, b, r; -assert (256 <= input && input <512 ); - a = (input *2 ) +1 ; - b = (1 <<19 ) / a; - r = (b +1 ) >>1 ; -assert (256 <= r && r <512 ); -return r; -} - -/* -* Common wrapper to call recip_estimate -* -* The parameters are exponent and 64 bit fraction (without implicit -* bit) where the binary point is nominally at bit 52. Returns a -* float64 which can then be rounded to the appropriate size by the -* callee. -*/ - -static uint64_t call_recip_estimate (int *exp,int exp_off,uint64_t frac) -{ -uint32_t scaled, estimate; -uint64_t result_frac; -int result_exp; - -/* Handle sub-normals */ -if (*exp ==0 ) { -if (extract64 (frac,51 ,1 ) ==0 ) { - *exp =-1 ; - frac <<=2 ; - }else { - frac <<=1 ; - } - } - -/* scaled = UInt('1':fraction<51:44>) */ - scaled =deposit32 (1 <<8 ,0 ,8 ,extract64 (frac,44 ,8 )); - estimate =recip_estimate (scaled); - - result_exp = exp_off - *exp; - result_frac =deposit64 (0 ,44 ,8 , estimate); -if (result_exp ==0 ) { - result_frac =deposit64 (result_frac >>1 ,51 ,1 ,1 ); - }else if (result_exp ==-1 ) { - result_frac =deposit64 (result_frac >>2 ,50 ,2 ,1 ); - result_exp =0 ; - } - - *exp = result_exp; - -return result_frac; -} - -static bool round_to_inf (float_status *fpst,bool sign_bit) -{ -switch (fpst->float_rounding_mode) { -case float_round_nearest_even:/* Round to Nearest */ -return true; -case float_round_up:/* Round to +Inf */ -return !sign_bit; -case float_round_down:/* Round to -Inf */ -return sign_bit; -case float_round_to_zero:/* Round to Zero */ -return false; - } - -g_assert_not_reached (); -} - -uint32_t HELPER (recpe_f16 )(uint32_t input,void *fpstp) -{ -float_status *fpst = fpstp; -float16 f16 =float16_squash_input_denormal (input, fpst); -uint32_t f16_val =float16_val (f16); -uint32_t f16_sign =float16_is_neg (f16); -int f16_exp =extract32 (f16_val,10 ,5 ); -uint32_t f16_frac =extract32 (f16_val,0 ,10 ); -uint64_t f64_frac; - -if (float16_is_any_nan (f16)) { -float16 nan = f16; -if (float16_is_signaling_nan (f16, fpst)) { -float_raise (float_flag_invalid, fpst); - nan =float16_silence_nan (f16, fpst); - } -if (fpst->default_nan_mode) { - nan =float16_default_nan (fpst); - } -return nan; - }else if (float16_is_infinity (f16)) { -return float16_set_sign (float16_zero,float16_is_neg (f16)); - }else if (float16_is_zero (f16)) { -float_raise (float_flag_divbyzero, fpst); -return float16_set_sign (float16_infinity,float16_is_neg (f16)); - }else if (float16_abs (f16) < (1 <<8 )) { -/* Abs(value) < 2.0^-16 */ -float_raise (float_flag_overflow | float_flag_inexact, fpst); -if (round_to_inf (fpst, f16_sign)) { -return float16_set_sign (float16_infinity, f16_sign); - }else { -return float16_set_sign (float16_maxnorm, f16_sign); - } - }else if (f16_exp >=29 && fpst->flush_to_zero) { -float_raise (float_flag_underflow, fpst); -return float16_set_sign (float16_zero,float16_is_neg (f16)); - } - - f64_frac =call_recip_estimate (&f16_exp,29 , - ((uint64_t ) f16_frac) << (52 -10 )); - -/* result = sign : result_exp<4:0> : fraction<51:42> */ - f16_val =deposit32 (0 ,15 ,1 , f16_sign); - f16_val =deposit32 (f16_val,10 ,5 , f16_exp); - f16_val =deposit32 (f16_val,0 ,10 ,extract64 (f64_frac,52 -10 ,10 )); -return make_float16 (f16_val); -} - -float32 HELPER (recpe_f32 )(float32 input,void *fpstp) -{ -float_status *fpst = fpstp; -float32 f32 =float32_squash_input_denormal (input, fpst); -uint32_t f32_val =float32_val (f32); -bool f32_sign =float32_is_neg (f32); -int f32_exp =extract32 (f32_val,23 ,8 ); -uint32_t f32_frac =extract32 (f32_val,0 ,23 ); -uint64_t f64_frac; - -if (float32_is_any_nan (f32)) { -float32 nan = f32; -if (float32_is_signaling_nan (f32, fpst)) { -float_raise (float_flag_invalid, fpst); - nan =float32_silence_nan (f32, fpst); - } -if (fpst->default_nan_mode) { - nan =float32_default_nan (fpst); - } -return nan; - }else if (float32_is_infinity (f32)) { -return float32_set_sign (float32_zero,float32_is_neg (f32)); - }else if (float32_is_zero (f32)) { -float_raise (float_flag_divbyzero, fpst); -return float32_set_sign (float32_infinity,float32_is_neg (f32)); - }else if (float32_abs (f32) < (1ULL <<21 )) { -/* Abs(value) < 2.0^-128 */ -float_raise (float_flag_overflow | float_flag_inexact, fpst); -if (round_to_inf (fpst, f32_sign)) { -return float32_set_sign (float32_infinity, f32_sign); - }else { -return float32_set_sign (float32_maxnorm, f32_sign); - } - }else if (f32_exp >=253 && fpst->flush_to_zero) { -float_raise (float_flag_underflow, fpst); -return float32_set_sign (float32_zero,float32_is_neg (f32)); - } - - f64_frac =call_recip_estimate (&f32_exp,253 , - ((uint64_t ) f32_frac) << (52 -23 )); - -/* result = sign : result_exp<7:0> : fraction<51:29> */ - f32_val =deposit32 (0 ,31 ,1 , f32_sign); - f32_val =deposit32 (f32_val,23 ,8 , f32_exp); - f32_val =deposit32 (f32_val,0 ,23 ,extract64 (f64_frac,52 -23 ,23 )); -return make_float32 (f32_val); -} - -float64 HELPER (recpe_f64 )(float64 input,void *fpstp) -{ -float_status *fpst = fpstp; -float64 f64 =float64_squash_input_denormal (input, fpst); -uint64_t f64_val =float64_val (f64); -bool f64_sign =float64_is_neg (f64); -int f64_exp =extract64 (f64_val,52 ,11 ); -uint64_t f64_frac =extract64 (f64_val,0 ,52 ); - -/* Deal with any special cases */ -if (float64_is_any_nan (f64)) { -float64 nan = f64; -if (float64_is_signaling_nan (f64, fpst)) { -float_raise (float_flag_invalid, fpst); - nan =float64_silence_nan (f64, fpst); - } -if (fpst->default_nan_mode) { - nan =float64_default_nan (fpst); - } -return nan; - }else if (float64_is_infinity (f64)) { -return float64_set_sign (float64_zero,float64_is_neg (f64)); - }else if (float64_is_zero (f64)) { -float_raise (float_flag_divbyzero, fpst); -return float64_set_sign (float64_infinity,float64_is_neg (f64)); - }else if ((f64_val & ~(1ULL <<63 )) < (1ULL <<50 )) { -/* Abs(value) < 2.0^-1024 */ -float_raise (float_flag_overflow | float_flag_inexact, fpst); -if (round_to_inf (fpst, f64_sign)) { -return float64_set_sign (float64_infinity, f64_sign); - }else { -return float64_set_sign (float64_maxnorm, f64_sign); - } - }else if (f64_exp >=2045 && fpst->flush_to_zero) { -float_raise (float_flag_underflow, fpst); -return float64_set_sign (float64_zero,float64_is_neg (f64)); - } - - f64_frac =call_recip_estimate (&f64_exp,2045 , f64_frac); - -/* result = sign : result_exp<10:0> : fraction<51:0>; */ - f64_val =deposit64 (0 ,63 ,1 , f64_sign); - f64_val =deposit64 (f64_val,52 ,11 , f64_exp); - f64_val =deposit64 (f64_val,0 ,52 , f64_frac); -return make_float64 (f64_val); -} - -/* The algorithm that must be used to calculate the estimate -* is specified by the ARM ARM. -*/ - -static int do_recip_sqrt_estimate (int a) -{ -int b, estimate; - -assert (128 <= a && a <512 ); -if (a <256 ) { - a = a *2 +1 ; - }else { - a = (a >>1 ) <<1 ; - a = (a +1 ) *2 ; - } - b =512 ; -while (a * (b +1 ) * (b +1 ) < (1 <<28 )) { - b +=1 ; - } - estimate = (b +1 ) /2 ; -assert (256 <= estimate && estimate <512 ); - -return estimate; -} - - -static uint64_t recip_sqrt_estimate (int *exp ,int exp_off,uint64_t frac) -{ -int estimate; -uint32_t scaled; - -if (*exp ==0 ) { -while (extract64 (frac,51 ,1 ) ==0 ) { - frac = frac <<1 ; - *exp -=1 ; - } - frac =extract64 (frac,0 ,51 ) <<1 ; - } - -if (*exp &1 ) { -/* scaled = UInt('01':fraction<51:45>) */ - scaled =deposit32 (1 <<7 ,0 ,7 ,extract64 (frac,45 ,7 )); - }else { -/* scaled = UInt('1':fraction<51:44>) */ - scaled =deposit32 (1 <<8 ,0 ,8 ,extract64 (frac,44 ,8 )); - } - estimate =do_recip_sqrt_estimate (scaled); - - *exp = (exp_off - *exp) /2 ; -return extract64 (estimate,0 ,8 ) <<44 ; -} - -uint32_t HELPER (rsqrte_f16 )(uint32_t input,void *fpstp) -{ -float_status *s = fpstp; -float16 f16 =float16_squash_input_denormal (input, s); -uint16_t val =float16_val (f16); -bool f16_sign =float16_is_neg (f16); -int f16_exp =extract32 (val,10 ,5 ); -uint16_t f16_frac =extract32 (val,0 ,10 ); -uint64_t f64_frac; - -if (float16_is_any_nan (f16)) { -float16 nan = f16; -if (float16_is_signaling_nan (f16, s)) { -float_raise (float_flag_invalid, s); - nan =float16_silence_nan (f16, s); - } -if (s->default_nan_mode) { - nan =float16_default_nan (s); - } -return nan; - }else if (float16_is_zero (f16)) { -float_raise (float_flag_divbyzero, s); -return float16_set_sign (float16_infinity, f16_sign); - }else if (f16_sign) { -float_raise (float_flag_invalid, s); -return float16_default_nan (s); - }else if (float16_is_infinity (f16)) { -return float16_zero; - } - -/* Scale and normalize to a double-precision value between 0.25 and 1.0, -* preserving the parity of the exponent. */ - - f64_frac = ((uint64_t ) f16_frac) << (52 -10 ); - - f64_frac =recip_sqrt_estimate (&f16_exp,44 , f64_frac); - -/* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(2) */ - val =deposit32 (0 ,15 ,1 , f16_sign); - val =deposit32 (val,10 ,5 , f16_exp); - val =deposit32 (val,2 ,8 ,extract64 (f64_frac,52 -8 ,8 )); -return make_float16 (val); -} - -float32 HELPER (rsqrte_f32 )(float32 input,void *fpstp) -{ -float_status *s = fpstp; -float32 f32 =float32_squash_input_denormal (input, s); -uint32_t val =float32_val (f32); -uint32_t f32_sign =float32_is_neg (f32); -int f32_exp =extract32 (val,23 ,8 ); -uint32_t f32_frac =extract32 (val,0 ,23 ); -uint64_t f64_frac; - -if (float32_is_any_nan (f32)) { -float32 nan = f32; -if (float32_is_signaling_nan (f32, s)) { -float_raise (float_flag_invalid, s); - nan =float32_silence_nan (f32, s); - } -if (s->default_nan_mode) { - nan =float32_default_nan (s); - } -return nan; - }else if (float32_is_zero (f32)) { -float_raise (float_flag_divbyzero, s); -return float32_set_sign (float32_infinity,float32_is_neg (f32)); - }else if (float32_is_neg (f32)) { -float_raise (float_flag_invalid, s); -return float32_default_nan (s); - }else if (float32_is_infinity (f32)) { -return float32_zero; - } - -/* Scale and normalize to a double-precision value between 0.25 and 1.0, -* preserving the parity of the exponent. */ - - f64_frac = ((uint64_t ) f32_frac) <<29 ; - - f64_frac =recip_sqrt_estimate (&f32_exp,380 , f64_frac); - -/* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(15) */ - val =deposit32 (0 ,31 ,1 , f32_sign); - val =deposit32 (val,23 ,8 , f32_exp); - val =deposit32 (val,15 ,8 ,extract64 (f64_frac,52 -8 ,8 )); -return make_float32 (val); -} - -float64 HELPER (rsqrte_f64 )(float64 input,void *fpstp) -{ -float_status *s = fpstp; -float64 f64 =float64_squash_input_denormal (input, s); -uint64_t val =float64_val (f64); -bool f64_sign =float64_is_neg (f64); -int f64_exp =extract64 (val,52 ,11 ); -uint64_t f64_frac =extract64 (val,0 ,52 ); - -if (float64_is_any_nan (f64)) { -float64 nan = f64; -if (float64_is_signaling_nan (f64, s)) { -float_raise (float_flag_invalid, s); - nan =float64_silence_nan (f64, s); - } -if (s->default_nan_mode) { - nan =float64_default_nan (s); - } -return nan; - }else if (float64_is_zero (f64)) { -float_raise (float_flag_divbyzero, s); -return float64_set_sign (float64_infinity,float64_is_neg (f64)); - }else if (float64_is_neg (f64)) { -float_raise (float_flag_invalid, s); -return float64_default_nan (s); - }else if (float64_is_infinity (f64)) { -return float64_zero; - } - - f64_frac =recip_sqrt_estimate (&f64_exp,3068 , f64_frac); - -/* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(44) */ - val =deposit64 (0 ,61 ,1 , f64_sign); - val =deposit64 (val,52 ,11 , f64_exp); - val =deposit64 (val,44 ,8 ,extract64 (f64_frac,52 -8 ,8 )); -return make_float64 (val); -} - -uint32_t HELPER (recpe_u32 )(uint32_t a,void *fpstp) -{ -/* float_status *s = fpstp; */ -int input, estimate; - -if ((a &0x80000000 ) ==0 ) { -return 0xffffffff ; - } - - input =extract32 (a,23 ,9 ); - estimate =recip_estimate (input); - -return deposit32 (0 , (32 -9 ),9 , estimate); -} - -uint32_t HELPER (rsqrte_u32 )(uint32_t a,void *fpstp) -{ -int estimate; - -if ((a &0xc0000000 ) ==0 ) { -return 0xffffffff ; - } - - estimate =do_recip_sqrt_estimate (extract32 (a,23 ,9 )); - -return deposit32 (0 ,23 ,9 , estimate); -} - -/* VFPv4 fused multiply-accumulate */ -float32 VFP_HELPER (muladd ,s )(float32 a,float32 b,float32 c,void *fpstp) -{ -float_status *fpst = fpstp; -return float32_muladd (a, b, c,0 , fpst); -} - -float64 VFP_HELPER (muladd ,d )(float64 a,float64 b,float64 c,void *fpstp) -{ -float_status *fpst = fpstp; -return float64_muladd (a, b, c,0 , fpst); -} - -/* ARMv8 round to integral */ -float32 HELPER (rints_exact )(float32 x,void *fp_status) -{ -return float32_round_to_int (x, fp_status); -} - -float64 HELPER (rintd_exact )(float64 x,void *fp_status) -{ -return float64_round_to_int (x, fp_status); -} - -float32 HELPER (rints )(float32 x,void *fp_status) -{ -int old_flags =get_float_exception_flags (fp_status), new_flags; -float32 ret; - - ret =float32_round_to_int (x, fp_status); - -/* Suppress any inexact exceptions the conversion produced */ -if (!(old_flags & float_flag_inexact)) { - new_flags =get_float_exception_flags (fp_status); -set_float_exception_flags (new_flags & ~float_flag_inexact, fp_status); - } - -return ret; -} - -float64 HELPER (rintd )(float64 x,void *fp_status) -{ -int old_flags =get_float_exception_flags (fp_status), new_flags; -float64 ret; - - ret =float64_round_to_int (x, fp_status); - - new_flags =get_float_exception_flags (fp_status); - -/* Suppress any inexact exceptions the conversion produced */ -if (!(old_flags & float_flag_inexact)) { - new_flags =get_float_exception_flags (fp_status); -set_float_exception_flags (new_flags & ~float_flag_inexact, fp_status); - } - -return ret; -}/* Convert ARM rounding mode to softfloat */ int arm_rmode_to_sf (int rmode)
target/arm/vfp_helper.c new file +893 -0
893 lines not on this page · raw message
target/arm/Makefile.objs +1 -1
@@ -6,7 +6,7 @@ obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o -obj-y += gdbstub.o m_helper.o excp_helper.o +obj-y += gdbstub.o m_helper.o excp_helper.o vfp_helper.o obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o obj-y += crypto_helper.o obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
Signature · 1 line
2.19.1
PATCH 11/13 target: arm: Define TCG dependent functions when TCG is enabled
In reply to Samuel Ortizdo_interrupt, do_unaligned_access, do_transaction_failed and debug_excp are only relevant in the TCG context, so we should not define them when TCG is disabled.
--- target/arm/cpu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
target/arm/cpu.c +6 -2
@@ -1444,7 +1444,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) {CPUClass *cc =CPU_CLASS (oc); -#ifndef CONFIG_USER_ONLY +#if !defined(CONFIG_USER_ONLY ) && defined(CONFIG_TCG ) cc->do_interrupt = arm_v7m_cpu_do_interrupt;#endif
@@ -2061,9 +2061,14 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)#ifdef CONFIG_USER_ONLY cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;#else + +#ifdef CONFIG_TCG cc->do_interrupt = arm_cpu_do_interrupt; cc->do_unaligned_access = arm_cpu_do_unaligned_access; cc->do_transaction_failed = arm_cpu_do_transaction_failed; + cc->debug_excp_handler = arm_debug_excp_handler; +#endif + cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug; cc->asidx_from_attrs = arm_asidx_from_attrs; cc->vmsd = &vmstate_arm_cpu;
@@ -2076,7 +2081,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_arch_name = arm_gdb_arch_name; cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml; cc->gdb_stop_before_watchpoint = true; - cc->debug_excp_handler = arm_debug_excp_handler; cc->debug_check_watchpoint = arm_debug_check_watchpoint;#if !defined(CONFIG_USER_ONLY ) cc->adjust_watchpoint_address = arm_adjust_watchpoint_address;
Signature · 1 line
2.19.1
PATCH 9/13 target: arm: Move CPU state dumping routines to helper.c
In reply to Samuel OrtizThey're not TCG specific and should be living the generic helper file instead.
--- target/arm/internals.h | 12 +++ target/arm/translate.h | 7 -- target/arm/helper.c | 214 +++++++++++++++++++++++++++++++++++++ target/arm/translate-a64.c | 125 ---------------------- target/arm/translate.c | 87 --------------- 5 files changed, 226 insertions(+), 219 deletions(-)
target/arm/internals.h +12 -0
@@ -937,4 +937,16 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, int *prot, bool *is_subpage, ARMMMUFaultInfo *fi, uint32_t *mregion); +#ifdef TARGET_AARCH64 +void aarch64_cpu_dump_state (CPUState *cs,FILE *f, +fprintf_function cpu_fprintf,int flags); + +#else +static inline void aarch64_cpu_dump_state (CPUState *cs,FILE *f, +fprintf_function cpu_fprintf, +int flags) +{ +} +#endif +#endif
target/arm/translate.h +0 -7
@@ -155,8 +155,6 @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)#ifdef TARGET_AARCH64 void a64_translate_init (void );void gen_a64_set_pc_im (uint64_t val); -void aarch64_cpu_dump_state (CPUState *cs,FILE *f, -fprintf_function cpu_fprintf,int flags);extern const TranslatorOps aarch64_translator_ops;#else static inline void a64_translate_init (void )
@@ -167,11 +165,6 @@ static inline void gen_a64_set_pc_im(uint64_t val) { } -static inline void aarch64_cpu_dump_state (CPUState *cs,FILE *f, -fprintf_function cpu_fprintf, -int flags) -{ -}#endif void arm_test_cc (DisasCompare *cmp,int cc);
target/arm/helper.c +214 -0
218 lines not on this page · raw message
target/arm/translate-a64.c +0 -125
131 lines not on this page · raw message
target/arm/translate.c +0 -87
93 lines not on this page · raw message
Signature · 1 line
2.19.1
PATCH 3/13 target: arm: Move all v7m helpers into their own file
In reply to Samuel OrtizIn preparation for supporting TCG disablement on ARM, we move all TCG related v7m helpers and APIs into their own file (m_helper.c for all v*-m helpers).arm_v7m_cpu_do_interrupt pulls a large number of static functions out of helper.c into m_helper.c because it is TCG dependent.
--- target/arm/internals.h | 37 + target/arm/helper.c | 2209 +++----------------------------------- target/arm/m_helper.c | 1892 ++++++++++++++++++++++++++++++++ target/arm/Makefile.objs | 2 +- 4 files changed, 2086 insertions(+), 2054 deletions(-) create mode 100644 target/arm/m_helper.c
target/arm/internals.h +37 -0
@@ -905,4 +905,41 @@ void arm_cpu_update_virq(ARMCPU *cpu);*/ void arm_cpu_update_vfiq (ARMCPU *cpu); +void arm_log_exception (int idx); + +/* Cacheability and shareability attributes for a memory access */ +typedef struct ARMCacheAttrs { +unsigned int attrs:8 ;/* as in the MAIR register encoding */ +unsigned int shareability:2 ;/* as in the SH field of the VMSAv8-64 PTEs */ +}ARMCacheAttrs ; + +bool get_phys_addr (CPUARMState *env,target_ulong address, +MMUAccessType access_type,ARMMMUIdx mmu_idx, +hwaddr *phys_ptr,MemTxAttrs *attrs,int *prot, +target_ulong *page_size, +ARMMMUFaultInfo *fi,ARMCacheAttrs *cacheattrs); + +/* Security attributes for an address, as returned by v8m_security_lookup. */ +typedef struct V8M_SAttributes { +bool subpage;/* true if these attrs don't cover the whole TARGET_PAGE */ +bool ns; +bool nsc; +uint8_t sregion; +bool srvalid; +uint8_t iregion; +bool irvalid; +}V8M_SAttributes ; + +void v8m_security_lookup (CPUARMState *env,uint32_t address, +MMUAccessType access_type,ARMMMUIdx mmu_idx, +V8M_SAttributes *sattrs); + +void switch_mode (CPUARMState *,int ); + +bool pmsav8_mpu_lookup (CPUARMState *env,uint32_t address, +MMUAccessType access_type,ARMMMUIdx mmu_idx, +hwaddr *phys_ptr,MemTxAttrs *txattrs, +int *prot,bool *is_subpage, +ARMMMUFaultInfo *fi,uint32_t *mregion); +#endif
target/arm/helper.c +156 -2053
2,316 lines not on this page · raw message
target/arm/m_helper.c new file +1892 -0
643 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.19.1
Part of the diff is not shown here. View the raw message.
PATCH 2/13 target: arm: Remove unused headers
In reply to Samuel OrtizFrom: Philippe Mathieu-Daudé <[email protected]>
--- target/arm/helper.c | 3 --- 1 file changed, 3 deletions(-)
target/arm/helper.c +0 -3
@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" #include "sysemu/arch_init.h" #include "sysemu/sysemu.h" -#include "qemu/bitops.h" #include "qemu/crc32c.h" #include "exec/exec-all.h" -#include "exec/cpu_ldst.h" #include "arm_ldst.h" #include <zlib.h> /* For crc32 */ #include "exec/semihost.h"
Signature · 1 line
2.19.1
PATCH 5/13 target: arm: Move the DC ZVA helper into op_helper
In reply to Samuel Ortiz--- target/arm/helper.c | 84 ------------------------------------------ target/arm/op_helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 84 deletions(-)
target/arm/helper.c +0 -84
@@ -8917,90 +8917,6 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,#endif -void HELPER (dc_zva )(CPUARMState *env,uint64_t vaddr_in) -{ -/* Implement DC ZVA, which zeroes a fixed-length block of memory. -* Note that we do not implement the (architecturally mandated) -* alignment fault for attempts to use this on Device memory -* (which matches the usual QEMU behaviour of not implementing either -* alignment faults or any memory attribute handling). -*/ - -ARMCPU *cpu =arm_env_get_cpu (env); -uint64_t blocklen =4 << cpu->dcz_blocksize; -uint64_t vaddr = vaddr_in & ~(blocklen -1 ); - -#ifndef CONFIG_USER_ONLY - { -/* Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than -* the block size so we might have to do more than one TLB lookup. -* We know that in fact for any v8 CPU the page size is at least 4K -* and the block size must be 2K or less, but TARGET_PAGE_SIZE is only -* 1K as an artefact of legacy v5 subpage support being present in the -* same QEMU executable. -*/ -int maxidx =DIV_ROUND_UP (blocklen,TARGET_PAGE_SIZE ); -void *hostaddr[maxidx]; -int try, i; -unsigned mmu_idx =cpu_mmu_index (env, false); -TCGMemOpIdx oi =make_memop_idx (MO_UB , mmu_idx); - -for (try =0 ; try <2 ; try++) { - -for (i =0 ; i < maxidx; i++) { - hostaddr[i] =tlb_vaddr_to_host (env, - vaddr +TARGET_PAGE_SIZE * i, -1 , mmu_idx); -if (!hostaddr[i]) { -break ; - } - } -if (i == maxidx) { -/* If it's all in the TLB it's fair game for just writing to; -* we know we don't need to update dirty status, etc. -*/ -for (i =0 ; i < maxidx -1 ; i++) { -memset (hostaddr[i],0 ,TARGET_PAGE_SIZE ); - } -memset (hostaddr[i],0 , blocklen - (i *TARGET_PAGE_SIZE )); -return ; - } -/* OK, try a store and see if we can populate the tlb. This -* might cause an exception if the memory isn't writable, -* in which case we will longjmp out of here. We must for -* this purpose use the actual register value passed to us -* so that we get the fault address right. -*/ -helper_ret_stb_mmu (env, vaddr_in,0 , oi,GETPC ()); -/* Now we can populate the other TLB entries, if any */ -for (i =0 ; i < maxidx; i++) { -uint64_t va = vaddr +TARGET_PAGE_SIZE * i; -if (va != (vaddr_in &TARGET_PAGE_MASK )) { -helper_ret_stb_mmu (env, va,0 , oi,GETPC ()); - } - } - } - -/* Slow path (probably attempt to do this to an I/O device or -* similar, or clearing of a block of code we have translations -* cached for). Just do a series of byte writes as the architecture -* demands. It's not worth trying to use a cpu_physical_memory_map(), -* memset(), unmap() sequence here because: -* + we'd need to account for the blocksize being larger than a page -* + the direct-RAM access case is almost always going to be dealt -* with in the fastpath code above, so there's no speed benefit -* + we would have to deal with the map returning NULL because the -* bounce buffer was in use -*/ -for (i =0 ; i < blocklen; i++) { -helper_ret_stb_mmu (env, vaddr + i,0 , oi,GETPC ()); - } - } -#else -memset (g2h (vaddr),0 , blocklen); -#endif -} -/* Note that signed overflow is undefined in C. The following routines are careful to use unsigned types where modulo arithmetic is required. Failure to do so _will_ break on newer gcc. */
target/arm/op_helper.c +84 -0
87 lines not on this page · raw message
Signature · 1 line
2.19.1
PATCH 7/13 target: arm: Remove the LDST headers
In reply to Samuel OrtizThey are no longer needed.
--- target/arm/helper.c | 1 - 1 file changed, 1 deletion(-)
target/arm/helper.c +0 -1
@@ -16,7 +16,6 @@#include "sysemu/sysemu.h" #include "qemu/crc32c.h" #include "exec/exec-all.h" -#include "arm_ldst.h" #include <zlib.h> /* For crc32 */ #include "exec/semihost.h" #include "sysemu/kvm.h"
Signature · 1 line
2.19.1
PATCH 1/13 target: arm: Add copyright boilerplate
In reply to Samuel OrtizFrom: Philippe Mathieu-Daudé <[email protected]>
--- target/arm/helper.c | 7 +++++++ 1 file changed, 7 insertions(+)
target/arm/helper.c +7 -0
@@ -1,3 +1,10 @@ +/* +* ARM generic helpers. +* +* This code is licensed under the GNU GPL v2. +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ #include "qemu/osdep.h" #include "target/arm/idau.h" #include "trace.h"
Signature · 1 line
2.19.1
PATCH 6/13 target: arm: Make ARM TLB filling routine static
In reply to Samuel OrtizIt's only used in op_helper.c, it does not need to be exported and moreover it should only be build when TCG is enabled.
--- target/arm/internals.h | 5 ----- target/arm/helper.c | 37 ------------------------------------- target/arm/op_helper.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 42 deletions(-)
target/arm/internals.h +0 -5
@@ -741,11 +741,6 @@ static inline bool arm_extabort_type(MemTxResult result)return result !=MEMTX_DECODE_ERROR ; } -/* Do a page table walk and add page to TLB if possible */ -bool arm_tlb_fill (CPUState *cpu,vaddr address, -MMUAccessType access_type,int mmu_idx, -ARMMMUFaultInfo *fi); -/* Return true if the stage 1 translation regime is using LPAE format page * tables */ bool arm_s1_regime_using_lpae_format (CPUARMState *env,ARMMMUIdx mmu_idx);
target/arm/helper.c +0 -37
@@ -8855,43 +8855,6 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, } } -/* Walk the page table and (if the mapping exists) add the page -* to the TLB. Return false on success, or true on failure. Populate -* fsr with ARM DFSR/IFSR fault register format value on failure. -*/ -bool arm_tlb_fill (CPUState *cs,vaddr address, -MMUAccessType access_type,int mmu_idx, -ARMMMUFaultInfo *fi) -{ -ARMCPU *cpu =ARM_CPU (cs); -CPUARMState *env = &cpu->env; -hwaddr phys_addr; -target_ulong page_size; -int prot; -int ret; -MemTxAttrs attrs = {}; - - ret =get_phys_addr (env, address, access_type, -core_to_arm_mmu_idx (env, mmu_idx), &phys_addr, - &attrs, &prot, &page_size, fi,NULL ); -if (!ret) { -/* -* Map a single [sub]page. Regions smaller than our declared -* target page size are handled specially, so for those we -* pass in the exact addresses. -*/ -if (page_size >=TARGET_PAGE_SIZE ) { - phys_addr &=TARGET_PAGE_MASK ; - address &=TARGET_PAGE_MASK ; - } -tlb_set_page_with_attrs (cs, address, phys_addr, attrs, - prot, mmu_idx, page_size); -return 0 ; - } - -return ret; -} -hwaddr arm_cpu_get_phys_page_attrs_debug (CPUState *cs,vaddr addr,MemTxAttrs *attrs) {
target/arm/op_helper.c +38 -0
@@ -179,6 +179,44 @@ static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,raise_exception (env, exc, syn, target_el); } +/* Walk the page table and (if the mapping exists) add the page +* to the TLB. Return false on success, or true on failure. Populate +* fsr with ARM DFSR/IFSR fault register format value on failure. +*/ +static bool arm_tlb_fill (CPUState *cs,vaddr address, +MMUAccessType access_type,int mmu_idx, +ARMMMUFaultInfo *fi) +{ +ARMCPU *cpu =ARM_CPU (cs); +CPUARMState *env = &cpu->env; +hwaddr phys_addr; +target_ulong page_size; +int prot; +int ret; +MemTxAttrs attrs = {}; + + ret =get_phys_addr (env, address, access_type, +core_to_arm_mmu_idx (env, mmu_idx), &phys_addr, + &attrs, &prot, &page_size, fi,NULL ); +if (!ret) { +/* +* Map a single [sub]page. Regions smaller than our declared +* target page size are handled specially, so for those we +* pass in the exact addresses. +*/ +if (page_size >=TARGET_PAGE_SIZE ) { + phys_addr &=TARGET_PAGE_MASK ; + address &=TARGET_PAGE_MASK ; + } +tlb_set_page_with_attrs (cs, address, phys_addr, attrs, + prot, mmu_idx, page_size); +return 0 ; + } + +return ret; +} + +/* try to fill the TLB and return an exception if error. If retaddr is * NULL, it means that the function was called in C code (i.e. not * from generated code or from helper.c)
Signature · 1 line
2.19.1
cover Support disabling TCG on ARM
This patchset allows for building and running ARM targets with TCG disabled. It splits the target/arm/helper.c file into logical TCG and non TCG dependent files so that one can build and run QEMU binaries with or without TCG enabled.
The rationale behind this work comes from the NEMU project where we're trying to only support x86 and ARM 64-bit architectures, without including the TCG code base. We can only do so if we can build and run ARM binaries with TCG disabled.
The patches are also available here:
https://github.com/intel/nemu/tree/topic/upstream/arm-tcg-disable
Philippe Mathieu-Daudé (2):
target: arm: Add copyright boilerplate
target: arm: Remove unused headers
Samuel Ortiz (11):
target: arm: Move all v7m helpers into their own file
target: arm: Move all interrupt and exception handlers into their own
file
target: arm: Move the DC ZVA helper into op_helper
target: arm: Make ARM TLB filling routine static
target: arm: Remove the LDST headers
target: arm: Move all VFP helpers into their own file
target: arm: Move CPU state dumping routines to helper.c
target: arm: Move watchpoints APIs to helper.c
target: arm: Define TCG dependent functions when TCG is enabled
target: arm: Makefile cleanup
target: arm: Do not build TCG objects when TCG is off
target/arm/internals.h | 60 +- target/arm/translate.h | 7 - target/arm/cpu.c | 8 +- target/arm/excp_helper.c | 550 +++ target/arm/helper.c | 8467 ++++++++++++------------------------ target/arm/m_helper.c | 1892 ++++++++ target/arm/op_helper.c | 326 +- target/arm/translate-a64.c | 125 - target/arm/translate.c | 87 - target/arm/vfp_helper.c | 893 ++++ target/arm/Makefile.objs | 19 +- 11 files changed, 6262 insertions(+), 6172 deletions(-) create mode 100644 target/arm/excp_helper.c create mode 100644 target/arm/m_helper.c create mode 100644 target/arm/vfp_helper.c
Signature · 1 line
2.19.1
Re: [Qemu-devel] [PATCH 02/13] target: arm: Remove unused headers
In reply to Peter MaydellQuoted 20 lines · Peter Maydell
Quoted 19 lines · Philippe Mathieu-Daudé
Quoted 12 lines · Peter Maydell
target/arm/helper.c line 15
Quoted 7 lines · Samuel Ortiz
target/arm/helper.c +0
-1@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" This is for
muldiv64().But it is already included by "
cpu.h" -> "exec/cpu-defs.h"So they are not "unused" but "unnecessary".
Quoted 8 lines
Quoted 1 line
I thought this would be better to clean this once, before Samuel split.
Generally I think that if a .c file directly uses function X declared in header Y it should #include Y, even if it happens that it already includes other header Z that includes Y. Otherwise if we refactor Z later such that it no longer needs to include Y, it will break compilation of the .c file. (That is, Z including Y is a detail of the implementation of Z, not a guarantee made by Z to its users.)
Yes, this makes sense now, thanks.
Phil.
Quoted 5 lines
The exception here is where the header guarantees that it's going to include certain other things (which is the case for eg our
osdep.h).thanks
-- PMM
Re: [Qemu-arm] [PATCH 02/13] target: arm: Remove unused headers
In reply to Philippe Mathieu-DaudéQuoted 16 lines · Philippe Mathieu-Daudé
Quoted 13 lines · Peter Maydell
target/arm/helper.c line 15
Quoted 7 lines · Samuel Ortiz
target/arm/helper.c +0
-1@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" This is for
muldiv64().
Quoted 5 lines
But it is already included by "
cpu.h" -> "exec/cpu-defs.h"So they are not "unused" but "unnecessary".
I thought this would be better to clean this once, before Samuel split.
Generally I think that if a .c file directly uses function X declared in header Y it should #include Y, even if it happens that it already includes other header Z that includes Y. Otherwise if we refactor Z later such that it no longer needs to include Y, it will break compilation of the .c file. (That is, Z including Y is a detail of the implementation of Z, not a guarantee made by Z to its users.)
The exception here is where the header guarantees that it's going to include certain other things (which is the case for eg our osdep.h).
thanks
-- PMM
Re: [Qemu-arm] [PATCH 02/13] target: arm: Remove unused headers
In reply to Peter MaydellQuoted 10 lines · Peter Maydell
Quoted 9 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 3 --- 1 file changed, 3 deletions(-)
Quoted 11 lines
target/arm/helper.c line 15
Quoted 9 lines
target/arm/helper.c +0
-1@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" This is for
muldiv64().
But it is already included by "cpu.h" -> "exec/cpu-defs.h"
Quoted 4 lines
target/arm/helper.c line 18
Quoted 4 lines
target/arm/helper.c +0
-1#include "sysemu/arch_init.h" #include "sysemu/sysemu.h" -#include "qemu/bitops.h"
"cpu.h" -> "cpu-qom.h" -> "qom/cpu.h" -> "qemu/bitmap.h"
Quoted 8 lines
This is for
extract32()and friends.target/arm/helper.c line 21
Quoted 3 lines
target/arm/helper.c +0
-1#include "qemu/crc32c.h" #include "exec/exec-all.h" -#include "exec/cpu_ldst.h" This is for
cpu_stl_data().
Included by "arm_ldst.h"
Quoted 4 lines
target/arm/helper.c line 21
Quoted 4 lines
target/arm/helper.c +0
-0#include "arm_ldst.h" #include <zlib.h> /* For crc32 */ #include "exec/semihost.h"
So they are not "unused" but "unnecessary".
I thought this would be better to clean this once, before Samuel split.
Samuel: please drop this patch from your series.
Thanks,
Phil.
Re: [Qemu-arm] [PATCH 02/13] target: arm: Remove unused headers
Hi Philippe,
Quoted 48 lines · Philippe Mathieu-Daudé
Quoted 10 lines · Peter Maydell
Quoted 9 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 3 --- 1 file changed, 3 deletions(-)Quoted 11 lines
target/arm/helper.c line 15
Quoted 9 lines
target/arm/helper.c +0
-1@@ -12,13 +12,10 @@#include "internals.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" This is for
muldiv64().But it is already included by "
cpu.h" -> "exec/cpu-defs.h"Quoted 4 lines
target/arm/helper.c line 18
Quoted 4 lines
target/arm/helper.c +0
-1#include "sysemu/arch_init.h" #include "sysemu/sysemu.h" -#include "qemu/bitops.h" "
cpu.h" -> "cpu-qom.h" -> "qom/cpu.h" -> "qemu/bitmap.h"Quoted 8 lines
This is for
extract32()and friends.target/arm/helper.c line 21
Quoted 3 lines
target/arm/helper.c +0
-1#include "qemu/crc32c.h" #include "exec/exec-all.h" -#include "exec/cpu_ldst.h" This is for
cpu_stl_data().Included by "
arm_ldst.h"Quoted 4 lines
target/arm/helper.c line 21
Quoted 4 lines
target/arm/helper.c +0
-0#include "arm_ldst.h" #include <zlib.h> /* For crc32 */ #include "exec/semihost.h"
Quoted 5 lines
So they are not "unused" but "unnecessary".
I thought this would be better to clean this once, before Samuel split.
Samuel: please drop this patch from your series.
Dropped. I updated my
https://github.com/intel/nemu/tree/topic/upstream/arm-tcg-disable branch accordingly. I will wait for Richard's review before sending a v2.
Cheers,
Samuel.
Re: [Qemu-arm] [Qemu-devel] [PATCH 01/13] target: arm: Add copyright boilerplate
In reply to Peter MaydellQuoted 10 lines · Peter Maydell
Quoted 9 lines · Samuel Ortiz
From: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>Reviewed-by Samuel Ortiz <[email protected]>--- target/arm/helper.c | 7 +++++++ 1 file changed, 7 insertions(+)
Quoted 16 lines
target/arm/helper.c line 7
Quoted 12 lines
target/arm/helper.c +7
-0@@ -1,3 +1,10 @@ +/* +* ARM generic helpers. +* +* This code is licensed under the GNU GPL v2. +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ The human readable text says "v2", but the SPDX tag says "v2 or later". Which is right? (The top level LICENSE file says source files with no specific license are 2-or-later).
Fixed in my
https://github.com/intel/nemu/tree/topic/upstream/arm-tcg-disable
branch, thanks.
Cheers,
Samuel.
This series seems to have some coding style problems. See output below for more information:
Hi,
This series seems to have some coding style problems. See output below for more information:
Message-id: [email protected]
Type: series
Subject: [Qemu-devel] [PATCH 00/13] Support disabling TCG on ARM
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
3af868c target: arm: Do not build TCG objects when TCG is off
cb922de target: arm: Makefile cleanup
44ffa5e target: arm: Define TCG dependent functions when TCG is enabled b68743a target: arm: Move watchpoints APIs to helper.c
9e2028d target: arm: Move CPU state dumping routines to helper.c 3a52e33 target: arm: Move all VFP helpers into their own file
c39a434 target: arm: Remove the LDST headers
90d9715 target: arm: Make ARM TLB filling routine static
f726b41 target: arm: Move the DC ZVA helper into op_helper
ffc449b target: arm: Move all interrupt and exception handlers into their own file b76f167 target: arm: Move all v7m helpers into their own file
8f010ec target: arm: Remove unused headers
dfb3f64 target: arm: Add copyright boilerplate
=== OUTPUT BEGIN ===
Checking PATCH 1/13: target: arm: Add copyright boilerplate... Checking PATCH 2/13: target: arm: Remove unused headers... Checking PATCH 3/13: target: arm: Move all v7m helpers into their own file...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #2165:
new file mode 100644
total: 0 errors, 1 warnings, 4002 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 4/13: target: arm: Move all interrupt and exception handlers into their own file...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#32:
new file mode 100644
total: 0 errors, 1 warnings, 1095 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 5/13: target: arm: Move the DC ZVA helper into op_helper... Checking PATCH 6/13: target: arm: Make ARM TLB filling routine static... Checking PATCH 7/13: target: arm: Remove the LDST headers... Checking PATCH 8/13: target: arm: Move all VFP helpers into their own file...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #916:
new file mode 100644
ERROR: Macros with multiple statements should be enclosed in a do - while loop #935: FILE: target/arm/vfp_helper.c:15:
+#define VFP_BINOP(name) \
+float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \
+{ \
+ float_status *fpst = fpstp; \
+ return float32_ ## name(a, b, fpst); \
+} \
+float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \
+{ \
+ float_status *fpst = fpstp; \
+ return float64_ ## name(a, b, fpst); \+}
ERROR: space prohibited before that close parenthesis ')' #1048: FILE: target/arm/vfp_helper.c:128:
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
ERROR: space prohibited before that close parenthesis ')' #1051: FILE: target/arm/vfp_helper.c:131:
+FLOAT_CONVS(si, h, uint32_t, 16, )
ERROR: space prohibited before that close parenthesis ')' #1052: FILE: target/arm/vfp_helper.c:132:
+FLOAT_CONVS(si, s, float32, 32, )
ERROR: space prohibited before that close parenthesis ')' #1053: FILE: target/arm/vfp_helper.c:133:
+FLOAT_CONVS(si, d, float64, 64, )
ERROR: space prohibited before that close parenthesis ')' #1095: FILE: target/arm/vfp_helper.c:175:
+ get_float_rounding_mode(fpst), )
ERROR: space prohibited before that close parenthesis ')' #1100: FILE: target/arm/vfp_helper.c:180:
+ get_float_rounding_mode(fpst), )
total: 7 errors, 1 warnings, 1778 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 9/13: target: arm: Move CPU state dumping routines to helper.c... Checking PATCH 10/13: target: arm: Move watchpoints APIs to helper.c... Checking PATCH 11/13: target: arm: Define TCG dependent functions when TCG is enabled... Checking PATCH 12/13: target: arm: Makefile cleanup...
Checking PATCH 13/13: target: arm: Do not build TCG objects when TCG is off... === OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to [email protected]
Re: [Qemu-arm] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
In reply to Samuel OrtizQuoted 6 lines · Samuel Ortiz
Most of them are TCG dependent so we want to be able to not build them in order to support TCG disablement with ARM.
Signed-off-by Samuel Ortiz <[email protected]>Reviewed-by Robert Bradford <[email protected]>
Quoted 6 lines
--- target/arm/excp_helper.c | 550 +++++++++++++++++++++++++++++++++++++++ target/arm/helper.c | 531 ------------------------------------- target/arm/Makefile.objs | 2 +- 3 files changed, 551 insertions(+), 532 deletions(-) create mode 100644 target/arm/excp_helper.c
You'll find that you need to rebase as there is a recent change that your moved copies are missing: commit e24ad484909e7. (I have just discovered git diff's --color-moved option which is great for checking this sort of code-movement patch.)
What is your plan for dealing with the way that the KVM code for injecting a breakpoint exception into the guest works by calling the do_interrupt code ?
(see target/arm/kvm64.c:kvm_arm_handle_debug(),
which calls cc->do_interrupt(cs).) This patch moves those functions to a file which won't be compiled and a later one in the series seems to stop cc->do_interrupt being set at all if CONFIG_TCG is not defined. That will result in QEMU crashing when it tries to inject an exception, won't it?
thanks
-- PMM
Re: [Qemu-arm] [PATCH 03/13] target: arm: Move all v7m helpers into their own file
In reply to Samuel OrtizQuoted 87 lines · Samuel Ortiz
In preparation for supporting TCG disablement on ARM, we move all TCG related v7m helpers and APIs into their own file (
m_helper.cfor all v*-m helpers).arm_v7m_cpu_do_interruptpulls a large number of static functions out ofhelper.cintom_helper.cbecause it is TCG dependent.Signed-off-by Samuel Ortiz <[email protected]>Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/internals.h | 37 + target/arm/helper.c | 2209 +++----------------------------------- target/arm/m_helper.c | 1892 ++++++++++++++++++++++++++++++++ target/arm/Makefile.objs | 2 +- 4 files changed, 2086 insertions(+), 2054 deletions(-) create mode 100644 target/arm/m_helper.ctarget/arm/helper.c +25
-34+/* Function used to synchronize QEMU's AArch64 register set with AArch32 +* register set. This is necessary when switching between AArch32 and AArch64 +* execution state. +*/ +void aarch64_sync_32_to_64 (CPUARMState *env) { -uint32_t new_ss_msp, new_ss_psp; +int i; +uint32_t mode = env->uncached_cpsr &CPSR_M ; -if (env->v7m.secure == new_secstate) { -return ; +/* We can blanket copy R[0:7] to X[0:7] */ +for (i =0 ; i <8 ; i++) { + env->xregs[i] = env->regs[i]; } -/* All the banked state is accessed by looking at env->v7m.secure -* except for the stack pointer; rearrange the SP appropriately. +/* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12. +* Otherwise, they come from the banked user regs. */ - new_ss_msp = env->v7m.other_ss_msp; - new_ss_psp = env->v7m.other_ss_psp; - -if (v7m_using_psp (env)) { - env->v7m.other_ss_psp = env->regs[13 ]; - env->v7m.other_ss_msp = env->v7m.other_sp; - }else { - env->v7m.other_ss_msp = env->regs[13 ]; - env->v7m.other_ss_psp = env->v7m.other_sp; - } - - env->v7m.secure = new_secstate; - -if (v7m_using_psp (env)) { - env->regs[13 ] = new_ss_psp; - env->v7m.other_sp = new_ss_msp; +if (mode ==ARM_CPU_MODE_FIQ ) { +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->usr_regs[i -8 ]; + } }else { - env->regs[13 ] = new_ss_msp; - env->v7m.other_sp = new_ss_psp; +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->regs[i]; + } } -} -void HELPER (v7m_bxns )(CPUARMState *env,uint32_t dest) -{ -/* Handle v7M BXNS: -* - if the return value is a magic value, do exception return (like BX) -* - otherwise bit 0 of the return value is the target security state +/* Registers x13-x23 are the various mode SP and FP registers. Registers +* r13 and r14 are only copied if we are in that mode, otherwise we copy +* from the mode banked register. */ -uint32_t min_magic; - -if (arm_feature (env,ARM_FEATURE_M_SECURITY )) { -/* Covers FNC_RETURN and EXC_RETURN magic */ - min_magic =FNC_RETURN_MIN_MAGIC ; +if (mode ==ARM_CPU_MODE_USR || mode ==ARM_CPU_MODE_SYS ) { + env->xregs[13 ] = env->regs[13 ]; + env->xregs[14 ] = env->regs[14 ]; }else {
target/arm/helper.c void write_v7m_exception(CPUARMState *env, uint32_t new_exc) · line 6539
Quoted 10 lines
target/arm/helper.c +7
-2-/* EXC_RETURN magic only */ - min_magic =EXC_RETURN_MIN_MAGIC ; + env->xregs[13 ] = env->banked_r13[bank_number (ARM_CPU_MODE_USR )]; +/* HYP is an exception in that it is copied from r14 */ +if (mode ==ARM_CPU_MODE_HYP ) { + env->xregs[14 ] = env->regs[14 ]; + }else { + env->xregs[14 ] = env->banked_r14[bank_number (ARM_CPU_MODE_USR )]; + } }
This part of the patch is a mess to read. I suspect this is a combination of (a) your git not being configured to use a better diff algorithm than the default (try "algorithm = histogram" in the [diff] section of your .gitconfig), and it doing an effective revert of 593cfa2b637b92d37 by accident.
It's also an absolutely enormous patch, even for a "just moving code" patch, which makes it hard to review even with diff --color-moved. Maybe it would be better in two pieces ("helper routines for various insns" and "exception handling functions" seems like a workable split).
thanks
-- PMM
Re: [Qemu-arm] [PATCH 07/13] target: arm: Remove the LDST headers
In reply to Samuel OrtizQuoted 1 line · Samuel Ortiz
They are no longer needed.
...because a previous patch moved the code using them out to excp_helper.c.
Quoted 7 lines
Signed-off-by Samuel Ortiz <[email protected]>Reviewed-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/helper.c | 1 - 1 file changed, 1 deletion(-)
thanks
-- PMM
Re: [Qemu-arm] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
In reply to Samuel OrtizQuoted 19 lines · Samuel Ortiz
Most of them are TCG dependent so we want to be able to not build them in order to support TCG disablement with ARM.
Signed-off-by Samuel Ortiz <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/excp_helper.c | 550 +++++++++++++++++++++++++++++++++++++++ target/arm/helper.c | 531 ------------------------------------- target/arm/Makefile.objs | 2 +- 3 files changed, 551 insertions(+), 532 deletions(-) create mode 100644 target/arm/excp_helper.ctarget/arm/excp_helper.c new file +0
-0
target/arm/excp_helper.c line 4
Quoted 4 lines
target/arm/excp_helper.c new file +4
-0@@ -0,0 +1,550 @@ +/* +* Exception and interrupt helpers. +* +* This code is licensed under the GNU GPL v2 and later.
*or* later. Wording matters in licensing. Same for other new files added in this series.
target/arm/excp_helper.c line 7
Quoted 3 lines
target/arm/excp_helper.c new file +3
-0+* +* SPDX-License-Identifier: GPL-2.0-or-later +*/
thanks
-- PMM
Re: [Qemu-arm] [PATCH 11/13] target: arm: Define TCG dependent functions when TCG is enabled
In reply to Samuel OrtizQuoted 26 lines · Samuel Ortiz
do_interrupt,do_unaligned_access,do_transaction_failedanddebug_excpare only relevant in the TCG context, so we should not define them when TCG is disabled.Signed-off-by Samuel Ortiz <[email protected]>Reviewed-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/cpu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)target/arm/cpu.c +1
-1@@ -1444,7 +1444,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) {CPUClass *cc =CPU_CLASS (oc); -#ifndef CONFIG_USER_ONLY +#if !defined(CONFIG_USER_ONLY ) && defined(CONFIG_TCG ) cc->do_interrupt = arm_v7m_cpu_do_interrupt;#endif
target/arm/cpu.c static void arm_cpu_class_init(ObjectClass *oc, void *data) · line 2066
Quoted 6 lines
target/arm/cpu.c +2
-0@@ -2061,9 +2061,14 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)#ifdef CONFIG_USER_ONLY cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;#else + +#ifdef CONFIG_TCG cc->do_interrupt = arm_cpu_do_interrupt;
As noted on an earlier patch, this breaks KVM injection of interrupts into the guest.
target/arm/cpu.c static void arm_cpu_class_init(ObjectClass *oc, void *data) · line 2070
Quoted 4 lines
target/arm/cpu.c +2
-0cc->do_unaligned_access = arm_cpu_do_unaligned_access; cc->do_transaction_failed = arm_cpu_do_transaction_failed; + cc->debug_excp_handler = arm_debug_excp_handler; +#endif
thanks
-- PMM
Re: [Qemu-arm] [PATCH 03/13] target: arm: Move all v7m helpers into their own file
In reply to Peter MaydellQuoted 96 lines · Peter Maydell
Quoted 95 lines · Samuel Ortiz
In preparation for supporting TCG disablement on ARM, we move all TCG related v7m helpers and APIs into their own file (
m_helper.cfor all v*-m helpers).arm_v7m_cpu_do_interruptpulls a large number of static functions out ofhelper.cintom_helper.cbecause it is TCG dependent.Signed-off-by Samuel Ortiz <[email protected]>Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/internals.h | 37 + target/arm/helper.c | 2209 +++----------------------------------- target/arm/m_helper.c | 1892 ++++++++++++++++++++++++++++++++ target/arm/Makefile.objs | 2 +- 4 files changed, 2086 insertions(+), 2054 deletions(-)create mode 100644
target/arm/m_helper.ctarget/arm/helper.c +31
-36+/* Function used to synchronize QEMU's AArch64 register set with AArch32 +* register set. This is necessary when switching between AArch32 and AArch64 +* execution state. +*/ +void aarch64_sync_32_to_64 (CPUARMState *env) { -uint32_t new_ss_msp, new_ss_psp; +int i; +uint32_t mode = env->uncached_cpsr &CPSR_M ; -if (env->v7m.secure == new_secstate) { -return ; +/* We can blanket copy R[0:7] to X[0:7] */ +for (i =0 ; i <8 ; i++) { + env->xregs[i] = env->regs[i]; } -/* All the banked state is accessed by looking at env->v7m.secure -* except for the stack pointer; rearrange the SP appropriately. +/* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12. +* Otherwise, they come from the banked user regs. */ - new_ss_msp = env->v7m.other_ss_msp; - new_ss_psp = env->v7m.other_ss_psp; - -if (v7m_using_psp (env)) { - env->v7m.other_ss_psp = env->regs[13 ]; - env->v7m.other_ss_msp = env->v7m.other_sp; - }else { - env->v7m.other_ss_msp = env->regs[13 ]; - env->v7m.other_ss_psp = env->v7m.other_sp; - } - - env->v7m.secure = new_secstate; - -if (v7m_using_psp (env)) { - env->regs[13 ] = new_ss_psp; - env->v7m.other_sp = new_ss_msp; +if (mode ==ARM_CPU_MODE_FIQ ) { +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->usr_regs[i -8 ]; + } }else { - env->regs[13 ] = new_ss_msp; - env->v7m.other_sp = new_ss_psp; +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->regs[i]; + } } -} -void HELPER (v7m_bxns )(CPUARMState *env,uint32_t dest) -{ -/* Handle v7M BXNS: -* - if the return value is a magic value, do exception return (like BX) -* - otherwise bit 0 of the return value is the target security state +/* Registers x13-x23 are the various mode SP and FP registers. Registers +* r13 and r14 are only copied if we are in that mode, otherwise we copy +* from the mode banked register. */ -uint32_t min_magic; - -if (arm_feature (env,ARM_FEATURE_M_SECURITY )) { -/* Covers FNC_RETURN and EXC_RETURN magic */ - min_magic =FNC_RETURN_MIN_MAGIC ; +if (mode ==ARM_CPU_MODE_USR || mode ==ARM_CPU_MODE_SYS ) { + env->xregs[13 ] = env->regs[13 ]; + env->xregs[14 ] = env->regs[14 ]; }else { -/* EXC_RETURN magic only */ - min_magic =EXC_RETURN_MIN_MAGIC ; + env->xregs[13 ] = env->banked_r13[bank_number (ARM_CPU_MODE_USR )]; +/* HYP is an exception in that it is copied from r14 */ +if (mode ==ARM_CPU_MODE_HYP ) { + env->xregs[14 ] = env->regs[14 ]; + }else { + env->xregs[14 ] = env->banked_r14[bank_number (ARM_CPU_MODE_USR )];
Quoted 8 lines
Quoted 2 lines
+ }
}This part of the patch is a mess to read. I suspect this is a combination of (a) your git not being configured to use a better diff algorithm than the default (try "algorithm = histogram" in the [diff] section of your .gitconfig), and it doing an effective revert of
593cfa2b637b92d37by accident.
I did the review offline, applying the series then looking at each commit with gitk, this is why I did not notice this.
Quoted 5 lines
It's also an absolutely enormous patch, even for a "just moving code" patch, which makes it hard to review even with diff --color-moved. Maybe it would be better in two pieces ("helper routines for various insns" and "exception handling functions" seems like a workable split).
Good idea.
Regards,
Phil.
Re: [Qemu-arm] [Qemu-devel] [PATCH 03/13] target: arm: Move all v7m helpers into their own file
In reply to Peter MaydellHi Peter,
Quoted 96 lines · Peter Maydell
Quoted 95 lines · Samuel Ortiz
In preparation for supporting TCG disablement on ARM, we move all TCG related v7m helpers and APIs into their own file (
m_helper.cfor all v*-m helpers).arm_v7m_cpu_do_interruptpulls a large number of static functions out ofhelper.cintom_helper.cbecause it is TCG dependent.Signed-off-by Samuel Ortiz <[email protected]>Signed-off-by Philippe Mathieu-Daudé <[email protected]>Reviewed-by Robert Bradford <[email protected]>--- target/arm/internals.h | 37 + target/arm/helper.c | 2209 +++----------------------------------- target/arm/m_helper.c | 1892 ++++++++++++++++++++++++++++++++ target/arm/Makefile.objs | 2 +- 4 files changed, 2086 insertions(+), 2054 deletions(-) create mode 100644 target/arm/m_helper.ctarget/arm/helper.c +31
-36+/* Function used to synchronize QEMU's AArch64 register set with AArch32 +* register set. This is necessary when switching between AArch32 and AArch64 +* execution state. +*/ +void aarch64_sync_32_to_64 (CPUARMState *env) { -uint32_t new_ss_msp, new_ss_psp; +int i; +uint32_t mode = env->uncached_cpsr &CPSR_M ; -if (env->v7m.secure == new_secstate) { -return ; +/* We can blanket copy R[0:7] to X[0:7] */ +for (i =0 ; i <8 ; i++) { + env->xregs[i] = env->regs[i]; } -/* All the banked state is accessed by looking at env->v7m.secure -* except for the stack pointer; rearrange the SP appropriately. +/* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12. +* Otherwise, they come from the banked user regs. */ - new_ss_msp = env->v7m.other_ss_msp; - new_ss_psp = env->v7m.other_ss_psp; - -if (v7m_using_psp (env)) { - env->v7m.other_ss_psp = env->regs[13 ]; - env->v7m.other_ss_msp = env->v7m.other_sp; - }else { - env->v7m.other_ss_msp = env->regs[13 ]; - env->v7m.other_ss_psp = env->v7m.other_sp; - } - - env->v7m.secure = new_secstate; - -if (v7m_using_psp (env)) { - env->regs[13 ] = new_ss_psp; - env->v7m.other_sp = new_ss_msp; +if (mode ==ARM_CPU_MODE_FIQ ) { +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->usr_regs[i -8 ]; + } }else { - env->regs[13 ] = new_ss_msp; - env->v7m.other_sp = new_ss_psp; +for (i =8 ; i <13 ; i++) { + env->xregs[i] = env->regs[i]; + } } -} -void HELPER (v7m_bxns )(CPUARMState *env,uint32_t dest) -{ -/* Handle v7M BXNS: -* - if the return value is a magic value, do exception return (like BX) -* - otherwise bit 0 of the return value is the target security state +/* Registers x13-x23 are the various mode SP and FP registers. Registers +* r13 and r14 are only copied if we are in that mode, otherwise we copy +* from the mode banked register. */ -uint32_t min_magic; - -if (arm_feature (env,ARM_FEATURE_M_SECURITY )) { -/* Covers FNC_RETURN and EXC_RETURN magic */ - min_magic =FNC_RETURN_MIN_MAGIC ; +if (mode ==ARM_CPU_MODE_USR || mode ==ARM_CPU_MODE_SYS ) { + env->xregs[13 ] = env->regs[13 ]; + env->xregs[14 ] = env->regs[14 ]; }else { -/* EXC_RETURN magic only */ - min_magic =EXC_RETURN_MIN_MAGIC ; + env->xregs[13 ] = env->banked_r13[bank_number (ARM_CPU_MODE_USR )]; +/* HYP is an exception in that it is copied from r14 */ +if (mode ==ARM_CPU_MODE_HYP ) { + env->xregs[14 ] = env->regs[14 ]; + }else { + env->xregs[14 ] = env->banked_r14[bank_number (ARM_CPU_MODE_USR )];
Quoted 8 lines
Quoted 2 lines
+ }
}This part of the patch is a mess to read. I suspect this is a combination of (a) your git not being configured to use a better diff algorithm than the default (try "algorithm = histogram" in the [diff] section of your .gitconfig), and it doing an effective revert of
593cfa2b637b92d37by accident.
Yes, the unintentional and partial revert made the patch messy. I fixed that.
Quoted 5 lines
It's also an absolutely enormous patch, even for a "just moving code" patch, which makes it hard to review even with diff --color-moved. Maybe it would be better in two pieces ("helper routines for various insns" and "exception handling functions" seems like a workable split).
Splitting and fixing the original patch made things much easier to read, thanks for the suggestion. See:
https://github.com/intel/nemu/pull/167/commits/5da42ba691bc05f3311332cfb3fe6db33b456904
https://github.com/intel/nemu/pull/167/commits/43cf20ed61e8c1f77d4706e29ba54df620a5091e
Cheers,
Samuel.
Re: [Qemu-arm] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
In reply to Peter MaydellQuoted 19 lines · Peter Maydell
Quoted 6 lines · Samuel Ortiz
Most of them are TCG dependent so we want to be able to not build them in order to support TCG disablement with ARM.
Signed-off-by Samuel Ortiz <[email protected]>Reviewed-by Robert Bradford <[email protected]>Quoted 6 lines
--- target/arm/excp_helper.c | 550 +++++++++++++++++++++++++++++++++++++++ target/arm/helper.c | 531 ------------------------------------- target/arm/Makefile.objs | 2 +- 3 files changed, 551 insertions(+), 532 deletions(-) create mode 100644 target/arm/excp_helper.cYou'll find that you need to rebase as there is a recent change that your moved copies are missing: commit
e24ad484909e7. (I have just discovered git diff's --color-moved option which is great for checking this sort of code-movement patch.)
Quoted 9 lines
What is your plan for dealing with the way that the KVM code for injecting a breakpoint exception into the guest works by calling the
do_interruptcode ?
(see target/arm/kvm64.c:kvm_arm_handle_debug(),
which callscc->do_interrupt(cs).) This patch moves those functions to a file which won't be compiled and a later one in the series seems to stopcc->do_interruptbeing set at all ifCONFIG_TCGis not defined. That will result in QEMU crashing when it tries to inject an exception, won't it?
Yes, indeed.
So it seems we need to inject an exception back into the guest when doing hardware assisted debugging and when we have not set any breakpoint from QEMU. So it's essentially handling the debugging from the guest case.
Would returning an error when that happens be an acceptable solution? So when building qemu for arm64 with TCG disabled, one would basically no longer be able to debug from the guest. Something along those lines:
target/arm/kvm64.c +5 -0
@@ -1079,6 +1079,11 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) __func__, debug_exit->hsr, env->pc); } +if (!tcg_enabled ()) { +error_report ("guest debugging not supported" ); +return false; + } +/* If we are not handling the debug exception it must belong to * the guest. Let's re-use the existing TCG interrupt code to set * everything up properly.
Re: [Qemu-arm] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
Quoted 11 lines · Samuel Ortiz
Quoted 9 lines · Peter Maydell
What is your plan for dealing with the way that the KVM code for injecting a breakpoint exception into the guest works by calling the
do_interruptcode ?
(see target/arm/kvm64.c:kvm_arm_handle_debug(),
which callscc->do_interrupt(cs).) This patch moves those functions to a file which won't be compiled and a later one in the series seems to stopcc->do_interruptbeing set at all ifCONFIG_TCGis not defined. That will result in QEMU crashing when it tries to inject an exception, won't it?
Quoted 8 lines
Yes, indeed.
So it seems we need to inject an exception back into the guest when doing hardware assisted debugging and when we have not set any breakpoint from QEMU. So it's essentially handling the debugging from the guest case.
Would returning an error when that happens be an acceptable solution? So when building qemu for arm64 with TCG disabled, one would basically no longer be able to debug from the guest.
I don't think that's a good idea. --disable-tcg shouldn't imply "and you lose some features of KVM". This code is used in both TCG and KVM, so needs to still be in the binary for KVM.
NB that it will also be used by the codepath for injecting SErrors when the host detects a RAS memory error in RAM used by the guest and wants to inform the guest of that. There are patches on-list for that, currently undergoing code review.
thanks
-- PMM
Re: [Qemu-devel] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
Quoted 21 lines · Peter Maydell
Quoted 11 lines · Samuel Ortiz
Quoted 9 lines · Peter Maydell
What is your plan for dealing with the way that the KVM code for injecting a breakpoint exception into the guest works by calling the
do_interruptcode ?
(see target/arm/kvm64.c:kvm_arm_handle_debug(),
which callscc->do_interrupt(cs).) This patch moves those functions to a file which won't be compiled and a later one in the series seems to stopcc->do_interruptbeing set at all ifCONFIG_TCGis not defined. That will result in QEMU crashing when it tries to inject an exception, won't it?Quoted 8 lines
Yes, indeed.
So it seems we need to inject an exception back into the guest when doing hardware assisted debugging and when we have not set any breakpoint from QEMU. So it's essentially handling the debugging from the guest case.
Would returning an error when that happens be an acceptable solution? So when building qemu for arm64 with TCG disabled, one would basically no longer be able to debug from the guest.
Quoted 2 lines
I don't think that's a good idea. --disable-tcg shouldn't imply "and you lose some features of KVM".
I see your point but as you're certainly aware, at the moment building with --disable-tcg implies you don't get an ARM QEMU binary at all. I felt this was an improvement over the current situation ;)
Quoted 2 lines
This code is used in both TCG
and KVM, so needs to still be in the binary for KVM.
Given that this piece of code effectively builds a dependency to TCG from the KVM code, I see a few solutions but I need your input here. We could:
- Decide we don't want to support --disable-tcg for ARM. We'd then carry this patch serie from the NEMU code repo. Worst case scenario, at least for us.
- Manage to implement exception injection from userspace without TCG. Would it even be possible?
- Offload exception injections back to the kernel in those cases. I feel this would be the cleanest solution but may need kernel changes.
Any other suggestions?
Cheers,
Samuel.
Re: [Qemu-devel] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
Quoted 11 lines · Samuel Ortiz
Given that this piece of code effectively builds a dependency to TCG from the KVM code, I see a few solutions but I need your input here. We could:
- Decide we don't want to support --disable-tcg for ARM. We'd then carry this patch serie from the NEMU code repo. Worst case scenario, at least for us.
- Manage to implement exception injection from userspace without TCG. Would it even be possible?
- Offload exception injections back to the kernel in those cases. I feel this would be the cleanest solution but may need kernel changes.
The kernel folk were firmly against 3, IIRC, but you can go and have the discussion if you like.
I don't really see what the problem is. This is just a bit of code that's used by both TCG and KVM. Therefore it goes in the binary whether TCG is enabled or not. Other functions and bits of code are TCG only and therefore don't go in a KVM-only binary. --disable-tcg just means "remove the code we don't need"; there's nothing special about these functions that says "they're really TCG and should be removed here".
thanks
-- PMM
Re: [Qemu-devel] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
Quoted 13 lines · Peter Maydell
Quoted 11 lines · Samuel Ortiz
Given that this piece of code effectively builds a dependency to TCG from the KVM code, I see a few solutions but I need your input here. We could:
- Decide we don't want to support --disable-tcg for ARM. We'd then carry this patch serie from the NEMU code repo. Worst case scenario, at least for us.
- Manage to implement exception injection from userspace without TCG. Would it even be possible?
- Offload exception injections back to the kernel in those cases. I feel this would be the cleanest solution but may need kernel changes.
Quoted 8 lines
The kernel folk were firmly against 3, IIRC, but you can go and have the discussion if you like.
I don't really see what the problem is. This is just a bit of code that's used by both TCG and KVM. Therefore it goes in the binary whether TCG is enabled or not. Other functions and bits of code are TCG only and therefore don't go in a KVM-only binary.
Keeping this code with --disable-tcg means:
Keep arm_cpu_do_interrupt -> Keep check_for_semihosting -> Keep the arm instruction loading code -> Keep a large chunk of the TCG core code itself. Does that dependency chain looks fine to you?
Cheers,
Samuel.
Re: [Qemu-arm] [Qemu-devel] [PATCH 04/13] target: arm: Move all interrupt and exception handlers into their own file
Quoted 22 lines · Samuel Ortiz
Quoted 13 lines · Peter Maydell
Quoted 11 lines · Samuel Ortiz
Given that this piece of code effectively builds a dependency to TCG from the KVM code, I see a few solutions but I need your input here. We could:
- Decide we don't want to support --disable-tcg for ARM. We'd then carry this patch serie from the NEMU code repo. Worst case scenario, at least for us.
- Manage to implement exception injection from userspace without TCG. Would it even be possible?
- Offload exception injections back to the kernel in those cases. I feel this would be the cleanest solution but may need kernel changes.Quoted 8 lines
The kernel folk were firmly against 3, IIRC, but you can go and have the discussion if you like.
I don't really see what the problem is. This is just a bit of code that's used by both TCG and KVM. Therefore it goes in the binary whether TCG is enabled or not. Other functions and bits of code are TCG only and therefore don't go in a KVM-only binary.
Quoted 5 lines
Keeping this code with --disable-tcg means:
Keep
arm_cpu_do_interrupt-> Keepcheck_for_semihosting-> Keep the arm instruction loading code -> Keep a large chunk of the TCG core code itself. Does that dependency chain looks fine to you?
A simplified, aarch64 specific arm_cpu_do_interrupt() implementation would not pull the TCG code in. Something like:
target/arm/kvm64.c +16 -2
@@ -1034,7 +1034,6 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) {int hsr_ec =syn_get_ec (debug_exit->hsr);ARMCPU *cpu =ARM_CPU (cs); -CPUClass *cc =CPU_GET_CLASS (cs);CPUARMState *env = &cpu->env;/* Ensure PC is synchronised */
@@ -1088,7 +1087,22 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) env->exception.vaddress = debug_exit->far; env->exception.target_el =1 ;qemu_mutex_lock_iothread (); - cc->do_interrupt (cs); + +/* Hooks may change global state so BQL should be held, also the +* BQL needs to be held for any modification of +* cs->interrupt_request. +*/ +g_assert (qemu_mutex_iothread_locked ()); + +arm_call_pre_el_change_hook (cpu); + +assert (!excp_is_internal (cs->exception_index)); +arm_cpu_do_interrupt_aarch64 (cs); + +arm_call_el_change_hook (cpu); + + cs->interrupt_request |=CPU_INTERRUPT_EXITTB ; +qemu_mutex_unlock_iothread ();return false;