blob: 96a2fcfc77958594529f3d6d165a3bc79238ebd0 [file] [log] [blame]
// Macros for entering C code
//
// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
/****************************************************************
* 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
// As above, but get calling function from stack.
.macro ENTRY_ST
cli
cld
pushl %ecx
pushl %edx
pushw %es
pushw %ds
movw %ss, %cx // Move %ss to %ds
movw %cx, %ds
pushl %esp // Backup %esp, then clear high bits
movzwl %sp, %esp
movl 16(%esp), %ecx // Get calling function
movl %eax, 16(%esp) // Save %eax
calll *%ecx
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
pushl %eax // Save registers (matches struct bregs)
pushl %ecx
pushl %edx
pushl %ebx
pushl %esi
pushl %edi
pushw %es
pushw %ds
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)
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
.endm
// As above, but get calling function from stack.
.macro ENTRY_ARG_ST
cli
cld
pushl %ecx
pushl %edx
pushl %ebx
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 24(%esp), %ecx // Get calling function
movl %eax, 24(%esp) // Save %eax
movl %esp, %eax // First arg is pointer to struct bregs
calll *%ecx
movl %ebx, %esp // Restore %esp (including high bits)
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
.endm
// Same as ENTRY_ARG, but don't mangle %esp
.macro ENTRY_ARG_ESP cfunc
cli
cld
pushl %eax // Save registers (matches struct bregs)
pushl %ecx
pushl %edx
pushl %ebx
pushl %esi
pushl %edi
pushw %es
pushw %ds
movw %ss, %ax // Move %ss to %ds
movw %ax, %ds
movl %esp, %eax // First arg is pointer to struct bregs
calll \cfunc
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
.endm
// Reset stack, transition to 32bit mode, and call a C function.
// Clobbers %ax
.macro ENTRY_INTO32 cfunc
xorw %ax, %ax
movw %ax, %ss
movl $ BUILD_STACK_ADDR , %esp
pushl $ \cfunc
jmp transition32
.endm
// Declare a function
.macro DECLFUNC func
.section .text.asm.\func
.global \func
.endm