From patchwork Mon Jun 2 16:21:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 31302 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f70.google.com (mail-pb0-f70.google.com [209.85.160.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 836E0203C2 for ; Mon, 2 Jun 2014 17:22:55 +0000 (UTC) Received: by mail-pb0-f70.google.com with SMTP id rq2sf20505394pbb.1 for ; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) 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=X82F161qKk9KVdsAxzR2YX3KqTOFbWrfgklQMk1oBTA=; b=CXE0dGvf7Ptb6xAsu/YKkbZ17xag/pqovVz4WLIOVfhxvbh701L6qTpUXBkRa90nso QFd3BWxlGB9xZcL1KZi8obEfSUONtRv9GJ9Rg6Id9RYxkvYGewtNtHSOBF0cWVC8THD7 KqxL12V3fJhbji148hZgZ7A+RIRpl4hKIUL2MLTyQ/+O9qDjzjoUwsiEeYnQ3Vyxk9Ht tQo43jT2XgJZAWsYpc0E6bwyL9SjpZmM8Oow8UgUx1vXXRUmAMnb5M0NJuaeR0E5ZE2v 5k3muaE9CqQV5FTHF9+VvqKNECIc79zZdLRVaZ876pQsmyKl1ucGgJ8UGY74goTzhuRb L6xw== X-Gm-Message-State: ALoCoQmaSQNU4t3PRY8v8Ul4KExoBMssG9ZTzzWGihgfdOR/FZq3YfoAgDS5cSWcgMQnyHZquE7h X-Received: by 10.66.66.35 with SMTP id c3mr15355665pat.7.1401729774756; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.22.145 with SMTP id 17ls2137951qgn.21.gmail; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) X-Received: by 10.220.89.4 with SMTP id c4mr1962225vcm.53.1401729774443; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id xy4si8294544vcb.35.2014.06.02.10.22.54 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 02 Jun 2014 10:22:54 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id la4so5438631vcb.35 for ; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) X-Received: by 10.58.185.165 with SMTP id fd5mr2281188vec.41.1401729774301; Mon, 02 Jun 2014 10:22:54 -0700 (PDT) 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.221.72 with SMTP id ib8csp113965vcb; Mon, 2 Jun 2014 10:22:53 -0700 (PDT) X-Received: by 10.140.82.180 with SMTP id h49mr48863690qgd.84.1401729773848; Mon, 02 Jun 2014 10:22:53 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id l6si18897480qao.67.2014.06.02.10.22.53 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 02 Jun 2014 10:22:53 -0700 (PDT) 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]:47723 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WrV1R-0006T4-Os for patch@linaro.org; Mon, 02 Jun 2014 12:23:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WrV0Q-000526-O0 for qemu-devel@nongnu.org; Mon, 02 Jun 2014 12:22:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WrV0J-0007HD-4C for qemu-devel@nongnu.org; Mon, 02 Jun 2014 12:22:38 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:41880 helo=socrates.bennee.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WrV0I-0007H2-Rb for qemu-devel@nongnu.org; Mon, 02 Jun 2014 12:22:31 -0400 Received: from localhost ([127.0.0.1] helo=zen.linaro.local) by socrates.bennee.com with esmtp (Exim 4.80) (envelope-from ) id 1WrV1R-0007B7-Ey; Mon, 02 Jun 2014 18:23:41 +0200 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Mon, 2 Jun 2014 17:21:56 +0100 Message-Id: <1401726122-11132-3-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1401726122-11132-1-git-send-email-alex.bennee@linaro.org> References: <1401726122-11132-1-git-send-email-alex.bennee@linaro.org> X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: alex.bennee@linaro.org X-SA-Exim-Scanned: No (on socrates.bennee.com); SAEximRunCond expanded to false X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 88.198.71.155 Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, =?UTF-8?q?Alex=20Benn=C3=A9e?= , greg.bellows@linaro.org Subject: [Qemu-devel] [RCF PATCH 2/8] target-arm/cpu.h: implement common state save/restore 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: alex.bennee@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) 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 This adds a universal program state save and restore function. This is intended to simplify the migration serialisation functionality and avoid special casing depending on the mode of the CPU at serialisation time. --- WIP notes: - From this I'll look at - cpsr_read/cpsr_write - pstate_read/pstate_write - xpsr_read/xpsr_write - direct access to env->uncached_cpsr - direct access to env->pstate diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 5e6df38..9e41f82 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -430,26 +430,27 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, /* Execution state bits. MRS read as zero, MSR writes ignored. */ #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J) -/* Bit definitions for ARMv8 SPSR (PSTATE) format. - * Only these are valid when in AArch64 mode; in - * AArch32 mode SPSRs are basically CPSR-format. - */ + #define PSTATE_SP (1U) #define PSTATE_M (0xFU) #define PSTATE_nRW (1U << 4) +#define PSTATE_T (1U << 5) #define PSTATE_F (1U << 6) #define PSTATE_I (1U << 7) #define PSTATE_A (1U << 8) #define PSTATE_D (1U << 9) #define PSTATE_IL (1U << 20) #define PSTATE_SS (1U << 21) +#define PSTATE_Q (1U << 27) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) #define PSTATE_N (1U << 31) #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V) -#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F) -#define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF) +#define PSTATE_AIF (PSTATE_A | PSTATE_I | PSTATE_F) +#define PSTATE_DAIF (PSTATE_D | PSTATE_AIF) +#define AARCH64_CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF) +#define AARCH32_CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_Q | PSTATE_AIF | CACHED_CPSR_BITS) /* Mode values for AArch64 */ #define PSTATE_MODE_EL3h 13 #define PSTATE_MODE_EL3t 12 @@ -492,7 +493,7 @@ static inline void pstate_write(CPUARMState *env, uint32_t val) env->CF = (val >> 29) & 1; env->VF = (val << 3) & 0x80000000; env->daif = val & PSTATE_DAIF; - env->pstate = val & ~CACHED_PSTATE_BITS; + env->pstate = val & ~AARCH64_CACHED_PSTATE_BITS; } /* ARMv7-AR ARM B1.3.3 Current Program Status Register, CPSR @@ -681,6 +682,122 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el) return arm_feature(env, ARM_FEATURE_AARCH64); } +/* ARMv8 ARM D1.6.4, Saved Program Status Registers + * + * These are formats used to save program status when exceptions are + * taken. There are two forms: + * + * AArch64 -> AArch64 Exception + * 31 30 28 29 27 22 21 20 19 10 9 8 7 6 5 4 3 0 + * +---+---+---+---+------+----+----+------+---+---+---+---+---+------------+ + * | N | Z | C | V | RES0 | SS | IL | RES0 | D | A | I | F | 0 | 0 | M[3:0] | + * +---+---+---+---+------+----+----+------+---+---+---+---+---+------------+ + * + * AArch32 -> AArch64 Exception + * (see also ARMv7-AR ARM B1.3.3 CSPR/SPSR formats) + * 31 30 29 28 27 26 25 24 23 22 21 20 19 16 + * +---+---+---+---+---+---------+---+------+----+----+---------+ + * | N | Z | C | V | Q | IT[1:0] | J | RES0 | SS | IL | GE[3:0] | + * +---+---+---+---+---+---------+---+------+----+----+---------+ + * 15 10 9 8 7 6 5 4 3 0 + * +---------+---+---+---+---+---+---+--------+ + * | IT[7:2] | E | A | I | F | T | 1 | M[3:0] | + * +---------+---+---+---+---+---+---+--------+ + * + * M[4] = nRW - 0 = 64bit, 1 = 32bit + * Bit definitions for ARMv8 SPSR (PSTATE) format. + * Only these are valid when in AArch64 mode; in + * AArch32 mode SPSRs are basically CPSR-format. + */ + +/* Save the program state */ +static inline uint32_t save_state_to_spsr(CPUARMState *env) +{ + uint32_t final_spsr = 0; + + /* Calculate integer flags */ + final_spsr |= (env->NF & 0x80000000) ? PSTATE_N : 0; // bit 31 + final_spsr |= (env->ZF == 0) ? PSTATE_Z : 0; + final_spsr |= env->CF ? PSTATE_C : 0; // or |= env->CF << 29 + final_spsr |= (env->VF & 0x80000000) ? PSTATE_V : 0; // bit 31 + + /* will the compiler do better with the original? + int ZF; + ZF = (env->ZF == 0); + nzcv = (env->NF & 0x80000000) + | (ZF << 30) + | (env->CF << 29) + | ((env->VF & 0x80000000) >> 3); + */ + + if (is_a64(env)) { + /* SS - Software Step */ + /* IL - Illegal execution state */ + /* DAIF flags - should we mask?*/ + final_spsr |= (env->daif & PSTATE_DAIF); + /* And the final un-cached bits */ + final_spsr |= (env->pstate & ~AARCH64_CACHED_PSTATE_BITS); + } else { + if (arm_feature(env, ARM_FEATURE_M)) { + fprintf(stderr,"%s: M state not yet implmented\n", __func__); + } else { + final_spsr |= env->QF ? PSTATE_Q : 0; + /* condexec_bits is split over two parts */ + final_spsr |= ((env->condexec_bits & 3) << 25); + final_spsr |= ((env->condexec_bits & 0xfc) << 8); + /* GE needs shifting into place */ + final_spsr |= (env->GE << 16); + /* AIF is a a subset of DAIF */ + final_spsr |= (env->daif & PSTATE_AIF); + final_spsr |= env->thumb ? PSTATE_T : 0; + + final_spsr |= PSTATE_nRW; + + /* And the final un-cached bits */ + final_spsr |= (env->uncached_cpsr & ~AARCH32_CACHED_PSTATE_BITS); + } + } + return final_spsr; +} + +static inline void restore_state_from_spsr(CPUARMState *env, uint32_t saved_state) +{ + /* Process the integer flags directly */ + env->ZF = (~saved_state) & CPSR_Z; + env->NF = saved_state; + env->CF = (saved_state >> 29) & 1; + env->VF = (saved_state << 3) & 0x80000000; + + /* the rest depends on the mode we end up in */ + env->aarch64 = (saved_state & PSTATE_nRW) ? 0 : 1; + + if (is_a64(env)) { + env->daif = saved_state & PSTATE_DAIF; + env->pstate = (saved_state & ~AARCH64_CACHED_PSTATE_BITS); + } else { + if (arm_feature(env, ARM_FEATURE_M)) { + fprintf(stderr,"%s: M state not yet implmented\n", __func__); + } else { + env->QF = saved_state & PSTATE_Q ? 1 : 0; + /* condexec_bits is split over two parts */ + env->condexec_bits = (saved_state & CPSR_IT_0_1) >> 25; + env->condexec_bits |= (saved_state & CPSR_IT_2_7) >> 8; + + /* GE needs shifting into place */ + env->GE = (saved_state >> 16) & 0xf; + + /* AIF is a a subset of DAIF */ + env->daif = (saved_state & PSTATE_AIF); + + env->thumb = saved_state & PSTATE_T ? 1 : 0; + + /* And the final un-cached bits */ + env->uncached_cpsr = saved_state & ~AARCH32_CACHED_PSTATE_BITS; + } + } +} + + void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); /* Interface between CPU and Interrupt controller. */