From patchwork Sun Dec 22 22:49:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 22722 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 515ED202A0 for ; Sun, 22 Dec 2013 22:50:49 +0000 (UTC) Received: by mail-pb0-f70.google.com with SMTP id rq2sf13424877pbb.1 for ; Sun, 22 Dec 2013 14:50:48 -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:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=cnZLpXPKjHAv9q4LV3Ip+f1rMTxGyKYH9rOJ35bQQ9E=; b=ecT3Rnqpji8vDnXnmDMiUMcl2MDKBMgmxYWSp0/ksCchLv5ZEnCF+uCY8XxtCdb+bg U7qLoGoGWHx9Jq5SPAKKnc3RkkPWH8hxOnbyDcZoB12tfqFVcQg48CTz0GR/fYNV7DFi SzRENIJXSrCvl0OL3aavkML2m9UegpZgXsZ0JUWo1rNEql8vZ8Rpi+fnU7TK6voozG0o CTtE53epSRh493FKx0pEtK1psu2YNOSYA2vg9yEAZCRktWWxrZUNMWXq/oQ+jlyHnfk6 ez14hwcaVCZ/YYuqR2DZ2e6jrh3yddo8kS2FYB6QvSCiOM+ead9ouiBuYnTUByBH7e8d TMEA== X-Gm-Message-State: ALoCoQmmU5QTAnZls/iA4gbwHQYGt88PVWc8AD+apfuNz00aHklCpe51lcMP0sFJri0jKVsFCedP X-Received: by 10.66.190.197 with SMTP id gs5mr8691242pac.14.1387752648585; Sun, 22 Dec 2013 14:50:48 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.104.9 with SMTP id ga9ls1431501qeb.38.gmail; Sun, 22 Dec 2013 14:50:48 -0800 (PST) X-Received: by 10.52.22.40 with SMTP id a8mr88580vdf.49.1387752648407; Sun, 22 Dec 2013 14:50:48 -0800 (PST) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id gx6si4051239vdc.11.2013.12.22.14.50.48 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 22 Dec 2013 14:50:48 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id ht17so2450856vcb.4 for ; Sun, 22 Dec 2013 14:50:48 -0800 (PST) X-Received: by 10.58.186.198 with SMTP id fm6mr235641vec.16.1387752648323; Sun, 22 Dec 2013 14:50:48 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp193925ved; Sun, 22 Dec 2013 14:50:47 -0800 (PST) X-Received: by 10.194.92.109 with SMTP id cl13mr8816587wjb.13.1387752647264; Sun, 22 Dec 2013 14:50:47 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id r8si6121390wjw.9.2013.12.22.14.50.45 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 22 Dec 2013 14:50:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Vurqa-0006CW-Jf; Sun, 22 Dec 2013 22:50:08 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Alexander Graf , Michael Matz , Claudio Fontana , Dirk Mueller , Laurent Desnogues , kvmarm@lists.cs.columbia.edu, Richard Henderson , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Christoffer Dall , Will Newton , Peter Crosthwaite Subject: [PATCH v2 14/25] target-arm: A64: Implement MRS/MSR/SYS/SYSL Date: Sun, 22 Dec 2013 22:49:56 +0000 Message-Id: <1387752607-23755-15-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1387752607-23755-1-git-send-email-peter.maydell@linaro.org> References: <1387752607-23755-1-git-send-email-peter.maydell@linaro.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.220.173 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 Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The AArch64 equivalent of the traditional AArch32 cp15 coprocessor registers is the set of instructions MRS/MSR/SYS/SYSL, which cover between them both true system registers and the "operations with side effects" such as cache maintenance which in AArch32 are mixed in with other cp15 registers. Implement these instructions to look in the cpregs hashtable for the register or operation. Since we don't yet populate the cpregs hashtable with any registers with the "AA64" bit set, everything will still UNDEF at this point. MSR/MRS is the first user of is_jmp = DISAS_UPDATE, so fix an infelicity in its handling where the main loop was requiring the caller to do the update of PC rather than just doing it itself. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target-arm/translate-a64.c | 112 +++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 30 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index e35d2f3..7a9ee82 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -733,28 +733,88 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, unsupported_encoding(s, insn); } -/* C5.6.204 SYS */ -static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l, - unsigned int op1, unsigned int op2, +/* C5.6.129 MRS - move from system register + * C5.6.131 MSR (register) - move to system register + * C5.6.204 SYS + * C5.6.205 SYSL + * These are all essentially the same insn in 'read' and 'write' + * versions, with varying op0 fields. + */ +static void handle_sys(DisasContext *s, uint32_t insn, bool isread, + unsigned int op0, unsigned int op1, unsigned int op2, unsigned int crn, unsigned int crm, unsigned int rt) { - unsupported_encoding(s, insn); -} + const ARMCPRegInfo *ri; + TCGv_i64 tcg_rt; -/* C5.6.129 MRS - move from system register */ -static void handle_mrs(DisasContext *s, uint32_t insn, unsigned int op0, - unsigned int op1, unsigned int op2, - unsigned int crn, unsigned int crm, unsigned int rt) -{ - unsupported_encoding(s, insn); -} + ri = get_arm_cp_reginfo(s->cp_regs, + ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, + crn, crm, op0, op1, op2)); -/* C5.6.131 MSR (register) - move to system register */ -static void handle_msr(DisasContext *s, uint32_t insn, unsigned int op0, - unsigned int op1, unsigned int op2, - unsigned int crn, unsigned int crm, unsigned int rt) -{ - unsupported_encoding(s, insn); + if (!ri) { + /* Unknown register */ + unallocated_encoding(s); + return; + } + + /* Check access permissions */ + if (!cp_access_ok(s->current_pl, ri, isread)) { + unallocated_encoding(s); + return; + } + + /* Handle special cases first */ + switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) { + case ARM_CP_NOP: + return; + default: + break; + } + + if (use_icount && (ri->type & ARM_CP_IO)) { + gen_io_start(); + } + + tcg_rt = cpu_reg(s, rt); + + if (isread) { + if (ri->type & ARM_CP_CONST) { + tcg_gen_movi_i64(tcg_rt, ri->resetvalue); + } else if (ri->readfn) { + TCGv_ptr tmpptr; + gen_a64_set_pc_im(s->pc - 4); + tmpptr = tcg_const_ptr(ri); + gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr); + tcg_temp_free_ptr(tmpptr); + } else { + tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset); + } + } else { + if (ri->type & ARM_CP_CONST) { + /* If not forbidden by access permissions, treat as WI */ + return; + } else if (ri->writefn) { + TCGv_ptr tmpptr; + gen_a64_set_pc_im(s->pc - 4); + tmpptr = tcg_const_ptr(ri); + gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt); + tcg_temp_free_ptr(tmpptr); + } else { + tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset); + } + } + + if (use_icount && (ri->type & ARM_CP_IO)) { + /* I/O operations must end the TB here (whether read or write) */ + gen_io_end(); + s->is_jmp = DISAS_UPDATE; + } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) { + /* We default to ending the TB on a coprocessor register write, + * but allow this to be suppressed by the register definition + * (usually only necessary to work around guest bugs). + */ + s->is_jmp = DISAS_UPDATE; + } } /* C3.2.4 System @@ -795,17 +855,7 @@ static void disas_system(DisasContext *s, uint32_t insn) } return; } - - if (op0 == 1) { - /* C5.6.204 SYS */ - handle_sys(s, insn, l, op1, op2, crn, crm, rt); - } else if (l) { /* op0 > 1 */ - /* C5.6.129 MRS - move from system register */ - handle_mrs(s, insn, op0, op1, op2, crn, crm, rt); - } else { - /* C5.6.131 MSR (register) - move to system register */ - handle_msr(s, insn, op0, op1, op2, crn, crm, rt); - } + handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt); } /* C3.2.3 Exception generation @@ -3098,8 +3148,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, gen_goto_tb(dc, 1, dc->pc); break; default: - case DISAS_JUMP: case DISAS_UPDATE: + gen_a64_set_pc_im(dc->pc); + /* fall through */ + case DISAS_JUMP: /* indicate that the hash table must be used to find the next TB */ tcg_gen_exit_tb(0); break;