1dd1aab02SCyrill Gorcunov/* 2dd1aab02SCyrill Gorcunov * Our pretty trivial BIOS emulation 3dd1aab02SCyrill Gorcunov */ 4dd1aab02SCyrill Gorcunov 5dd1aab02SCyrill Gorcunov#include <kvm/bios.h> 628ce0d66SCyrill Gorcunov#include <kvm/assembly.h> 728ce0d66SCyrill Gorcunov 828ce0d66SCyrill Gorcunov .org 0 9dd1aab02SCyrill Gorcunov .code16gcc 1028ce0d66SCyrill Gorcunov 11dd1aab02SCyrill Gorcunov#include "macro.S" 12dd1aab02SCyrill Gorcunov 13*24a93433SPekka Enberg#define EFLAGS_CF (1 << 0) 14*24a93433SPekka Enberg 15dd1aab02SCyrill Gorcunov/* 16dd1aab02SCyrill Gorcunov * fake interrupt handler, nothing can be faster ever 17dd1aab02SCyrill Gorcunov */ 18dd1aab02SCyrill GorcunovENTRY(bios_intfake) 19*24a93433SPekka Enberg /* 20*24a93433SPekka Enberg * Set CF to indicate failure. We don't want callers to think that the 21*24a93433SPekka Enberg * interrupt handler succeeded and then treat the return values in 22*24a93433SPekka Enberg * registers as valid data. 23*24a93433SPekka Enberg */ 24*24a93433SPekka Enberg orl $EFLAGS_CF, 0x4(%esp) 25*24a93433SPekka Enberg 26dd1aab02SCyrill Gorcunov IRET 27dd1aab02SCyrill GorcunovENTRY_END(bios_intfake) 28dd1aab02SCyrill Gorcunov 29dd1aab02SCyrill Gorcunov/* 30dd1aab02SCyrill Gorcunov * int 10 - video - service 31dd1aab02SCyrill Gorcunov */ 32dd1aab02SCyrill GorcunovENTRY(bios_int10) 33dd1aab02SCyrill Gorcunov pushw %fs 34dd1aab02SCyrill Gorcunov pushl %es 35dd1aab02SCyrill Gorcunov pushl %edi 36dd1aab02SCyrill Gorcunov pushl %esi 37dd1aab02SCyrill Gorcunov pushl %ebp 38dd1aab02SCyrill Gorcunov pushl %esp 39dd1aab02SCyrill Gorcunov pushl %edx 40dd1aab02SCyrill Gorcunov pushl %ecx 41dd1aab02SCyrill Gorcunov pushl %ebx 42dd1aab02SCyrill Gorcunov pushl %eax 43dd1aab02SCyrill Gorcunov 44dd1aab02SCyrill Gorcunov movl %esp, %eax 45dd1aab02SCyrill Gorcunov /* this is way easier than doing it in assembly */ 46dd1aab02SCyrill Gorcunov /* just push all the regs and jump to a C handler */ 47dd1aab02SCyrill Gorcunov call int10_handler 48dd1aab02SCyrill Gorcunov 49dd1aab02SCyrill Gorcunov popl %eax 50dd1aab02SCyrill Gorcunov popl %ebx 51dd1aab02SCyrill Gorcunov popl %ecx 52dd1aab02SCyrill Gorcunov popl %edx 53dd1aab02SCyrill Gorcunov popl %esp 54dd1aab02SCyrill Gorcunov popl %ebp 55dd1aab02SCyrill Gorcunov popl %esi 56dd1aab02SCyrill Gorcunov popl %edi 57dd1aab02SCyrill Gorcunov popl %es 58dd1aab02SCyrill Gorcunov popw %fs 59dd1aab02SCyrill Gorcunov 60*24a93433SPekka Enberg /* Clear CF to indicate success. */ 61*24a93433SPekka Enberg andl $~EFLAGS_CF, 0x4(%esp) 62*24a93433SPekka Enberg 63dd1aab02SCyrill Gorcunov IRET 64dd1aab02SCyrill GorcunovENTRY_END(bios_int10) 65dd1aab02SCyrill Gorcunov 66dd1aab02SCyrill GorcunovENTRY(bios_int15) 67dd1aab02SCyrill Gorcunov cmp $0xE820, %eax 68dd1aab02SCyrill Gorcunov jne 1f 69dd1aab02SCyrill Gorcunov 70dd1aab02SCyrill Gorcunov pushw %fs 71dd1aab02SCyrill Gorcunov 72dd1aab02SCyrill Gorcunov pushl %edx 73dd1aab02SCyrill Gorcunov pushl %ecx 74dd1aab02SCyrill Gorcunov pushl %edi 75dd1aab02SCyrill Gorcunov pushl %ebx 76dd1aab02SCyrill Gorcunov pushl %eax 77dd1aab02SCyrill Gorcunov 78dd1aab02SCyrill Gorcunov movl %esp, %eax # it's bioscall case 79dd1aab02SCyrill Gorcunov call e820_query_map 80dd1aab02SCyrill Gorcunov 81dd1aab02SCyrill Gorcunov popl %eax 82dd1aab02SCyrill Gorcunov popl %ebx 83dd1aab02SCyrill Gorcunov popl %edi 84dd1aab02SCyrill Gorcunov popl %ecx 85dd1aab02SCyrill Gorcunov popl %edx 86dd1aab02SCyrill Gorcunov 87dd1aab02SCyrill Gorcunov popw %fs 88dd1aab02SCyrill Gorcunov 89*24a93433SPekka Enberg /* Clear CF to indicate success. */ 90dd1aab02SCyrill Gorcunov andl $~EFLAGS_CF, 0x4(%esp) 91dd1aab02SCyrill Gorcunov1: 92dd1aab02SCyrill Gorcunov IRET 93dd1aab02SCyrill GorcunovENTRY_END(bios_int15) 94dd1aab02SCyrill Gorcunov 95dd1aab02SCyrill GorcunovGLOBAL(__locals) 96dd1aab02SCyrill Gorcunov 97dd1aab02SCyrill Gorcunov#include "local.S" 98dd1aab02SCyrill Gorcunov 99dd1aab02SCyrill GorcunovEND(__locals) 100