blob: 1b71f898f8ec3551ee43296dee4e033bf3c5ccd9 [file] [log] [blame]
/*
* Our pretty trivial BIOS emulation
*/
#include <kvm/bios.h>
#include <kvm/assembly.h>
.org 0
.code16gcc
#define EFLAGS_CF (1 << 0)
#include "macro.S"
/* If you change these macros, remember to update 'struct biosregs' */
.macro SAVE_BIOSREGS
pushl %fs
pushl %es
pushl %ds
pushl %edi
pushl %esi
pushl %ebp
pushl %esp
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
.endm
.macro RESTORE_BIOSREGS
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %esp
popl %ebp
popl %esi
popl %edi
popl %ds
popl %es
popl %fs
.endm
/*
* fake interrupt handler, nothing can be faster ever
*/
ENTRY(bios_intfake)
/*
* Set CF to indicate failure. We don't want callers to think that the
* interrupt handler succeeded and then treat the return values in
* registers as valid data.
*/
orl $EFLAGS_CF, 0x4(%esp)
IRET
ENTRY_END(bios_intfake)
/*
* int 10 - video - service
*/
ENTRY(bios_int10)
SAVE_BIOSREGS
movl %esp, %eax
/* this is way easier than doing it in assembly */
/* just push all the regs and jump to a C handler */
call int10_handler
RESTORE_BIOSREGS
/* Clear CF to indicate success. */
andl $~EFLAGS_CF, 0x4(%esp)
IRET
ENTRY_END(bios_int10)
ENTRY(bios_int15)
SAVE_BIOSREGS
movl %esp, %eax
call int15_handler
RESTORE_BIOSREGS
IRET
ENTRY_END(bios_int15)
GLOBAL(__locals)
#include "local.S"
END(__locals)
/*
* Add this section to ensure final binary has a non-executable stack.
*/
.section .note.GNU-stack,"",@progbits