diff options
author | Wolfgang Denk <wd@denx.de> | 2010-10-11 10:00:34 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2010-10-11 10:00:34 +0200 |
commit | bfc7bea6adc46e1db2f5a5e3464d7652ed67c864 (patch) | |
tree | 4399dca93e4c42a3f652dd5b0b6143ab4aef50f4 /arch/i386/cpu/interrupts.c | |
parent | 29840de6b6d322e9cca3d22d254a1d066afbef02 (diff) | |
parent | c868af3e57610b41c6ed4fd8d8744d8cc0a21b29 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-x86
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 51023f3a86..e4d0868cde 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) \ |