diff options
Diffstat (limited to 'arch/i386/cpu/interrupts.c')
| -rw-r--r-- | arch/i386/cpu/interrupts.c | 28 | 
1 files changed, 19 insertions, 9 deletions
| diff --git a/arch/i386/cpu/interrupts.c b/arch/i386/cpu/interrupts.c index 51023f3a8..e4d0868cd 100644 --- a/arch/i386/cpu/interrupts.c +++ b/arch/i386/cpu/interrupts.c @@ -104,7 +104,7 @@ static inline unsigned long get_debugreg(int regno)  	return val;  } -void dump_regs(struct pt_regs *regs) +void dump_regs(struct irq_regs *regs)  {  	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;  	unsigned long d0, d1, d2, d3, d6, d7; @@ -225,7 +225,7 @@ int disable_interrupts(void)  }  /* IRQ Low-Level Service Routine */ -__isr__ irq_llsr(struct pt_regs *regs) +void irq_llsr(struct irq_regs *regs)  {  	/*  	 * For detailed description of each exception, refer to: @@ -234,7 +234,7 @@ __isr__ irq_llsr(struct pt_regs *regs)  	 * Order Number: 253665-029US, November 2008  	 * Table 6-1. Exceptions and Interrupts  	 */ -	switch (regs->orig_eax) { +	switch (regs->irq_id) {  	case 0x00:  		printf("Divide Error (Division by zero)\n");  		dump_regs(regs); @@ -340,7 +340,7 @@ __isr__ irq_llsr(struct pt_regs *regs)  	default:  		/* Hardware or User IRQ */ -		do_irq(regs->orig_eax); +		do_irq(regs->irq_id);  	}  } @@ -352,17 +352,30 @@ __isr__ irq_llsr(struct pt_regs *regs)   *  Interrupt entries are now very small (a push and a jump) but they are   *  now slower (all registers pushed on stack which provides complete   *  crash dumps in the low level handlers + * + * Interrupt Entry Point: + *  - Interrupt has caused eflags, CS and EIP to be pushed + *  - Interrupt Vector Handler has pushed orig_eax + *  - pt_regs.esp needs to be adjusted by 40 bytes: + *      12 bytes pushed by CPU (EFLAGSF, CS, EIP) + *      4 bytes pushed by vector handler (irq_id) + *      24 bytes pushed before SP (SS, GS, FS, ES, DS, EAX) + *      NOTE: Only longs are pushed on/popped off the stack!   */  asm(".globl irq_common_entry\n" \  	".hidden irq_common_entry\n" \  	".type irq_common_entry, @function\n" \  	"irq_common_entry:\n" \  	"cld\n" \ +	"pushl %ss\n" \  	"pushl %gs\n" \  	"pushl %fs\n" \  	"pushl %es\n" \  	"pushl %ds\n" \  	"pushl %eax\n" \ +	"movl  %esp, %eax\n" \ +	"addl  $40, %eax\n" \ +	"pushl %eax\n" \  	"pushl %ebp\n" \  	"pushl %edi\n" \  	"pushl %esi\n" \ @@ -370,12 +383,7 @@ asm(".globl irq_common_entry\n" \  	"pushl %ecx\n" \  	"pushl %ebx\n" \  	"mov   %esp, %eax\n" \ -	"pushl %ebp\n" \ -	"movl %esp,%ebp\n" \ -	"pushl %eax\n" \  	"call irq_llsr\n" \ -	"popl %eax\n" \ -	"leave\n"\  	"popl %ebx\n" \  	"popl %ecx\n" \  	"popl %edx\n" \ @@ -383,10 +391,12 @@ asm(".globl irq_common_entry\n" \  	"popl %edi\n" \  	"popl %ebp\n" \  	"popl %eax\n" \ +	"popl %eax\n" \  	"popl %ds\n" \  	"popl %es\n" \  	"popl %fs\n" \  	"popl %gs\n" \ +	"popl %ss\n" \  	"add  $4, %esp\n" \  	"iret\n" \  	DECLARE_INTERRUPT(0) \ |