From ecdc655a867480b938652d52a0880853595e2976 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 28 May 2012 14:25:15 -0400 Subject: Run all hardware irq handlers on the extra stack. Jump into the extra stack for all hardware irq handlers. This reduces the overall stack requirements of SeaBIOS. Replace all users of call16_simpint with call16_int. Only the hardware irq handlers used the old call, and they need to use the new call to ensure the extra stack is properly re-entrant. Also, pass in a 'struct bregs' to the hardware irq handlers now. It was not done previously to save stack space. Now that the extra stack is used, that is no longer an issue. Note that should an old OS invoke a hardware irq in 16bit protected mode, then this patch could break that OS. However, the chances of this causing a regression seem small as several existing hardware irq handlers already do not work in 16bit protected mode. Signed-off-by: Kevin O'Connor --- src/romlayout.S | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) (limited to 'src/romlayout.S') diff --git a/src/romlayout.S b/src/romlayout.S index 147cd3bd..aadc9cf2 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -219,12 +219,15 @@ __call16big: lretw .endm + IRQ_TRAMPOLINE 02 IRQ_TRAMPOLINE 10 IRQ_TRAMPOLINE 13 IRQ_TRAMPOLINE 15 IRQ_TRAMPOLINE 16 IRQ_TRAMPOLINE 18 IRQ_TRAMPOLINE 19 + IRQ_TRAMPOLINE 1c + IRQ_TRAMPOLINE 4a /**************************************************************** @@ -386,10 +389,55 @@ entry_elf: * Interrupt entry points ****************************************************************/ - // Main entry point for interrupts without args - DECLFUNC irqentry -irqentry: - ENTRY_ST + // Main entry point for interrupts handled on extra stack + DECLFUNC irqentry_extrastack +irqentry_extrastack: + cli + cld + pushw %ds + pushl %eax + movl $_datalow_seg, %eax + movl %eax, %ds + movl StackPos, %eax + subl $BREGS_size+12, %eax + popl BREGS_eax(%eax) + popw BREGS_ds(%eax) + movl %edi, BREGS_edi(%eax) + movl %esi, BREGS_esi(%eax) + movl %ebp, BREGS_ebp(%eax) + movl %ebx, BREGS_ebx(%eax) + movl %edx, BREGS_edx(%eax) + movl %ecx, BREGS_ecx(%eax) + movw %es, BREGS_es(%eax) + popl %ecx + popl BREGS_code(%eax) + popw BREGS_flags(%eax) + + movw %ss, BREGS_size+8(%eax) + movzwl %sp, %edx + movl %edx, BREGS_size+4(%eax) + movl %esp, BREGS_size+0(%eax) + movw %ds, %dx + movw %dx, %ss + movl %eax, %esp + calll *%ecx + + movl %esp, %eax + movw BREGS_size+8(%eax), %ss + movl BREGS_size+0(%eax), %esp + movl BREGS_edi(%eax), %edi + movl BREGS_esi(%eax), %esi + movl BREGS_ebp(%eax), %ebp + movl BREGS_ebx(%eax), %ebx + movl BREGS_edx(%eax), %edx + movl BREGS_ecx(%eax), %ecx + movw BREGS_es(%eax), %es + pushw BREGS_flags(%eax) + pushl BREGS_code(%eax) + pushw BREGS_ds(%eax) + pushl BREGS_eax(%eax) + popl %eax + popw %ds iretw // Main entry point for interrupts with args @@ -398,12 +446,12 @@ irqentryarg: ENTRY_ARG_ST iretw - // Define an entry point for an interrupt (no args passed). + // Define an entry point for hardware interrupts. .macro IRQ_ENTRY num .global entry_\num entry_\num : pushl $ handle_\num - jmp irqentry + jmp irqentry_extrastack .endm .macro DECL_IRQ_ENTRY num -- cgit