From patchwork Thu Jul 10 15:49:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 33438 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f200.google.com (mail-ob0-f200.google.com [209.85.214.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 6DC9D203F4 for ; Thu, 10 Jul 2014 15:54:14 +0000 (UTC) Received: by mail-ob0-f200.google.com with SMTP id nu7sf9234533obb.11 for ; Thu, 10 Jul 2014 08:54:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version: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:content-type :content-transfer-encoding; bh=F7K+aw7Ap3UbbZ0acN6usaq3aNDGzkjE1TiNuQO7W+U=; b=ab+tr6zjXXHFUg0/aR/xK3JofhErikSkuE0EX0mAqToSSlkcu13IB3sDkNf4eY78IW r3X67IosHaHkeFBjgx/5MUrurAwmJ15a8MyQeOK8Wv7WdChjnsAmWEmI/fKEJh7C66jK a4t6qPgLBKSQcT1eXxJqEId9xoeC/eGO4AlA5zEpob70jvLmAez3PKs6WBw7xX8Cbozm S0U6cLR4/u3ahV/6dEMIZolb5m0gCwgaPCayv19QBTgFaEAnsHpR6jueQHNUZUJeBFYO B9bMkLckcUHJV772l2pidyyGOYtGgodF3rW2VNhkCi+N8lU2ZnV3SX7qy4iZ4dL5lviu E8sQ== X-Gm-Message-State: ALoCoQlbJDYRcb0ITyv2DzlhlVyy/Q3jaY6FPLG7pH7jGopT6VEYNQ/dAHZNNXUVhtVqrMt98a7z X-Received: by 10.50.85.6 with SMTP id d6mr7768025igz.0.1405007654050; Thu, 10 Jul 2014 08:54:14 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.108.228 with SMTP id j91ls105018qgf.31.gmail; Thu, 10 Jul 2014 08:54:13 -0700 (PDT) X-Received: by 10.58.18.211 with SMTP id y19mr1047915ved.58.1405007653907; Thu, 10 Jul 2014 08:54:13 -0700 (PDT) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by mx.google.com with ESMTPS id jp10si5554525vdb.9.2014.07.10.08.54.13 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 10 Jul 2014 08:54:13 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.171 as permitted sender) client-ip=209.85.220.171; Received: by mail-vc0-f171.google.com with SMTP id id10so10928726vcb.16 for ; Thu, 10 Jul 2014 08:54:13 -0700 (PDT) X-Received: by 10.221.34.13 with SMTP id sq13mr22559616vcb.16.1405007653806; Thu, 10 Jul 2014 08:54:13 -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.221.37.5 with SMTP id tc5csp146072vcb; Thu, 10 Jul 2014 08:54:13 -0700 (PDT) X-Received: by 10.224.26.18 with SMTP id b18mr81419797qac.20.1405007653342; Thu, 10 Jul 2014 08:54:13 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x64si33115930qgx.80.2014.07.10.08.54.13 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 10 Jul 2014 08:54:13 -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]:38683 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X5Gfk-0002jb-UH for patch@linaro.org; Thu, 10 Jul 2014 11:54:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50582) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X5GbM-0001Qu-Mo for qemu-devel@nongnu.org; Thu, 10 Jul 2014 11:49:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X5GbH-0006y7-CY for qemu-devel@nongnu.org; Thu, 10 Jul 2014 11:49:40 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:35643 helo=socrates.bennee.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X5GbH-0006xt-0b for qemu-devel@nongnu.org; Thu, 10 Jul 2014 11:49:35 -0400 Received: from localhost ([127.0.0.1] helo=zen.linaro.local) by socrates.bennee.com with esmtp (Exim 4.80) (envelope-from ) id 1X5Gg7-0007L4-Fl; Thu, 10 Jul 2014 17:54:35 +0200 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Thu, 10 Jul 2014 16:49:59 +0100 Message-Id: <1405007407-23549-3-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1405007407-23549-1-git-send-email-alex.bennee@linaro.org> References: <1405007407-23549-1-git-send-email-alex.bennee@linaro.org> MIME-Version: 1.0 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: Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [Qemu-devel] [PATCH v2 02/10] target-arm/cpu.h: common pstate 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.171 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. Signed-off-by: Alex Bennée --- v2: - reword commentary for restore_state_from_spsr - rm commented out code - add set_condition_codes for flags - add xpsr_read functionality v3: - rebase - checkpatch.pl issues diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c2312d0..fe4d4f3 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -453,19 +453,24 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, #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 @@ -508,7 +513,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 @@ -698,6 +703,137 @@ 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. + * + * Also ARMv7-M ARM B1.4.2, special purpose program status register xPSR + */ + +/* 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 */ + + 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 { + /* condexec_bits is split over two parts */ + final_spsr |= ((env->condexec_bits & 3) << 25); + final_spsr |= ((env->condexec_bits & 0xfc) << 8); + + if (arm_feature(env, ARM_FEATURE_M)) { + final_spsr |= (env->thumb << 24); /* alt pos */ + final_spsr |= env->v7m.exception; + } else { + final_spsr |= env->QF ? PSTATE_Q : 0; + /* 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; +} + +/* Restore the program state. + * + * This restores the program execution state including it's current + * execution mode. However validation of mode changes and additional + * registers and state that need changing should be done by the + * calling function. + * + * The simple set_condition_codes() function can be used just to + * update the cached integer flags which are quite often manipulated + * alone. + */ + +/* Only update the cached condition codes. */ +static inline void set_condition_codes(CPUARMState *env, uint32_t new_flags) +{ + /* Process the integer flags directly */ + env->ZF = (~new_flags) & CPSR_Z; + env->NF = new_flags; + env->CF = (new_flags >> 29) & 1; + env->VF = (new_flags << 3) & 0x80000000; +} + +/* Restore the complete program state */ +static inline void restore_state_from_spsr(CPUARMState *env, + uint32_t saved_state) +{ + set_condition_codes(env, saved_state); + + /* 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. */