[SeaBIOS] [PATCH 2/2] Support using the "extra stack" for all 16bit irq entry points.

Kevin O'Connor kevin at koconnor.net
Sun Mar 3 21:08:54 CET 2013


Using the internal stack reduces the amount of space that SeaBIOS uses
on the caller's stack.  This is known to help some very old operating
systems (like DOS 1.0).  However, there is a possibility that this
will break any operating systems that calls a legacy 16bit irq in
16bit protected mode (no OSes have yet to be identified as doing
this), so make the ability config dependent.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/Kconfig     |  9 +++++++++
 src/romlayout.S | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/src/Kconfig b/src/Kconfig
index 98a6642..3141069 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -103,6 +103,15 @@ endchoice
         default y
         help
             Support floppy images in coreboot flash.
+    config ENTRY_EXTRASTACK
+        bool "Use internal stack for 16bit interrupt entry points"
+        default y
+        help
+            Utilize an internal stack for all the legacy 16bit
+            interrupt entry points.  This reduces the amount of space
+            on the caller's stack that SeaBIOS uses.  This may
+            adversely impact any legacy operating systems that call
+            the BIOS in 16bit protected mode.
 
 endmenu
 
diff --git a/src/romlayout.S b/src/romlayout.S
index b152b3e..291b798 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -480,6 +480,60 @@ irqentry_extrastack:
         popw %ds
         iretw
 
+        // Main entry point for interrupts handled on extra stack
+        DECLFUNC irqentry_arg_extrastack
+irqentry_arg_extrastack:
+        cli
+        cld
+        pushw %ds               // Set %ds:%eax to space on ExtraStack
+        pushl %eax
+        movl $_zonelow_seg, %eax
+        movl %eax, %ds
+        movl StackPos, %eax
+        subl $BREGS_size+8, %eax
+        popl BREGS_eax(%eax)    // Backup registers
+        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)
+        popl %ecx
+        movw %es, BREGS_es(%eax)
+        movl %esp, BREGS_size+0(%eax)
+        movzwl %sp, %esp
+        movw %ss, BREGS_size+4(%eax)
+        movl (%esp), %edx
+        movl %edx, BREGS_code(%eax)
+        movw 4(%esp), %dx
+        movw %dx, BREGS_flags(%eax)
+
+        movw %ds, %dx           // Setup %ss/%esp and call function
+        movw %dx, %ss
+        movl %eax, %esp
+        calll *%ecx
+
+        movl %esp, %eax         // Restore registers and return
+        movw BREGS_size+4(%eax), %ss
+        movl BREGS_size+0(%eax), %esp
+        popl %edx
+        popw %dx
+        pushw BREGS_flags(%eax)
+        pushl BREGS_code(%eax)
+        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_ds(%eax)
+        pushl BREGS_eax(%eax)
+        popl %eax
+        popw %ds
+        iretw
+
         // Main entry point for interrupts with args
         DECLFUNC irqentryarg
 irqentryarg:
@@ -504,7 +558,11 @@ irqentryarg:
         .global entry_\num
         entry_\num :
         pushl $ handle_\num
+#if CONFIG_ENTRY_EXTRASTACK
+        jmp irqentry_arg_extrastack
+#else
         jmp irqentryarg
+#endif
         .endm
 
         .macro DECL_IRQ_ENTRY_ARG num
-- 
1.7.11.7




More information about the SeaBIOS mailing list