diff options
-rw-r--r-- | i386/i386at/interrupt.S | 51 | ||||
-rw-r--r-- | x86_64/interrupt.S | 44 |
2 files changed, 68 insertions, 27 deletions
diff --git a/i386/i386at/interrupt.S b/i386/i386at/interrupt.S index e6a6af00..8fd18392 100644 --- a/i386/i386at/interrupt.S +++ b/i386/i386at/interrupt.S @@ -30,24 +30,48 @@ * * On entry, %eax contains the irq number. */ + +#define S_REGS 32(%esp) +#define S_RET 28(%esp) +#define S_IRQ 24(%esp) +#define S_IPL 20(%esp) + ENTRY(interrupt) #ifdef APIC cmpl $255,%eax /* was this a spurious intr? */ je _no_eoi /* if so, just return */ #endif - pushl %eax /* save irq number */ - movl %eax,%ecx /* copy irq number */ - shll $2,%ecx /* irq * 4 */ + subl $28,%esp /* Two local variables + 5 parameters */ + movl %eax,S_IRQ /* save irq number */ call spl7 /* set ipl */ - movl EXT(iunit)(%ecx),%edx /* get device unit number */ - pushl %eax /* push previous ipl */ - pushl %edx /* push unit number */ - call *EXT(ivect)(%ecx) /* call interrupt handler */ - addl $4,%esp /* pop unit number */ + movl %eax,S_IPL /* save previous ipl */ + + movl S_IPL,%eax + movl %eax,4(%esp) /* previous ipl as 2nd arg */ + + movl S_IRQ,%eax + movl %eax,8(%esp) /* irq number as 3rd arg */ + + movl S_RET,%eax + movl %eax,12(%esp) /* return address as 4th arg */ + + movl S_REGS,%eax + movl %eax,16(%esp) /* address of interrupted registers as 5th arg */ + + movl S_IRQ,%eax /* copy irq number */ + shll $2,%eax /* irq * 4 */ + movl EXT(iunit)(%eax),%edx /* get device unit number */ + movl %edx,(%esp) /* unit number as 1st arg */ + + call *EXT(ivect)(%eax) /* call interrupt handler */ + + movl S_IPL,%eax /* restore previous ipl */ + movl %eax,S_ARG0 call splx_cli /* restore previous ipl */ - addl $4,%esp /* pop previous ipl */ cli /* XXX no more nested interrupts */ - popl %ecx /* restore irq number */ + + movl S_IRQ,%ecx /* restore irq number */ + #ifndef APIC movl $1,%eax shll %cl,%eax /* get corresponding IRQ mask */ @@ -84,15 +108,14 @@ ENTRY(interrupt) movl EXT(curr_pic_mask),%eax /* restore original mask */ outb %al,$(PIC_MASTER_OCW) /* unmask master */ 2: - ret #else cmpl $16,%ecx /* was this a low ISA intr? */ jge _no_eoi /* no, must be PCI (let irq_ack handle EOI) */ _isa_eoi: - pushl %ecx /* push irq number */ + movl %ecx,S_ARG0 /* load irq number as 1st arg */ call EXT(ioapic_irq_eoi) /* ioapic irq specific EOI */ - addl $4,%esp /* pop irq number */ +#endif + addl $28,%esp /* pop local variables */ _no_eoi: ret -#endif END(interrupt) diff --git a/x86_64/interrupt.S b/x86_64/interrupt.S index 73151b06..56cd771b 100644 --- a/x86_64/interrupt.S +++ b/x86_64/interrupt.S @@ -28,30 +28,48 @@ /* * Generic interrupt handler. * - * On entry, %rax contains the irq number. + * On entry, %eax contains the irq number. */ + +#define S_REGS 24(%rsp) +#define S_RET 16(%rsp) +#define S_IRQ 8(%rsp) +#define S_IPL 0(%rsp) + ENTRY(interrupt) #ifdef APIC cmpl $255,%eax /* was this a spurious intr? */ je _no_eoi /* if so, just return */ #endif - pushq %rax /* save irq number */ + subq $16,%rsp /* Two local variables */ + movl %eax,S_IRQ /* save irq number */ call spl7 /* set ipl */ - pushq %rax /* save previous ipl */ - movl %eax, %esi /* previous ipl as 2nd arg */ - movl 8(%esp),%edx /* set irq number as 3rd arg */ - movl %edx,%eax /* copy irq number */ + movl %eax,S_IPL /* save previous ipl */ + + ; + movq S_IPL,S_ARG1 /* previous ipl as 2nd arg */ + + ; + movq S_IRQ,S_ARG2 /* irq number as 3rd arg */ + + ; + movq S_RET,S_ARG3 /* return address as 4th arg */ + + ; + movq S_REGS,S_ARG4 /* address of interrupted registers as 5th arg */ + + movl S_IRQ,%eax /* copy irq number */ shll $2,%eax /* irq * 4 */ movl EXT(iunit)(%eax),%edi /* get device unit number as 1st arg */ - movq 16(%esp), %rcx /* return address as 4th arg */ - movq 24(%esp), %r8 /* address of interrupted registers as 5th arg */ + shll $1,%eax /* irq * 8 */ call *EXT(ivect)(%eax) /* call interrupt handler */ - popq %rdi /* restore previous ipl */ - call splx_cli /* restore previous ipl */ + movl S_IPL,%edi /* restore previous ipl */ + call splx_cli /* restore previous ipl */ cli /* XXX no more nested interrupts */ - popq %rcx /* restore irq number */ + + movl S_IRQ,%ecx /* restore irq number */ #ifndef APIC movl $1,%eax @@ -89,14 +107,14 @@ ENTRY(interrupt) movl EXT(curr_pic_mask),%eax /* restore original mask */ outb %al,$(PIC_MASTER_OCW) /* unmask master */ 2: - ret #else cmpl $16,%ecx /* was this a low ISA intr? */ jge _no_eoi /* no, must be PCI (let irq_ack handle EOI) */ _isa_eoi: movl %ecx,%edi /* load irq number as 1st arg */ call EXT(ioapic_irq_eoi) /* ioapic irq specific EOI */ +#endif + addq $16,%rsp /* pop local variables */ _no_eoi: ret -#endif END(interrupt) |