From patchwork Wed Feb 26 18:02:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 25431 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qa0-f71.google.com (mail-qa0-f71.google.com [209.85.216.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7663120636 for ; Wed, 26 Feb 2014 20:13:05 +0000 (UTC) Received: by mail-qa0-f71.google.com with SMTP id j7sf4798200qaq.10 for ; Wed, 26 Feb 2014 12:13:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=2e/APFWshPXHr3qHXL224iu3iyy8nWRi0EmZz7y8niM=; b=ObeuqPJeJDs/4PMQPux3MhJ6pzLW2SU4/r1GaudsKNC2EgysKfSz5Fm32Mbr0/cE2z F7Te4/d7FAuB/8uZZdc+i/h4vUkAKhorMlRF/nWqAN4SomW2irAl9vDQPo7loUZaprQN zKV/PUeeFzMyyRT6sJJ6BjqLhvQkS0IESGEtYUCyGE9uAaJc3pN9Jsbl6O6MXkm5qK9T To3r8Tg/XgXznXmCc4D/QLKeO6BN6bXyZPlZPxdXtG8T6piR2l/Bd/jvd3QJMulpCD4I +GfHTzryQd5JQQfs0wCiJzSA2Ri9E/0Sf0LPc4KVYa5wI59qcQdIs8PPWm6MIP73DNnZ UCWA== X-Gm-Message-State: ALoCoQkKS73GXycWB7DqH4fTKFMFH/4/gFYvqTznjF+4LuAmcE3SkreM2tWpU0yUHbEyPUlaX5tN X-Received: by 10.58.136.35 with SMTP id px3mr4297031veb.31.1393445585283; Wed, 26 Feb 2014 12:13:05 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.83.169 with SMTP id j38ls425516qgd.10.gmail; Wed, 26 Feb 2014 12:13:05 -0800 (PST) X-Received: by 10.58.37.67 with SMTP id w3mr7282309vej.22.1393445585144; Wed, 26 Feb 2014 12:13:05 -0800 (PST) Received: from mail-ve0-f179.google.com (mail-ve0-f179.google.com [209.85.128.179]) by mx.google.com with ESMTPS id cz20si521774veb.53.2014.02.26.12.13.05 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 26 Feb 2014 12:13:05 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.179; Received: by mail-ve0-f179.google.com with SMTP id oz11so2731482veb.24 for ; Wed, 26 Feb 2014 12:13:05 -0800 (PST) X-Received: by 10.220.106.84 with SMTP id w20mr7349998vco.18.1393445585001; Wed, 26 Feb 2014 12:13:05 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp51947vcz; Wed, 26 Feb 2014 12:13:04 -0800 (PST) X-Received: by 10.229.172.4 with SMTP id j4mr13209989qcz.6.1393445584383; Wed, 26 Feb 2014 12:13:04 -0800 (PST) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d67si668620qgf.125.2014.02.26.12.13.04 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 26 Feb 2014 12:13:04 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:42199 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIivu-00021I-EB for patch@linaro.org; Wed, 26 Feb 2014 13:10:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34062) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIiol-0000qi-Ju for qemu-devel@nongnu.org; Wed, 26 Feb 2014 13:02:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WIiok-0007M4-1z for qemu-devel@nongnu.org; Wed, 26 Feb 2014 13:02:51 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:46191) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIioj-0007Eu-MX for qemu-devel@nongnu.org; Wed, 26 Feb 2014 13:02:49 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WIioX-0006CV-5S; Wed, 26 Feb 2014 18:02:37 +0000 From: Peter Maydell To: Anthony Liguori Date: Wed, 26 Feb 2014 18:02:23 +0000 Message-Id: <1393437755-23586-34-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1393437755-23586-1-git-send-email-peter.maydell@linaro.org> References: <1393437755-23586-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 33/45] target-arm: Store AIF bits in env->pstate for AArch32 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 To avoid complication in code that otherwise would not need to care about whether EL1 is AArch32 or AArch64, we should store the interrupt mask bits (CPSR.AIF in AArch32 and PSTATE.DAIF in AArch64) in one place consistently regardless of EL1's mode. Since AArch64 has an extra enable bit (D for debug exceptions) which isn't visible in AArch32, this means we need to keep the enables in env->pstate. (This is also consistent with the general approach we're taking that we handle 32 bit CPUs as being like AArch64/ARMv8 CPUs but which only run in 32 bit mode.) Signed-off-by: Peter Maydell Reviewed-by: Peter Crosthwaite --- cpu-exec.c | 4 ++-- hw/arm/pxa2xx.c | 4 ++-- target-arm/cpu.c | 8 ++++---- target-arm/cpu.h | 12 +++++++++--- target-arm/helper.c | 29 +++++++++++++++++------------ 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 8943493..1b0f617 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -477,7 +477,7 @@ int cpu_exec(CPUArchState *env) } #elif defined(TARGET_ARM) if (interrupt_request & CPU_INTERRUPT_FIQ - && !(env->uncached_cpsr & CPSR_F)) { + && !(env->daif & PSTATE_F)) { env->exception_index = EXCP_FIQ; cc->do_interrupt(cpu); next_tb = 0; @@ -493,7 +493,7 @@ int cpu_exec(CPUArchState *env) pc contains a magic address. */ if (interrupt_request & CPU_INTERRUPT_HARD && ((IS_M(env) && env->regs[15] < 0xfffffff0) - || !(env->uncached_cpsr & CPSR_I))) { + || !(env->daif & PSTATE_I))) { env->exception_index = EXCP_IRQ; cc->do_interrupt(cpu); next_tb = 0; diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 5579036..904277a 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -272,8 +272,8 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, goto message; case 3: - s->cpu->env.uncached_cpsr = - ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; + s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC; + s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I; s->cpu->env.cp15.c1_sys = 0; s->cpu->env.cp15.c1_coproc = 0; s->cpu->env.cp15.ttbr0_el1 = 0; diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 2f94943..7384e17 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -94,8 +94,7 @@ static void arm_cpu_reset(CPUState *s) /* Userspace expects access to CTL_EL0 and the cache ops */ env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI; #else - env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F - | PSTATE_MODE_EL1h; + env->pstate = PSTATE_MODE_EL1h; #endif } @@ -110,13 +109,14 @@ static void arm_cpu_reset(CPUState *s) } #else /* SVC mode with interrupts disabled. */ - env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; + env->uncached_cpsr = ARM_CPU_MODE_SVC; + env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is clear at reset. Initial SP and PC are loaded from ROM. */ if (IS_M(env)) { uint32_t pc; uint8_t *rom; - env->uncached_cpsr &= ~CPSR_I; + env->daif &= ~PSTATE_I; rom = rom_ptr(0); if (rom) { /* We should really use ldl_phys here, in case the guest diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 9fe7da2..67e935d 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -135,6 +135,7 @@ typedef struct CPUARMState { * NZCV are kept in the split out env->CF/VF/NF/ZF, (which have the same * semantics as for AArch32, as described in the comments on each field) * nRW (also known as M[4]) is kept, inverted, in env->aarch64 + * DAIF (exception masks) are kept in env->daif * all other bits are stored in their correct places in env->pstate */ uint32_t pstate; @@ -164,6 +165,7 @@ typedef struct CPUARMState { uint32_t GE; /* cpsr[19:16] */ uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */ uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */ + uint32_t daif; /* exception masks, in the bits they are in in PSTATE */ /* System control coprocessor (cp15) */ struct { @@ -406,9 +408,11 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, #define CPSR_Z (1U << 30) #define CPSR_N (1U << 31) #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) +#define CPSR_AIF (CPSR_A | CPSR_I | CPSR_F) #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7) -#define CACHED_CPSR_BITS (CPSR_T | CPSR_GE | CPSR_IT | CPSR_Q | CPSR_NZCV) +#define CACHED_CPSR_BITS (CPSR_T | CPSR_AIF | CPSR_GE | CPSR_IT | CPSR_Q \ + | CPSR_NZCV) /* Bits writable in user mode. */ #define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE) /* Execution state bits. MRS read as zero, MSR writes ignored. */ @@ -431,7 +435,8 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, #define PSTATE_Z (1U << 30) #define PSTATE_N (1U << 31) #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V) -#define CACHED_PSTATE_BITS (PSTATE_NZCV) +#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F) +#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF) /* Mode values for AArch64 */ #define PSTATE_MODE_EL3h 13 #define PSTATE_MODE_EL3t 12 @@ -452,7 +457,7 @@ static inline uint32_t pstate_read(CPUARMState *env) ZF = (env->ZF == 0); return (env->NF & 0x80000000) | (ZF << 30) | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) - | env->pstate; + | env->pstate | env->daif; } static inline void pstate_write(CPUARMState *env, uint32_t val) @@ -461,6 +466,7 @@ static inline void pstate_write(CPUARMState *env, uint32_t val) env->NF = val; env->CF = (val >> 29) & 1; env->VF = (val << 3) & 0x80000000; + env->daif = val & PSTATE_DAIF; env->pstate = val & ~CACHED_PSTATE_BITS; } diff --git a/target-arm/helper.c b/target-arm/helper.c index 61303b6..01d1ef6 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2475,7 +2475,7 @@ uint32_t cpsr_read(CPUARMState *env) (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) | ((env->condexec_bits & 0xfc) << 8) - | (env->GE << 16); + | (env->GE << 16) | env->daif; } void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) @@ -2502,6 +2502,9 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) env->GE = (val >> 16) & 0xf; } + env->daif &= ~(CPSR_AIF & mask); + env->daif |= val & CPSR_AIF & mask; + if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { if (bad_mode_switch(env, val & CPSR_M)) { /* Attempt to switch to an invalid mode: this is UNPREDICTABLE. @@ -2963,7 +2966,7 @@ void arm_cpu_do_interrupt(CPUState *cs) env->condexec_bits = 0; /* Switch to the new mode, and to the correct instruction set. */ env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; - env->uncached_cpsr |= mask; + env->daif |= mask; /* this is a lie, as the was no c1_sys on V4T/V5, but who cares * and we should just guard the thumb mode on V4 */ if (arm_feature(env, ARM_FEATURE_V4T)) { @@ -3636,12 +3639,12 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) case 9: /* PSP */ return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ - return (env->uncached_cpsr & CPSR_I) != 0; + return (env->daif & PSTATE_I) != 0; case 17: /* BASEPRI */ case 18: /* BASEPRI_MAX */ return env->v7m.basepri; case 19: /* FAULTMASK */ - return (env->uncached_cpsr & CPSR_F) != 0; + return (env->daif & PSTATE_F) != 0; case 20: /* CONTROL */ return env->v7m.control; default: @@ -3688,10 +3691,11 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) env->v7m.other_sp = val; break; case 16: /* PRIMASK */ - if (val & 1) - env->uncached_cpsr |= CPSR_I; - else - env->uncached_cpsr &= ~CPSR_I; + if (val & 1) { + env->daif |= PSTATE_I; + } else { + env->daif &= ~PSTATE_I; + } break; case 17: /* BASEPRI */ env->v7m.basepri = val & 0xff; @@ -3702,10 +3706,11 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) env->v7m.basepri = val; break; case 19: /* FAULTMASK */ - if (val & 1) - env->uncached_cpsr |= CPSR_F; - else - env->uncached_cpsr &= ~CPSR_F; + if (val & 1) { + env->daif |= PSTATE_F; + } else { + env->daif &= ~PSTATE_F; + } break; case 20: /* CONTROL */ env->v7m.control = val & 3;