qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 30/36] target-arm: Use a single entry point for AArch64 and AArch32 exceptions
Date: Thu, 21 Jan 2016 14:56:23 +0000	[thread overview]
Message-ID: <1453388189-13092-31-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1453388189-13092-1-git-send-email-peter.maydell@linaro.org>

If EL2 or EL3 is present on an AArch64 CPU, then exceptions can be
taken to an exception level which is running AArch32 (if only EL0
and EL1 are present then EL1 must be AArch64 and all exceptions are
taken to AArch64). To support this we need to have a single
implementation of the CPU do_interrupt() method which can handle both
32 and 64 bit exception entry.

Pull the common parts of aarch64_cpu_do_interrupt() and
arm_cpu_do_interrupt() out into a new function which calls
either the AArch32 or AArch64 specific entry code once it has
worked out which one is needed.

We temporarily special-case the handling of EXCP_SEMIHOST to
avoid an assertion in arm_el_is_aa64(); the next patch will
pull all the semihosting handling out to the arm_cpu_do_interrupt()
level (since semihosting semantics depend on the register width
of the calling code, not on that of any higher EL).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 target-arm/cpu-qom.h |  2 --
 target-arm/cpu64.c   |  3 ---
 target-arm/helper.c  | 75 ++++++++++++++++++++++++++++++----------------------
 3 files changed, 44 insertions(+), 36 deletions(-)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 979e1ee..07c0a71 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -254,6 +254,4 @@ int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 #endif
 
-void aarch64_cpu_do_interrupt(CPUState *cs);
-
 #endif
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 5f8a177..cc177bb 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -291,9 +291,6 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
 
-#if !defined(CONFIG_USER_ONLY)
-    cc->do_interrupt = aarch64_cpu_do_interrupt;
-#endif
     cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
     cc->set_pc = aarch64_cpu_set_pc;
     cc->gdb_read_register = aarch64_cpu_gdb_read_register;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 573e155..8f3a457 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5708,8 +5708,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
     env->regs[15] = env->pc;
 }
 
-/* Handle a CPU exception.  */
-void arm_cpu_do_interrupt(CPUState *cs)
+static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
@@ -5719,16 +5718,6 @@ void arm_cpu_do_interrupt(CPUState *cs)
     uint32_t offset;
     uint32_t moe;
 
-    assert(!IS_M(env));
-
-    arm_log_exception(cs->exception_index);
-
-    if (arm_is_psci_call(cpu, cs->exception_index)) {
-        arm_handle_psci_call(cpu);
-        qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
-        return;
-    }
-
     /* If this is a debug exception we must update the DBGDSCR.MOE bits */
     switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) {
     case EC_BREAKPOINT:
@@ -5900,11 +5889,10 @@ void arm_cpu_do_interrupt(CPUState *cs)
     }
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
-    cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
 }
 
-/* Handle a CPU exception.  */
-void aarch64_cpu_do_interrupt(CPUState *cs)
+/* Handle exception entry to a target EL which is using AArch64 */
+static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
@@ -5922,22 +5910,6 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
         addr += 0x200;
     }
 
-    arm_log_exception(cs->exception_index);
-    qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
-                  new_el);
-    if (qemu_loglevel_mask(CPU_LOG_INT)
-        && !excp_is_internal(cs->exception_index)) {
-        qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n",
-                      env->exception.syndrome >> ARM_EL_EC_SHIFT,
-                      env->exception.syndrome);
-    }
-
-    if (arm_is_psci_call(cpu, cs->exception_index)) {
-        arm_handle_psci_call(cpu);
-        qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
-        return;
-    }
-
     switch (cs->exception_index) {
     case EXCP_PREFETCH_ABORT:
     case EXCP_DATA_ABORT:
@@ -5997,6 +5969,47 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
 
     qemu_log_mask(CPU_LOG_INT, "...to EL%d PC 0x%" PRIx64 " PSTATE 0x%x\n",
                   new_el, env->pc, pstate_read(env));
+}
+
+/* Handle a CPU exception for A and R profile CPUs.
+ * Do any appropriate logging, handle PSCI calls, and then hand off
+ * to the AArch64-entry or AArch32-entry function depending on the
+ * target exception level's register width.
+ */
+void arm_cpu_do_interrupt(CPUState *cs)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    unsigned int new_el = env->exception.target_el;
+
+    assert(!IS_M(env));
+
+    arm_log_exception(cs->exception_index);
+    qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
+                  new_el);
+    if (qemu_loglevel_mask(CPU_LOG_INT)
+        && !excp_is_internal(cs->exception_index)) {
+        qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n",
+                      env->exception.syndrome >> ARM_EL_EC_SHIFT,
+                      env->exception.syndrome);
+    }
+
+    if (arm_is_psci_call(cpu, cs->exception_index)) {
+        arm_handle_psci_call(cpu);
+        qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
+        return;
+    }
+
+    /* Temporary special case for EXCP_SEMIHOST, which is used only
+     * for 64-bit semihosting calls -- as this is an internal exception
+     * it has no specified target level and arm_el_is_aa64() would
+     * assert because new_el could be 0.
+     */
+    if (cs->exception_index == EXCP_SEMIHOST || arm_el_is_aa64(env, new_el)) {
+        arm_cpu_do_interrupt_aarch64(cs);
+    } else {
+        arm_cpu_do_interrupt_aarch32(cs);
+    }
 
     if (!kvm_enabled()) {
         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-- 
1.9.1

  parent reply	other threads:[~2016-01-21 14:56 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-21 14:55 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 01/36] qdev: get_child_bus(): Use QOM lookup if available Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 02/36] m25p80.c: Add sst25wf080 SPI flash device Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 03/36] ssi: Move ssi.h into a separate directory Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 04/36] xilinx_spips: Separate the state struct into a header Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 05/36] xlnx-zynqmp: Connect the SPI devices Peter Maydell
2016-01-21 14:55 ` [Qemu-devel] [PULL 06/36] xlnx-ep108: Connect the SPI Flash Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 07/36] misc: zynq-xadc: Fix off-by-one Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 08/36] exec.c: Don't set cpu->as until cpu_address_space_init Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 09/36] exec.c: Allow target CPUs to define multiple AddressSpaces Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 10/36] exec-all.h: Document tlb_set_page_with_attrs, tlb_set_page Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 11/36] cpu: Add new get_phys_page_attrs_debug() method Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 12/36] cpu: Add new asidx_from_attrs() method Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 13/36] cputlb.c: Use correct address space when looking up MemoryRegionSection Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 14/36] exec.c: Pass MemTxAttrs to iotlb_to_region so it uses the right AS Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 15/36] exec.c: Add cpu_get_address_space() Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 16/36] exec.c: Use cpu_get_phys_page_attrs_debug Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 17/36] exec.c: Use correct AddressSpace in watch_mem_read and watch_mem_write Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 18/36] memory: Add address_space_init_shareable() Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 19/36] qom/cpu: Add MemoryRegion property Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 20/36] target-arm: Add QOM property for Secure memory region Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 21/36] target-arm: Implement asidx_from_attrs Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 22/36] target-arm: Implement cpu_get_phys_page_attrs_debug Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 23/36] target-arm: Support multiple address spaces in page table walks Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 24/36] hw/arm/virt: Wire up memory region to CPUs explicitly Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 25/36] hw/arm/virt: add secure memory region and UART Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 26/36] hw/arm/virt: Add always-on property to the virt board timer Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 27/36] arm_gic: Update ID registers based on revision Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 28/36] target-arm: Properly support EL2 and EL3 in arm_el_is_aa64() Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 29/36] target-arm: Move aarch64_cpu_do_interrupt() to helper.c Peter Maydell
2016-01-21 14:56 ` Peter Maydell [this message]
2016-01-21 14:56 ` [Qemu-devel] [PULL 31/36] target-arm: Pull semihosting handling out to arm_cpu_do_interrupt() Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 32/36] target-arm: Fix wrong AArch64 entry offset for EL2/EL3 target Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 33/36] target-arm: Handle exception return from AArch64 to non-EL0 AArch32 Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 34/36] target-arm: Implement remaining illegal return event checks Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 35/36] target-arm: ignore ELR_ELx[1] for exception return to 32-bit ARM mode Peter Maydell
2016-01-21 14:56 ` [Qemu-devel] [PULL 36/36] target-arm: Implement FPEXC32_EL2 system register Peter Maydell
2016-01-21 15:53 ` [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453388189-13092-31-git-send-email-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).