From patchwork Tue Dec 3 08:48:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Fedorov X-Patchwork-Id: 296114 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C87372C0079 for ; Tue, 3 Dec 2013 19:56:37 +1100 (EST) Received: from localhost ([::1]:41001 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VnlmW-0002rk-3t for incoming@patchwork.ozlabs.org; Tue, 03 Dec 2013 03:56:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45202) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnlfm-0001A8-NM for qemu-devel@nongnu.org; Tue, 03 Dec 2013 03:49:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vnlfc-00076v-Ns for qemu-devel@nongnu.org; Tue, 03 Dec 2013 03:49:38 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:32220) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnlfc-00076j-Hx for qemu-devel@nongnu.org; Tue, 03 Dec 2013 03:49:28 -0500 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MX8004NS36FK630@mailout1.w1.samsung.com> for qemu-devel@nongnu.org; Tue, 03 Dec 2013 08:49:27 +0000 (GMT) X-AuditID: cbfec7f5-b7fd16d000007299-94-529d9b171b8f Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 00.C2.29337.71B9D925; Tue, 03 Dec 2013 08:49:27 +0000 (GMT) Received: from s-fedorov.rnd.samsung.ru ([106.109.129.80]) by eusync1.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0MX800L8S361JP30@eusync1.samsung.com>; Tue, 03 Dec 2013 08:49:27 +0000 (GMT) From: Sergey Fedorov To: qemu-devel@nongnu.org Date: Tue, 03 Dec 2013 12:48:49 +0400 Message-id: <1386060535-15908-16-git-send-email-s.fedorov@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1386060535-15908-1-git-send-email-s.fedorov@samsung.com> References: <1386060535-15908-1-git-send-email-s.fedorov@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOJMWRmVeSWpSXmKPExsVy+t/xy7ris+cGGew+IWbx9vJPVov1bZNZ LeacecBicbx3B4tF2661LA6sHhcv72L1uHNtD5vHk2ubmTz6tqxiDGCJ4rJJSc3JLEst0rdL 4MqYcG8DU0G3VcX6f2/ZGhjPq3YxcnJICJhI/D58kwnCFpO4cG89WxcjF4eQwFJGiTWLzkA5 /UwSj/6+YQGpYhPQkZi97yIriC0iICnxu+s0M4jNLFAtsfzMGUYQW1jAW+J320Mwm0VAVWLN hqNgNbwCbhLzN+4G6uUA2qYgMWeSDUiYEyh8/NkdsCOEBFwlDh08wDyBkXcBI8MqRtHU0uSC 4qT0XCO94sTc4tK8dL3k/NxNjJDA+bqDcekxq0OMAhyMSjy8E/bMCRJiTSwrrsw9xCjBwawk wjs/fW6QEG9KYmVValF+fFFpTmrxIUYmDk6pBsZoyy8rTPruFW4VefC5bGe5dHyiUKOFsTYf T+cpwa/y3E3bREM69m/5dM17anWVK3d9ydbbc9tUsnMkLx1b/ef4t8Itxx4c6psiYWYbPz3Z NFIwJK//hC2LiOUOf8ufbLOPHz7jxygy8fzfOSU3WhUCN2ele9h+NM/cqVQXEfbM92zRTW0d BSWW4oxEQy3mouJEAFY8ueP6AQAA X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 210.118.77.11 Cc: peter.maydell@linaro.org, a.basov@samsung.com, Sergey Fedorov , johannes.winter@iaik.tugraz.at Subject: [Qemu-devel] [RFC PATCH 15/21] target-arm: add banked coprocessor register type 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 Banked CP registers are defined with BANKED_CP_REG macro which defines an active register state field followed by an adjacent banked register state array field. An active CP register state is accessed as usual through an active state field. Banked CP register state is save in banked register state array. The array is indexed by NS bit value. When translating a banked CP register access instruction in secure state, SCR.NS bit determines which field should be used. If SCR.NS bit is set then a non-secure banked value is used instead of an active one. That is possible only in monitor CPU mode. In non-secure state an active register state field is always used. Signed-off-by: Sergey Fedorov --- target-arm/cpu.h | 14 ++++++++++- target-arm/translate.c | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index a20f354..fe3a646 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -73,6 +73,17 @@ typedef void ARMWriteCPFunc(void *opaque, int cp_info, typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info, int dstreg, int operand); +/* Define a banked coprocessor register state field. Use %name as the active + * register state field name. The banked register state array field name has + * "banked_" prefix. The banked register state array indexes corresponds to + * SCR.NS bit value. + */ +#define BANKED_CP_REG(type, name) \ + struct { \ + type name; \ + type banked_##name[2]; \ + } + struct arm_boot_info; #define NB_MMU_MODES 4 @@ -572,13 +583,14 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) #define ARM_CP_OVERRIDE 16 #define ARM_CP_NO_MIGRATE 32 #define ARM_CP_IO 64 +#define ARM_CP_BANKED 128 #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8)) #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8)) #define ARM_LAST_SPECIAL ARM_CP_WFI /* Used only as a terminator for ARMCPRegInfo lists */ #define ARM_CP_SENTINEL 0xffff /* Mask of only the flag bits in a type field */ -#define ARM_CP_FLAG_MASK 0x7f +#define ARM_CP_FLAG_MASK 0xff /* Return true if cptype is a valid type field. This is used to try to * catch errors where the sentinel has been accidentally left off the end diff --git a/target-arm/translate.c b/target-arm/translate.c index 8548a4c..345866c 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6389,9 +6389,22 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) tmpptr = tcg_const_ptr(ri); gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr); tcg_temp_free_ptr(tmpptr); - } else { + } else if (!(ri->type & ARM_CP_BANKED) || IS_NS(s)) { tmp64 = tcg_temp_new_i64(); tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset); + } else { + TCGv_ptr tmpptr; + tmp = load_cpu_field(cp15.c1_scr); + tcg_gen_andi_i32(tmp, tmp, 1); + tcg_gen_shli_i32(tmp, tmp, 4); + tmpptr = tcg_temp_new_ptr(); + tcg_gen_ext_i32_ptr(tmpptr, cpu_env); + tcg_gen_addi_ptr(tmpptr, cpu_env, ri->fieldoffset); + tcg_gen_add_ptr(tmpptr, tmpptr, tmp); + tcg_temp_free_i32(tmp); + tmp64 = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp64, tmpptr, 0); + tcg_temp_free_ptr(tmpptr); } tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); @@ -6412,8 +6425,19 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) tmpptr = tcg_const_ptr(ri); gen_helper_get_cp_reg(tmp, cpu_env, tmpptr); tcg_temp_free_ptr(tmpptr); - } else { + } else if (!(ri->type & ARM_CP_BANKED) || IS_NS(s)) { tmp = load_cpu_offset(ri->fieldoffset); + } else { + TCGv_ptr tmpptr; + tmp = load_cpu_field(cp15.c1_scr); + tcg_gen_andi_i32(tmp, tmp, 1); + tcg_gen_shli_i32(tmp, tmp, 2); + tmpptr = tcg_temp_new_ptr(); + tcg_gen_ext_i32_ptr(tmpptr, cpu_env); + tcg_gen_addi_ptr(tmpptr, cpu_env, ri->fieldoffset); + tcg_gen_add_ptr(tmpptr, tmpptr, tmp); + tcg_gen_ld_i32(tmp, tmpptr, 0); + tcg_temp_free_ptr(tmpptr); } if (rt == 15) { /* Destination register of r15 for 32 bit loads sets @@ -6445,8 +6469,22 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) gen_set_pc_im(s, s->pc); gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64); tcg_temp_free_ptr(tmpptr); - } else { + } else if (!(ri->type & ARM_CP_BANKED) || IS_NS(s)) { tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset); + } else { + TCGv_i32 tmp; + TCGv_ptr tmpptr; + tmp = load_cpu_field(cp15.c1_scr); + tcg_gen_andi_i32(tmp, tmp, 1); + tcg_gen_shli_i32(tmp, tmp, 4); + tmpptr = tcg_temp_new_ptr(); + tcg_gen_ext_i32_ptr(tmpptr, cpu_env); + tcg_gen_addi_ptr(tmpptr, cpu_env, ri->fieldoffset); + tcg_gen_add_ptr(tmpptr, tmpptr, tmp); + tcg_temp_free_i32(tmp); + tmp64 = tcg_temp_new_i64(); + tcg_gen_st_i64(tmp64, tmpptr, 0); + tcg_temp_free_ptr(tmpptr); } tcg_temp_free_i64(tmp64); } else { @@ -6459,9 +6497,23 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) gen_helper_set_cp_reg(cpu_env, tmpptr, tmp); tcg_temp_free_ptr(tmpptr); tcg_temp_free_i32(tmp); - } else { + } else if (!(ri->type & ARM_CP_BANKED) || IS_NS(s)) { TCGv_i32 tmp = load_reg(s, rt); store_cpu_offset(tmp, ri->fieldoffset); + } else { + TCGv_i32 tmp; + TCGv_ptr tmpptr; + tmp = load_cpu_field(cp15.c1_scr); + tcg_gen_andi_i32(tmp, tmp, 1); + tcg_gen_shli_i32(tmp, tmp, 2); + tmpptr = tcg_temp_new_ptr(); + tcg_gen_ext_i32_ptr(tmpptr, cpu_env); + tcg_gen_addi_ptr(tmpptr, cpu_env, ri->fieldoffset); + tcg_gen_add_ptr(tmpptr, tmpptr, tmp); + load_reg_var(s, tmp, rt); + tcg_gen_st_i32(tmp, tmpptr, 0); + tcg_temp_free_ptr(tmpptr); + tcg_temp_free_i32(tmp); } } }