blob: 0a4bf5d3857a01b4da3ee8ac358c7ef161bba8c0 [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
Kevin O'Connor21e930b2008-03-01 09:49:37 -050010#define PROTECTED_MODE_CS (2 << 3) // 0x10
11#define PROTECTED_MODE_DS (3 << 3) // 0x18
12#define REAL_MODE_CS (4 << 3) // 0x20
13#define REAL_MODE_DS (5 << 3) // 0x28
14
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050015 .code16gcc
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050016
17
18/****************************************************************
19 * Include of 16bit C code
20 ****************************************************************/
21
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050022 .globl bios16c_start, bios16c_end
23bios16c_start:
24.include "out/blob.proc.16.s"
25 .text
26bios16c_end:
27
28
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050029/****************************************************************
30 * POST handler
31 ****************************************************************/
32
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050033 // Macro to reset the 16bit stack
34 // Clobbers %ax
35 .macro RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050036 xorw %ax, %ax
37 movw %ax, %ss
38 movl $ CONFIG_STACK_OFFSET , %esp
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050039 .endm
40
41 .org 0xe05b
42 .globl post16
43post16:
44 // init the stack pointer
45 RESET_STACK
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050046
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050047 // Set entry point of rombios32 code - the actual address
Kevin O'Connor21e930b2008-03-01 09:49:37 -050048 // is altered later in the build process.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050049 .globl set_entry32
50set_entry32:
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050051 pushl $0xf0000000
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050052
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050053 // Fall through to transition32 function below
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050054
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050055
56/****************************************************************
57 * Call trampolines
58 ****************************************************************/
59
60// Place CPU into 32bit mode from 16bit mode.
61// Clobbers: %eax, flags, stack registers, cr0, idt/gdt
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050062transition32:
63 // Disable irqs
64 cli
65
66 // enable a20
67 inb $0x92, %al
68 orb $0x02, %al
69 outb %al, $0x92
70
71 // Set segment descriptors
72 lidt %cs:pmode_IDT_info
73 lgdt %cs:rombios32_gdt_48
74
75 // set PE bit in CR0
76 movl %cr0, %eax
77 orb $0x01, %al
78 movl %eax, %cr0
79
80 // start protected mode code
Kevin O'Connorcb6735f2008-03-01 13:39:52 -050081 // ljmpl $PROTECTED_MODE_CS, $(1f | 0xf0000)
82 .word 0xea66, 1f, 0x000f, PROTECTED_MODE_CS
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050083
84 .code32
851:
86 // init data segments
Kevin O'Connor21e930b2008-03-01 09:49:37 -050087 movl $PROTECTED_MODE_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050088 movw %ax, %ds
89 movw %ax, %es
90 movw %ax, %ss
91 xorl %eax, %eax
92 movw %ax, %fs
93 movw %ax, %gs
94
95 cld
96
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050097 retl
98
99// Call a 16bit function from 32bit mode.
Kevin O'Connorcb6735f2008-03-01 13:39:52 -0500100// %eax = address of struct bregs
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500101// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt
102 .globl __call16_from32
103__call16_from32:
104 pushl %eax
105
106 // Jump to 16bit mode
107 ljmp $0x20, $1f
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500108
109 .code16gcc
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001101:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500111 // restore data segment limits to 0xffff
112 movw $0x28, %ax
113 movw %ax, %ds
114 movw %ax, %es
115 movw %ax, %ss
116 movw %ax, %fs
117 movw %ax, %gs
118
119 // reset PE bit in CR0
120 movl %cr0, %eax
121 andb $0xfe, %al
122 movl %eax, %cr0
123
124 // far jump to flush CPU queue after transition to real mode
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500125 ljmpw $0xf000, $2f
Kevin O'Connor21e930b2008-03-01 09:49:37 -0500126
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001272:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500128 // restore IDT to normal real-mode defaults
129 lidt %cs:rmode_IDT_info
130
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500131 // Clear segment registers
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500132 xorw %ax, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500133 movw %ax, %fs
134 movw %ax, %gs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500135 movw %ax, %es
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500136 movw %ax, %ds
137 movw %ax, %ss // Assume stack is in segment 0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500138
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500139 popl %eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500140 pushl $transition32
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500141
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500142 // Fall through to __call16
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500143
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500144
Kevin O'Connor21e930b2008-03-01 09:49:37 -0500145// Call a 16bit function from 16bit mode with a specified cpu register state
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500146// %eax = address of struct bregs
147// Clobbers: all gp registers, es
148 .globl __call16
149__call16:
150 // Save eax
151 pushl %eax
152
153 // Setup for iretw call
154 pushw $0xf000
155 pushw $1f // return point
156 pushw 0x28(%eax) // flags
157 pushl 0x24(%eax) // CS:IP
158
159 // Load calling registers.
160 movl 0x04(%eax), %edi
161 movl 0x08(%eax), %esi
162 movl 0x0c(%eax), %ebp
163 movl 0x14(%eax), %ebx
164 movl 0x18(%eax), %edx
165 movl 0x1c(%eax), %ecx
166 movw 0x02(%eax), %es // XXX - should load %ds too
167 movl 0x20(%eax), %eax
168
169 // Invoke call
170 iretw // XXX - just do a lcalll
1711:
172 // Store flags, eax, ecx
173 pushfw
174 pushl %eax
175 movl 0x06(%esp), %eax
176 movl %ecx, 0x1c(%eax) // Save %ecx
177 popl %ecx
178 movl %ecx, 0x20(%eax) // Save %eax
179 popw %cx
180 movw %cx, 0x28(%eax) // Save flags
181
182 // Store remaining registers
183 movw %es, 0x02(%eax)
184 movl %edi, 0x04(%eax)
185 movl %esi, 0x08(%eax)
186 movl %ebp, 0x0c(%eax)
187 movl %ebx, 0x14(%eax)
188 movl %edx, 0x18(%eax)
189
190 // Remove %eax
191 popl %eax
192
193 retl
194
195
196/****************************************************************
197 * GDT and IDT tables
198 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500199
200// Protected mode IDT descriptor
201//
202// I just make the limit 0, so the machine will shutdown
203// if an exception occurs during protected mode memory
204// transfers.
205//
206// Set base to f0000 to correspond to beginning of BIOS,
207// in case I actually define an IDT later
208// Set limit to 0
209pmode_IDT_info:
210 .word 0x0000 // limit 15:00
Kevin O'Connorddd4bfd2008-02-28 20:00:20 -0500211 .long 0xf0000 // base 16:47
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500212
213// Real mode IDT descriptor
214//
215// Set to typical real-mode values.
216// base = 000000
217// limit = 03ff
218rmode_IDT_info:
219 .word 0x03ff // limit 15:00
Kevin O'Connorddd4bfd2008-02-28 20:00:20 -0500220 .long 0 // base 16:47
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500221
222rombios32_gdt_48:
223 .word 0x30
224 .word rombios32_gdt
225 .word 0x000f
226
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500227 .balign 8
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500228rombios32_gdt:
229 .word 0, 0, 0, 0
230 .word 0, 0, 0, 0
Kevin O'Connorcb6735f2008-03-01 13:39:52 -0500231 // 32 bit flat code segment (PROTECTED_MODE_CS)
232 .word 0xffff, 0, 0x9b00, 0x00cf
233 // 32 bit flat data segment (PROTECTED_MODE_DS)
234 .word 0xffff, 0, 0x9300, 0x00cf
235 // 16 bit code segment base=0xf0000 limit=0xffff (REAL_MODE_CS)
236 .word 0xffff, 0, 0x9b0f, 0x0000
237 // 16 bit data segment base=0x0 limit=0xffff (REAL_MODE_DS)
238 .word 0xffff, 0, 0x9300, 0x0000
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500239
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500240
241/****************************************************************
242 * Interrupt entry points
243 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500244
245 .macro ENTRY cfunc
Kevin O'Connor63dbcfb2008-03-01 22:17:07 -0500246 cli // In case something far-calls instead of using "int"
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500247 pushal
248 pushw %es
249 pushw %ds
250 movw %ss, %ax
251 movw %ax, %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500252 movzwl %sp, %esp
253 movl %esp, %eax
254 calll \cfunc
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500255 popw %ds
256 popw %es
257 popal
258 .endm
259
260 .macro IRQ_ENTRY num
261 .globl entry_\num
262 entry_\num :
263 ENTRY handle_\num
264 iretw
265 .endm
266
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500267 .macro IRQ_TRAMPOLINE num
268 .globl irq_trampoline_0x\num
269 irq_trampoline_0x\num :
270 int $0x\num
271 lretw
272 .endm
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500273
274 .org 0xe2c3
275 IRQ_ENTRY nmi
276
277 IRQ_ENTRY 13
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500278 IRQ_ENTRY 12
279 IRQ_ENTRY 11
280 IRQ_ENTRY 76
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500281 IRQ_ENTRY 1c
282 IRQ_ENTRY 70
283 IRQ_ENTRY 74
284 IRQ_ENTRY 75
285
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500286 .globl entry_19
287entry_19:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500288 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500289 calll handle_19
290
291 .globl entry_18
292entry_18:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500293 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500294 calll handle_18
295
296 IRQ_TRAMPOLINE 02
297 IRQ_TRAMPOLINE 10
298 IRQ_TRAMPOLINE 13
299 IRQ_TRAMPOLINE 15
300 IRQ_TRAMPOLINE 18
301 IRQ_TRAMPOLINE 19
302 IRQ_TRAMPOLINE 1c
303 IRQ_TRAMPOLINE 4a
304
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500305 .org 0xe3fe
306 jmp entry_13
307
308 .org 0xe401
309 // XXX - Fixed Disk Parameter Table
310
311 .org 0xe6f2
312 jmp entry_19
313
314 .org 0xe6f5
315.include "out/cbt.proc.16.s"
316 .text
317
318 .org 0xe729
319 // XXX - Baud Rate Generator Table
320
321 .org 0xe739
322 IRQ_ENTRY 14
323
324 .org 0xe82e
325 IRQ_ENTRY 16
326
327 .org 0xe987
328 IRQ_ENTRY 09
329
330 .org 0xec59
331 IRQ_ENTRY 40
332
333 .org 0xef57
334 IRQ_ENTRY 0e
335
336 .org 0xefc7
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500337.include "out/floppy_dbt.proc.16.s"
338 .text
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500339
340 .org 0xefd2
341 IRQ_ENTRY 17
342
343 .org 0xf045
344 // XXX int 10
345 iretw
346
347 .org 0xf065
348 IRQ_ENTRY 10
349
350 .org 0xf0a4
351 // XXX int 1D
352 iretw
353
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500354 .globl freespace2_start, freespace2_end
355freespace2_start:
356
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500357 .org 0xf841
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500358freespace2_end:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500359 jmp entry_12
360
361 .org 0xf84d
362 jmp entry_11
363
364 .org 0xf859
365 IRQ_ENTRY 15
366
367 .org 0xfa6e
368.include "out/font.proc.16.s"
369 .text
370
371 .org 0xfe6e
372 IRQ_ENTRY 1a
373
374 .org 0xfea5
375 IRQ_ENTRY 08
376
377 .org 0xfef3
378 // XXX - Initial Interrupt Vector Offsets Loaded by POST
379
380 .org 0xff00
381 // XXX - BIOS_COPYRIGHT_STRING
382 .ascii "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
383
384 .org 0xff53
385 .globl dummy_iret_handler
386dummy_iret_handler:
387 iretw
388
389 .org 0xff54
390 IRQ_ENTRY 05
391
392 .org 0xfff0 // Power-up Entry Point
393 ljmpw $0xf000, $post16
394
395 .org 0xfff5
396 // BIOS build date
397 .ascii "06/23/99"
398
399 .org 0xfffe
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500400 .byte CONFIG_MODEL_ID
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500401 .byte 0x00
402
403 .end