From patchwork Thu Jul 21 17:01:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 106109 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0FA82B6F69 for ; Fri, 22 Jul 2011 03:08:35 +1000 (EST) Received: from localhost ([::1]:42283 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QjwdO-0002So-GB for incoming@patchwork.ozlabs.org; Thu, 21 Jul 2011 13:02:02 -0400 Received: from eggs.gnu.org ([140.186.70.92]:60496) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QjwdJ-0002Sj-2a for qemu-devel@nongnu.org; Thu, 21 Jul 2011 13:01:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QjwdG-0007b3-TJ for qemu-devel@nongnu.org; Thu, 21 Jul 2011 13:01:56 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:59792) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QjwdG-0007ao-KW for qemu-devel@nongnu.org; Thu, 21 Jul 2011 13:01:54 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1QjwdD-00030f-Uz; Thu, 21 Jul 2011 18:01:51 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 21 Jul 2011 18:01:51 +0100 Message-Id: <1311267711-11546-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 81.2.115.146 Cc: patches@linaro.org Subject: [Qemu-devel] [PATCH] target-arm: Support v6 barriers in linux-user mode 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org ARMv6 implemented various operations as special cases of cp15 accesses which are true instructions in v7; this includes barriers (DMB, DSB, ISB). Catch this special case at translate time, so that it works in linux-user mode (which doesn't provide a functional get_cp15 helper) as well as system mode. Includes minor cleanup of the existing cases (single switch statement, and doing the "OK in user mode?" test explicitly rather than hiding it in cp15_user_ok()). Signed-off-by: Peter Maydell --- target-arm/translate.c | 51 +++++++++++++++++++++++++++++++---------------- 1 files changed, 33 insertions(+), 18 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 34d5e6e..c7961b8 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2498,12 +2498,6 @@ static int cp15_user_ok(CPUState *env, uint32_t insn) if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT))) return 1; } - if (cpn == 7) { - /* ISB, DSB, DMB. */ - if ((cpm == 5 && op == 4) - || (cpm == 10 && (op == 4 || op == 5))) - return 1; - } return 0; } @@ -2579,39 +2573,60 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) /* cdp */ return 1; } - if (IS_USER(s) && !cp15_user_ok(env, insn)) { - return 1; - } - - /* Pre-v7 versions of the architecture implemented WFI via coprocessor - * instructions rather than a separate instruction. + /* We special case a number of cp15 instructions which were used + * for things which are real instructions in ARMv7. This allows + * them to work in linux-user mode which doesn't provide functional + * get_cp15/set_cp15 helpers, and is more efficient anyway. */ - if ((insn & 0x0fff0fff) == 0x0e070f90) { + switch ((insn & 0x0fff0fff)) { + case 0x0e070f90: /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores). * In v7, this must NOP. */ + if (IS_USER(s)) { + return 1; + } if (!arm_feature(env, ARM_FEATURE_V7)) { /* Wait for interrupt. */ gen_set_pc_im(s->pc); s->is_jmp = DISAS_WFI; } return 0; - } - - if ((insn & 0x0fff0fff) == 0x0e070f58) { + case 0x0e070f58: /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI, * so this is slightly over-broad. */ - if (!arm_feature(env, ARM_FEATURE_V6)) { + if (!IS_USER(s) && !arm_feature(env, ARM_FEATURE_V6)) { /* Wait for interrupt. */ gen_set_pc_im(s->pc); s->is_jmp = DISAS_WFI; return 0; } - /* Otherwise fall through to handle via helper function. + /* Otherwise continue to handle via helper function. * In particular, on v7 and some v6 cores this is one of * the VA-PA registers. */ + break; + case 0x0e070f3d: + /* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */ + if (arm_feature(env, ARM_FEATURE_V6)) { + return IS_USER(s) ? 1 : 0; + } + break; + case 0x0e070f95: /* 0,c7,c5,4 : ISB */ + case 0x0e070f9a: /* 0,c7,c10,4: DSB */ + case 0x0e070fba: /* 0,c7,c10,5: DMB */ + /* Barriers in both v6 and v7 */ + if (arm_feature(env, ARM_FEATURE_V6)) { + return 0; + } + break; + default: + break; + } + + if (IS_USER(s) && !cp15_user_ok(env, insn)) { + return 1; } rd = (insn >> 12) & 0xf;