xref: /kvmtool/x86/bios/entry.S (revision a68a52cd8ab76483b3592ddc0f7dbf40b4bd55ba)
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
115682ea77SPekka Enberg#define EFLAGS_CF	(1 << 0)
125682ea77SPekka Enberg
13dd1aab02SCyrill Gorcunov#include "macro.S"
14dd1aab02SCyrill Gorcunov
155682ea77SPekka Enberg/* If you change these macros, remember to update 'struct biosregs' */
165682ea77SPekka Enberg.macro SAVE_BIOSREGS
17193d2030SPekka Enberg	pushl	%fs
185682ea77SPekka Enberg	pushl	%es
19b4eab05eSPekka Enberg	pushl	%ds
205682ea77SPekka Enberg	pushl	%edi
215682ea77SPekka Enberg	pushl	%esi
225682ea77SPekka Enberg	pushl	%ebp
235682ea77SPekka Enberg	pushl	%esp
245682ea77SPekka Enberg	pushl	%edx
255682ea77SPekka Enberg	pushl	%ecx
265682ea77SPekka Enberg	pushl	%ebx
275682ea77SPekka Enberg	pushl	%eax
285682ea77SPekka Enberg.endm
295682ea77SPekka Enberg
305682ea77SPekka Enberg.macro RESTORE_BIOSREGS
315682ea77SPekka Enberg	popl	%eax
325682ea77SPekka Enberg	popl	%ebx
335682ea77SPekka Enberg	popl	%ecx
345682ea77SPekka Enberg	popl	%edx
355682ea77SPekka Enberg	popl	%esp
365682ea77SPekka Enberg	popl	%ebp
375682ea77SPekka Enberg	popl	%esi
385682ea77SPekka Enberg	popl	%edi
39b4eab05eSPekka Enberg	popl	%ds
405682ea77SPekka Enberg	popl	%es
41193d2030SPekka Enberg	popl	%fs
425682ea77SPekka Enberg.endm
4324a93433SPekka Enberg
44dd1aab02SCyrill Gorcunov/*
45dd1aab02SCyrill Gorcunov * fake interrupt handler, nothing can be faster ever
46dd1aab02SCyrill Gorcunov */
47dd1aab02SCyrill GorcunovENTRY(bios_intfake)
4824a93433SPekka Enberg	/*
4924a93433SPekka Enberg	 * Set CF to indicate failure. We don't want callers to think that the
5024a93433SPekka Enberg	 * interrupt handler succeeded and then treat the return values in
5124a93433SPekka Enberg	 * registers as valid data.
5224a93433SPekka Enberg	 */
5324a93433SPekka Enberg	orl	$EFLAGS_CF, 0x4(%esp)
5424a93433SPekka Enberg
55dd1aab02SCyrill Gorcunov	IRET
56dd1aab02SCyrill GorcunovENTRY_END(bios_intfake)
57dd1aab02SCyrill Gorcunov
58dd1aab02SCyrill Gorcunov/*
59dd1aab02SCyrill Gorcunov * int 10 - video - service
60dd1aab02SCyrill Gorcunov */
61dd1aab02SCyrill GorcunovENTRY(bios_int10)
625682ea77SPekka Enberg	SAVE_BIOSREGS
63dd1aab02SCyrill Gorcunov
64dd1aab02SCyrill Gorcunov	movl		%esp, %eax
65dd1aab02SCyrill Gorcunov	/* this is way easier than doing it in assembly */
66dd1aab02SCyrill Gorcunov	/* just push all the regs and jump to a C handler */
67dd1aab02SCyrill Gorcunov	call	int10_handler
68dd1aab02SCyrill Gorcunov
695682ea77SPekka Enberg	RESTORE_BIOSREGS
70dd1aab02SCyrill Gorcunov
7124a93433SPekka Enberg	/* Clear CF to indicate success.  */
7224a93433SPekka Enberg	andl	$~EFLAGS_CF, 0x4(%esp)
7324a93433SPekka Enberg
74dd1aab02SCyrill Gorcunov	IRET
75dd1aab02SCyrill GorcunovENTRY_END(bios_int10)
76dd1aab02SCyrill Gorcunov
77dd1aab02SCyrill GorcunovENTRY(bios_int15)
788f8e0548SPekka Enberg	SAVE_BIOSREGS
79dd1aab02SCyrill Gorcunov
80677a2bf1SPekka Enberg	movl	%esp, %eax
81677a2bf1SPekka Enberg	call	int15_handler
82dd1aab02SCyrill Gorcunov
838f8e0548SPekka Enberg	RESTORE_BIOSREGS
84677a2bf1SPekka Enberg
85dd1aab02SCyrill Gorcunov	IRET
86dd1aab02SCyrill GorcunovENTRY_END(bios_int15)
87dd1aab02SCyrill Gorcunov
88dd1aab02SCyrill GorcunovGLOBAL(__locals)
89dd1aab02SCyrill Gorcunov
90dd1aab02SCyrill Gorcunov#include "local.S"
91dd1aab02SCyrill Gorcunov
92dd1aab02SCyrill GorcunovEND(__locals)
93*a68a52cdSMartin Radev
94*a68a52cdSMartin Radev/*
95*a68a52cdSMartin Radev * Add this section to ensure final binary has a non-executable stack.
96*a68a52cdSMartin Radev */
97*a68a52cdSMartin Radev.section .note.GNU-stack,"",@progbits
98