All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] target-mips: non-enabled interrupts can wake up the CPU in R6
@ 2015-09-14 12:58 Leon Alrae
  2015-09-14 12:58 ` [Qemu-devel] [PATCH 1/2] target-mips: move the test for enabled interrupts to a separate function Leon Alrae
  2015-09-14 12:58 ` [Qemu-devel] [PATCH 2/2] target-mips: implement the CPU wake-up on non-enabled interrupts in R6 Leon Alrae
  0 siblings, 2 replies; 3+ messages in thread
From: Leon Alrae @ 2015-09-14 12:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

MIPS Release 6 requires that the CPU blocked on WAIT instruction can be
woken up by an interrupt, even if interrupts are not enabled.

First patch does not contain any functional change, it just moves the
"are interrupts enabled?" part into separate
cpu_mips_hw_interrupts_enabled() function.

Second patch allows the R6 CPU to resume the execution regardless of
cpu_mips_hw_interrupts_enabled().

Leon Alrae (2):
  target-mips: move the test for enabled interrupts to a separate
    function
  target-mips: implement the CPU wake-up on non-enabled interrupts in R6

 target-mips/cpu.c    |  9 ++++++---
 target-mips/cpu.h    | 29 +++++++++++++++--------------
 target-mips/helper.c |  3 ++-
 3 files changed, 23 insertions(+), 18 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH 1/2] target-mips: move the test for enabled interrupts to a separate function
  2015-09-14 12:58 [Qemu-devel] [PATCH 0/2] target-mips: non-enabled interrupts can wake up the CPU in R6 Leon Alrae
@ 2015-09-14 12:58 ` Leon Alrae
  2015-09-14 12:58 ` [Qemu-devel] [PATCH 2/2] target-mips: implement the CPU wake-up on non-enabled interrupts in R6 Leon Alrae
  1 sibling, 0 replies; 3+ messages in thread
From: Leon Alrae @ 2015-09-14 12:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.c    |  4 +++-
 target-mips/cpu.h    | 29 +++++++++++++++--------------
 target-mips/helper.c |  3 ++-
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 4027d0f..144eea9 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -58,7 +58,9 @@ static bool mips_cpu_has_work(CPUState *cs)
        check for interrupts that can be taken. */
     if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
         cpu_mips_hw_interrupts_pending(env)) {
-        has_work = true;
+        if (cpu_mips_hw_interrupts_enabled(env)) {
+            has_work = true;
+        }
     }
 
     /* MIPS-MT has the ability to halt the CPU.  */
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c91883d..210370e 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -639,23 +639,24 @@ static inline int cpu_mmu_index (CPUMIPSState *env)
     return env->hflags & MIPS_HFLAG_KSU;
 }
 
-static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
+static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env)
 {
-    int32_t pending;
-    int32_t status;
-    int r;
-
-    if (!(env->CP0_Status & (1 << CP0St_IE)) ||
-        (env->CP0_Status & (1 << CP0St_EXL)) ||
-        (env->CP0_Status & (1 << CP0St_ERL)) ||
+    return (env->CP0_Status & (1 << CP0St_IE)) &&
+        !(env->CP0_Status & (1 << CP0St_EXL)) &&
+        !(env->CP0_Status & (1 << CP0St_ERL)) &&
+        !(env->hflags & MIPS_HFLAG_DM) &&
         /* Note that the TCStatus IXMT field is initialized to zero,
            and only MT capable cores can set it to one. So we don't
            need to check for MT capabilities here.  */
-        (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
-        (env->hflags & MIPS_HFLAG_DM)) {
-        /* Interrupts are disabled */
-        return 0;
-    }
+        !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT));
+}
+
+/* Check if there is pending and not masked out interrupt */
+static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
+{
+    int32_t pending;
+    int32_t status;
+    bool r;
 
     pending = env->CP0_Cause & CP0Ca_IP_mask;
     status = env->CP0_Status & CP0Ca_IP_mask;
@@ -669,7 +670,7 @@ static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
         /* A MIPS configured with compatibility or VInt (Vectored Interrupts)
            treats the pending lines as individual interrupt lines, the status
            lines are individual masks.  */
-        r = pending & status;
+        r = (pending & status) != 0;
     }
     return r;
 }
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 01c4461..2d86323 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -759,7 +759,8 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         MIPSCPU *cpu = MIPS_CPU(cs);
         CPUMIPSState *env = &cpu->env;
 
-        if (cpu_mips_hw_interrupts_pending(env)) {
+        if (cpu_mips_hw_interrupts_enabled(env) &&
+            cpu_mips_hw_interrupts_pending(env)) {
             /* Raise it */
             cs->exception_index = EXCP_EXT_INTERRUPT;
             env->error_code = 0;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH 2/2] target-mips: implement the CPU wake-up on non-enabled interrupts in R6
  2015-09-14 12:58 [Qemu-devel] [PATCH 0/2] target-mips: non-enabled interrupts can wake up the CPU in R6 Leon Alrae
  2015-09-14 12:58 ` [Qemu-devel] [PATCH 1/2] target-mips: move the test for enabled interrupts to a separate function Leon Alrae
@ 2015-09-14 12:58 ` Leon Alrae
  1 sibling, 0 replies; 3+ messages in thread
From: Leon Alrae @ 2015-09-14 12:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

In Release 6, the behaviour of WAIT has been modified to make it a
requirement that a processor that has disabled operation as a result of
executing a WAIT will resume operation on arrival of an interrupt even if
interrupts are not enabled.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 144eea9..cbeca04 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -53,12 +53,13 @@ static bool mips_cpu_has_work(CPUState *cs)
     CPUMIPSState *env = &cpu->env;
     bool has_work = false;
 
-    /* It is implementation dependent if non-enabled interrupts
-       wake-up the CPU, however most of the implementations only
+    /* Prior to MIPS Release 6 it is implementation dependent if non-enabled
+       interrupts wake-up the CPU, however most of the implementations only
        check for interrupts that can be taken. */
     if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
         cpu_mips_hw_interrupts_pending(env)) {
-        if (cpu_mips_hw_interrupts_enabled(env)) {
+        if (cpu_mips_hw_interrupts_enabled(env) ||
+            (env->insn_flags & ISA_MIPS32R6)) {
             has_work = true;
         }
     }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-09-14 12:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-14 12:58 [Qemu-devel] [PATCH 0/2] target-mips: non-enabled interrupts can wake up the CPU in R6 Leon Alrae
2015-09-14 12:58 ` [Qemu-devel] [PATCH 1/2] target-mips: move the test for enabled interrupts to a separate function Leon Alrae
2015-09-14 12:58 ` [Qemu-devel] [PATCH 2/2] target-mips: implement the CPU wake-up on non-enabled interrupts in R6 Leon Alrae

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.