From patchwork Tue Dec 17 15:12:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 22580 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f71.google.com (mail-pa0-f71.google.com [209.85.220.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1F4AD23FBC for ; Tue, 17 Dec 2013 15:12:35 +0000 (UTC) Received: by mail-pa0-f71.google.com with SMTP id kl14sf13816549pab.2 for ; Tue, 17 Dec 2013 07:12:34 -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=Y0OBaOsV4i9BQYk9kh16h8sq72kacaSRVn6mTY7iXV4=; b=mwdj47oSyyCdcnKeT3A+9+qLWQ1wDz/5nzXE1C8uObJXLruOPNJOuwTKWKj9KhrDCO FQX7DgenZeNSbwAoMUypu/jEC8RKOxDl+M+R37lNlA2xHPc9hYjvN6xISltLD62Vy/sD dJu4/NS+HomT1LHq/27uQ8mRq0s1nVIoG/sYAC+uA1KhEpXLhKHJk93813kxbJbBreyy xHK7VuBFuPbgVAoKwTzA51qsicaEP5JX9fHcfkYn/oPVvWPjlpYAtGkKMlOzqtqQ5DQs 6UlvANgT6uegr9LIp/zdfLicn0en+Hl+rzinMq6o4DW56u8xp1HEFAvq+x24KSQywASb ZwhA== X-Gm-Message-State: ALoCoQn75EVl6NAgiXrj94HFW6WHYX9uFo6ITN3ppbP/cNKZ4B7orJ5FP5rl66BlyUsc3mdmfHxw X-Received: by 10.68.131.97 with SMTP id ol1mr12805565pbb.4.1387293154378; Tue, 17 Dec 2013 07:12:34 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.83.2 with SMTP id m2ls2608900qey.37.gmail; Tue, 17 Dec 2013 07:12:34 -0800 (PST) X-Received: by 10.220.169.203 with SMTP id a11mr6466166vcz.26.1387293154222; Tue, 17 Dec 2013 07:12:34 -0800 (PST) Received: from mail-vb0-f51.google.com (mail-vb0-f51.google.com [209.85.212.51]) by mx.google.com with ESMTPS id tj7si4982222vdc.124.2013.12.17.07.12.34 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 17 Dec 2013 07:12:34 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.51 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.51; Received: by mail-vb0-f51.google.com with SMTP id 11so4240856vbe.10 for ; Tue, 17 Dec 2013 07:12:34 -0800 (PST) X-Received: by 10.52.36.14 with SMTP id m14mr669406vdj.79.1387293154047; Tue, 17 Dec 2013 07:12:34 -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.220.174.196 with SMTP id u4csp74953vcz; Tue, 17 Dec 2013 07:12:33 -0800 (PST) X-Received: by 10.194.79.165 with SMTP id k5mr19914296wjx.44.1387293150459; Tue, 17 Dec 2013 07:12:30 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [81.2.115.146]) by mx.google.com with ESMTPS id u49si715416eep.64.2013.12.17.07.12.28 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 17 Dec 2013 07:12:30 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1VswJt-00031f-JG; Tue, 17 Dec 2013 15:12:25 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, 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 Subject: [PATCH 13/21] target-arm: A64: Implement MRS/MSR/SYS/SYSL Date: Tue, 17 Dec 2013 15:12:16 +0000 Message-Id: <1387293144-11554-14-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1387293144-11554-1-git-send-email-peter.maydell@linaro.org> References: <1387293144-11554-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.212.51 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. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target-arm/translate-a64.c | 115 +++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 38017a3..dd37962 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -113,6 +113,13 @@ void gen_a64_set_pc_im(uint64_t val) tcg_gen_movi_i64(cpu_pc, val); } +/* Force a TB lookup after an instruction that changes the CPU state */ +static inline void gen_lookup_tb(DisasContext *s) +{ + gen_a64_set_pc_im(s->pc); + s->is_jmp = DISAS_UPDATE; +} + static void gen_exception(int excp) { TCGv_i32 tmp = tcg_temp_new_i32(); @@ -731,28 +738,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(env, 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(); + gen_lookup_tb(s); + } 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). + */ + gen_lookup_tb(s); + } } /* C3.2.4 System @@ -793,17 +860,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