// Macros for entering C code
//
-// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2008-2014 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
/****************************************************************
- * Entry macros
+ * Macros for save and restore of 'struct bregs' registers
****************************************************************/
+ // Save registers (matches struct bregs) to stack
.macro PUSHBREGS
- pushl %eax // Save registers (matches struct bregs)
+ pushl %eax
pushl %ecx
pushl %edx
pushl %ebx
pushw %ds
.endm
+ // Restore registers (from struct bregs) from stack
.macro POPBREGS
- popw %ds // Restore registers (from struct bregs)
+ popw %ds
popw %es
popl %edi
popl %esi
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.
pushw BREGS_flags(%eax) // flags
pushl BREGS_code(%eax) // CS:IP
- // Load calling registers.
- 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
-
- // Invoke call
+ // Load calling registers and invoke call
+ RESTOREBREGS_DSEAX
iretw // XXX - just do a lcalll
1:
// Store flags, es, eax
pushl %eax
movw 0x08(%esp), %ds
movl 0x0c(%esp), %eax
- popl BREGS_eax(%eax)
- popw BREGS_es(%eax)
+ SAVEBREGS_POP_DSEAX
popw BREGS_flags(%eax)
-
- // Store remaining registers
- 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_ds(%eax)
movw %ss, %cx
movw %cx, %ds // Restore %ds == %ss
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)
+ SAVEBREGS_POP_DSEAX // Save registers on extra stack
popl %ecx
- movw %es, BREGS_es(%eax)
movl %esp, BREGS_size+0(%eax)
movw %ss, BREGS_size+4(%eax)
popl BREGS_code(%eax)
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
+ RESTOREBREGS_DSEAX
iretw
// Main entry point for interrupts with args
pushl %eax
movw %cs:ExtraStackSeg, %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)
+ SAVEBREGS_POP_DSEAX // Save registers on extra stack
movl %esp, BREGS_size+0(%eax)
movw %ss, BREGS_size+4(%eax)
popl BREGS_code(%eax)
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
+ RESTOREBREGS_DSEAX
iretw