blob: 039a1d83d9a851d5181a1871aefb3bbd80fe4827 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001// Rom layout and bios assembler to C interface.
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2002 MandrakeSoft S.A.
5//
6// This file may be distributed under the terms of the GNU GPLv3 license.
7
8#include "config.h"
9
10 .code16gcc
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050011
12
13/****************************************************************
14 * Include of 16bit C code
15 ****************************************************************/
16
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050017 .globl bios16c_start, bios16c_end
18bios16c_start:
19.include "out/blob.proc.16.s"
20 .text
21bios16c_end:
22
23
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050024/****************************************************************
25 * POST handler
26 ****************************************************************/
27
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050028 // Macro to reset the 16bit stack
29 // Clobbers %ax
30 .macro RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050031 xorw %ax, %ax
32 movw %ax, %ss
33 movl $ CONFIG_STACK_OFFSET , %esp
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050034 .endm
35
36 .org 0xe05b
37 .globl post16
38post16:
39 // init the stack pointer
40 RESET_STACK
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050041
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050042 // Set entry point of rombios32 code - the actual address
Kevin O'Connor4b60c002008-02-25 22:29:55 -050043 // is altered later in the build process.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050044 .globl set_entry32
45set_entry32:
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050046 pushl $0xf0000000
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050047
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050048 // Fall through to transition32 function below
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050049
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050050
51/****************************************************************
52 * Call trampolines
53 ****************************************************************/
54
55// Place CPU into 32bit mode from 16bit mode.
56// Clobbers: %eax, flags, stack registers, cr0, idt/gdt
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050057transition32:
58 // Disable irqs
59 cli
60
61 // enable a20
62 inb $0x92, %al
63 orb $0x02, %al
64 outb %al, $0x92
65
66 // Set segment descriptors
67 lidt %cs:pmode_IDT_info
68 lgdt %cs:rombios32_gdt_48
69
70 // set PE bit in CR0
71 movl %cr0, %eax
72 orb $0x01, %al
73 movl %eax, %cr0
74
75 // start protected mode code
Kevin O'Connor4b60c002008-02-25 22:29:55 -050076 .word 0xea66, 1f, 0x000f, 0x0010 // ljmpl $0x10, $(1f | 0xf0000)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050077
78 .code32
791:
80 // init data segments
81 movl $0x18, %eax
82 movw %ax, %ds
83 movw %ax, %es
84 movw %ax, %ss
85 xorl %eax, %eax
86 movw %ax, %fs
87 movw %ax, %gs
88
89 cld
90
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050091 retl
92
93// Call a 16bit function from 32bit mode.
94// 4(%esp) = address of struct bregs
95// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt
96 .globl __call16_from32
97__call16_from32:
98 pushl %eax
99
100 // Jump to 16bit mode
101 ljmp $0x20, $1f
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500102
103 .code16gcc
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001041:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500105 // restore data segment limits to 0xffff
106 movw $0x28, %ax
107 movw %ax, %ds
108 movw %ax, %es
109 movw %ax, %ss
110 movw %ax, %fs
111 movw %ax, %gs
112
113 // reset PE bit in CR0
114 movl %cr0, %eax
115 andb $0xfe, %al
116 movl %eax, %cr0
117
118 // far jump to flush CPU queue after transition to real mode
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500119 ljmpw $0xf000, $2f
1202:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500121 // restore IDT to normal real-mode defaults
122 lidt %cs:rmode_IDT_info
123
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500124 // Clear segment registers
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500125 xorw %ax, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500126 movw %ax, %fs
127 movw %ax, %gs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500128 movw %ax, %es
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500129 movw %ax, %ds
130 movw %ax, %ss // Assume stack is in segment 0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500131
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500132 popl %eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500133 pushl $transition32
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500134
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500135 // Fall through to __call16
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500136
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500137
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500138// Call a 16bit function with a specified cpu register state
139// %eax = address of struct bregs
140// Clobbers: all gp registers, es
141 .globl __call16
142__call16:
143 // Save eax
144 pushl %eax
145
146 // Setup for iretw call
147 pushw $0xf000
148 pushw $1f // return point
149 pushw 0x28(%eax) // flags
150 pushl 0x24(%eax) // CS:IP
151
152 // Load calling registers.
153 movl 0x04(%eax), %edi
154 movl 0x08(%eax), %esi
155 movl 0x0c(%eax), %ebp
156 movl 0x14(%eax), %ebx
157 movl 0x18(%eax), %edx
158 movl 0x1c(%eax), %ecx
159 movw 0x02(%eax), %es // XXX - should load %ds too
160 movl 0x20(%eax), %eax
161
162 // Invoke call
163 iretw // XXX - just do a lcalll
1641:
165 // Store flags, eax, ecx
166 pushfw
167 pushl %eax
168 movl 0x06(%esp), %eax
169 movl %ecx, 0x1c(%eax) // Save %ecx
170 popl %ecx
171 movl %ecx, 0x20(%eax) // Save %eax
172 popw %cx
173 movw %cx, 0x28(%eax) // Save flags
174
175 // Store remaining registers
176 movw %es, 0x02(%eax)
177 movl %edi, 0x04(%eax)
178 movl %esi, 0x08(%eax)
179 movl %ebp, 0x0c(%eax)
180 movl %ebx, 0x14(%eax)
181 movl %edx, 0x18(%eax)
182
183 // Remove %eax
184 popl %eax
185
186 retl
187
188
189/****************************************************************
190 * GDT and IDT tables
191 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500192
193// Protected mode IDT descriptor
194//
195// I just make the limit 0, so the machine will shutdown
196// if an exception occurs during protected mode memory
197// transfers.
198//
199// Set base to f0000 to correspond to beginning of BIOS,
200// in case I actually define an IDT later
201// Set limit to 0
202pmode_IDT_info:
203 .word 0x0000 // limit 15:00
204 .word 0x0000 // base 15:00
205 .byte 0x0f // base 23:16
206
207// Real mode IDT descriptor
208//
209// Set to typical real-mode values.
210// base = 000000
211// limit = 03ff
212rmode_IDT_info:
213 .word 0x03ff // limit 15:00
214 .word 0x0000 // base 15:00
215 .byte 0x00 // base 23:16
216
217rombios32_gdt_48:
218 .word 0x30
219 .word rombios32_gdt
220 .word 0x000f
221
222rombios32_gdt:
223 .word 0, 0, 0, 0
224 .word 0, 0, 0, 0
225 .word 0xffff, 0, 0x9b00, 0x00cf // 32 bit flat code segment (0x10)
226 .word 0xffff, 0, 0x9300, 0x00cf // 32 bit flat data segment (0x18)
227 .word 0xffff, 0, 0x9b0f, 0x0000 // 16 bit code segment base=0xf0000 limit=0xffff
228 .word 0xffff, 0, 0x9300, 0x0000 // 16 bit data segment base=0x0 limit=0xffff
229
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500230// We need a copy of this string, but we are not actually a PnP BIOS,
231// so make sure it is *not* aligned, so OSes will not see it if they
232// scan.
233 .align 2
234 .byte 0
235 .globl pnp_string
236pnp_string:
237 .ascii "$PnP"
238
239
240/****************************************************************
241 * Interrupt entry points
242 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500243
244 .macro ENTRY cfunc
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500245 cli // In case something far-calls insted of using "int"
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500246 pushal
247 pushw %es
248 pushw %ds
249 movw %ss, %ax
250 movw %ax, %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500251 movzwl %sp, %esp
252 movl %esp, %eax
253 calll \cfunc
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500254 popw %ds
255 popw %es
256 popal
257 .endm
258
259 .macro IRQ_ENTRY num
260 .globl entry_\num
261 entry_\num :
262 ENTRY handle_\num
263 iretw
264 .endm
265
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500266 .macro IRQ_TRAMPOLINE num
267 .globl irq_trampoline_0x\num
268 irq_trampoline_0x\num :
269 int $0x\num
270 lretw
271 .endm
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500272
273 .org 0xe2c3
274 IRQ_ENTRY nmi
275
276 IRQ_ENTRY 13
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500277 IRQ_ENTRY 12
278 IRQ_ENTRY 11
279 IRQ_ENTRY 76
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500280 IRQ_ENTRY 1c
281 IRQ_ENTRY 70
282 IRQ_ENTRY 74
283 IRQ_ENTRY 75
284
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500285 .globl entry_19
286entry_19:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500287 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500288 calll handle_19
289
290 .globl entry_18
291entry_18:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500292 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500293 calll handle_18
294
295 IRQ_TRAMPOLINE 02
296 IRQ_TRAMPOLINE 10
297 IRQ_TRAMPOLINE 13
298 IRQ_TRAMPOLINE 15
299 IRQ_TRAMPOLINE 18
300 IRQ_TRAMPOLINE 19
301 IRQ_TRAMPOLINE 1c
302 IRQ_TRAMPOLINE 4a
303
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500304 .org 0xe3fe
305 jmp entry_13
306
307 .org 0xe401
308 // XXX - Fixed Disk Parameter Table
309
310 .org 0xe6f2
311 jmp entry_19
312
313 .org 0xe6f5
314.include "out/cbt.proc.16.s"
315 .text
316
317 .org 0xe729
318 // XXX - Baud Rate Generator Table
319
320 .org 0xe739
321 IRQ_ENTRY 14
322
323 .org 0xe82e
324 IRQ_ENTRY 16
325
326 .org 0xe987
327 IRQ_ENTRY 09
328
329 .org 0xec59
330 IRQ_ENTRY 40
331
332 .org 0xef57
333 IRQ_ENTRY 0e
334
335 .org 0xefc7
336 // XXX - Diskette Controller Parameter Table
337
338 .org 0xefd2
339 IRQ_ENTRY 17
340
341 .org 0xf045
342 // XXX int 10
343 iretw
344
345 .org 0xf065
346 IRQ_ENTRY 10
347
348 .org 0xf0a4
349 // XXX int 1D
350 iretw
351
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500352 .globl freespace2_start, freespace2_end
353freespace2_start:
354
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500355 .org 0xf841
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500356freespace2_end:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500357 jmp entry_12
358
359 .org 0xf84d
360 jmp entry_11
361
362 .org 0xf859
363 IRQ_ENTRY 15
364
365 .org 0xfa6e
366.include "out/font.proc.16.s"
367 .text
368
369 .org 0xfe6e
370 IRQ_ENTRY 1a
371
372 .org 0xfea5
373 IRQ_ENTRY 08
374
375 .org 0xfef3
376 // XXX - Initial Interrupt Vector Offsets Loaded by POST
377
378 .org 0xff00
379 // XXX - BIOS_COPYRIGHT_STRING
380 .ascii "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
381
382 .org 0xff53
383 .globl dummy_iret_handler
384dummy_iret_handler:
385 iretw
386
387 .org 0xff54
388 IRQ_ENTRY 05
389
390 .org 0xfff0 // Power-up Entry Point
391 ljmpw $0xf000, $post16
392
393 .org 0xfff5
394 // BIOS build date
395 .ascii "06/23/99"
396
397 .org 0xfffe
398 // model byte 0xFC = AT
399 .byte 0xfc
400 .byte 0x00
401
402 .end