aboutsummaryrefslogtreecommitdiffstats
path: root/vgasrc/vgaentry.S
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2013-11-30 19:16:15 -0500
committerKevin O'Connor <kevin@koconnor.net>2013-12-04 10:34:18 -0500
commit4a8b58cb6cccc8f6431167dfdd36f3e39601ff79 (patch)
treebf69a1208db0de73a8699da7827116205dfb59af /vgasrc/vgaentry.S
parent865bfedf106a02807cbb27108f2c207add4c3013 (diff)
downloadseabios-4a8b58cb6cccc8f6431167dfdd36f3e39601ff79.tar.gz
vgabios: Support allocating an extra stack for vgabios calls and default on.
Add code to allocate an extra stack for the main vgabios int 0x10 entry point. The allocation is done via the PMM spec and uses a PCI v3 permanent low memory region request. This request will work with SeaBIOS - it is unknown how many other main BIOS implementations support this PMM call. The extra stack is useful for old DOS programs that call the VGABIOS and expect it to work with very small amounts of stack space. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'vgasrc/vgaentry.S')
-rw-r--r--vgasrc/vgaentry.S53
1 files changed, 53 insertions, 0 deletions
diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S
index a65136d0..1d2fe927 100644
--- a/vgasrc/vgaentry.S
+++ b/vgasrc/vgaentry.S
@@ -5,6 +5,7 @@
// This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "asm-offsets.h" // BREGS_*
#include "config.h" // CONFIG_*
#include "entryfuncs.S" // ENTRY_*
@@ -75,3 +76,55 @@ _optionrom_entry:
entry_10:
ENTRY_ARG_VGA handle_10
iretw
+
+ // Entry point using extra stack
+ DECLFUNC entry_10_extrastack
+entry_10_extrastack:
+ cli
+ cld
+ pushw %ds // Set %ds:%eax to space on ExtraStack
+ pushl %eax
+ movzwl %cs:ExtraStackSeg, %eax
+ movl %eax, %ds
+ movl $(CONFIG_VGA_EXTRA_STACK_SIZE-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)
+ 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
+ pushw %ax ; callw handle_10
+
+ 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