From nobody Sat Feb 7 05:26:23 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534251222429759.8889651306845; Tue, 14 Aug 2018 05:53:42 -0700 (PDT) Received: from localhost ([::1]:44215 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpYpR-0005yo-8A for importer@patchew.org; Tue, 14 Aug 2018 08:53:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43942) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpYfM-0005b9-8n for qemu-devel@nongnu.org; Tue, 14 Aug 2018 08:43:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpYfL-0002Qj-2q for qemu-devel@nongnu.org; Tue, 14 Aug 2018 08:43:16 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44346) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fpYfH-0002IZ-GC; Tue, 14 Aug 2018 08:43:11 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpYfG-0006sF-Dd; Tue, 14 Aug 2018 13:43:10 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 14 Aug 2018 13:42:54 +0100 Message-Id: <20180814124254.5229-11-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814124254.5229-1-peter.maydell@linaro.org> References: <20180814124254.5229-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 10/10] target/arm: Implement support for taking exceptions to Hyp mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgari@xilinx.com, Luc Michel , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement the necessary support code for taking exceptions to Hyp mode in AArch32. Signed-off-by: Peter Maydell --- target/arm/helper.c | 146 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 23 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 80855302089..167203ac664 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8013,6 +8013,123 @@ void aarch64_sync_64_to_32(CPUARMState *env) env->regs[15] =3D env->pc; } =20 +static void take_aarch32_exception(CPUARMState *env, int new_mode, + uint32_t mask, uint32_t offset, + uint32_t newpc) +{ + /* Change the CPU state so as to actually take the exception. */ + switch_mode(env, new_mode); + /* + * For exceptions taken to AArch32 we must clear the SS bit in both + * PSTATE and in the old-state value we save to SPSR_, so zero i= t now. + */ + env->uncached_cpsr &=3D ~PSTATE_SS; + env->spsr =3D cpsr_read(env); + /* Clear IT bits. */ + env->condexec_bits =3D 0; + /* Switch to the new mode, and to the correct instruction set. */ + env->uncached_cpsr =3D (env->uncached_cpsr & ~CPSR_M) | new_mode; + /* Set new mode endianness */ + env->uncached_cpsr &=3D ~CPSR_E; + if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) { + env->uncached_cpsr |=3D CPSR_E; + } + env->daif |=3D mask; + + if (new_mode =3D=3D ARM_CPU_MODE_HYP) { + env->thumb =3D (env->cp15.sctlr_el[2] & SCTLR_TE) !=3D 0; + env->elr_el[2] =3D env->regs[15]; + } else { + /* + * this is a lie, as there was no c1_sys on V4T/V5, but who cares + * and we should just guard the thumb mode on V4 + */ + if (arm_feature(env, ARM_FEATURE_V4T)) { + env->thumb =3D + (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) !=3D 0; + } + env->regs[14] =3D env->regs[15] + offset; + } + env->regs[15] =3D newpc; +} + +static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs) +{ + /* + * Handle exception entry to Hyp mode; this is sufficiently + * different to entry to other AArch32 modes that we handle it + * separately here. + * + * The vector table entry used is always the 0x14 Hyp mode entry point, + * unless this is an UNDEF/HVC/abort taken from Hyp to Hyp. + * The offset applied to the preferred return address is always zero + * (see DDI0487C.a section G1.12.3). + * PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values. + */ + uint32_t addr, mask; + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + + switch (cs->exception_index) { + case EXCP_UDEF: + addr =3D 0x04; + break; + case EXCP_SWI: + addr =3D 0x14; + break; + case EXCP_BKPT: + /* Fall through to prefetch abort. */ + case EXCP_PREFETCH_ABORT: + env->cp15.ifar_s =3D env->exception.vaddress; + qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n", + (uint32_t)env->exception.vaddress); + addr =3D 0x0c; + break; + case EXCP_DATA_ABORT: + env->cp15.dfar_s =3D env->exception.vaddress; + qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n", + (uint32_t)env->exception.vaddress); + addr =3D 0x10; + break; + case EXCP_IRQ: + addr =3D 0x18; + break; + case EXCP_FIQ: + addr =3D 0x1c; + break; + case EXCP_HVC: + addr =3D 0x08; + break; + case EXCP_HYP_TRAP: + addr =3D 0x14; + default: + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + } + + if (cs->exception_index !=3D EXCP_IRQ && cs->exception_index !=3D EXCP= _FIQ) { + env->cp15.esr_el[2] =3D env->exception.syndrome; + } + + if (arm_current_el(env) !=3D 2 && addr < 0x14) { + addr =3D 0x14; + } + + mask =3D 0; + if (!(env->cp15.scr_el3 & SCR_EA)) { + mask |=3D CPSR_A; + } + if (!(env->cp15.scr_el3 & SCR_IRQ)) { + mask |=3D CPSR_I; + } + if (!(env->cp15.scr_el3 & SCR_IRQ)) { + mask |=3D CPSR_F; + } + + addr +=3D env->cp15.hvbar; + + take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr); +} + static void arm_cpu_do_interrupt_aarch32(CPUState *cs) { ARMCPU *cpu =3D ARM_CPU(cs); @@ -8048,6 +8165,11 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *c= s) env->cp15.mdscr_el1 =3D deposit64(env->cp15.mdscr_el1, 2, 4, moe); } =20 + if (env->exception.target_el =3D=3D 2) { + arm_cpu_do_interrupt_aarch32_hyp(cs); + return; + } + /* TODO: Vectored interrupt controller. */ switch (cs->exception_index) { case EXCP_UDEF: @@ -8155,29 +8277,7 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *c= s) env->cp15.scr_el3 &=3D ~SCR_NS; } =20 - switch_mode (env, new_mode); - /* For exceptions taken to AArch32 we must clear the SS bit in both - * PSTATE and in the old-state value we save to SPSR_, so zero i= t now. - */ - env->uncached_cpsr &=3D ~PSTATE_SS; - env->spsr =3D cpsr_read(env); - /* Clear IT bits. */ - env->condexec_bits =3D 0; - /* Switch to the new mode, and to the correct instruction set. */ - env->uncached_cpsr =3D (env->uncached_cpsr & ~CPSR_M) | new_mode; - /* Set new mode endianness */ - env->uncached_cpsr &=3D ~CPSR_E; - if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) { - env->uncached_cpsr |=3D CPSR_E; - } - env->daif |=3D mask; - /* this is a lie, as the was no c1_sys on V4T/V5, but who cares - * and we should just guard the thumb mode on V4 */ - if (arm_feature(env, ARM_FEATURE_V4T)) { - env->thumb =3D (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE)= !=3D 0; - } - env->regs[14] =3D env->regs[15] + offset; - env->regs[15] =3D addr; + take_aarch32_exception(env, new_mode, mask, offset, addr); } =20 /* Handle exception entry to a target EL which is using AArch64 */ --=20 2.18.0