From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 8/9] sparc64: interrupt trap handling
Date: Wed, 06 Jan 2010 02:19:43 +0300 [thread overview]
Message-ID: <20100105231943.6526.42311.stgit@skyserv> (raw)
In-Reply-To: <20100105231558.6526.44483.stgit@skyserv>
From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
cpu_check_irqs
- handle SOFTINT register TICK and STICK timer bits
- only check interrupt levels greater than PIL value
- handle preemption by higher level traps
cpu_exec
- handle CPU_INTERRUPT_HARD only if interrupts are enabled
- PIL 15 is not special level on sparcv9
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
cpu-exec.c | 40 ++++++++++++++++++++++------------------
hw/sun4u.c | 52 +++++++++++++++++++++++++++++++++++++---------------
2 files changed, 59 insertions(+), 33 deletions(-)
diff --git a/cpu-exec.c b/cpu-exec.c
index af4595b..65192c1 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -449,24 +449,28 @@ int cpu_exec(CPUState *env1)
next_tb = 0;
}
#elif defined(TARGET_SPARC)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_interrupts_enabled(env)) {
- int pil = env->interrupt_index & 15;
- int type = env->interrupt_index & 0xf0;
-
- if (((type == TT_EXTINT) &&
- (pil == 15 || pil > env->psrpil)) ||
- type != TT_EXTINT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- env->exception_index = env->interrupt_index;
- do_interrupt(env);
- env->interrupt_index = 0;
- next_tb = 0;
- }
- } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
- //do_interrupt(0, 0, 0, 0, 0);
- env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
- }
+ if ((interrupt_request & CPU_INTERRUPT_HARD)) {
+ if (cpu_interrupts_enabled(env)) {
+ int pil = env->interrupt_index & 0xf;
+ int type = env->interrupt_index & 0xf0;
+
+ if (((type == TT_EXTINT) && (pil > env->psrpil)) ||
+ type != TT_EXTINT) {
+ //env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ if (env->interrupt_index > 0) {
+ env->exception_index = env->interrupt_index;
+ do_interrupt(env);
+ next_tb = 0;
+ }
+ }
+ }
+ }
+ else if (interrupt_request & CPU_INTERRUPT_TIMER) {
+ env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
+#if !defined(CONFIG_USER_ONLY)
+ cpu_check_irqs(env);
+#endif
+ }
#elif defined(TARGET_ARM)
if (interrupt_request & CPU_INTERRUPT_FIQ
&& !(env->uncached_cpsr & CPSR_F)) {
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 9d46f08..84a8043 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -233,29 +233,51 @@ void irq_info(Monitor *mon)
void cpu_check_irqs(CPUState *env)
{
- uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) |
- ((env->softint & SOFTINT_TIMER) << 14);
+ uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TM | SOFTINT_SM));
+
+ /* check if TM or SM in SOFTINT are set
+ setting these also causes interrupt 14 */
+ if (env->softint & (SOFTINT_TM | SOFTINT_SM))
+ pil |= 1 << 14;
+
+ if (!pil) {
+ if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+ CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %X)\n",
+ env->interrupt_index);
+ env->interrupt_index = 0;
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ }
+ return;
+ }
+
+ if (cpu_interrupts_enabled(env)) {
- if (pil && (env->interrupt_index == 0 ||
- (env->interrupt_index & ~15) == TT_EXTINT)) {
unsigned int i;
- for (i = 15; i > 0; i--) {
+ for (i = 15; i > env->psrpil; i--) {
if (pil & (1 << i)) {
int old_interrupt = env->interrupt_index;
-
- env->interrupt_index = TT_EXTINT | i;
- if (old_interrupt != env->interrupt_index) {
- CPUIRQ_DPRINTF("Set CPU IRQ %d\n", i);
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
+ int new_interrupt = TT_EXTINT | i;
+
+ if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
+ CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
+ "current %X >= pending %X\n",
+ env->tl, cpu_tsptr(env)->tt, new_interrupt);
+ }
+ else if (old_interrupt != new_interrupt) {
+ env->interrupt_index = new_interrupt;
+ CPUIRQ_DPRINTF("Set CPU IRQ %d old=%X new=%X\n", i,
+ old_interrupt, new_interrupt);
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+ }
break;
}
}
- } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {
- CPUIRQ_DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
- env->interrupt_index = 0;
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ }
+ else {
+ CPUIRQ_DPRINTF("Interrupts disabled, pil=%08X pil_in=%08X softint=%08X "
+ "current interrupt %X\n",
+ pil, env->pil_in, env->softint, env->interrupt_index);
}
}
next prev parent reply other threads:[~2010-01-05 23:19 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-05 23:19 [Qemu-devel] [PATCH 0/9] sparc64: tick timers Igor V. Kovalenko
2010-01-05 23:19 ` [Qemu-devel] [PATCH 1/9] sparc64: trace pstate and global register set changes Igor V. Kovalenko
2010-01-06 15:24 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 2/9] sparc64: add PSR and PIL to cpu state dump Igor V. Kovalenko
2010-01-06 15:31 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 3/9] sparc64: use helper_wrpil to check pending irq on write Igor V. Kovalenko
2010-01-06 15:41 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 4/9] sparc64: check for pending irq when pil, pstate or softint is changed Igor V. Kovalenko
2010-01-06 15:54 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 5/9] sparc64: add macros to deal with softint and timer interrupt Igor V. Kovalenko
2010-01-06 15:58 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 6/9] sparc64: clear exception_index with -1 value Igor V. Kovalenko
2010-01-06 17:36 ` Blue Swirl
2010-01-06 23:29 ` Artyom Tarasenko
2010-01-06 23:57 ` Igor Kovalenko
2010-01-07 20:05 ` Blue Swirl
2010-01-05 23:19 ` [Qemu-devel] [PATCH 7/9] sparc64: move cpu_interrupts_enabled to cpu.h Igor V. Kovalenko
2010-01-05 23:19 ` Igor V. Kovalenko [this message]
2010-01-06 17:00 ` [Qemu-devel] [PATCH 8/9] sparc64: interrupt trap handling Blue Swirl
2010-01-07 17:24 ` Igor Kovalenko
-- strict thread matches above, loose matches on Subject: below --
2010-01-07 20:27 [Qemu-devel] [PATCH 0/9] sparc64: interrupts and tick timers v1 Igor V. Kovalenko
2010-01-07 20:28 ` [Qemu-devel] [PATCH 8/9] sparc64: interrupt trap handling Igor V. Kovalenko
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=20100105231943.6526.42311.stgit@skyserv \
--to=igor.v.kovalenko@gmail.com \
--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).