From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40199) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wulk5-0007FY-K3 for qemu-devel@nongnu.org; Wed, 11 Jun 2014 12:51:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wuljy-0003fU-Ek for qemu-devel@nongnu.org; Wed, 11 Jun 2014 12:51:17 -0400 Received: from mail-qc0-f177.google.com ([209.85.216.177]:63439) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wuljy-0003f8-9K for qemu-devel@nongnu.org; Wed, 11 Jun 2014 12:51:10 -0400 Received: by mail-qc0-f177.google.com with SMTP id i17so23114qcy.8 for ; Wed, 11 Jun 2014 09:51:09 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1402326269-8573-10-git-send-email-edgar.iglesias@gmail.com> References: <1402326269-8573-1-git-send-email-edgar.iglesias@gmail.com> <1402326269-8573-10-git-send-email-edgar.iglesias@gmail.com> Date: Wed, 11 Jun 2014 11:51:09 -0500 Message-ID: From: Greg Bellows Content-Type: multipart/alternative; boundary=001a11c14dba4da0c604fb9240b7 Subject: Re: [Qemu-devel] [PATCH v2 09/17] target-arm: A64: Refactor aarch64_cpu_do_interrupt List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Edgar E. Iglesias" Cc: Peter Maydell , Peter Crosthwaite , Rob Herring , Fabian Aggeler , QEMU Developers , Alexander Graf , Blue Swirl , John Williams , pbonzini@redhat.com, =?UTF-8?B?QWxleCBCZW5uw6ll?= , Christoffer Dall , rth@twiddle.net --001a11c14dba4da0c604fb9240b7 Content-Type: text/plain; charset=UTF-8 On 9 June 2014 10:04, Edgar E. Iglesias wrote: > From: "Edgar E. Iglesias" > > Introduce new_el and new_mode in preparation for future patches > that add support for taking exceptions to and from EL2 and 3. > No functional change. > > Signed-off-by: Edgar E. Iglesias > --- > target-arm/cpu.h | 7 +++++++ > target-arm/helper-a64.c | 24 +++++++++++++----------- > target-arm/helper.c | 13 +++++++++++++ > 3 files changed, 33 insertions(+), 11 deletions(-) > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index 111577c..de00e01 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -461,6 +461,12 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr > address, int rw, > #define PSTATE_MODE_EL1t 4 > #define PSTATE_MODE_EL0t 0 > > +/* Map EL and handler into a PSTATE_MODE. */ > +static inline unsigned int aarch64_pstate_mode(unsigned int el, bool > handler) > +{ > + return (el << 2) | handler; > +} > + > /* Return the current PSTATE value. For the moment we don't support > 32<->64 bit > * interprocessing, so we don't attempt to sync with the cpsr state used > by > * the 32 bit decoder. > @@ -709,6 +715,7 @@ static inline bool arm_el_is_aa64(CPUARMState *env, > int el) > } > > void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); > +unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx); > > /* Interface between CPU and Interrupt controller. */ > void armv7m_nvic_set_pending(void *opaque, int irq); > diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c > index d647441..7d94a74 100644 > --- a/target-arm/helper-a64.c > +++ b/target-arm/helper-a64.c > @@ -443,10 +443,12 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > { > ARMCPU *cpu = ARM_CPU(cs); > CPUARMState *env = &cpu->env; > - target_ulong addr = env->cp15.vbar_el[1]; > + unsigned int new_el = arm_excp_target_el(cs, cs->exception_index); > + target_ulong addr = env->cp15.vbar_el[new_el]; > + unsigned int new_mode = aarch64_pstate_mode(new_el, true); > int i; > > - if (arm_current_pl(env) == 0) { > + if (arm_current_pl(env) < new_el) { > if (env->aarch64) { > addr += 0x400; > } else { > @@ -464,14 +466,14 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > env->exception.syndrome); > } > > - env->cp15.esr_el[1] = env->exception.syndrome; > - env->cp15.far_el[1] = env->exception.vaddress; > + env->cp15.esr_el[new_el] = env->exception.syndrome; > + env->cp15.far_el[new_el] = env->exception.vaddress; > > switch (cs->exception_index) { > case EXCP_PREFETCH_ABORT: > case EXCP_DATA_ABORT: > qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n", > - env->cp15.far_el[1]); > + env->cp15.far_el[new_el]); > break; > case EXCP_BKPT: > case EXCP_UDEF: > @@ -488,15 +490,15 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > } > > if (is_a64(env)) { > - env->banked_spsr[aarch64_banked_spsr_index(1)] = pstate_read(env); > + env->banked_spsr[aarch64_banked_spsr_index(new_el)] = > pstate_read(env); > aarch64_save_sp(env, arm_current_pl(env)); > - env->elr_el[1] = env->pc; > + env->elr_el[new_el] = env->pc; > } else { > env->banked_spsr[0] = cpsr_read(env); > if (!env->thumb) { > - env->cp15.esr_el[1] |= 1 << 25; > + env->cp15.esr_el[new_el] |= 1 << 25; > } > - env->elr_el[1] = env->regs[15]; > + env->elr_el[new_el] = env->regs[15]; > > for (i = 0; i < 15; i++) { > env->xregs[i] = env->regs[i]; > @@ -505,9 +507,9 @@ void aarch64_cpu_do_interrupt(CPUState *cs) > env->condexec_bits = 0; > } > > - pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h); > + pstate_write(env, PSTATE_DAIF | new_mode); > env->aarch64 = 1; > - aarch64_restore_sp(env, 1); > + aarch64_restore_sp(env, new_el); > > env->pc = addr; > cs->interrupt_request |= CPU_INTERRUPT_EXITTB; > diff --git a/target-arm/helper.c b/target-arm/helper.c > index 17cf80e..86e098f 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -3217,6 +3217,11 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, > uint32_t mode) > return 0; > } > > +unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx) > +{ > + return 1; > +} > + > #else > > /* Map CPU modes onto saved register banks. */ > @@ -3272,6 +3277,14 @@ void switch_mode(CPUARMState *env, int mode) > env->spsr = env->banked_spsr[i]; > } > > +/* > + * Determine the target EL for a given exception type. > + */ > +unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx) > +{ > + return 1; > +} > + > Unless this is just a preparation to make the non CONFIG_USER_ONLY version of this different, this can be moved out of the ifdef and made common. > static void v7m_push(CPUARMState *env, uint32_t val) > { > CPUState *cs = CPU(arm_env_get_cpu(env)); > -- > 1.8.3.2 > > Otherwise... Reviewed-by: Greg Bellows --001a11c14dba4da0c604fb9240b7 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable



On 9 June 2014 10:04, Edgar E. Iglesias <edgar.iglesias@gma= il.com> wrote:
From: "Edgar E. Iglesias" <edgar.iglesias@x= ilinx.com>

Introduce new_el and new_mode in preparation for future patches
that add support for taking exceptions to and from EL2 and 3.
No functional change.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
=C2=A0target-arm/cpu.h =C2=A0 =C2=A0 =C2=A0 =C2=A0| =C2=A07 +++++++
=C2=A0target-arm/helper-a64.c | 24 +++++++++++++-----------
=C2=A0target-arm/helper.c =C2=A0 =C2=A0 | 13 +++++++++++++
=C2=A03 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 111577c..de00e01 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -461,6 +461,12 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr= ess, int rw,
=C2=A0#define PSTATE_MODE_EL1t 4
=C2=A0#define PSTATE_MODE_EL0t 0

+/* Map EL and handler into a PSTATE_MODE. =C2=A0*/
+static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handl= er)
+{
+ =C2=A0 =C2=A0return (el << 2) | handler;
+}
+
=C2=A0/* Return the current PSTATE value. For the moment we don't suppo= rt 32<->64 bit
=C2=A0 * interprocessing, so we don't attempt to sync with the cpsr sta= te used by
=C2=A0 * the 32 bit decoder.
@@ -709,6 +715,7 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int= el)
=C2=A0}

=C2=A0void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
+unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);

=C2=A0/* Interface between CPU and Interrupt controller. =C2=A0*/
=C2=A0void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index d647441..7d94a74 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -443,10 +443,12 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
=C2=A0{
=C2=A0 =C2=A0 =C2=A0ARMCPU *cpu =3D ARM_CPU(cs);
=C2=A0 =C2=A0 =C2=A0CPUARMState *env =3D &cpu->env;
- =C2=A0 =C2=A0target_ulong addr =3D env->cp15.vbar_el[1];
+ =C2=A0 =C2=A0unsigned int new_el =3D arm_excp_target_el(cs, cs->except= ion_index);
+ =C2=A0 =C2=A0target_ulong addr =3D env->cp15.vbar_el[new_el];
+ =C2=A0 =C2=A0unsigned int new_mode =3D aarch64_pstate_mode(new_el, true);=
=C2=A0 =C2=A0 =C2=A0int i;

- =C2=A0 =C2=A0if (arm_current_pl(env) =3D=3D 0) {
+ =C2=A0 =C2=A0if (arm_current_pl(env) < new_el) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (env->aarch64) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0addr +=3D 0x400;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} else {
@@ -464,14 +466,14 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0env->exception.syndrome);
=C2=A0 =C2=A0 =C2=A0}

- =C2=A0 =C2=A0env->cp15.esr_el[1] =3D env->exception.syndrome;
- =C2=A0 =C2=A0env->cp15.far_el[1] =3D env->exception.vaddress;
+ =C2=A0 =C2=A0env->cp15.esr_el[new_el] =3D env->exception.syndrome;<= br> + =C2=A0 =C2=A0env->cp15.far_el[new_el] =3D env->exception.vaddress;<= br>
=C2=A0 =C2=A0 =C2=A0switch (cs->exception_index) {
=C2=A0 =C2=A0 =C2=A0case EXCP_PREFETCH_ABORT:
=C2=A0 =C2=A0 =C2=A0case EXCP_DATA_ABORT:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_log_mask(CPU_LOG_INT, "...with = FAR 0x%" PRIx64 "\n",
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0env->cp15.far_el[1]);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0env->cp15.far_el[new_el]);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
=C2=A0 =C2=A0 =C2=A0case EXCP_BKPT:
=C2=A0 =C2=A0 =C2=A0case EXCP_UDEF:
@@ -488,15 +490,15 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
=C2=A0 =C2=A0 =C2=A0}

=C2=A0 =C2=A0 =C2=A0if (is_a64(env)) {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0env->banked_spsr[aarch64_banked_spsr_index(= 1)] =3D pstate_read(env);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0env->banked_spsr[aarch64_banked_spsr_index(= new_el)] =3D pstate_read(env);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0aarch64_save_sp(env, arm_current_pl(env))= ;
- =C2=A0 =C2=A0 =C2=A0 =C2=A0env->elr_el[1] =3D env->pc;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0env->elr_el[new_el] =3D env->pc;
=C2=A0 =C2=A0 =C2=A0} else {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->banked_spsr[0] =3D cpsr_read(env)= ;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!env->thumb) {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cp15.esr_el[1] |=3D 1 &l= t;< 25;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->cp15.esr_el[new_el] |=3D= 1 << 25;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
- =C2=A0 =C2=A0 =C2=A0 =C2=A0env->elr_el[1] =3D env->regs[15];
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0env->elr_el[new_el] =3D env->regs[15];
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < 15; i++) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->xregs[i] =3D env-&g= t;regs[i];
@@ -505,9 +507,9 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0env->condexec_bits =3D 0;
=C2=A0 =C2=A0 =C2=A0}

- =C2=A0 =C2=A0pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h);
+ =C2=A0 =C2=A0pstate_write(env, PSTATE_DAIF | new_mode);
=C2=A0 =C2=A0 =C2=A0env->aarch64 =3D 1;
- =C2=A0 =C2=A0aarch64_restore_sp(env, 1);
+ =C2=A0 =C2=A0aarch64_restore_sp(env, new_el);

=C2=A0 =C2=A0 =C2=A0env->pc =3D addr;
=C2=A0 =C2=A0 =C2=A0cs->interrupt_request |=3D CPU_INTERRUPT_EXITTB;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 17cf80e..86e098f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3217,6 +3217,11 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, ui= nt32_t mode)
=C2=A0 =C2=A0 =C2=A0return 0;
=C2=A0}

+unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
+{
+ =C2=A0 =C2=A0return 1;
+}
+
=C2=A0#else

=C2=A0/* Map CPU modes onto saved register banks. =C2=A0*/
@@ -3272,6 +3277,14 @@ void switch_mode(CPUARMState *env, int mode)
=C2=A0 =C2=A0 =C2=A0env->spsr =3D env->banked_spsr[i];
=C2=A0}

+/*
+ * Determine the target EL for a given exception type.
+ */
+unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
+{
+ =C2=A0 =C2=A0return 1;
+}
+

Unless this is just a preparation to = make the non CONFIG_USER_ONLY version of this =C2=A0different, this can be = moved out of the ifdef and made common.
=C2=A0
=C2=A0static void v7m_push(CPUARMState *env, uint32_t val)
=C2=A0{
=C2=A0 =C2=A0 =C2=A0CPUState *cs =3D CPU(arm_env_get_cpu(env));
--
1.8.3.2


Other= wise...

Reviewed-by: Greg Bellows <= greg.bellows@linaro.org>
--001a11c14dba4da0c604fb9240b7--