On Mon, Nov 16, 2009 at 7:19 PM, Artyom Tarasenko
<atar4q...@googlemail.com> wrote:
> 2009/11/16 Blue Swirl <blauwir...@gmail.com>:
>> On Mon, Nov 16, 2009 at 1:47 PM, Artyom Tarasenko
>> <atar4q...@googlemail.com> wrote:
>>> 2009/11/15 Blue Swirl <blauwir...@gmail.com>:
>>>> On Sun, Nov 15, 2009 at 1:15 AM, Artyom Tarasenko
>>>> <atar4q...@googlemail.com> wrote:
>>>>> 2009/11/14 Blue Swirl <blauwir...@gmail.com>:
>>>>>> On Sat, Nov 14, 2009 at 3:03 AM, Artyom Tarasenko
>>>>>> <atar4q...@googlemail.com> wrote:
>>>>>>> According to NCR89C105 documentation
>>>>>>> http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
>>>>>>>
>>>>>>> Interrupts are cleared by disabling and then re-enabling them.
>>>>>>> This patch implements the specified behaviour. The most visible effects:
>>>>>>
>>>>>> I think the current version also implements this behaviour. The
>>>>>> difference is that now we clear on disable, with your version, the
>>>>>> interrupts are cleared when re-enabling them.
>>>>>
>>>>> Doesn't this imply that the current version does not implement this
>>>>> ("Interrupts are cleared by disabling and then re-enabling them") 
>>>>> behavior? ;-)
>>>>
>>>> The specification only says that the sequence disable-enable clears
>>>> interrupts, but not which of these is true:
>>>> - clearing happens in the moment of disabling (and interrupts after
>>>> that are not cleared, current version)
>>>> - clearing happens  in the moment of re-enabling (your version, sort of)
>>>> - clearing happens in both cases (lose interrupts)
>>>
>>> English is not my native language, but fwiw I think "and then
>>> re-enabling" can only be the second variant. Without "then" it could
>>> be either one or three. And if the first variant is what they really
>>> meant, the part with "and then" is totally redundant and misleading.
>>
>> Still, this is user documentation, not implementation specification.
>> I'm open to both versions, if they work.
>>
>>>> It's also interesting to think what happens between the interrupt
>>>> controller and the devices. Clearing an interrupt at controller level
>>>> does not clear the interrupt condition at the device. Aren't the
>>>> interrupts level triggered on Sparc, so the interrupt is still posted?
>>>> Is the interrupt actually masked by clearing until the level is
>>>> deactivated?
>>>
>>> Looks unlikely to me. In the book "Panic! Unix system crash dump
>>> analysis" the authors write that the first thing interrupt handler has
>>> to do is disable the interrupt, and yes wrting "unix" they mean
>>> "SunOS/Solaris".
>>>
>>> That's also what I observe debugging the Solaris kernel code
>>> (Solaris kernel debugger is a really powerful tool).
>>> Looks like interrupts can be shared between devices, so the general
>>> handler disables the interrupt and then calls multiple device-specific
>>> handlers sequentially and checks if any of then claims the interrupt.
>>> If no one does it writes the message "Spurious interrupt %d\n".
>>>
>>>
>>>> Or maybe the controller latches the interrupt so that even after the
>>>> device releases the interrupt line, interrupt is still active towards
>>>> the CPU. Then the clearing would make sense.
>>>
>>> Looks very realistic to me. I think that's the way the interrupts are
>>> handled at least under x86.
>>
>> It's a must on x86, because the interrupts are edge triggered.
>
> I don't know, how the real sun4m reacts in the case where irq stays
> on, not being cleared.
> It can not be though that it would try to process irq for every next
> tick. The CPU must have some time to clear the pending irq, so it must
> be edge triggered too, at least in a way.

This patch makes the interrupts latch: ignore source clearing the
interrupt. It seems be ~okay for my usual test setup, but does not
help NetBSD 1.3.3. Some other NetBSD tests are changed, but they
crashed before.
From bf8c381c4c6f7140ddc73865eba64640f4c75352 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Mon, 16 Nov 2009 21:48:53 +0000
Subject: [PATCH] Sparc32: latch incoming interrupts

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/slavio_intctl.c |   11 ++---------
 1 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index 9aff892..a67d5c9 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -188,8 +188,8 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
     case 3: // set (disable, clear pending)
         // Force clear unused bits
         val &= MASTER_IRQ_MASK;
-        s->intregm_disabled |= val;
         s->intregm_pending &= ~val;
+        s->intregm_disabled |= val;
         slavio_check_interrupts(s, 1);
         DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
                 s->intregm_disabled);
@@ -338,15 +338,8 @@ static void slavio_set_irq(void *opaque, int irq, int level)
                     s->slaves[i].intreg_pending |= 1 << pil;
                 }
             }
-        } else {
-            s->intregm_pending &= ~mask;
-            if (pil == 15) {
-                for (i = 0; i < MAX_CPUS; i++) {
-                    s->slaves[i].intreg_pending &= ~(1 << pil);
-                }
-            }
+            slavio_check_interrupts(s, 1);
         }
-        slavio_check_interrupts(s, 1);
     }
 }
 
-- 
1.5.6.5

Reply via email to