xref: /kvmtool/x86/bios/entry.S (revision 24a93433bb964a456c8477e10f87e56a96e67ecc)
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