Am Thursday 18 March 2010 14:07:26 schrieben Sie: > Hi, > > On Wednesday 17 March 2010 00:15:48 Michael Walle wrote: > > Am Tuesday 16 March 2010 15:53:41 schrieb Sébastien Bourdeauducq: > > > Therefore, it gets ALL interrupts (masked or not). We should AND > > > register IP with register IM. > > > > yep. imho that should be done within the asm code. > > Yes, but this requires extra asm instructions that no longer fit between > two LM32 exception vectors and therefore a jump is needed. I wanted to > avoid it, that's why I did it this way. But since it is inconsistent with > other Linux ports, I will change it. > > > other linux ports pass only one single irq number to do_IRQ(). > > > > What about the following steps: > > 1. interrupt vector gets called > > 2. save regs > > 3. r2 <- IM & IP > > 4. find position of first bit set in r2, store it in r1 > > (4a. r2 <- pt_regs) > > 5. mask irq > > 6. call do_IRQ (which only takes one irq number) > > 7. ack irq > > 8. unmask irq > > 9. restore regs > > 10. eret > > > > Processing only one interrupt at a time should avoid the second problem, > > mentioned above. > > Sounds good. It takes more CPU cycles to achieve the same thing when > interrupts come at the same time, but since I guess this rarely happens, > the small performance improvement is not worth the cost of doing > differently than other Linux ports.
see attachment -- wkr michael
From e6b18c3b3f63df3ed184403b1afb662974508906 Mon Sep 17 00:00:00 2001 From: Michael Walle <[email protected]> Date: Thu, 1 Apr 2010 00:01:54 +0200 Subject: [PATCH] new irq handling code --- arch/lm32/kernel/entry.S | 38 ++++++++++++++++++++++++++++++-------- arch/lm32/kernel/irq.c | 27 ++++++--------------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/arch/lm32/kernel/entry.S b/arch/lm32/kernel/entry.S index 15d8d39..232d253 100644 --- a/arch/lm32/kernel/entry.S +++ b/arch/lm32/kernel/entry.S @@ -79,14 +79,13 @@ ENTRY(divide_by_zero_handler) KERNEL_EXCEPTION_VECTOR(160) ENTRY(interrupt_handler) - addi sp, sp, -128 - sw (sp+120), ra - calli _save_irq_frame - rcsr r1, IP - - addi r2, sp, 4 - calli asm_do_IRQ - bi _restore_irq_frame_and_return + bi _long_interrupt_handler + nop + nop + nop + nop + nop + nop nop ENTRY(system_call) @@ -358,6 +357,29 @@ ENTRY(sys_clone_wrapper) /* in IRQ we call a function between save and restore */ /* we therefore only save and restore the caller saved registers */ /* (r1-r10, ra, ea because an interrupt could interrupt another one) */ +_long_interrupt_handler: + addi sp, sp, -128 + sw (sp+120), ra + calli _save_irq_frame + + rcsr r2, IP + rcsr r3, IM + mvi r1, 0 + and r2, r2, r3 + mvi r3, 1 + be r2, r0, 3f +1: + and r4, r2, r3 + bne r4, r0, 2f + sli r3, r3, 1 + addi r1, r1, 1 + bi 1b +2: + addi r2, sp, 4 + calli asm_do_IRQ +3: + bi _restore_irq_frame_and_return + _save_irq_frame: sw (sp+8), r1 sw (sp+12), r2 diff --git a/arch/lm32/kernel/irq.c b/arch/lm32/kernel/irq.c index 2dd57f4..32e7256 100644 --- a/arch/lm32/kernel/irq.c +++ b/arch/lm32/kernel/irq.c @@ -188,31 +188,16 @@ asmlinkage void manage_signals_irq(struct pt_regs* regs); * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void asm_do_IRQ(unsigned long vec, struct pt_regs *regs) +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs; - unsigned int irq; - - old_regs = set_irq_regs(regs); + struct pt_regs *old_regs = set_irq_regs(regs); irq_enter(); - /* Only process unmasked interrupts. - * This avoids a race condition if several interrupts - * arrive at the same time! - */ - vec &= lm32_current_irq_mask; - /* mask ALL interrupts we are going to process */ - lm32_irq_multimask(vec); - - /* decode irq */ - for (irq=0 ; irq<32; ++irq ) { - if ( vec & (1 << irq) ) { - generic_handle_irq(irq); /* < this (re)enables interrupts globally */ - lm32_irq_ack(irq); - lm32_irq_unmask(irq); - } - } + lm32_irq_mask(irq); + generic_handle_irq(irq); /* < this (re)enables interrupts globally */ + lm32_irq_ack(irq); + lm32_irq_unmask(irq); irq_exit(); -- 1.5.6.5
_______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkym...@freenode Webchat: www.milkymist.org/irc.html Wiki: www.milkymist.org/wiki
