From 212154821e6dc400315a67ad8204f5e5c4b3023c Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 21 Feb 2023 13:37:14 +0000 Subject: [PATCH 01/25] include/hw/arm/allwinner-a10.h: Remove superfluous includes from the header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_device.h is not needed at all in allwinner-a10.h, and serial.h is only needed by the corresponding .c file. Signed-off-by: Thomas Huth Reviewed-by: Alex Bennée Message-id: 20230215152233.210024-1-thuth@redhat.com Signed-off-by: Peter Maydell --- hw/arm/allwinner-a10.c | 1 + include/hw/arm/allwinner-a10.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index dc1966ff7a..b7ca795c71 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" +#include "hw/char/serial.h" #include "hw/sysbus.h" #include "hw/arm/allwinner-a10.h" #include "hw/misc/unimp.h" diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index 79e0c80568..095afb225d 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -1,9 +1,7 @@ #ifndef HW_ARM_ALLWINNER_A10_H #define HW_ARM_ALLWINNER_A10_H -#include "hw/char/serial.h" #include "hw/arm/boot.h" -#include "hw/pci/pci_device.h" #include "hw/timer/allwinner-a10-pit.h" #include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" From fa05d1abb998a3272f97a70db2f8a01852ebc06c Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:27 -0300 Subject: [PATCH 02/25] target/arm: Wrap breakpoint/watchpoint updates with tcg_enabled This is in preparation for restricting compilation of some parts of debug_helper.c to TCG only. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell --- target/arm/cpu.c | 6 ++++-- target/arm/debug_helper.c | 16 ++++++++++++---- target/arm/machine.c | 7 +++++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 876ab8f3bf..da416f7b1c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -539,8 +539,10 @@ static void arm_cpu_reset_hold(Object *obj) } #endif - hw_breakpoint_update_all(cpu); - hw_watchpoint_update_all(cpu); + if (tcg_enabled()) { + hw_breakpoint_update_all(cpu); + hw_watchpoint_update_all(cpu); + } arm_rebuild_hflags(env); } diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 3c671c88c1..3325eb9d7d 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -939,7 +939,9 @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, value &= ~3ULL; raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); + if (tcg_enabled()) { + hw_watchpoint_update(cpu, i); + } } static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -949,7 +951,9 @@ static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, int i = ri->crm; raw_write(env, ri, value); - hw_watchpoint_update(cpu, i); + if (tcg_enabled()) { + hw_watchpoint_update(cpu, i); + } } void hw_breakpoint_update(ARMCPU *cpu, int n) @@ -1062,7 +1066,9 @@ static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, int i = ri->crm; raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); + if (tcg_enabled()) { + hw_breakpoint_update(cpu, i); + } } static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1079,7 +1085,9 @@ static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, value = deposit64(value, 8, 1, extract64(value, 7, 1)); raw_write(env, ri, value); - hw_breakpoint_update(cpu, i); + if (tcg_enabled()) { + hw_breakpoint_update(cpu, i); + } } void define_debug_regs(ARMCPU *cpu) diff --git a/target/arm/machine.c b/target/arm/machine.c index b4c3850570..fd6323f6d8 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" +#include "sysemu/tcg.h" #include "kvm_arm.h" #include "internals.h" #include "migration/cpu.h" @@ -848,8 +849,10 @@ static int cpu_post_load(void *opaque, int version_id) return -1; } - hw_breakpoint_update_all(cpu); - hw_watchpoint_update_all(cpu); + if (tcg_enabled()) { + hw_breakpoint_update_all(cpu); + hw_watchpoint_update_all(cpu); + } /* * TCG gen_update_fp_context() relies on the invariant that From 2059ec754f9040a6a9f62a9abfeb76a9d8655e11 Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:28 -0300 Subject: [PATCH 03/25] target/arm: Wrap TCG-only code in debug_helper.c The next few patches will move helpers under CONFIG_TCG. We'd prefer to keep the debug helpers and debug registers close together, so rearrange the file a bit to be able to wrap the helpers with a TCG ifdef. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell --- target/arm/debug_helper.c | 476 +++++++++++++++++++------------------- 1 file changed, 239 insertions(+), 237 deletions(-) diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c index 3325eb9d7d..dfc8b2a1a5 100644 --- a/target/arm/debug_helper.c +++ b/target/arm/debug_helper.c @@ -12,8 +12,9 @@ #include "cpregs.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "sysemu/tcg.h" - +#ifdef CONFIG_TCG /* Return the Exception Level targeted by debug exceptions. */ static int arm_debug_target_el(CPUARMState *env) { @@ -536,6 +537,243 @@ void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome) raise_exception_debug(env, EXCP_UDEF, syndrome); } +void hw_watchpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + vaddr len = 0; + vaddr wvr = env->cp15.dbgwvr[n]; + uint64_t wcr = env->cp15.dbgwcr[n]; + int mask; + int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; + + if (env->cpu_watchpoint[n]) { + cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); + env->cpu_watchpoint[n] = NULL; + } + + if (!FIELD_EX64(wcr, DBGWCR, E)) { + /* E bit clear : watchpoint disabled */ + return; + } + + switch (FIELD_EX64(wcr, DBGWCR, LSC)) { + case 0: + /* LSC 00 is reserved and must behave as if the wp is disabled */ + return; + case 1: + flags |= BP_MEM_READ; + break; + case 2: + flags |= BP_MEM_WRITE; + break; + case 3: + flags |= BP_MEM_ACCESS; + break; + } + + /* + * Attempts to use both MASK and BAS fields simultaneously are + * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, + * thus generating a watchpoint for every byte in the masked region. + */ + mask = FIELD_EX64(wcr, DBGWCR, MASK); + if (mask == 1 || mask == 2) { + /* + * Reserved values of MASK; we must act as if the mask value was + * some non-reserved value, or as if the watchpoint were disabled. + * We choose the latter. + */ + return; + } else if (mask) { + /* Watchpoint covers an aligned area up to 2GB in size */ + len = 1ULL << mask; + /* + * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE + * whether the watchpoint fires when the unmasked bits match; we opt + * to generate the exceptions. + */ + wvr &= ~(len - 1); + } else { + /* Watchpoint covers bytes defined by the byte address select bits */ + int bas = FIELD_EX64(wcr, DBGWCR, BAS); + int basstart; + + if (extract64(wvr, 2, 1)) { + /* + * Deprecated case of an only 4-aligned address. BAS[7:4] are + * ignored, and BAS[3:0] define which bytes to watch. + */ + bas &= 0xf; + } + + if (bas == 0) { + /* This must act as if the watchpoint is disabled */ + return; + } + + /* + * The BAS bits are supposed to be programmed to indicate a contiguous + * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether + * we fire for each byte in the word/doubleword addressed by the WVR. + * We choose to ignore any non-zero bits after the first range of 1s. + */ + basstart = ctz32(bas); + len = cto32(bas >> basstart); + wvr += basstart; + } + + cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, + &env->cpu_watchpoint[n]); +} + +void hw_watchpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* + * Completely clear out existing QEMU watchpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { + hw_watchpoint_update(cpu, i); + } +} + +void hw_breakpoint_update(ARMCPU *cpu, int n) +{ + CPUARMState *env = &cpu->env; + uint64_t bvr = env->cp15.dbgbvr[n]; + uint64_t bcr = env->cp15.dbgbcr[n]; + vaddr addr; + int bt; + int flags = BP_CPU; + + if (env->cpu_breakpoint[n]) { + cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); + env->cpu_breakpoint[n] = NULL; + } + + if (!extract64(bcr, 0, 1)) { + /* E bit clear : watchpoint disabled */ + return; + } + + bt = extract64(bcr, 20, 4); + + switch (bt) { + case 4: /* unlinked address mismatch (reserved if AArch64) */ + case 5: /* linked address mismatch (reserved if AArch64) */ + qemu_log_mask(LOG_UNIMP, + "arm: address mismatch breakpoint types not implemented\n"); + return; + case 0: /* unlinked address match */ + case 1: /* linked address match */ + { + /* + * Bits [1:0] are RES0. + * + * It is IMPLEMENTATION DEFINED whether bits [63:49] + * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit + * of the VA field ([48] or [52] for FEAT_LVA), or whether the + * value is read as written. It is CONSTRAINED UNPREDICTABLE + * whether the RESS bits are ignored when comparing an address. + * Therefore we are allowed to compare the entire register, which + * lets us avoid considering whether FEAT_LVA is actually enabled. + * + * The BAS field is used to allow setting breakpoints on 16-bit + * wide instructions; it is CONSTRAINED UNPREDICTABLE whether + * a bp will fire if the addresses covered by the bp and the addresses + * covered by the insn overlap but the insn doesn't start at the + * start of the bp address range. We choose to require the insn and + * the bp to have the same address. The constraints on writing to + * BAS enforced in dbgbcr_write mean we have only four cases: + * 0b0000 => no breakpoint + * 0b0011 => breakpoint on addr + * 0b1100 => breakpoint on addr + 2 + * 0b1111 => breakpoint on addr + * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). + */ + int bas = extract64(bcr, 5, 4); + addr = bvr & ~3ULL; + if (bas == 0) { + return; + } + if (bas == 0xc) { + addr += 2; + } + break; + } + case 2: /* unlinked context ID match */ + case 8: /* unlinked VMID match (reserved if no EL2) */ + case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ + qemu_log_mask(LOG_UNIMP, + "arm: unlinked context breakpoint types not implemented\n"); + return; + case 9: /* linked VMID match (reserved if no EL2) */ + case 11: /* linked context ID and VMID match (reserved if no EL2) */ + case 3: /* linked context ID match */ + default: + /* + * We must generate no events for Linked context matches (unless + * they are linked to by some other bp/wp, which is handled in + * updates for the linking bp/wp). We choose to also generate no events + * for reserved values. + */ + return; + } + + cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); +} + +void hw_breakpoint_update_all(ARMCPU *cpu) +{ + int i; + CPUARMState *env = &cpu->env; + + /* + * Completely clear out existing QEMU breakpoints and our array, to + * avoid possible stale entries following migration load. + */ + cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); + memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); + + for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { + hw_breakpoint_update(cpu, i); + } +} + +#if !defined(CONFIG_USER_ONLY) + +vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + /* + * In BE32 system mode, target memory is stored byteswapped (on a + * little-endian host system), and by the time we reach here (via an + * opcode helper) the addresses of subword accesses have been adjusted + * to account for that, which means that watchpoints will not match. + * Undo the adjustment here. + */ + if (arm_sctlr_b(env)) { + if (len == 1) { + addr ^= 3; + } else if (len == 2) { + addr ^= 2; + } + } + + return addr; +} + +#endif /* !CONFIG_USER_ONLY */ +#endif /* CONFIG_TCG */ + /* * Check for traps to "powerdown debug" registers, which are controlled * by MDCR.TDOSA @@ -813,112 +1051,6 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = { .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, }; -void hw_watchpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - vaddr len = 0; - vaddr wvr = env->cp15.dbgwvr[n]; - uint64_t wcr = env->cp15.dbgwcr[n]; - int mask; - int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; - - if (env->cpu_watchpoint[n]) { - cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]); - env->cpu_watchpoint[n] = NULL; - } - - if (!FIELD_EX64(wcr, DBGWCR, E)) { - /* E bit clear : watchpoint disabled */ - return; - } - - switch (FIELD_EX64(wcr, DBGWCR, LSC)) { - case 0: - /* LSC 00 is reserved and must behave as if the wp is disabled */ - return; - case 1: - flags |= BP_MEM_READ; - break; - case 2: - flags |= BP_MEM_WRITE; - break; - case 3: - flags |= BP_MEM_ACCESS; - break; - } - - /* - * Attempts to use both MASK and BAS fields simultaneously are - * CONSTRAINED UNPREDICTABLE; we opt to ignore BAS in this case, - * thus generating a watchpoint for every byte in the masked region. - */ - mask = FIELD_EX64(wcr, DBGWCR, MASK); - if (mask == 1 || mask == 2) { - /* - * Reserved values of MASK; we must act as if the mask value was - * some non-reserved value, or as if the watchpoint were disabled. - * We choose the latter. - */ - return; - } else if (mask) { - /* Watchpoint covers an aligned area up to 2GB in size */ - len = 1ULL << mask; - /* - * If masked bits in WVR are not zero it's CONSTRAINED UNPREDICTABLE - * whether the watchpoint fires when the unmasked bits match; we opt - * to generate the exceptions. - */ - wvr &= ~(len - 1); - } else { - /* Watchpoint covers bytes defined by the byte address select bits */ - int bas = FIELD_EX64(wcr, DBGWCR, BAS); - int basstart; - - if (extract64(wvr, 2, 1)) { - /* - * Deprecated case of an only 4-aligned address. BAS[7:4] are - * ignored, and BAS[3:0] define which bytes to watch. - */ - bas &= 0xf; - } - - if (bas == 0) { - /* This must act as if the watchpoint is disabled */ - return; - } - - /* - * The BAS bits are supposed to be programmed to indicate a contiguous - * range of bytes. Otherwise it is CONSTRAINED UNPREDICTABLE whether - * we fire for each byte in the word/doubleword addressed by the WVR. - * We choose to ignore any non-zero bits after the first range of 1s. - */ - basstart = ctz32(bas); - len = cto32(bas >> basstart); - wvr += basstart; - } - - cpu_watchpoint_insert(CPU(cpu), wvr, len, flags, - &env->cpu_watchpoint[n]); -} - -void hw_watchpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* - * Completely clear out existing QEMU watchpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_watchpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) { - hw_watchpoint_update(cpu, i); - } -} - static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -956,109 +1088,6 @@ static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri, } } -void hw_breakpoint_update(ARMCPU *cpu, int n) -{ - CPUARMState *env = &cpu->env; - uint64_t bvr = env->cp15.dbgbvr[n]; - uint64_t bcr = env->cp15.dbgbcr[n]; - vaddr addr; - int bt; - int flags = BP_CPU; - - if (env->cpu_breakpoint[n]) { - cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]); - env->cpu_breakpoint[n] = NULL; - } - - if (!extract64(bcr, 0, 1)) { - /* E bit clear : watchpoint disabled */ - return; - } - - bt = extract64(bcr, 20, 4); - - switch (bt) { - case 4: /* unlinked address mismatch (reserved if AArch64) */ - case 5: /* linked address mismatch (reserved if AArch64) */ - qemu_log_mask(LOG_UNIMP, - "arm: address mismatch breakpoint types not implemented\n"); - return; - case 0: /* unlinked address match */ - case 1: /* linked address match */ - { - /* - * Bits [1:0] are RES0. - * - * It is IMPLEMENTATION DEFINED whether bits [63:49] - * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit - * of the VA field ([48] or [52] for FEAT_LVA), or whether the - * value is read as written. It is CONSTRAINED UNPREDICTABLE - * whether the RESS bits are ignored when comparing an address. - * Therefore we are allowed to compare the entire register, which - * lets us avoid considering whether FEAT_LVA is actually enabled. - * - * The BAS field is used to allow setting breakpoints on 16-bit - * wide instructions; it is CONSTRAINED UNPREDICTABLE whether - * a bp will fire if the addresses covered by the bp and the addresses - * covered by the insn overlap but the insn doesn't start at the - * start of the bp address range. We choose to require the insn and - * the bp to have the same address. The constraints on writing to - * BAS enforced in dbgbcr_write mean we have only four cases: - * 0b0000 => no breakpoint - * 0b0011 => breakpoint on addr - * 0b1100 => breakpoint on addr + 2 - * 0b1111 => breakpoint on addr - * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). - */ - int bas = extract64(bcr, 5, 4); - addr = bvr & ~3ULL; - if (bas == 0) { - return; - } - if (bas == 0xc) { - addr += 2; - } - break; - } - case 2: /* unlinked context ID match */ - case 8: /* unlinked VMID match (reserved if no EL2) */ - case 10: /* unlinked context ID and VMID match (reserved if no EL2) */ - qemu_log_mask(LOG_UNIMP, - "arm: unlinked context breakpoint types not implemented\n"); - return; - case 9: /* linked VMID match (reserved if no EL2) */ - case 11: /* linked context ID and VMID match (reserved if no EL2) */ - case 3: /* linked context ID match */ - default: - /* - * We must generate no events for Linked context matches (unless - * they are linked to by some other bp/wp, which is handled in - * updates for the linking bp/wp). We choose to also generate no events - * for reserved values. - */ - return; - } - - cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]); -} - -void hw_breakpoint_update_all(ARMCPU *cpu) -{ - int i; - CPUARMState *env = &cpu->env; - - /* - * Completely clear out existing QEMU breakpoints and our array, to - * avoid possible stale entries following migration load. - */ - cpu_breakpoint_remove_all(CPU(cpu), BP_CPU); - memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint)); - - for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) { - hw_breakpoint_update(cpu, i); - } -} - static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1210,30 +1239,3 @@ void define_debug_regs(ARMCPU *cpu) g_free(dbgwcr_el1_name); } } - -#if !defined(CONFIG_USER_ONLY) - -vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len) -{ - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - - /* - * In BE32 system mode, target memory is stored byteswapped (on a - * little-endian host system), and by the time we reach here (via an - * opcode helper) the addresses of subword accesses have been adjusted - * to account for that, which means that watchpoints will not match. - * Undo the adjustment here. - */ - if (arm_sctlr_b(env)) { - if (len == 1) { - addr ^= 3; - } else if (len == 2) { - addr ^= 2; - } - } - - return addr; -} - -#endif From f0984d4040c328d1c021ae6680479cbbe13c485b Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:29 -0300 Subject: [PATCH 04/25] target/arm: move translate modules to tcg/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the target/arm/tcg directory. Its purpose is to hold the TCG code that is selected by CONFIG_TCG. Signed-off-by: Claudio Fontana Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- MAINTAINERS | 1 + target/arm/meson.build | 30 ++++------------------- target/arm/{ => tcg}/a32-uncond.decode | 0 target/arm/{ => tcg}/a32.decode | 0 target/arm/{ => tcg}/m-nocp.decode | 0 target/arm/tcg/meson.build | 32 +++++++++++++++++++++++++ target/arm/{ => tcg}/mve.decode | 0 target/arm/{ => tcg}/neon-dp.decode | 0 target/arm/{ => tcg}/neon-ls.decode | 0 target/arm/{ => tcg}/neon-shared.decode | 0 target/arm/{ => tcg}/sme-fa64.decode | 0 target/arm/{ => tcg}/sme.decode | 0 target/arm/{ => tcg}/sve.decode | 0 target/arm/{ => tcg}/t16.decode | 0 target/arm/{ => tcg}/t32.decode | 0 target/arm/{ => tcg}/translate-a64.c | 0 target/arm/{ => tcg}/translate-a64.h | 0 target/arm/{ => tcg}/translate-m-nocp.c | 0 target/arm/{ => tcg}/translate-mve.c | 0 target/arm/{ => tcg}/translate-neon.c | 0 target/arm/{ => tcg}/translate-sme.c | 0 target/arm/{ => tcg}/translate-sve.c | 0 target/arm/{ => tcg}/translate-vfp.c | 0 target/arm/{ => tcg}/translate.c | 0 target/arm/{ => tcg}/translate.h | 0 target/arm/{ => tcg}/vfp-uncond.decode | 0 target/arm/{ => tcg}/vfp.decode | 0 27 files changed, 37 insertions(+), 26 deletions(-) rename target/arm/{ => tcg}/a32-uncond.decode (100%) rename target/arm/{ => tcg}/a32.decode (100%) rename target/arm/{ => tcg}/m-nocp.decode (100%) create mode 100644 target/arm/tcg/meson.build rename target/arm/{ => tcg}/mve.decode (100%) rename target/arm/{ => tcg}/neon-dp.decode (100%) rename target/arm/{ => tcg}/neon-ls.decode (100%) rename target/arm/{ => tcg}/neon-shared.decode (100%) rename target/arm/{ => tcg}/sme-fa64.decode (100%) rename target/arm/{ => tcg}/sme.decode (100%) rename target/arm/{ => tcg}/sve.decode (100%) rename target/arm/{ => tcg}/t16.decode (100%) rename target/arm/{ => tcg}/t32.decode (100%) rename target/arm/{ => tcg}/translate-a64.c (100%) rename target/arm/{ => tcg}/translate-a64.h (100%) rename target/arm/{ => tcg}/translate-m-nocp.c (100%) rename target/arm/{ => tcg}/translate-mve.c (100%) rename target/arm/{ => tcg}/translate-neon.c (100%) rename target/arm/{ => tcg}/translate-sme.c (100%) rename target/arm/{ => tcg}/translate-sve.c (100%) rename target/arm/{ => tcg}/translate-vfp.c (100%) rename target/arm/{ => tcg}/translate.c (100%) rename target/arm/{ => tcg}/translate.h (100%) rename target/arm/{ => tcg}/vfp-uncond.decode (100%) rename target/arm/{ => tcg}/vfp.decode (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 5c1ee41139..c6e6549f06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -161,6 +161,7 @@ M: Peter Maydell L: qemu-arm@nongnu.org S: Maintained F: target/arm/ +F: target/arm/tcg/ F: tests/tcg/arm/ F: tests/tcg/aarch64/ F: tests/qtest/arm-cpu-features.c diff --git a/target/arm/meson.build b/target/arm/meson.build index 87e911b27f..b2904b676b 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -1,22 +1,4 @@ -gen = [ - decodetree.process('sve.decode', extra_args: '--decode=disas_sve'), - decodetree.process('sme.decode', extra_args: '--decode=disas_sme'), - decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'), - decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'), - decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'), - decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'), - decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'), - decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'), - decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'), - decodetree.process('mve.decode', extra_args: '--decode=disas_mve'), - decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'), - decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'), - decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'), - decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']), -] - arm_ss = ss.source_set() -arm_ss.add(gen) arm_ss.add(files( 'cpu.c', 'crypto_helper.c', @@ -29,11 +11,6 @@ arm_ss.add(files( 'neon_helper.c', 'op_helper.c', 'tlb_helper.c', - 'translate.c', - 'translate-m-nocp.c', - 'translate-mve.c', - 'translate-neon.c', - 'translate-vfp.c', 'vec_helper.c', 'vfp_helper.c', 'cpu_tcg.c', @@ -50,9 +27,6 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'pauth_helper.c', 'sve_helper.c', 'sme_helper.c', - 'translate-a64.c', - 'translate-sve.c', - 'translate-sme.c', )) arm_softmmu_ss = ss.source_set() @@ -67,5 +41,9 @@ arm_softmmu_ss.add(files( subdir('hvf') +if 'CONFIG_TCG' in config_all + subdir('tcg') +endif + target_arch += {'arm': arm_ss} target_softmmu_arch += {'arm': arm_softmmu_ss} diff --git a/target/arm/a32-uncond.decode b/target/arm/tcg/a32-uncond.decode similarity index 100% rename from target/arm/a32-uncond.decode rename to target/arm/tcg/a32-uncond.decode diff --git a/target/arm/a32.decode b/target/arm/tcg/a32.decode similarity index 100% rename from target/arm/a32.decode rename to target/arm/tcg/a32.decode diff --git a/target/arm/m-nocp.decode b/target/arm/tcg/m-nocp.decode similarity index 100% rename from target/arm/m-nocp.decode rename to target/arm/tcg/m-nocp.decode diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build new file mode 100644 index 0000000000..044561bd4d --- /dev/null +++ b/target/arm/tcg/meson.build @@ -0,0 +1,32 @@ +gen = [ + decodetree.process('sve.decode', extra_args: '--decode=disas_sve'), + decodetree.process('sme.decode', extra_args: '--decode=disas_sme'), + decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'), + decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'), + decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'), + decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'), + decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'), + decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'), + decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'), + decodetree.process('mve.decode', extra_args: '--decode=disas_mve'), + decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'), + decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'), + decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'), + decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']), +] + +arm_ss.add(gen) + +arm_ss.add(files( + 'translate.c', + 'translate-m-nocp.c', + 'translate-mve.c', + 'translate-neon.c', + 'translate-vfp.c', +)) + +arm_ss.add(when: 'TARGET_AARCH64', if_true: files( + 'translate-a64.c', + 'translate-sve.c', + 'translate-sme.c', +)) diff --git a/target/arm/mve.decode b/target/arm/tcg/mve.decode similarity index 100% rename from target/arm/mve.decode rename to target/arm/tcg/mve.decode diff --git a/target/arm/neon-dp.decode b/target/arm/tcg/neon-dp.decode similarity index 100% rename from target/arm/neon-dp.decode rename to target/arm/tcg/neon-dp.decode diff --git a/target/arm/neon-ls.decode b/target/arm/tcg/neon-ls.decode similarity index 100% rename from target/arm/neon-ls.decode rename to target/arm/tcg/neon-ls.decode diff --git a/target/arm/neon-shared.decode b/target/arm/tcg/neon-shared.decode similarity index 100% rename from target/arm/neon-shared.decode rename to target/arm/tcg/neon-shared.decode diff --git a/target/arm/sme-fa64.decode b/target/arm/tcg/sme-fa64.decode similarity index 100% rename from target/arm/sme-fa64.decode rename to target/arm/tcg/sme-fa64.decode diff --git a/target/arm/sme.decode b/target/arm/tcg/sme.decode similarity index 100% rename from target/arm/sme.decode rename to target/arm/tcg/sme.decode diff --git a/target/arm/sve.decode b/target/arm/tcg/sve.decode similarity index 100% rename from target/arm/sve.decode rename to target/arm/tcg/sve.decode diff --git a/target/arm/t16.decode b/target/arm/tcg/t16.decode similarity index 100% rename from target/arm/t16.decode rename to target/arm/tcg/t16.decode diff --git a/target/arm/t32.decode b/target/arm/tcg/t32.decode similarity index 100% rename from target/arm/t32.decode rename to target/arm/tcg/t32.decode diff --git a/target/arm/translate-a64.c b/target/arm/tcg/translate-a64.c similarity index 100% rename from target/arm/translate-a64.c rename to target/arm/tcg/translate-a64.c diff --git a/target/arm/translate-a64.h b/target/arm/tcg/translate-a64.h similarity index 100% rename from target/arm/translate-a64.h rename to target/arm/tcg/translate-a64.h diff --git a/target/arm/translate-m-nocp.c b/target/arm/tcg/translate-m-nocp.c similarity index 100% rename from target/arm/translate-m-nocp.c rename to target/arm/tcg/translate-m-nocp.c diff --git a/target/arm/translate-mve.c b/target/arm/tcg/translate-mve.c similarity index 100% rename from target/arm/translate-mve.c rename to target/arm/tcg/translate-mve.c diff --git a/target/arm/translate-neon.c b/target/arm/tcg/translate-neon.c similarity index 100% rename from target/arm/translate-neon.c rename to target/arm/tcg/translate-neon.c diff --git a/target/arm/translate-sme.c b/target/arm/tcg/translate-sme.c similarity index 100% rename from target/arm/translate-sme.c rename to target/arm/tcg/translate-sme.c diff --git a/target/arm/translate-sve.c b/target/arm/tcg/translate-sve.c similarity index 100% rename from target/arm/translate-sve.c rename to target/arm/tcg/translate-sve.c diff --git a/target/arm/translate-vfp.c b/target/arm/tcg/translate-vfp.c similarity index 100% rename from target/arm/translate-vfp.c rename to target/arm/tcg/translate-vfp.c diff --git a/target/arm/translate.c b/target/arm/tcg/translate.c similarity index 100% rename from target/arm/translate.c rename to target/arm/tcg/translate.c diff --git a/target/arm/translate.h b/target/arm/tcg/translate.h similarity index 100% rename from target/arm/translate.h rename to target/arm/tcg/translate.h diff --git a/target/arm/vfp-uncond.decode b/target/arm/tcg/vfp-uncond.decode similarity index 100% rename from target/arm/vfp-uncond.decode rename to target/arm/tcg/vfp-uncond.decode diff --git a/target/arm/vfp.decode b/target/arm/tcg/vfp.decode similarity index 100% rename from target/arm/vfp.decode rename to target/arm/tcg/vfp.decode From a3ef070ea9b2d9af95422b38b022f11d8c302d2e Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Fri, 17 Feb 2023 17:11:30 -0300 Subject: [PATCH 05/25] target/arm: move helpers to tcg/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Claudio Fontana Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- target/arm/meson.build | 15 ++------------- target/arm/tcg-stubs.c | 23 +++++++++++++++++++++++ target/arm/{ => tcg}/crypto_helper.c | 0 target/arm/{ => tcg}/helper-a64.c | 0 target/arm/{ => tcg}/iwmmxt_helper.c | 0 target/arm/{ => tcg}/m_helper.c | 0 target/arm/tcg/meson.build | 13 +++++++++++++ target/arm/{ => tcg}/mte_helper.c | 0 target/arm/{ => tcg}/mve_helper.c | 0 target/arm/{ => tcg}/neon_helper.c | 0 target/arm/{ => tcg}/op_helper.c | 0 target/arm/{ => tcg}/pauth_helper.c | 0 target/arm/{ => tcg}/sme_helper.c | 0 target/arm/{ => tcg}/sve_helper.c | 0 target/arm/{ => tcg}/tlb_helper.c | 0 target/arm/{ => tcg}/vec_helper.c | 0 target/arm/{ => tcg}/vec_internal.h | 0 17 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 target/arm/tcg-stubs.c rename target/arm/{ => tcg}/crypto_helper.c (100%) rename target/arm/{ => tcg}/helper-a64.c (100%) rename target/arm/{ => tcg}/iwmmxt_helper.c (100%) rename target/arm/{ => tcg}/m_helper.c (100%) rename target/arm/{ => tcg}/mte_helper.c (100%) rename target/arm/{ => tcg}/mve_helper.c (100%) rename target/arm/{ => tcg}/neon_helper.c (100%) rename target/arm/{ => tcg}/op_helper.c (100%) rename target/arm/{ => tcg}/pauth_helper.c (100%) rename target/arm/{ => tcg}/sme_helper.c (100%) rename target/arm/{ => tcg}/sve_helper.c (100%) rename target/arm/{ => tcg}/tlb_helper.c (100%) rename target/arm/{ => tcg}/vec_helper.c (100%) rename target/arm/{ => tcg}/vec_internal.h (100%) diff --git a/target/arm/meson.build b/target/arm/meson.build index b2904b676b..3e2f403005 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -1,17 +1,9 @@ arm_ss = ss.source_set() arm_ss.add(files( 'cpu.c', - 'crypto_helper.c', 'debug_helper.c', 'gdbstub.c', 'helper.c', - 'iwmmxt_helper.c', - 'm_helper.c', - 'mve_helper.c', - 'neon_helper.c', - 'op_helper.c', - 'tlb_helper.c', - 'vec_helper.c', 'vfp_helper.c', 'cpu_tcg.c', )) @@ -22,11 +14,6 @@ arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c'), if_false: fil arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'cpu64.c', 'gdbstub64.c', - 'helper-a64.c', - 'mte_helper.c', - 'pauth_helper.c', - 'sve_helper.c', - 'sme_helper.c', )) arm_softmmu_ss = ss.source_set() @@ -43,6 +30,8 @@ subdir('hvf') if 'CONFIG_TCG' in config_all subdir('tcg') +else + arm_ss.add(files('tcg-stubs.c')) endif target_arch += {'arm': arm_ss} diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c new file mode 100644 index 0000000000..1a7ddb3664 --- /dev/null +++ b/target/arm/tcg-stubs.c @@ -0,0 +1,23 @@ +/* + * QEMU ARM stubs for some TCG helper functions + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "internals.h" + +void write_v7m_exception(CPUARMState *env, uint32_t new_exc) +{ + g_assert_not_reached(); +} + +void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, + uint32_t target_el, uintptr_t ra) +{ + g_assert_not_reached(); +} diff --git a/target/arm/crypto_helper.c b/target/arm/tcg/crypto_helper.c similarity index 100% rename from target/arm/crypto_helper.c rename to target/arm/tcg/crypto_helper.c diff --git a/target/arm/helper-a64.c b/target/arm/tcg/helper-a64.c similarity index 100% rename from target/arm/helper-a64.c rename to target/arm/tcg/helper-a64.c diff --git a/target/arm/iwmmxt_helper.c b/target/arm/tcg/iwmmxt_helper.c similarity index 100% rename from target/arm/iwmmxt_helper.c rename to target/arm/tcg/iwmmxt_helper.c diff --git a/target/arm/m_helper.c b/target/arm/tcg/m_helper.c similarity index 100% rename from target/arm/m_helper.c rename to target/arm/tcg/m_helper.c diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build index 044561bd4d..1f27ba1272 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build @@ -23,10 +23,23 @@ arm_ss.add(files( 'translate-mve.c', 'translate-neon.c', 'translate-vfp.c', + 'crypto_helper.c', + 'iwmmxt_helper.c', + 'm_helper.c', + 'mve_helper.c', + 'neon_helper.c', + 'op_helper.c', + 'tlb_helper.c', + 'vec_helper.c', )) arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'translate-a64.c', 'translate-sve.c', 'translate-sme.c', + 'helper-a64.c', + 'mte_helper.c', + 'pauth_helper.c', + 'sme_helper.c', + 'sve_helper.c', )) diff --git a/target/arm/mte_helper.c b/target/arm/tcg/mte_helper.c similarity index 100% rename from target/arm/mte_helper.c rename to target/arm/tcg/mte_helper.c diff --git a/target/arm/mve_helper.c b/target/arm/tcg/mve_helper.c similarity index 100% rename from target/arm/mve_helper.c rename to target/arm/tcg/mve_helper.c diff --git a/target/arm/neon_helper.c b/target/arm/tcg/neon_helper.c similarity index 100% rename from target/arm/neon_helper.c rename to target/arm/tcg/neon_helper.c diff --git a/target/arm/op_helper.c b/target/arm/tcg/op_helper.c similarity index 100% rename from target/arm/op_helper.c rename to target/arm/tcg/op_helper.c diff --git a/target/arm/pauth_helper.c b/target/arm/tcg/pauth_helper.c similarity index 100% rename from target/arm/pauth_helper.c rename to target/arm/tcg/pauth_helper.c diff --git a/target/arm/sme_helper.c b/target/arm/tcg/sme_helper.c similarity index 100% rename from target/arm/sme_helper.c rename to target/arm/tcg/sme_helper.c diff --git a/target/arm/sve_helper.c b/target/arm/tcg/sve_helper.c similarity index 100% rename from target/arm/sve_helper.c rename to target/arm/tcg/sve_helper.c diff --git a/target/arm/tlb_helper.c b/target/arm/tcg/tlb_helper.c similarity index 100% rename from target/arm/tlb_helper.c rename to target/arm/tcg/tlb_helper.c diff --git a/target/arm/vec_helper.c b/target/arm/tcg/vec_helper.c similarity index 100% rename from target/arm/vec_helper.c rename to target/arm/tcg/vec_helper.c diff --git a/target/arm/vec_internal.h b/target/arm/tcg/vec_internal.h similarity index 100% rename from target/arm/vec_internal.h rename to target/arm/tcg/vec_internal.h From 9def656e7a23515d5afd5e5e350574d1dfb7fcc9 Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Fri, 17 Feb 2023 17:11:31 -0300 Subject: [PATCH 06/25] target/arm: Move psci.c into the tcg directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Claudio Fontana Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- target/arm/meson.build | 1 - target/arm/tcg/meson.build | 4 ++++ target/arm/{ => tcg}/psci.c | 0 3 files changed, 4 insertions(+), 1 deletion(-) rename target/arm/{ => tcg}/psci.c (100%) diff --git a/target/arm/meson.build b/target/arm/meson.build index 3e2f403005..a5191b57e1 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -22,7 +22,6 @@ arm_softmmu_ss.add(files( 'arm-powerctl.c', 'machine.c', 'monitor.c', - 'psci.c', 'ptw.c', )) diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build index 1f27ba1272..fa8a9eab93 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build @@ -43,3 +43,7 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'sme_helper.c', 'sve_helper.c', )) + +arm_softmmu_ss.add(files( + 'psci.c', +)) diff --git a/target/arm/psci.c b/target/arm/tcg/psci.c similarity index 100% rename from target/arm/psci.c rename to target/arm/tcg/psci.c From 2b77ad4de615542dd8f6b9886a816e744b0abffd Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:32 -0300 Subject: [PATCH 07/25] target/arm: Wrap arm_rebuild_hflags calls with tcg_enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation to moving the hflags code into its own file under the tcg/ directory. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- hw/arm/boot.c | 6 +++++- hw/intc/armv7m_nvic.c | 20 +++++++++++++------- target/arm/arm-powerctl.c | 7 +++++-- target/arm/cpu.c | 3 ++- target/arm/helper.c | 18 +++++++++++++----- target/arm/machine.c | 5 ++++- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 3d7d11f782..1e021c4a34 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -15,6 +15,7 @@ #include "hw/arm/boot.h" #include "hw/arm/linux-boot-if.h" #include "sysemu/kvm.h" +#include "sysemu/tcg.h" #include "sysemu/sysemu.h" #include "sysemu/numa.h" #include "hw/boards.h" @@ -827,7 +828,10 @@ static void do_cpu_reset(void *opaque) info->secondary_cpu_reset_hook(cpu, info); } } - arm_rebuild_hflags(env); + + if (tcg_enabled()) { + arm_rebuild_hflags(env); + } } } diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index e54553283f..8e289051a4 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -18,6 +18,7 @@ #include "hw/intc/armv7m_nvic.h" #include "hw/irq.h" #include "hw/qdev-properties.h" +#include "sysemu/tcg.h" #include "sysemu/runstate.h" #include "target/arm/cpu.h" #include "exec/exec-all.h" @@ -2454,8 +2455,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, /* This is UNPREDICTABLE; treat as RAZ/WI */ exit_ok: - /* Ensure any changes made are reflected in the cached hflags. */ - arm_rebuild_hflags(&s->cpu->env); + if (tcg_enabled()) { + /* Ensure any changes made are reflected in the cached hflags. */ + arm_rebuild_hflags(&s->cpu->env); + } return MEMTX_OK; } @@ -2636,11 +2639,14 @@ static void armv7m_nvic_reset(DeviceState *dev) } } - /* - * We updated state that affects the CPU's MMUidx and thus its hflags; - * and we can't guarantee that we run before the CPU reset function. - */ - arm_rebuild_hflags(&s->cpu->env); + if (tcg_enabled()) { + /* + * We updated state that affects the CPU's MMUidx and thus its + * hflags; and we can't guarantee that we run before the CPU + * reset function. + */ + arm_rebuild_hflags(&s->cpu->env); + } } static void nvic_systick_trigger(void *opaque, int n, int level) diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c index b75f813b40..326a03153d 100644 --- a/target/arm/arm-powerctl.c +++ b/target/arm/arm-powerctl.c @@ -15,6 +15,7 @@ #include "arm-powerctl.h" #include "qemu/log.h" #include "qemu/main-loop.h" +#include "sysemu/tcg.h" #ifndef DEBUG_ARM_POWERCTL #define DEBUG_ARM_POWERCTL 0 @@ -127,8 +128,10 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state, target_cpu->env.regs[0] = info->context_id; } - /* CP15 update requires rebuilding hflags */ - arm_rebuild_hflags(&target_cpu->env); + if (tcg_enabled()) { + /* CP15 update requires rebuilding hflags */ + arm_rebuild_hflags(&target_cpu->env); + } /* Start the new CPU at the requested address */ cpu_set_pc(target_cpu_state, info->entry); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index da416f7b1c..0b333a749f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -542,8 +542,9 @@ static void arm_cpu_reset_hold(Object *obj) if (tcg_enabled()) { hw_breakpoint_update_all(cpu); hw_watchpoint_update_all(cpu); + + arm_rebuild_hflags(env); } - arm_rebuild_hflags(env); } #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) diff --git a/target/arm/helper.c b/target/arm/helper.c index 07d4100365..af72e6d16c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -5173,7 +5173,7 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, /* This may enable/disable the MMU, so do a TLB flush. */ tlb_flush(CPU(cpu)); - if (ri->type & ARM_CP_SUPPRESS_TB_END) { + if (tcg_enabled() && ri->type & ARM_CP_SUPPRESS_TB_END) { /* * Normally we would always end the TB on an SCTLR write; see the * comment in ARMCPRegInfo sctlr initialization below for why Xscale @@ -6841,7 +6841,9 @@ void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask) memset(env->zarray, 0, sizeof(env->zarray)); } - arm_rebuild_hflags(env); + if (tcg_enabled()) { + arm_rebuild_hflags(env); + } } static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -9886,7 +9888,7 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask, } mask &= ~CACHED_CPSR_BITS; env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); - if (rebuild_hflags) { + if (tcg_enabled() && rebuild_hflags) { arm_rebuild_hflags(env); } } @@ -10445,7 +10447,10 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->regs[14] = env->regs[15] + offset; } env->regs[15] = newpc; - arm_rebuild_hflags(env); + + if (tcg_enabled()) { + arm_rebuild_hflags(env); + } } static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs) @@ -11001,7 +11006,10 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) pstate_write(env, PSTATE_DAIF | new_mode); env->aarch64 = true; aarch64_restore_sp(env, new_el); - helper_rebuild_hflags_a64(env, new_el); + + if (tcg_enabled()) { + helper_rebuild_hflags_a64(env, new_el); + } env->pc = addr; diff --git a/target/arm/machine.c b/target/arm/machine.c index fd6323f6d8..fc4a4a4064 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -871,7 +871,10 @@ static int cpu_post_load(void *opaque, int version_id) if (!kvm_enabled()) { pmu_op_finish(&cpu->env); } - arm_rebuild_hflags(&cpu->env); + + if (tcg_enabled()) { + arm_rebuild_hflags(&cpu->env); + } return 0; } From 671efad16a242b3fb5fb5111e9981d56887f7755 Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:33 -0300 Subject: [PATCH 08/25] target/arm: Move hflags code into the tcg directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hflags are used only for TCG code, so introduce a new file hflags.c to keep that code. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- target/arm/helper.c | 393 +----------------------------------- target/arm/internals.h | 2 + target/arm/tcg-stubs.c | 4 + target/arm/tcg/hflags.c | 403 +++++++++++++++++++++++++++++++++++++ target/arm/tcg/meson.build | 1 + 5 files changed, 411 insertions(+), 392 deletions(-) create mode 100644 target/arm/tcg/hflags.c diff --git a/target/arm/helper.c b/target/arm/helper.c index af72e6d16c..14af7ba095 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6669,32 +6669,6 @@ int sme_exception_el(CPUARMState *env, int el) return 0; } -/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */ -static bool sme_fa64(CPUARMState *env, int el) -{ - if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) { - return false; - } - - if (el <= 1 && !el_is_in_host(env, el)) { - if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) { - return false; - } - } - if (el <= 2 && arm_is_el2_enabled(env)) { - if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) { - return false; - } - } - if (arm_feature(env, ARM_FEATURE_EL3)) { - if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) { - return false; - } - } - - return true; -} - /* * Given that SVE is enabled, return the vector length for EL. */ @@ -11150,7 +11124,7 @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx) } } -static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx) +int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx) { if (regime_has_2_ranges(mmu_idx)) { return extract64(tcr, 57, 2); @@ -11861,371 +11835,6 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env) return arm_mmu_idx_el(env, arm_current_el(env)); } -static inline bool fgt_svc(CPUARMState *env, int el) -{ - /* - * Assuming fine-grained-traps are active, return true if we - * should be trapping on SVC instructions. Only AArch64 can - * trap on an SVC at EL1, but we don't need to special-case this - * because if this is AArch32 EL1 then arm_fgt_active() is false. - * We also know el is 0 or 1. - */ - return el == 0 ? - FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) : - FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1); -} - -static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el, - ARMMMUIdx mmu_idx, - CPUARMTBFlags flags) -{ - DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el); - DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx)); - - if (arm_singlestep_active(env)) { - DP_TBFLAG_ANY(flags, SS_ACTIVE, 1); - } - - return flags; -} - -static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el, - ARMMMUIdx mmu_idx, - CPUARMTBFlags flags) -{ - bool sctlr_b = arm_sctlr_b(env); - - if (sctlr_b) { - DP_TBFLAG_A32(flags, SCTLR__B, 1); - } - if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) { - DP_TBFLAG_ANY(flags, BE_DATA, 1); - } - DP_TBFLAG_A32(flags, NS, !access_secure_reg(env)); - - return rebuild_hflags_common(env, fp_el, mmu_idx, flags); -} - -static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el, - ARMMMUIdx mmu_idx) -{ - CPUARMTBFlags flags = {}; - uint32_t ccr = env->v7m.ccr[env->v7m.secure]; - - /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */ - if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) { - DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); - } - - if (arm_v7m_is_handler_mode(env)) { - DP_TBFLAG_M32(flags, HANDLER, 1); - } - - /* - * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN - * is suppressing them because the requested execution priority - * is less than 0. - */ - if (arm_feature(env, ARM_FEATURE_V8) && - !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) && - (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) { - DP_TBFLAG_M32(flags, STACKCHECK, 1); - } - - if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) { - DP_TBFLAG_M32(flags, SECURE, 1); - } - - return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); -} - -static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el, - ARMMMUIdx mmu_idx) -{ - CPUARMTBFlags flags = {}; - int el = arm_current_el(env); - - if (arm_sctlr(env, el) & SCTLR_A) { - DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); - } - - if (arm_el_is_aa64(env, 1)) { - DP_TBFLAG_A32(flags, VFPEN, 1); - } - - if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) && - (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) { - DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1); - } - - if (arm_fgt_active(env, el)) { - DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); - if (fgt_svc(env, el)) { - DP_TBFLAG_ANY(flags, FGT_SVC, 1); - } - } - - if (env->uncached_cpsr & CPSR_IL) { - DP_TBFLAG_ANY(flags, PSTATE__IL, 1); - } - - /* - * The SME exception we are testing for is raised via - * AArch64.CheckFPAdvSIMDEnabled(), as called from - * AArch32.CheckAdvSIMDOrFPEnabled(). - */ - if (el == 0 - && FIELD_EX64(env->svcr, SVCR, SM) - && (!arm_is_el2_enabled(env) - || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE))) - && arm_el_is_aa64(env, 1) - && !sme_fa64(env, el)) { - DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1); - } - - return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); -} - -static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, - ARMMMUIdx mmu_idx) -{ - CPUARMTBFlags flags = {}; - ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx); - uint64_t tcr = regime_tcr(env, mmu_idx); - uint64_t sctlr; - int tbii, tbid; - - DP_TBFLAG_ANY(flags, AARCH64_STATE, 1); - - /* Get control bits for tagged addresses. */ - tbid = aa64_va_parameter_tbi(tcr, mmu_idx); - tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx); - - DP_TBFLAG_A64(flags, TBII, tbii); - DP_TBFLAG_A64(flags, TBID, tbid); - - if (cpu_isar_feature(aa64_sve, env_archcpu(env))) { - int sve_el = sve_exception_el(env, el); - - /* - * If either FP or SVE are disabled, translator does not need len. - * If SVE EL > FP EL, FP exception has precedence, and translator - * does not need SVE EL. Save potential re-translations by forcing - * the unneeded data to zero. - */ - if (fp_el != 0) { - if (sve_el > fp_el) { - sve_el = 0; - } - } else if (sve_el == 0) { - DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el)); - } - DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el); - } - if (cpu_isar_feature(aa64_sme, env_archcpu(env))) { - int sme_el = sme_exception_el(env, el); - bool sm = FIELD_EX64(env->svcr, SVCR, SM); - - DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el); - if (sme_el == 0) { - /* Similarly, do not compute SVL if SME is disabled. */ - int svl = sve_vqm1_for_el_sm(env, el, true); - DP_TBFLAG_A64(flags, SVL, svl); - if (sm) { - /* If SVE is disabled, we will not have set VL above. */ - DP_TBFLAG_A64(flags, VL, svl); - } - } - if (sm) { - DP_TBFLAG_A64(flags, PSTATE_SM, 1); - DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el)); - } - DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA)); - } - - sctlr = regime_sctlr(env, stage1); - - if (sctlr & SCTLR_A) { - DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); - } - - if (arm_cpu_data_is_big_endian_a64(el, sctlr)) { - DP_TBFLAG_ANY(flags, BE_DATA, 1); - } - - if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) { - /* - * In order to save space in flags, we record only whether - * pauth is "inactive", meaning all insns are implemented as - * a nop, or "active" when some action must be performed. - * The decision of which action to take is left to a helper. - */ - if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) { - DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1); - } - } - - if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { - /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */ - if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) { - DP_TBFLAG_A64(flags, BT, 1); - } - } - - /* Compute the condition for using AccType_UNPRIV for LDTR et al. */ - if (!(env->pstate & PSTATE_UAO)) { - switch (mmu_idx) { - case ARMMMUIdx_E10_1: - case ARMMMUIdx_E10_1_PAN: - /* TODO: ARMv8.3-NV */ - DP_TBFLAG_A64(flags, UNPRIV, 1); - break; - case ARMMMUIdx_E20_2: - case ARMMMUIdx_E20_2_PAN: - /* - * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is - * gated by HCR_EL2. == '11', and so is LDTR. - */ - if (env->cp15.hcr_el2 & HCR_TGE) { - DP_TBFLAG_A64(flags, UNPRIV, 1); - } - break; - default: - break; - } - } - - if (env->pstate & PSTATE_IL) { - DP_TBFLAG_ANY(flags, PSTATE__IL, 1); - } - - if (arm_fgt_active(env, el)) { - DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); - if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) { - DP_TBFLAG_A64(flags, FGT_ERET, 1); - } - if (fgt_svc(env, el)) { - DP_TBFLAG_ANY(flags, FGT_SVC, 1); - } - } - - if (cpu_isar_feature(aa64_mte, env_archcpu(env))) { - /* - * Set MTE_ACTIVE if any access may be Checked, and leave clear - * if all accesses must be Unchecked: - * 1) If no TBI, then there are no tags in the address to check, - * 2) If Tag Check Override, then all accesses are Unchecked, - * 3) If Tag Check Fail == 0, then Checked access have no effect, - * 4) If no Allocation Tag Access, then all accesses are Unchecked. - */ - if (allocation_tag_access_enabled(env, el, sctlr)) { - DP_TBFLAG_A64(flags, ATA, 1); - if (tbid - && !(env->pstate & PSTATE_TCO) - && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) { - DP_TBFLAG_A64(flags, MTE_ACTIVE, 1); - } - } - /* And again for unprivileged accesses, if required. */ - if (EX_TBFLAG_A64(flags, UNPRIV) - && tbid - && !(env->pstate & PSTATE_TCO) - && (sctlr & SCTLR_TCF0) - && allocation_tag_access_enabled(env, 0, sctlr)) { - DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1); - } - /* Cache TCMA as well as TBI. */ - DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx)); - } - - return rebuild_hflags_common(env, fp_el, mmu_idx, flags); -} - -static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env) -{ - int el = arm_current_el(env); - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - - if (is_a64(env)) { - return rebuild_hflags_a64(env, el, fp_el, mmu_idx); - } else if (arm_feature(env, ARM_FEATURE_M)) { - return rebuild_hflags_m32(env, fp_el, mmu_idx); - } else { - return rebuild_hflags_a32(env, fp_el, mmu_idx); - } -} - -void arm_rebuild_hflags(CPUARMState *env) -{ - env->hflags = rebuild_hflags_internal(env); -} - -/* - * If we have triggered a EL state change we can't rely on the - * translator having passed it to us, we need to recompute. - */ -void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env) -{ - int el = arm_current_el(env); - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - - env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); -} - -void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el) -{ - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - - env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); -} - -/* - * If we have triggered a EL state change we can't rely on the - * translator having passed it to us, we need to recompute. - */ -void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env) -{ - int el = arm_current_el(env); - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); -} - -void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el) -{ - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - - env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); -} - -void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el) -{ - int fp_el = fp_exception_el(env, el); - ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); - - env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx); -} - -static inline void assert_hflags_rebuild_correctly(CPUARMState *env) -{ -#ifdef CONFIG_DEBUG_TCG - CPUARMTBFlags c = env->hflags; - CPUARMTBFlags r = rebuild_hflags_internal(env); - - if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) { - fprintf(stderr, "TCG hflags mismatch " - "(current:(0x%08x,0x" TARGET_FMT_lx ")" - " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n", - c.flags, c.flags2, r.flags, r.flags2); - abort(); - } -#endif -} - static bool mve_no_pred(CPUARMState *env) { /* diff --git a/target/arm/internals.h b/target/arm/internals.h index 759b70c646..ed48f8c9a6 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1073,6 +1073,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx); int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx); +int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx); /* Determine if allocation tags are available. */ static inline bool allocation_tag_access_enabled(CPUARMState *env, int el, @@ -1383,4 +1384,5 @@ static inline bool arm_fgt_active(CPUARMState *env, int el) (!arm_feature(env, ARM_FEATURE_EL3) || (env->cp15.scr_el3 & SCR_FGTEN)); } +void assert_hflags_rebuild_correctly(CPUARMState *env); #endif diff --git a/target/arm/tcg-stubs.c b/target/arm/tcg-stubs.c index 1a7ddb3664..152b172e24 100644 --- a/target/arm/tcg-stubs.c +++ b/target/arm/tcg-stubs.c @@ -21,3 +21,7 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, { g_assert_not_reached(); } +/* Temporarily while cpu_get_tb_cpu_state() is still in common code */ +void assert_hflags_rebuild_correctly(CPUARMState *env) +{ +} diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c new file mode 100644 index 0000000000..b2ccd77cff --- /dev/null +++ b/target/arm/tcg/hflags.c @@ -0,0 +1,403 @@ +/* + * ARM hflags + * + * This code is licensed under the GNU GPL v2 or later. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "qemu/osdep.h" +#include "cpu.h" +#include "internals.h" +#include "exec/helper-proto.h" +#include "cpregs.h" + +static inline bool fgt_svc(CPUARMState *env, int el) +{ + /* + * Assuming fine-grained-traps are active, return true if we + * should be trapping on SVC instructions. Only AArch64 can + * trap on an SVC at EL1, but we don't need to special-case this + * because if this is AArch32 EL1 then arm_fgt_active() is false. + * We also know el is 0 or 1. + */ + return el == 0 ? + FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) : + FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1); +} + +static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el, + ARMMMUIdx mmu_idx, + CPUARMTBFlags flags) +{ + DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el); + DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx)); + + if (arm_singlestep_active(env)) { + DP_TBFLAG_ANY(flags, SS_ACTIVE, 1); + } + + return flags; +} + +static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el, + ARMMMUIdx mmu_idx, + CPUARMTBFlags flags) +{ + bool sctlr_b = arm_sctlr_b(env); + + if (sctlr_b) { + DP_TBFLAG_A32(flags, SCTLR__B, 1); + } + if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) { + DP_TBFLAG_ANY(flags, BE_DATA, 1); + } + DP_TBFLAG_A32(flags, NS, !access_secure_reg(env)); + + return rebuild_hflags_common(env, fp_el, mmu_idx, flags); +} + +static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el, + ARMMMUIdx mmu_idx) +{ + CPUARMTBFlags flags = {}; + uint32_t ccr = env->v7m.ccr[env->v7m.secure]; + + /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */ + if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) { + DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); + } + + if (arm_v7m_is_handler_mode(env)) { + DP_TBFLAG_M32(flags, HANDLER, 1); + } + + /* + * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN + * is suppressing them because the requested execution priority + * is less than 0. + */ + if (arm_feature(env, ARM_FEATURE_V8) && + !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) && + (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) { + DP_TBFLAG_M32(flags, STACKCHECK, 1); + } + + if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) { + DP_TBFLAG_M32(flags, SECURE, 1); + } + + return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); +} + +/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */ +static bool sme_fa64(CPUARMState *env, int el) +{ + if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) { + return false; + } + + if (el <= 1 && !el_is_in_host(env, el)) { + if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) { + return false; + } + } + if (el <= 2 && arm_is_el2_enabled(env)) { + if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) { + return false; + } + } + if (arm_feature(env, ARM_FEATURE_EL3)) { + if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) { + return false; + } + } + + return true; +} + +static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el, + ARMMMUIdx mmu_idx) +{ + CPUARMTBFlags flags = {}; + int el = arm_current_el(env); + + if (arm_sctlr(env, el) & SCTLR_A) { + DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); + } + + if (arm_el_is_aa64(env, 1)) { + DP_TBFLAG_A32(flags, VFPEN, 1); + } + + if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) && + (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) { + DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1); + } + + if (arm_fgt_active(env, el)) { + DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); + if (fgt_svc(env, el)) { + DP_TBFLAG_ANY(flags, FGT_SVC, 1); + } + } + + if (env->uncached_cpsr & CPSR_IL) { + DP_TBFLAG_ANY(flags, PSTATE__IL, 1); + } + + /* + * The SME exception we are testing for is raised via + * AArch64.CheckFPAdvSIMDEnabled(), as called from + * AArch32.CheckAdvSIMDOrFPEnabled(). + */ + if (el == 0 + && FIELD_EX64(env->svcr, SVCR, SM) + && (!arm_is_el2_enabled(env) + || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE))) + && arm_el_is_aa64(env, 1) + && !sme_fa64(env, el)) { + DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1); + } + + return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); +} + +static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, + ARMMMUIdx mmu_idx) +{ + CPUARMTBFlags flags = {}; + ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx); + uint64_t tcr = regime_tcr(env, mmu_idx); + uint64_t sctlr; + int tbii, tbid; + + DP_TBFLAG_ANY(flags, AARCH64_STATE, 1); + + /* Get control bits for tagged addresses. */ + tbid = aa64_va_parameter_tbi(tcr, mmu_idx); + tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx); + + DP_TBFLAG_A64(flags, TBII, tbii); + DP_TBFLAG_A64(flags, TBID, tbid); + + if (cpu_isar_feature(aa64_sve, env_archcpu(env))) { + int sve_el = sve_exception_el(env, el); + + /* + * If either FP or SVE are disabled, translator does not need len. + * If SVE EL > FP EL, FP exception has precedence, and translator + * does not need SVE EL. Save potential re-translations by forcing + * the unneeded data to zero. + */ + if (fp_el != 0) { + if (sve_el > fp_el) { + sve_el = 0; + } + } else if (sve_el == 0) { + DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el)); + } + DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el); + } + if (cpu_isar_feature(aa64_sme, env_archcpu(env))) { + int sme_el = sme_exception_el(env, el); + bool sm = FIELD_EX64(env->svcr, SVCR, SM); + + DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el); + if (sme_el == 0) { + /* Similarly, do not compute SVL if SME is disabled. */ + int svl = sve_vqm1_for_el_sm(env, el, true); + DP_TBFLAG_A64(flags, SVL, svl); + if (sm) { + /* If SVE is disabled, we will not have set VL above. */ + DP_TBFLAG_A64(flags, VL, svl); + } + } + if (sm) { + DP_TBFLAG_A64(flags, PSTATE_SM, 1); + DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el)); + } + DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA)); + } + + sctlr = regime_sctlr(env, stage1); + + if (sctlr & SCTLR_A) { + DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); + } + + if (arm_cpu_data_is_big_endian_a64(el, sctlr)) { + DP_TBFLAG_ANY(flags, BE_DATA, 1); + } + + if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) { + /* + * In order to save space in flags, we record only whether + * pauth is "inactive", meaning all insns are implemented as + * a nop, or "active" when some action must be performed. + * The decision of which action to take is left to a helper. + */ + if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) { + DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1); + } + } + + if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { + /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */ + if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) { + DP_TBFLAG_A64(flags, BT, 1); + } + } + + /* Compute the condition for using AccType_UNPRIV for LDTR et al. */ + if (!(env->pstate & PSTATE_UAO)) { + switch (mmu_idx) { + case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: + /* TODO: ARMv8.3-NV */ + DP_TBFLAG_A64(flags, UNPRIV, 1); + break; + case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: + /* + * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is + * gated by HCR_EL2. == '11', and so is LDTR. + */ + if (env->cp15.hcr_el2 & HCR_TGE) { + DP_TBFLAG_A64(flags, UNPRIV, 1); + } + break; + default: + break; + } + } + + if (env->pstate & PSTATE_IL) { + DP_TBFLAG_ANY(flags, PSTATE__IL, 1); + } + + if (arm_fgt_active(env, el)) { + DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); + if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) { + DP_TBFLAG_A64(flags, FGT_ERET, 1); + } + if (fgt_svc(env, el)) { + DP_TBFLAG_ANY(flags, FGT_SVC, 1); + } + } + + if (cpu_isar_feature(aa64_mte, env_archcpu(env))) { + /* + * Set MTE_ACTIVE if any access may be Checked, and leave clear + * if all accesses must be Unchecked: + * 1) If no TBI, then there are no tags in the address to check, + * 2) If Tag Check Override, then all accesses are Unchecked, + * 3) If Tag Check Fail == 0, then Checked access have no effect, + * 4) If no Allocation Tag Access, then all accesses are Unchecked. + */ + if (allocation_tag_access_enabled(env, el, sctlr)) { + DP_TBFLAG_A64(flags, ATA, 1); + if (tbid + && !(env->pstate & PSTATE_TCO) + && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) { + DP_TBFLAG_A64(flags, MTE_ACTIVE, 1); + } + } + /* And again for unprivileged accesses, if required. */ + if (EX_TBFLAG_A64(flags, UNPRIV) + && tbid + && !(env->pstate & PSTATE_TCO) + && (sctlr & SCTLR_TCF0) + && allocation_tag_access_enabled(env, 0, sctlr)) { + DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1); + } + /* Cache TCMA as well as TBI. */ + DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx)); + } + + return rebuild_hflags_common(env, fp_el, mmu_idx, flags); +} + +static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env) +{ + int el = arm_current_el(env); + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + + if (is_a64(env)) { + return rebuild_hflags_a64(env, el, fp_el, mmu_idx); + } else if (arm_feature(env, ARM_FEATURE_M)) { + return rebuild_hflags_m32(env, fp_el, mmu_idx); + } else { + return rebuild_hflags_a32(env, fp_el, mmu_idx); + } +} + +void arm_rebuild_hflags(CPUARMState *env) +{ + env->hflags = rebuild_hflags_internal(env); +} + +/* + * If we have triggered a EL state change we can't rely on the + * translator having passed it to us, we need to recompute. + */ +void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env) +{ + int el = arm_current_el(env); + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + + env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); +} + +void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el) +{ + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + + env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); +} + +/* + * If we have triggered a EL state change we can't rely on the + * translator having passed it to us, we need to recompute. + */ +void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env) +{ + int el = arm_current_el(env); + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); +} + +void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el) +{ + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + + env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); +} + +void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el) +{ + int fp_el = fp_exception_el(env, el); + ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); + + env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx); +} + +void assert_hflags_rebuild_correctly(CPUARMState *env) +{ +#ifdef CONFIG_DEBUG_TCG + CPUARMTBFlags c = env->hflags; + CPUARMTBFlags r = rebuild_hflags_internal(env); + + if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) { + fprintf(stderr, "TCG hflags mismatch " + "(current:(0x%08x,0x" TARGET_FMT_lx ")" + " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n", + c.flags, c.flags2, r.flags, r.flags2); + abort(); + } +#endif +} diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build index fa8a9eab93..d27e76af6c 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build @@ -24,6 +24,7 @@ arm_ss.add(files( 'translate-neon.c', 'translate-vfp.c', 'crypto_helper.c', + 'hflags.c', 'iwmmxt_helper.c', 'm_helper.c', 'mve_helper.c', From 2ea2998f27da92ae1225c1da95cee51a4a6783af Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:34 -0300 Subject: [PATCH 09/25] target/arm: Move regime_using_lpae_format into internal.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is needed by common code (ptw.c), so move it along with the other regime_* functions in internal.h. When we enable the build without TCG, the tlb_helper.c file will not be present. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- target/arm/internals.h | 21 ++++++++++++++++++--- target/arm/tcg/tlb_helper.c | 18 ------------------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index ed48f8c9a6..680c574717 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -600,9 +600,6 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx); /* Return the MMU index for a v7M CPU in the specified security state */ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate); -/* Return true if the translation regime is using LPAE format page tables */ -bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx); - /* * Return true if the stage 1 translation regime is using LPAE * format page tables @@ -767,6 +764,24 @@ static inline uint64_t regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx) return env->cp15.tcr_el[regime_el(env, mmu_idx)]; } +/* Return true if the translation regime is using LPAE format page tables */ +static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + int el = regime_el(env, mmu_idx); + if (el == 2 || arm_el_is_aa64(env, el)) { + return true; + } + if (arm_feature(env, ARM_FEATURE_PMSA) && + arm_feature(env, ARM_FEATURE_V8)) { + return true; + } + if (arm_feature(env, ARM_FEATURE_LPAE) + && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) { + return true; + } + return false; +} + /** * arm_num_brps: Return number of implemented breakpoints. * Note that the ID register BRPS field is "number of bps - 1", diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index 60abcbebe6..31eb77f7df 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -12,24 +12,6 @@ #include "exec/helper-proto.h" -/* Return true if the translation regime is using LPAE format page tables */ -bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - int el = regime_el(env, mmu_idx); - if (el == 2 || arm_el_is_aa64(env, el)) { - return true; - } - if (arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V8)) { - return true; - } - if (arm_feature(env, ARM_FEATURE_LPAE) - && (regime_tcr(env, mmu_idx) & TTBCR_EAE)) { - return true; - } - return false; -} - /* * Returns true if the stage 1 translation regime is using LPAE format page * tables. Used when raising alignment exceptions, whose FSR changes depending From 0d3de77a07f4f774f7a9248afa8ea497ad5f2ae5 Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:35 -0300 Subject: [PATCH 10/25] target/arm: Don't access TCG code when debugging with KVM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When TCG is disabled this part of the code should not be reachable, so wrap it with an ifdef for now. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- target/arm/ptw.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 2b125fff44..be0cc6bc15 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -254,6 +254,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, ptw->out_host = NULL; ptw->out_rw = false; } else { +#ifdef CONFIG_TCG CPUTLBEntryFull *full; int flags; @@ -270,6 +271,9 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, ptw->out_rw = full->prot & PAGE_WRITE; pte_attrs = full->pte_attrs; pte_secure = full->attrs.secure; +#else + g_assert_not_reached(); +#endif } if (regime_is_stage2(s2_mmu_idx)) { From 4cb884e994a85a86e4e305ea3e6296434f4af0df Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:36 -0300 Subject: [PATCH 11/25] cpu-defs.h: Expose CPUTLBEntryFull to non-TCG code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This struct has no dependencies on TCG code and it is being used in target/arm/ptw.c to simplify the passing around of page table walk results. Those routines can be reached by KVM code via the gdbstub breakpoint code, so take the structure out of CONFIG_TCG to make it visible when building with --disable-tcg. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- include/exec/cpu-defs.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 21309cf567..d5a4f30717 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -135,6 +135,10 @@ typedef struct CPUTLBEntry { QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS)); + +#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */ + +#if !defined(CONFIG_USER_ONLY) /* * The full TLB entry, which is not accessed by generated TCG code, * so the layout is not as critical as that of CPUTLBEntry. This is @@ -176,7 +180,9 @@ typedef struct CPUTLBEntryFull { TARGET_PAGE_ENTRY_EXTRA #endif } CPUTLBEntryFull; +#endif /* !CONFIG_USER_ONLY */ +#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG) /* * Data elements that are per MMU mode, minus the bits accessed by * the TCG fast path. From 9880e9bc63efcaf3f5230c2f93fb03068df2e465 Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Fri, 17 Feb 2023 17:11:46 -0300 Subject: [PATCH 12/25] tests/avocado: add machine:none tag to version.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test currently fails when run on a host for which the QEMU target has no default machine set: ERROR| Output: qemu-system-aarch64: No machine specified, and there is no default Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Fabiano Rosas Signed-off-by: Peter Maydell --- tests/avocado/version.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/avocado/version.py b/tests/avocado/version.py index ded7f039c1..dd775955eb 100644 --- a/tests/avocado/version.py +++ b/tests/avocado/version.py @@ -15,6 +15,7 @@ from avocado_qemu import QemuSystemTest class Version(QemuSystemTest): """ :avocado: tags=quick + :avocado: tags=machine:none """ def test_qmp_human_info_version(self): self.vm.add_args('-nodefaults') From cb4c33f014925d860387ecef4d74a7f03cab6626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:07 +0100 Subject: [PATCH 13/25] hw/gpio/max7310: Simplify max7310_realize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since &I2C_SLAVE(dev)->qdev == dev, no need to go back and forth with QOM type casting. Directly use 'dev'. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20230220115114.25237-2-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/gpio/max7310.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c index db6b5e3d76..031482d939 100644 --- a/hw/gpio/max7310.c +++ b/hw/gpio/max7310.c @@ -183,11 +183,10 @@ static void max7310_gpio_set(void *opaque, int line, int level) * but also accepts sequences that are not SMBus so return an I2C device. */ static void max7310_realize(DeviceState *dev, Error **errp) { - I2CSlave *i2c = I2C_SLAVE(dev); MAX7310State *s = MAX7310(dev); - qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8); - qdev_init_gpio_out(&i2c->qdev, s->handler, 8); + qdev_init_gpio_in(dev, max7310_gpio_set, ARRAY_SIZE(s->handler)); + qdev_init_gpio_out(dev, s->handler, ARRAY_SIZE(s->handler)); } static void max7310_class_init(ObjectClass *klass, void *data) From 11f2ee1db6ed333a74a71fa38ce66fda926e230d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:08 +0100 Subject: [PATCH 14/25] hw/char/pl011: Un-inline pl011_create() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pl011_create() is only used in DeviceRealize handlers, not a hot-path. Inlining is not justified. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20230220115114.25237-3-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/char/pl011.c | 17 +++++++++++++++++ include/hw/char/pl011.h | 19 +------------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/hw/char/pl011.c b/hw/char/pl011.c index c15cb7af20..77bbc2a982 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -19,10 +19,12 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/char/pl011.h" #include "hw/irq.h" #include "hw/sysbus.h" #include "hw/qdev-clock.h" +#include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "migration/vmstate.h" #include "chardev/char-fe.h" @@ -31,6 +33,21 @@ #include "qemu/module.h" #include "trace.h" +DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr) +{ + DeviceState *dev; + SysBusDevice *s; + + dev = qdev_new("pl011"); + s = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", chr); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, addr); + sysbus_connect_irq(s, 0, irq); + + return dev; +} + #define PL011_INT_TX 0x20 #define PL011_INT_RX 0x10 diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index 926322e242..d82870c006 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -15,10 +15,8 @@ #ifndef HW_PL011_H #define HW_PL011_H -#include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "chardev/char-fe.h" -#include "qapi/error.h" #include "qom/object.h" #define TYPE_PL011 "pl011" @@ -57,22 +55,7 @@ struct PL011State { const unsigned char *id; }; -static inline DeviceState *pl011_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new("pl011"); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - - return dev; -} +DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr); static inline DeviceState *pl011_luminary_create(hwaddr addr, qemu_irq irq, From b7f93098d1899c88eec4026b0a2118c94cbdefc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:09 +0100 Subject: [PATCH 15/25] hw/char/pl011: Open-code pl011_luminary_create() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pl011_luminary_create() is only used for the Stellaris board, open-code it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20230220115114.25237-4-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/arm/stellaris.c | 11 ++++++++--- include/hw/char/pl011.h | 17 ----------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 67a2293d35..f7e99baf62 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1146,9 +1146,14 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) for (i = 0; i < 4; i++) { if (board->dc2 & (1 << i)) { - pl011_luminary_create(0x4000c000 + i * 0x1000, - qdev_get_gpio_in(nvic, uart_irq[i]), - serial_hd(i)); + SysBusDevice *sbd; + + dev = qdev_new("pl011_luminary"); + sbd = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", serial_hd(i)); + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map(sbd, 0, 0x4000c000 + i * 0x1000); + sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i])); } } if (board->dc2 & (1 << 4)) { diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index d82870c006..d853802132 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -57,21 +57,4 @@ struct PL011State { DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr); -static inline DeviceState *pl011_luminary_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new("pl011_luminary"); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - - return dev; -} - #endif From 3440a4a93aebb2abe9d9ed6ba4a0f8db86b2a6ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:10 +0100 Subject: [PATCH 16/25] hw/char/xilinx_uartlite: Expose XILINX_UARTLITE QOM type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20230220115114.25237-5-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/char/xilinx_uartlite.c | 4 +--- include/hw/char/xilinx_uartlite.h | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index 99b9a6f851..180bb97202 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "hw/char/xilinx_uartlite.h" #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" @@ -53,9 +54,6 @@ #define CONTROL_RST_RX 0x02 #define CONTROL_IE 0x10 -#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite" -OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE) - struct XilinxUARTLite { SysBusDevice parent_obj; diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h index dd09c06801..753d3a453e 100644 --- a/include/hw/char/xilinx_uartlite.h +++ b/include/hw/char/xilinx_uartlite.h @@ -18,6 +18,10 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "qapi/error.h" +#include "qom/object.h" + +#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite" +OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE) static inline DeviceState *xilinx_uartlite_create(hwaddr addr, qemu_irq irq, @@ -26,7 +30,7 @@ static inline DeviceState *xilinx_uartlite_create(hwaddr addr, DeviceState *dev; SysBusDevice *s; - dev = qdev_new("xlnx.xps-uartlite"); + dev = qdev_new(TYPE_XILINX_UARTLITE); s = SYS_BUS_DEVICE(dev); qdev_prop_set_chr(dev, "chardev", chr); sysbus_realize_and_unref(s, &error_fatal); From dc1daf392c7cc6d1481bd9ce40a5594e624e7b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:11 +0100 Subject: [PATCH 17/25] hw/char/xilinx_uartlite: Open-code xilinx_uartlite_create() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Open-code the single use of xilinx_uartlite_create(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20230220115114.25237-6-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/microblaze/petalogix_s3adsp1800_mmu.c | 7 +++++-- include/hw/char/xilinx_uartlite.h | 20 -------------------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index 9d959d1ad8..505639c298 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -100,8 +100,11 @@ petalogix_s3adsp1800_init(MachineState *machine) irq[i] = qdev_get_gpio_in(dev, i); } - xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ], - serial_hd(0)); + dev = qdev_new(TYPE_XILINX_UARTLITE); + qdev_prop_set_chr(dev, "chardev", serial_hd(0)); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]); /* 2 timers at irq 2 @ 62 Mhz. */ dev = qdev_new("xlnx.xps-timer"); diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h index 753d3a453e..36d4e8444d 100644 --- a/include/hw/char/xilinx_uartlite.h +++ b/include/hw/char/xilinx_uartlite.h @@ -15,29 +15,9 @@ #ifndef XILINX_UARTLITE_H #define XILINX_UARTLITE_H -#include "hw/qdev-properties.h" -#include "hw/sysbus.h" -#include "qapi/error.h" #include "qom/object.h" #define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite" OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE) -static inline DeviceState *xilinx_uartlite_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new(TYPE_XILINX_UARTLITE); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - - return dev; -} - #endif From 4ab694b9a81df82f3ac7ce1e59f7855c57af2eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:12 +0100 Subject: [PATCH 18/25] hw/char/cmsdk-apb-uart: Open-code cmsdk_apb_uart_create() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmsdk_apb_uart_create() is only used twice in the same file. Open-code it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Message-id: 20230220115114.25237-7-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/arm/mps2.c | 41 +++++++++++++++++++++----------- include/hw/char/cmsdk-apb-uart.h | 34 -------------------------- 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index a86a994dba..d92fd60684 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -35,6 +35,7 @@ #include "hw/boards.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" +#include "hw/qdev-properties.h" #include "hw/misc/unimp.h" #include "hw/char/cmsdk-apb-uart.h" #include "hw/timer/cmsdk-apb-timer.h" @@ -282,6 +283,9 @@ static void mps2_common_init(MachineState *machine) qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12)); for (i = 0; i < 5; i++) { + DeviceState *dev; + SysBusDevice *s; + static const hwaddr uartbase[] = {0x40004000, 0x40005000, 0x40006000, 0x40007000, 0x40009000}; @@ -294,12 +298,16 @@ static void mps2_common_init(MachineState *machine) rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1); } - cmsdk_apb_uart_create(uartbase[i], - qdev_get_gpio_in(armv7m, uartirq[i] + 1), - qdev_get_gpio_in(armv7m, uartirq[i]), - txovrint, rxovrint, - NULL, - serial_hd(i), SYSCLK_FRQ); + dev = qdev_new(TYPE_CMSDK_APB_UART); + s = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", serial_hd(i)); + qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, uartbase[i]); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1)); + sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i])); + sysbus_connect_irq(s, 2, txovrint); + sysbus_connect_irq(s, 3, rxovrint); } break; } @@ -324,7 +332,8 @@ static void mps2_common_init(MachineState *machine) 0x4002c000, 0x4002d000, 0x4002e000}; Object *txrx_orgate; - DeviceState *txrx_orgate_dev; + DeviceState *txrx_orgate_dev, *dev; + SysBusDevice *s; txrx_orgate = object_new(TYPE_OR_IRQ); object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal); @@ -332,13 +341,17 @@ static void mps2_common_init(MachineState *machine) txrx_orgate_dev = DEVICE(txrx_orgate); qdev_connect_gpio_out(txrx_orgate_dev, 0, qdev_get_gpio_in(armv7m, uart_txrx_irqno[i])); - cmsdk_apb_uart_create(uartbase[i], - qdev_get_gpio_in(txrx_orgate_dev, 0), - qdev_get_gpio_in(txrx_orgate_dev, 1), - qdev_get_gpio_in(orgate_dev, i * 2), - qdev_get_gpio_in(orgate_dev, i * 2 + 1), - NULL, - serial_hd(i), SYSCLK_FRQ); + + dev = qdev_new(TYPE_CMSDK_APB_UART); + s = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", serial_hd(i)); + qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, uartbase[i]); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0)); + sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1)); + sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2)); + sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1)); } break; } diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h index 64b0a3d534..7de8f8d1b9 100644 --- a/include/hw/char/cmsdk-apb-uart.h +++ b/include/hw/char/cmsdk-apb-uart.h @@ -12,10 +12,8 @@ #ifndef CMSDK_APB_UART_H #define CMSDK_APB_UART_H -#include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "chardev/char-fe.h" -#include "qapi/error.h" #include "qom/object.h" #define TYPE_CMSDK_APB_UART "cmsdk-apb-uart" @@ -45,36 +43,4 @@ struct CMSDKAPBUART { uint8_t rxbuf; }; -/** - * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART - * @addr: location in system memory to map registers - * @chr: Chardev backend to connect UART to, or NULL if no backend - * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate) - */ -static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr, - qemu_irq txint, - qemu_irq rxint, - qemu_irq txovrint, - qemu_irq rxovrint, - qemu_irq uartint, - Chardev *chr, - uint32_t pclk_frq) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new(TYPE_CMSDK_APB_UART); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, txint); - sysbus_connect_irq(s, 1, rxint); - sysbus_connect_irq(s, 2, txovrint); - sysbus_connect_irq(s, 3, rxovrint); - sysbus_connect_irq(s, 4, uartint); - return dev; -} - #endif From 7c72f2196ac3d1fe46e4f0bff103beef2b555633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:13 +0100 Subject: [PATCH 19/25] hw/timer/cmsdk-apb-timer: Remove unused 'qdev-properties.h' header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Message-id: 20230220115114.25237-8-philmd@linaro.org Signed-off-by: Peter Maydell --- include/hw/timer/cmsdk-apb-timer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h index c4c7eae849..2dd615d1be 100644 --- a/include/hw/timer/cmsdk-apb-timer.h +++ b/include/hw/timer/cmsdk-apb-timer.h @@ -12,7 +12,6 @@ #ifndef CMSDK_APB_TIMER_H #define CMSDK_APB_TIMER_H -#include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "hw/ptimer.h" #include "hw/clock.h" From d4fb55a6083c8535ad7b46019ae3cbc1be5497e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 20 Feb 2023 12:51:14 +0100 Subject: [PATCH 20/25] hw/intc/armv7m_nvic: Use QOM cast CPU() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid accessing 'parent_obj' directly. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alex Bennée Message-id: 20230220115114.25237-9-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/intc/armv7m_nvic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 8e289051a4..63afe1fdf5 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -578,7 +578,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure, * which saves having to have an extra argument is_terminal * that we'd only use in one place. */ - cpu_abort(&s->cpu->parent_obj, + cpu_abort(CPU(s->cpu), "Lockup: can't take terminal derived exception " "(original exception priority %d)\n", s->vectpending_prio); @@ -644,7 +644,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure, * Lockup condition due to a guest bug. We don't model * Lockup, so report via cpu_abort() instead. */ - cpu_abort(&s->cpu->parent_obj, + cpu_abort(CPU(s->cpu), "Lockup: can't escalate %d to HardFault " "(current priority %d)\n", irq, running); } @@ -742,7 +742,7 @@ void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure) * We want to escalate to HardFault but the context the * FP state belongs to prevents the exception pre-empting. */ - cpu_abort(&s->cpu->parent_obj, + cpu_abort(CPU(s->cpu), "Lockup: can't escalate to HardFault during " "lazy FP register stacking\n"); } From 799d6a3c9923308f8ae7d12438e0723c4eadd124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 9 Jan 2023 10:26:09 +0100 Subject: [PATCH 21/25] hw/arm/musicpal: Remove unused dummy MemoryRegion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell --- hw/arm/musicpal.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 89b66606c3..06d9add7c7 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1072,7 +1072,6 @@ struct musicpal_key_state { SysBusDevice parent_obj; /*< public >*/ - MemoryRegion iomem; uint32_t kbd_extended; uint32_t pressed_keys; qemu_irq out[8]; @@ -1161,9 +1160,6 @@ static void musicpal_key_init(Object *obj) DeviceState *dev = DEVICE(sbd); musicpal_key_state *s = MUSICPAL_KEY(dev); - memory_region_init(&s->iomem, obj, "dummy", 0); - sysbus_init_mmio(sbd, &s->iomem); - s->kbd_extended = 0; s->pressed_keys = 0; From dc892d1e4c8d3682d624725d7cfeee90f35d6eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Jan 2023 21:01:35 +0100 Subject: [PATCH 22/25] iothread: Remove unused IOThreadClass / IOTHREAD_CLASS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit be8d853766 ("iothread: add I/O thread object") we never used IOThreadClass / IOTHREAD_CLASS() / IOTHREAD_GET_CLASS(), remove these definitions. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Reviewed-by: Alistair Francis Message-id: 20230113200138.52869-2-philmd@linaro.org Signed-off-by: Peter Maydell --- iothread.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/iothread.c b/iothread.c index 3862a64471..b41c305bd9 100644 --- a/iothread.c +++ b/iothread.c @@ -25,10 +25,6 @@ #include "qemu/rcu.h" #include "qemu/main-loop.h" -typedef ObjectClass IOThreadClass; - -DECLARE_CLASS_CHECKERS(IOThreadClass, IOTHREAD, - TYPE_IOTHREAD) #ifdef CONFIG_POSIX /* Benchmark results from 2016 on NVMe SSD drives show max polling times around From 4703f6c2f7a982ccc6e970ad3010bfe1203a828d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Jan 2023 21:01:36 +0100 Subject: [PATCH 23/25] hw/irq: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QOM *DECLARE* macros expect a typedef as first argument, not a structure. Replace 'struct IRQState' by 'IRQState' to avoid when modifying the macros: ../hw/core/irq.c:29:1: error: declaration of anonymous struct must be a definition DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ, ^ Use OBJECT_DECLARE_SIMPLE_TYPE instead of DECLARE_INSTANCE_CHECKER. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Reviewed-by: Alistair Francis Message-id: 20230113200138.52869-3-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/core/irq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/core/irq.c b/hw/core/irq.c index 3623f711fe..3f14e2dda7 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -26,8 +26,7 @@ #include "hw/irq.h" #include "qom/object.h" -DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ, - TYPE_IRQ) +OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ) struct IRQState { Object parent_obj; @@ -68,7 +67,7 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) { - struct IRQState *irq; + IRQState *irq; irq = IRQ(object_new(TYPE_IRQ)); irq->handler = handler; @@ -94,7 +93,7 @@ void qemu_free_irq(qemu_irq irq) static void qemu_notirq(void *opaque, int line, int level) { - struct IRQState *irq = opaque; + IRQState *irq = opaque; irq->handler(irq->opaque, irq->n, !level); } @@ -120,7 +119,7 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) static const TypeInfo irq_type_info = { .name = TYPE_IRQ, .parent = TYPE_OBJECT, - .instance_size = sizeof(struct IRQState), + .instance_size = sizeof(IRQState), }; static void irq_register_types(void) From 60d3ccfbe119974d3adda799de85cdae698c5434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Jan 2023 21:01:37 +0100 Subject: [PATCH 24/25] hw/or-irq: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missed during automatic conversion from commit 8063396bf3 ("Use OBJECT_DECLARE_SIMPLE_TYPE when possible"). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Reviewed-by: Alistair Francis Message-id: 20230113200138.52869-4-philmd@linaro.org Signed-off-by: Peter Maydell --- include/hw/or-irq.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h index f2f0a27381..131abc2e0c 100644 --- a/include/hw/or-irq.h +++ b/include/hw/or-irq.h @@ -37,8 +37,7 @@ typedef struct OrIRQState qemu_or_irq; -DECLARE_INSTANCE_CHECKER(qemu_or_irq, OR_IRQ, - TYPE_OR_IRQ) +OBJECT_DECLARE_SIMPLE_TYPE(OrIRQState, OR_IRQ) struct OrIRQState { DeviceState parent_obj; From e844f0c5d0bd2c4d8d3c1622eb2a88586c9c4677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Jan 2023 21:01:38 +0100 Subject: [PATCH 25/25] hw: Replace qemu_or_irq typedef by OrIRQState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OBJECT_DECLARE_SIMPLE_TYPE() macro provides the OrIRQState declaration for free. Besides, the QOM code style is to use the structure name as typedef, and QEMU style is to use Camel Case, so rename qemu_or_irq as OrIRQState. Mechanical change using: $ sed -i -e 's/qemu_or_irq/OrIRQState/g' $(git grep -l qemu_or_irq) Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Hajnoczi Reviewed-by: Alistair Francis Message-id: 20230113200138.52869-5-philmd@linaro.org Signed-off-by: Peter Maydell --- hw/arm/exynos4210.c | 4 ++-- hw/arm/mps2-tz.c | 2 +- hw/core/or-irq.c | 18 +++++++++--------- hw/pci-host/raven.c | 2 +- include/hw/arm/armsse.h | 6 +++--- include/hw/arm/bcm2835_peripherals.h | 2 +- include/hw/arm/exynos4210.h | 4 ++-- include/hw/arm/stm32f205_soc.h | 2 +- include/hw/arm/stm32f405_soc.h | 2 +- include/hw/arm/xlnx-versal.h | 6 +++--- include/hw/arm/xlnx-zynqmp.h | 2 +- include/hw/or-irq.h | 2 -- 12 files changed, 25 insertions(+), 27 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 8dafa2215b..6f2dda13f6 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -507,7 +507,7 @@ static uint64_t exynos4210_calc_affinity(int cpu) return (0x9 << ARM_AFF1_SHIFT) | cpu; } -static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate, +static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate, qemu_irq irq, int nreq, int nevents, int width) { SysBusDevice *busdev; @@ -806,7 +806,7 @@ static void exynos4210_init(Object *obj) for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) { char *name = g_strdup_printf("pl330-irq-orgate%d", i); - qemu_or_irq *orgate = &s->pl330_irq_orgate[i]; + OrIRQState *orgate = &s->pl330_irq_orgate[i]; object_initialize_child(obj, name, orgate, TYPE_OR_IRQ); g_free(name); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 284c09c91d..07aecd9497 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -152,7 +152,7 @@ struct MPS2TZMachineState { TZMSC msc[4]; CMSDKAPBUART uart[6]; SplitIRQ sec_resp_splitter; - qemu_or_irq uart_irq_orgate; + OrIRQState uart_irq_orgate; DeviceState *lan9118; SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX]; Clock *sysclk; diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c index d8f3754e96..1df4bc05a7 100644 --- a/hw/core/or-irq.c +++ b/hw/core/or-irq.c @@ -31,7 +31,7 @@ static void or_irq_handler(void *opaque, int n, int level) { - qemu_or_irq *s = OR_IRQ(opaque); + OrIRQState *s = OR_IRQ(opaque); int or_level = 0; int i; @@ -46,7 +46,7 @@ static void or_irq_handler(void *opaque, int n, int level) static void or_irq_reset(DeviceState *dev) { - qemu_or_irq *s = OR_IRQ(dev); + OrIRQState *s = OR_IRQ(dev); int i; for (i = 0; i < MAX_OR_LINES; i++) { @@ -56,7 +56,7 @@ static void or_irq_reset(DeviceState *dev) static void or_irq_realize(DeviceState *dev, Error **errp) { - qemu_or_irq *s = OR_IRQ(dev); + OrIRQState *s = OR_IRQ(dev); assert(s->num_lines <= MAX_OR_LINES); @@ -65,7 +65,7 @@ static void or_irq_realize(DeviceState *dev, Error **errp) static void or_irq_init(Object *obj) { - qemu_or_irq *s = OR_IRQ(obj); + OrIRQState *s = OR_IRQ(obj); qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1); } @@ -84,7 +84,7 @@ static void or_irq_init(Object *obj) static bool vmstate_extras_needed(void *opaque) { - qemu_or_irq *s = OR_IRQ(opaque); + OrIRQState *s = OR_IRQ(opaque); return s->num_lines >= OLD_MAX_OR_LINES; } @@ -95,7 +95,7 @@ static const VMStateDescription vmstate_or_irq_extras = { .minimum_version_id = 1, .needed = vmstate_extras_needed, .fields = (VMStateField[]) { - VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0, + VMSTATE_VARRAY_UINT16_UNSAFE(levels, OrIRQState, num_lines, 0, vmstate_info_bool, bool), VMSTATE_END_OF_LIST(), }, @@ -106,7 +106,7 @@ static const VMStateDescription vmstate_or_irq = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES), + VMSTATE_BOOL_SUB_ARRAY(levels, OrIRQState, 0, OLD_MAX_OR_LINES), VMSTATE_END_OF_LIST(), }, .subsections = (const VMStateDescription*[]) { @@ -116,7 +116,7 @@ static const VMStateDescription vmstate_or_irq = { }; static Property or_irq_properties[] = { - DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1), + DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1), DEFINE_PROP_END_OF_LIST(), }; @@ -136,7 +136,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data) static const TypeInfo or_irq_type_info = { .name = TYPE_OR_IRQ, .parent = TYPE_DEVICE, - .instance_size = sizeof(qemu_or_irq), + .instance_size = sizeof(OrIRQState), .instance_init = or_irq_init, .class_init = or_irq_class_init, }; diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c index cdfb62ac2e..072ffe3c5e 100644 --- a/hw/pci-host/raven.c +++ b/hw/pci-host/raven.c @@ -60,7 +60,7 @@ DECLARE_INSTANCE_CHECKER(PREPPCIState, RAVEN_PCI_HOST_BRIDGE, struct PRePPCIState { PCIHostState parent_obj; - qemu_or_irq *or_irq; + OrIRQState *or_irq; qemu_irq pci_irqs[PCI_NUM_PINS]; PCIBus pci_bus; AddressSpace pci_io_as; diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 9648e7a419..cd0931d0a0 100644 --- a/include/hw/arm/armsse.h +++ b/include/hw/arm/armsse.h @@ -155,12 +155,12 @@ struct ARMSSE { TZPPC apb_ppc[NUM_INTERNAL_PPCS]; TZMPC mpc[IOTS_NUM_MPC]; CMSDKAPBTimer timer[3]; - qemu_or_irq ppc_irq_orgate; + OrIRQState ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; - qemu_or_irq mpc_irq_orgate; - qemu_or_irq nmi_orgate; + OrIRQState mpc_irq_orgate; + OrIRQState nmi_orgate; SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS]; diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h index c9d25d493e..d724a2fc28 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -56,7 +56,7 @@ struct BCM2835PeripheralState { BCM2835AuxState aux; BCM2835FBState fb; BCM2835DMAState dma; - qemu_or_irq orgated_dma_irq; + OrIRQState orgated_dma_irq; BCM2835ICState ic; BCM2835PropertyState property; BCM2835RngState rng; diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 97353f1c02..68db19f0cb 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -96,8 +96,8 @@ struct Exynos4210State { MemoryRegion boot_secondary; MemoryRegion bootreg_mem; I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; - qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; - qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS]; + OrIRQState pl330_irq_orgate[EXYNOS4210_NUM_DMA]; + OrIRQState cpu_irq_orgate[EXYNOS4210_NCPUS]; A9MPPrivState a9mpcore; Exynos4210GicState ext_gic; Exynos4210CombinerState int_combiner; diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h index 849d3ed889..5a4f776264 100644 --- a/include/hw/arm/stm32f205_soc.h +++ b/include/hw/arm/stm32f205_soc.h @@ -63,7 +63,7 @@ struct STM32F205State { STM32F2XXADCState adc[STM_NUM_ADCS]; STM32F2XXSPIState spi[STM_NUM_SPIS]; - qemu_or_irq *adc_irqs; + OrIRQState *adc_irqs; MemoryRegion sram; MemoryRegion flash; diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h index 249ab5434e..c968ce3ab2 100644 --- a/include/hw/arm/stm32f405_soc.h +++ b/include/hw/arm/stm32f405_soc.h @@ -63,7 +63,7 @@ struct STM32F405State { STM32F4xxExtiState exti; STM32F2XXUsartState usart[STM_NUM_USARTS]; STM32F2XXTimerState timer[STM_NUM_TIMERS]; - qemu_or_irq adc_irqs; + OrIRQState adc_irqs; STM32F2XXADCState adc[STM_NUM_ADCS]; STM32F2XXSPIState spi[STM_NUM_SPIS]; diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index cbe8a19c10..b6786e9832 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -85,7 +85,7 @@ struct Versal { } rpu; struct { - qemu_or_irq irq_orgate; + OrIRQState irq_orgate; XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM]; } xram; @@ -103,7 +103,7 @@ struct Versal { XlnxCSUDMA dma_src; XlnxCSUDMA dma_dst; MemoryRegion linear_mr; - qemu_or_irq irq_orgate; + OrIRQState irq_orgate; } ospi; } iou; @@ -113,7 +113,7 @@ struct Versal { XlnxVersalEFuseCtrl efuse_ctrl; XlnxVersalEFuseCache efuse_cache; - qemu_or_irq apb_irq_orgate; + OrIRQState apb_irq_orgate; } pmc; struct { diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 20bdf894aa..687c75e3b0 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -130,7 +130,7 @@ struct XlnxZynqMPState { XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH]; XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH]; XlnxCSUDMA qspi_dma; - qemu_or_irq qspi_irq_orgate; + OrIRQState qspi_irq_orgate; XlnxZynqMPAPUCtrl apu_ctrl; XlnxZynqMPCRF crf; CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC]; diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h index 131abc2e0c..c0a42f3711 100644 --- a/include/hw/or-irq.h +++ b/include/hw/or-irq.h @@ -35,8 +35,6 @@ */ #define MAX_OR_LINES 48 -typedef struct OrIRQState qemu_or_irq; - OBJECT_DECLARE_SIMPLE_TYPE(OrIRQState, OR_IRQ) struct OrIRQState {