[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 08/19] target-arm: Set PSTATE.SS correctly on excepti
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 08/19] target-arm: Set PSTATE.SS correctly on exception return from AArch64 |
Date: |
Tue, 19 Aug 2014 19:09:33 +0100 |
Set the PSTATE.SS bit correctly on exception returns from AArch64,
as required by the debug single-step functionality.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Edgar E. Iglesias <address@hidden>
---
target-arm/cpu.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-arm/op_helper.c | 20 +++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 8380c13..74f7b15 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -220,6 +220,7 @@ typedef struct CPUARMState {
uint64_t dbgbcr[16]; /* breakpoint control registers */
uint64_t dbgwvr[16]; /* watchpoint value registers */
uint64_t dbgwcr[16]; /* watchpoint control registers */
+ uint64_t mdscr_el1;
/* If the counter is enabled, this stores the last time the counter
* was reset. Otherwise it stores the counter value
*/
@@ -1119,6 +1120,66 @@ static inline int cpu_mmu_index (CPUARMState *env)
return arm_current_pl(env);
}
+/* Return the Exception Level targeted by debug exceptions;
+ * currently always EL1 since we don't implement EL2 or EL3.
+ */
+static inline int arm_debug_target_el(CPUARMState *env)
+{
+ return 1;
+}
+
+static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
+{
+ if (arm_current_pl(env) == arm_debug_target_el(env)) {
+ if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
+ || (env->daif & PSTATE_D)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
+{
+ if (arm_current_pl(env) == 0 && arm_el_is_aa64(env, 1)) {
+ return aa64_generate_debug_exceptions(env);
+ }
+ return arm_current_pl(env) != 2;
+}
+
+/* Return true if debugging exceptions are currently enabled.
+ * This corresponds to what in ARM ARM pseudocode would be
+ * if UsingAArch32() then
+ * return AArch32.GenerateDebugExceptions()
+ * else
+ * return AArch64.GenerateDebugExceptions()
+ * We choose to push the if() down into this function for clarity,
+ * since the pseudocode has it at all callsites except for the one in
+ * CheckSoftwareStep(), where it is elided because both branches would
+ * always return the same value.
+ *
+ * Parts of the pseudocode relating to EL2 and EL3 are omitted because we
+ * don't yet implement those exception levels or their associated trap bits.
+ */
+static inline bool arm_generate_debug_exceptions(CPUARMState *env)
+{
+ if (env->aarch64) {
+ return aa64_generate_debug_exceptions(env);
+ } else {
+ return aa32_generate_debug_exceptions(env);
+ }
+}
+
+/* Is single-stepping active? (Note that the "is EL_D AArch64?" check
+ * implicitly means this always returns false in pre-v8 CPUs.)
+ */
+static inline bool arm_singlestep_active(CPUARMState *env)
+{
+ return extract32(env->cp15.mdscr_el1, 0, 1)
+ && arm_el_is_aa64(env, arm_debug_target_el(env))
+ && arm_generate_debug_exceptions(env);
+}
+
#include "exec/cpu-all.h"
/* Bit usage in the TB flags field: bit 31 indicates whether we are
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 180a4a0..62cc07d 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -380,12 +380,26 @@ void HELPER(exception_return)(CPUARMState *env)
env->exclusive_addr = -1;
+ /* We must squash the PSTATE.SS bit to zero unless both of the
+ * following hold:
+ * 1. debug exceptions are currently disabled
+ * 2. singlestep will be active in the EL we return to
+ * We check 1 here and 2 after we've done the pstate/cpsr write() to
+ * transition to the EL we're going to.
+ */
+ if (arm_generate_debug_exceptions(env)) {
+ spsr &= ~PSTATE_SS;
+ }
+
if (spsr & PSTATE_nRW) {
/* TODO: We currently assume EL1/2/3 are running in AArch64. */
env->aarch64 = 0;
new_el = 0;
env->uncached_cpsr = 0x10;
cpsr_write(env, spsr, ~0);
+ if (!arm_singlestep_active(env)) {
+ env->uncached_cpsr &= ~PSTATE_SS;
+ }
for (i = 0; i < 15; i++) {
env->regs[i] = env->xregs[i];
}
@@ -410,6 +424,9 @@ void HELPER(exception_return)(CPUARMState *env)
}
env->aarch64 = 1;
pstate_write(env, spsr);
+ if (!arm_singlestep_active(env)) {
+ env->pstate &= ~PSTATE_SS;
+ }
aarch64_restore_sp(env, new_el);
env->pc = env->elr_el[cur_el];
}
@@ -429,6 +446,9 @@ illegal_return:
spsr &= PSTATE_NZCV | PSTATE_DAIF;
spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
pstate_write(env, spsr);
+ if (!arm_singlestep_active(env)) {
+ env->pstate &= ~PSTATE_SS;
+ }
}
/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
--
1.9.1
- [Qemu-devel] [PULL 18/19] arm: armv7m: Rename address_space_mem -> system_memory, (continued)
- [Qemu-devel] [PULL 18/19] arm: armv7m: Rename address_space_mem -> system_memory, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 17/19] aarch64: Allow -kernel option to take a gzip-compressed kernel., Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 15/19] arm: cortex-a9: Fix cache-line size and associativity, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 13/19] target-arm: Rename QEMU PSCI v0.1 definitions, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 12/19] target-arm: Implement MDSCR_EL1 as having state, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 11/19] target-arm: Implement ARMv8 single-stepping for AArch32 code, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 10/19] target-arm: Implement ARMv8 single-step handling for A64 code, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 14/19] arm/virt: Use PSCI v0.2 function IDs in the DT when KVM uses PSCI v0.2, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 16/19] loader: Add load_image_gzipped function., Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 09/19] target-arm: A64: Avoid duplicate exit_tb(0) in non-linked goto_tb, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 08/19] target-arm: Set PSTATE.SS correctly on exception return from AArch64,
Peter Maydell <=
- [Qemu-devel] [PULL 06/19] target-arm: Don't allow AArch32 to access RES0 CPSR bits, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 04/19] target-arm: Provide both 32 and 64 bit versions of debug registers, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 19/19] arm: stellaris: Remove misleading address_space_mem var, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 07/19] target-arm: Correctly handle PSTATE.SS when taking exception to AArch32, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 05/19] target-arm: Adjust debug ID registers per-CPU, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 01/19] target-arm: Fix return address for A64 BRK instructions, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 02/19] target-arm: Collect up the debug cp register definitions, Peter Maydell, 2014/08/19
- [Qemu-devel] [PULL 03/19] target-arm: Allow STATE_BOTH reginfo descriptions for more than cp14, Peter Maydell, 2014/08/19
- Re: [Qemu-devel] [PULL 00/19] target-arm queue, Peter Maydell, 2014/08/20