From patchwork Tue Dec 3 08:48:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Fedorov X-Patchwork-Id: 296115 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 C81342C0079 for ; Tue, 3 Dec 2013 19:56:47 +1100 (EST) Received: from localhost ([::1]:40989 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnlkq-0000tB-52 for incoming@patchwork.ozlabs.org; Tue, 03 Dec 2013 03:54:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45201) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnlfm-0001A7-Ma 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 1Vnlfe-00077W-Bh for qemu-devel@nongnu.org; Tue, 03 Dec 2013 03:49:38 -0500 Received: from mailout3.w1.samsung.com ([210.118.77.13]:61668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vnlfe-00077F-3p for qemu-devel@nongnu.org; Tue, 03 Dec 2013 03:49:30 -0500 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MX8004M036GXW30@mailout3.w1.samsung.com> for qemu-devel@nongnu.org; Tue, 03 Dec 2013 08:49:29 +0000 (GMT) X-AuditID: cbfec7f5-b7fd16d000007299-9f-529d9b189e83 Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id E1.C2.29337.81B9D925; Tue, 03 Dec 2013 08:49:28 +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:28 +0000 (GMT) From: Sergey Fedorov To: qemu-devel@nongnu.org Date: Tue, 03 Dec 2013 12:48:52 +0400 Message-id: <1386060535-15908-19-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+NgFnrGJMWRmVeSWpSXmKPExsVy+t/xy7oSs+cGGXz4Ymnx9vJPVov1bZNZ LeacecBicbx3B4tF2661LA6sHhcv72L1uHNtD5vHk2ubmTz6tqxiDGCJ4rJJSc3JLEst0rdL 4Mpo3bSZueCOdsW1J2fYGhgfKXUxcnJICJhITHp/iB3CFpO4cG89G4gtJLCUUWJqu1AXIxeQ 3c8ksXn/KlaQBJuAjsTsfRfBbBEBSYnfXaeZQWxmgWqJ5WfOMILYwgKOEgvPvwcbxCKgKnG2 ew9YDa+Am8SXmY1AvRxAyxQk5kyyAQlzAoWPP7vDBLHXVeLQwQPMExh5FzAyrGIUTS1NLihO Ss810itOzC0uzUvXS87P3cQICZuvOxiXHrM6xCjAwajEwzthz5wgIdbEsuLK3EOMEhzMSiK8 89PnBgnxpiRWVqUW5ccXleakFh9iZOLglGpg5HjyZOdnhtPc2940pnEfFnq861R7crutVIzM lA2d5lKWrWLr2dy9tmR9j91tclltnvq2h9x/jPgquTc37qn8yJj3UeRP2o1ntx1L07df/FV8 kfXjTYELCxQvLt6rczf9SJLTkjVaB364X2HOWGB8IG7Xnj25VsKub9Nuia04enmfz8WDxfcb uJRYijMSDbWYi4oTAdNO1sH5AQAA X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 210.118.77.13 Cc: peter.maydell@linaro.org, a.basov@samsung.com, Sergey Fedorov , johannes.winter@iaik.tugraz.at Subject: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers 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 coprocessor registers are switched on two cases: 1) Entering or leaving CPU monitor mode with SCR.NS bit set; 2) Setting SCR.NS bit not from CPU monitor mode Coprocessor register banking is done similar to CPU core register banking. Some of SCTRL bits are common for secure and non-secure state. Translation table base masks are updated on register switch instead of TTBCR write. Signed-off-by: Sergey Fedorov --- target-arm/helper.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index e1e9762..7bfadb0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -11,6 +11,7 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address, int access_type, int is_user, hwaddr *phys_ptr, int *prot, target_ulong *page_size); +static void switch_cp15_regs(CPUARMState *env, int secure); #endif static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) @@ -1553,6 +1554,17 @@ static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) } #ifndef CONFIG_USER_ONLY +static int scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) +{ + if ((value & 1/*NS*/) && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_MON) { + /* We are going to Non-secure state; switch banked system control registers */ + switch_cp15_regs(env, 0); + } + + env->cp15.c1_scr = value; + return 0; +} + static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1572,7 +1584,7 @@ static const ARMCPRegInfo tz_cp_reginfo[] = { #ifndef CONFIG_USER_ONLY { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), - .resetvalue = 0 }, + .writefn = scr_write, .resetvalue = 0 }, { .name = "VBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_BANKED, .writefn = vbar_write, .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar), @@ -2284,6 +2296,69 @@ void switch_mode(CPUARMState *env, int mode) env->regs[13] = env->banked_r13[i]; env->regs[14] = env->banked_r14[i]; env->spsr = env->banked_spsr[i]; + + if ((mode == ARM_CPU_MODE_MON || old_mode == ARM_CPU_MODE_MON) && + (env->cp15.c1_scr & 1/*NS*/)) { + /* We are going to change Security state; switch banked system control registers */ + switch_cp15_regs(env, (mode == ARM_CPU_MODE_MON)); + } +} + +void switch_cp15_regs(CPUARMState *env, int secure) +{ + int i; + + /* Save current Security state registers */ + i = arm_is_secure(env) ? 0 : 1; + env->cp15.banked_c0_cssel[i] = env->cp15.c0_cssel; + env->cp15.banked_c1_sys[i] = env->cp15.c1_sys; + env->cp15.banked_c2_base0[i] = env->cp15.c2_base0; + env->cp15.banked_c2_base0_hi[i] = env->cp15.c2_base0_hi; + env->cp15.banked_c2_base1[i] = env->cp15.c2_base1; + env->cp15.banked_c2_base1_hi[i] = env->cp15.c2_base1_hi; + env->cp15.banked_c2_control[i] = env->cp15.c2_control; + env->cp15.banked_c3[i] = env->cp15.c3; + env->cp15.banked_c5_data[i] = env->cp15.c5_data; + env->cp15.banked_c5_insn[i] = env->cp15.c5_insn; + env->cp15.banked_c6_data[i] = env->cp15.c6_data; + env->cp15.banked_c6_insn[i] = env->cp15.c6_insn; + env->cp15.banked_c7_par[i] = env->cp15.c7_par; + env->cp15.banked_c7_par_hi[i] = env->cp15.c7_par_hi; + env->cp15.banked_c13_context[i] = env->cp15.c13_context; + env->cp15.banked_c13_fcse[i] = env->cp15.c13_fcse; + env->cp15.banked_c13_tls1[i] = env->cp15.c13_tls1; + env->cp15.banked_c13_tls2[i] = env->cp15.c13_tls2; + env->cp15.banked_c13_tls3[i] = env->cp15.c13_tls3; + + /* Restore new Security state registers */ + i = secure ? 0 : 1; + env->cp15.c0_cssel = env->cp15.banked_c0_cssel[i]; + /* Maintain the value of common bits */ + env->cp15.c1_sys &= 0x8204000; + env->cp15.c1_sys |= env->cp15.banked_c1_sys[i] & ~0x8204000; + env->cp15.c2_base0 = env->cp15.banked_c2_base0[i]; + env->cp15.c2_base0_hi = env->cp15.banked_c2_base0_hi[i]; + env->cp15.c2_base1 = env->cp15.banked_c2_base1[i]; + env->cp15.c2_base1_hi = env->cp15.banked_c2_base1_hi[i]; + { + int maskshift; + env->cp15.c2_control = env->cp15.banked_c2_control[i]; + maskshift = extract32(env->cp15.c2_control, 0, 3); + env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift); + env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift); + } + env->cp15.c3 = env->cp15.banked_c3[i]; + env->cp15.c5_data = env->cp15.banked_c5_data[i]; + env->cp15.c5_insn = env->cp15.banked_c5_insn[i]; + env->cp15.c6_data = env->cp15.banked_c6_data[i]; + env->cp15.c6_insn = env->cp15.banked_c6_insn[i]; + env->cp15.c7_par = env->cp15.banked_c7_par[i]; + env->cp15.c7_par_hi = env->cp15.banked_c7_par_hi[i]; + env->cp15.c13_context = env->cp15.banked_c13_context[i]; + env->cp15.c13_fcse = env->cp15.banked_c13_fcse[i]; + env->cp15.c13_tls1 = env->cp15.banked_c13_tls1[i]; + env->cp15.c13_tls2 = env->cp15.banked_c13_tls2[i]; + env->cp15.c13_tls3 = env->cp15.banked_c13_tls3[i]; } static void v7m_push(CPUARMState *env, uint32_t val)