summaryrefslogtreecommitdiff
path: root/x86_64/interrupt.S
diff options
context:
space:
mode:
Diffstat (limited to 'x86_64/interrupt.S')
-rw-r--r--x86_64/interrupt.S22
1 files changed, 18 insertions, 4 deletions
diff --git a/x86_64/interrupt.S b/x86_64/interrupt.S
index 6fb77727..4b2d0482 100644
--- a/x86_64/interrupt.S
+++ b/x86_64/interrupt.S
@@ -61,6 +61,11 @@ ENTRY(interrupt)
je _call_local_ast
#endif
+ movb EXT(irqinfo)(,%rcx,2),%al /* look up irq_info[irq].trigger */
+ testb $1,%al /* was this a level triggered interrupt? */
+ jnz _call_handler /* yes: call handler before eoi */
+
+_eoi:
#ifndef APIC
movl $1,%eax
shll %cl,%eax /* get corresponding IRQ mask */
@@ -102,6 +107,12 @@ ENTRY(interrupt)
call EXT(ioapic_irq_eoi) /* ioapic irq specific EOI */
#endif
+ movl S_IRQ,%ecx
+ movb EXT(irqinfo)(,%rcx,2),%al /* look up irq_info[irq].trigger */
+ testb $1,%al /* was this a level triggered interrupt? */
+ jnz _completed /* yes: we are done */
+
+_call_handler:
;
movq S_IPL,S_ARG1 /* previous ipl as 2nd arg */
@@ -112,11 +123,14 @@ ENTRY(interrupt)
movq S_REGS,S_ARG3 /* address of interrupted registers as 4th arg */
movl S_IRQ,%eax /* copy irq number */
- shll $2,%eax /* irq * 4 */
- movl EXT(iunit)(%rax),%edi /* get device unit number as 1st arg */
+ movl EXT(iunit)(,%rax,4),%edi /* get device unit number as 1st arg */
+
+ call *EXT(ivect)(,%rax,8) /* call interrupt handler */
- shll $1,%eax /* irq * 8 */
- call *EXT(ivect)(%rax) /* call interrupt handler */
+ movl S_IRQ,%ecx
+ movb EXT(irqinfo)(,%rcx,2),%al /* look up irq_info[irq].trigger */
+ testb $1,%al /* was this a level triggered interrupt? */
+ jnz _eoi /* yes: eoi */
_completed:
movl S_IPL,%edi /* restore previous ipl */