summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/entryfuncs.S
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/seabios/src/entryfuncs.S')
-rw-r--r--qemu/roms/seabios/src/entryfuncs.S165
1 files changed, 165 insertions, 0 deletions
diff --git a/qemu/roms/seabios/src/entryfuncs.S b/qemu/roms/seabios/src/entryfuncs.S
new file mode 100644
index 000000000..7368bb6d5
--- /dev/null
+++ b/qemu/roms/seabios/src/entryfuncs.S
@@ -0,0 +1,165 @@
+// Macros for entering C code
+//
+// Copyright (C) 2008-2014 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+
+/****************************************************************
+ * Macros for save and restore of 'struct bregs' registers
+ ****************************************************************/
+
+#define PUSHBREGS_size 32
+
+ // Save registers (matches struct bregs) to stack
+ .macro PUSHBREGS
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ pushl %ebx
+ pushl %ebp
+ pushl %esi
+ pushl %edi
+ pushw %es
+ pushw %ds
+ .endm
+
+ // Restore registers (from struct bregs) from stack
+ .macro POPBREGS
+ popw %ds
+ popw %es
+ popl %edi
+ popl %esi
+ popl %ebp
+ popl %ebx
+ popl %edx
+ popl %ecx
+ popl %eax
+ .endm
+
+ // Save registers to struct bregs at %ds:%eax. The caller
+ // should "pushw %ds ; pushl %eax" prior to calling - this macro
+ // will pop them off.
+ .macro SAVEBREGS_POP_DSEAX
+ 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)
+ .endm
+
+ // Restore registers from struct bregs at %ds:%eax
+ .macro RESTOREBREGS_DSEAX
+ 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
+ pushl BREGS_eax(%eax)
+ movw BREGS_ds(%eax), %ds
+ popl %eax
+ .endm
+
+
+/****************************************************************
+ * Entry macros
+ ****************************************************************/
+
+ // Call a C function - this does the minimal work necessary to
+ // call into C. It sets up %ds, backs up %es, and backs up
+ // those registers that are call clobbered by the C compiler.
+ .macro ENTRY cfunc
+ cli // In case something far-calls instead of using "int"
+ cld
+ pushl %eax // Save registers clobbered by C code
+ pushl %ecx
+ pushl %edx
+ pushw %es
+ pushw %ds
+ movw %ss, %ax // Move %ss to %ds
+ movw %ax, %ds
+ pushl %esp // Backup %esp, then clear high bits
+ movzwl %sp, %esp
+ calll \cfunc
+ popl %esp // Restore %esp (including high bits)
+ popw %ds // Restore registers saved above
+ popw %es
+ popl %edx
+ popl %ecx
+ popl %eax
+ .endm
+
+ // Call a C function with current register list as an
+ // argument. This backs up the registers and sets %eax
+ // to point to the backup. On return, the registers are
+ // restored from the structure.
+ .macro ENTRY_ARG cfunc
+ cli
+ cld
+ PUSHBREGS
+ movw %ss, %ax // Move %ss to %ds
+ movw %ax, %ds
+ movl %esp, %ebx // Backup %esp, then zero high bits
+ movzwl %sp, %esp
+ movl %esp, %eax // First arg is pointer to struct bregs
+ calll \cfunc
+ movl %ebx, %esp // Restore %esp (including high bits)
+ POPBREGS
+ .endm
+
+ // As above, but get calling function from stack.
+ .macro ENTRY_ARG_ST
+ cli
+ cld
+ pushl %ecx
+ pushl %edx
+ pushl %ebx
+ pushl %ebp
+ pushl %esi
+ pushl %edi
+ pushw %es
+ pushw %ds
+ movw %ss, %cx // Move %ss to %ds
+ movw %cx, %ds
+ movl %esp, %ebx // Backup %esp, then zero high bits
+ movzwl %sp, %esp
+ movl 28(%esp), %ecx // Get calling function
+ movl %eax, 28(%esp) // Save %eax
+ movl %esp, %eax // First arg is pointer to struct bregs
+ calll *%ecx
+ movl %ebx, %esp // Restore %esp (including high bits)
+ POPBREGS
+ .endm
+
+ // Same as ENTRY_ARG, but don't mangle %esp
+ .macro ENTRY_ARG_ESP cfunc
+ cli
+ cld
+ PUSHBREGS
+ movw %ss, %ax // Move %ss to %ds
+ movw %ax, %ds
+ movl %esp, %eax // First arg is pointer to struct bregs
+ calll \cfunc
+ POPBREGS
+ .endm
+
+ // Reset stack, transition to 32bit mode, and call a C function.
+ .macro ENTRY_INTO32 cfunc
+ xorw %dx, %dx
+ movw %dx, %ss
+ movl $ BUILD_STACK_ADDR , %esp
+ movl $ \cfunc , %edx
+ jmp transition32
+ .endm
+
+ // Declare a function
+ .macro DECLFUNC func
+ .section .text.asm.\func
+ .global \func
+ .endm