1/* 2 * Our pretty trivial BIOS emulation 3 */ 4 5#include <kvm/bios.h> 6#include <kvm/assembly.h> 7 8 .org 0 9 .code16gcc 10 11#define EFLAGS_CF (1 << 0) 12 13#include "macro.S" 14 15/* If you change these macros, remember to update 'struct biosregs' */ 16.macro SAVE_BIOSREGS 17 pushl %fs 18 pushl %es 19 pushl %ds 20 pushl %edi 21 pushl %esi 22 pushl %ebp 23 pushl %esp 24 pushl %edx 25 pushl %ecx 26 pushl %ebx 27 pushl %eax 28.endm 29 30.macro RESTORE_BIOSREGS 31 popl %eax 32 popl %ebx 33 popl %ecx 34 popl %edx 35 popl %esp 36 popl %ebp 37 popl %esi 38 popl %edi 39 popl %ds 40 popl %es 41 popl %fs 42.endm 43 44/* 45 * fake interrupt handler, nothing can be faster ever 46 */ 47ENTRY(bios_intfake) 48 /* 49 * Set CF to indicate failure. We don't want callers to think that the 50 * interrupt handler succeeded and then treat the return values in 51 * registers as valid data. 52 */ 53 orl $EFLAGS_CF, 0x4(%esp) 54 55 IRET 56ENTRY_END(bios_intfake) 57 58/* 59 * int 10 - video - service 60 */ 61ENTRY(bios_int10) 62 SAVE_BIOSREGS 63 64 movl %esp, %eax 65 /* this is way easier than doing it in assembly */ 66 /* just push all the regs and jump to a C handler */ 67 call int10_handler 68 69 RESTORE_BIOSREGS 70 71 /* Clear CF to indicate success. */ 72 andl $~EFLAGS_CF, 0x4(%esp) 73 74 IRET 75ENTRY_END(bios_int10) 76 77ENTRY(bios_int15) 78 SAVE_BIOSREGS 79 80 movl %esp, %eax 81 call int15_handler 82 83 RESTORE_BIOSREGS 84 85 IRET 86ENTRY_END(bios_int15) 87 88GLOBAL(__locals) 89 90#include "local.S" 91 92END(__locals) 93 94/* 95 * Add this section to ensure final binary has a non-executable stack. 96 */ 97.section .note.GNU-stack,"",@progbits 98