1/*
2 * Our pretty trivial BIOS emulation
3 */
4
5#include "assembly.h"
6#include "processor-flags.h"
7
8	.org 0
9	.code16gcc
10
11/*
12 * handy BIOS macros
13 */
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
44ENTRY(bios_irq)
45	pushw	%ax
46	mov	$0x20, %al
47	out	%al, $0x20
48	popw	%ax
49	IRET
50ENTRY_END(bios_irq)
51
52/*
53 * fake interrupt handler, nothing can be faster ever
54 */
55ENTRY(bios_intfake)
56	/*
57	 * Set CF to indicate failure. We don't want callers to think that the
58	 * interrupt handler succeeded and then treat the return values in
59	 * registers as valid data.
60	 */
61	orb	$X86_EFLAGS_CF, 0x4(%esp)
62
63	IRET
64ENTRY_END(bios_intfake)
65
66/*
67 * int 10 - video - service
68 */
69ENTRY(bios_int10)
70	andb	$~X86_EFLAGS_CF, 0x4(%esp)
71	SAVE_BIOSREGS
72
73	movl		%esp, %eax
74	/* this is way easier than doing it in assembly */
75	/* just push all the regs and jump to a C handler */
76	call	int10_handler
77
78	RESTORE_BIOSREGS
79
80	IRET
81ENTRY_END(bios_int10)
82
83ENTRY(bios_int15)
84	andb	$~X86_EFLAGS_CF, 0x4(%esp)
85	SAVE_BIOSREGS
86
87	movl	%esp, %eax
88	call	int15_handler
89
90	RESTORE_BIOSREGS
91
92	IRET
93ENTRY_END(bios_int15)
94
95	.code32
96ENTRY(pcibios_entry)
97	clc
98	pushfl
99	SAVE_BIOSREGS
100
101	movl	%esp, %eax
102	call	pcibios_handler
103
104	RESTORE_BIOSREGS
105	popfl
106	lretl
107ENTRY_END(pcibios_entry)
108
109ENTRY(bios32_entry)
110	pushfl
111	testl	%ebx, %ebx	   /* BIOS32 service directory? */
112	jnz	2f
113	cmp	$0x49435024, %eax  /* "$PCI"? */
114	movb	$0x80, %al	   /* service not present */
115	jne	1f
116	xorl	%ebx, %ebx	   /* fill in base/length/entry */
117	movl	$(1 << 20), %ecx
118	movl	$pcibios_entry, %edx
119	movb	$0x00, %al	   /* service present */
1201:
121	popfl
122	lretl
1232:
124	movb	$0x81, %al	   /* unimplemented function */
125	popfl
126	lretl
127ENTRY_END(bios32_entry)
128
129ENTRY(pic_base)
130	call 1f
1312:
132	ret
1331:
134	popl	%eax
135	pushl	%eax
136	subl	$2b, %eax
137	ret			   /* return to 2b */
138ENTRY_END(pic_base)
139