blob: 96e2e8b1fa2f272ba44e2108962f94c10b364f67 [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
Kevin O'Connoracad0a62008-03-02 23:24:16 -0500107 ljmp $REAL_MODE_CS, $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
Kevin O'Connoracad0a62008-03-02 23:24:16 -0500112 movw $REAL_MODE_DS, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500113 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
Kevin O'Connorcbbb6672008-03-08 13:04:10 -0500176 movl %ecx, %ss:0x1c(%eax) // Save %ecx
177 movw %ss, %cx
178 movw %cx, %ds // Restore %ds == %ss
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500179 popl %ecx
Kevin O'Connorcbbb6672008-03-08 13:04:10 -0500180 movl %ecx, 0x20(%eax) // Save %eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500181 popw %cx
Kevin O'Connorcbbb6672008-03-08 13:04:10 -0500182 movw %cx, 0x28(%eax) // Save flags
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500183
184 // Store remaining registers
185 movw %es, 0x02(%eax)
186 movl %edi, 0x04(%eax)
187 movl %esi, 0x08(%eax)
188 movl %ebp, 0x0c(%eax)
189 movl %ebx, 0x14(%eax)
190 movl %edx, 0x18(%eax)
191
192 // Remove %eax
193 popl %eax
194
195 retl
196
197
198/****************************************************************
199 * GDT and IDT tables
200 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500201
202// Protected mode IDT descriptor
203//
204// I just make the limit 0, so the machine will shutdown
205// if an exception occurs during protected mode memory
206// transfers.
207//
208// Set base to f0000 to correspond to beginning of BIOS,
209// in case I actually define an IDT later
210// Set limit to 0
211pmode_IDT_info:
212 .word 0x0000 // limit 15:00
Kevin O'Connorddd4bfd2008-02-28 20:00:20 -0500213 .long 0xf0000 // base 16:47
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500214
215// Real mode IDT descriptor
216//
217// Set to typical real-mode values.
218// base = 000000
219// limit = 03ff
220rmode_IDT_info:
221 .word 0x03ff // limit 15:00
Kevin O'Connorddd4bfd2008-02-28 20:00:20 -0500222 .long 0 // base 16:47
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500223
224rombios32_gdt_48:
225 .word 0x30
226 .word rombios32_gdt
227 .word 0x000f
228
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500229 .balign 8
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500230rombios32_gdt:
231 .word 0, 0, 0, 0
232 .word 0, 0, 0, 0
Kevin O'Connorcb6735f2008-03-01 13:39:52 -0500233 // 32 bit flat code segment (PROTECTED_MODE_CS)
234 .word 0xffff, 0, 0x9b00, 0x00cf
235 // 32 bit flat data segment (PROTECTED_MODE_DS)
236 .word 0xffff, 0, 0x9300, 0x00cf
237 // 16 bit code segment base=0xf0000 limit=0xffff (REAL_MODE_CS)
238 .word 0xffff, 0, 0x9b0f, 0x0000
239 // 16 bit data segment base=0x0 limit=0xffff (REAL_MODE_DS)
240 .word 0xffff, 0, 0x9300, 0x0000
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500241
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500242
243/****************************************************************
244 * Interrupt entry points
245 ****************************************************************/
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500246
247 .macro ENTRY cfunc
Kevin O'Connor843a62c2008-03-09 00:59:58 -0500248 cld
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500249 pushal
250 pushw %es
251 pushw %ds
252 movw %ss, %ax
253 movw %ax, %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500254 movzwl %sp, %esp
255 movl %esp, %eax
256 calll \cfunc
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500257 popw %ds
258 popw %es
259 popal
260 .endm
261
262 .macro IRQ_ENTRY num
263 .globl entry_\num
264 entry_\num :
Kevin O'Connor44d65302008-03-08 11:34:46 -0500265 cli // In case something far-calls instead of using "int"
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500266 ENTRY handle_\num
267 iretw
268 .endm
269
Kevin O'Connor44d65302008-03-08 11:34:46 -0500270 // APM trampolines
271 .globl apm16protected_entry
272apm16protected_entry:
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -0500273 pushfw // save flags
274 pushl %eax // dummy
Kevin O'Connor44d65302008-03-08 11:34:46 -0500275 ENTRY handle_1553
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -0500276 addw $4, %sp // pop dummy
277 popfw // restore flags
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500278 lretw
Kevin O'Connor44d65302008-03-08 11:34:46 -0500279
280 .code32
281 .globl apm32protected_entry
282apm32protected_entry:
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -0500283 pushfw // save flags
284 pushw %cs // Setup for long jump to 16bitmode
Kevin O'Connor44d65302008-03-08 11:34:46 -0500285 incw (%esp)
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -0500286 pushw 1f
Kevin O'Connor44d65302008-03-08 11:34:46 -0500287 lcallw *(%esp)
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -0500288 addl $4, %esp // pop call address
289 popfw
Kevin O'Connor44d65302008-03-08 11:34:46 -0500290 lretl
291 .code16gcc
Kevin O'Connordcc7a4f2008-03-08 23:25:16 -05002921: // 16bit entry point for apm32 code.
293 ENTRY handle_1553
294 lretw
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500295
296 .org 0xe2c3
297 IRQ_ENTRY nmi
298
299 IRQ_ENTRY 13
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500300 IRQ_ENTRY 12
301 IRQ_ENTRY 11
302 IRQ_ENTRY 76
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500303 IRQ_ENTRY 1c
304 IRQ_ENTRY 70
305 IRQ_ENTRY 74
306 IRQ_ENTRY 75
307
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500308 .globl entry_19
309entry_19:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500310 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500311 calll handle_19
312
313 .globl entry_18
314entry_18:
Kevin O'Connorbdce35f2008-02-26 21:33:14 -0500315 RESET_STACK
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500316 calll handle_18
317
Kevin O'Connor44d65302008-03-08 11:34:46 -0500318
319 // IRQ trampolines
320 .macro IRQ_TRAMPOLINE num
321 .globl irq_trampoline_0x\num
322 irq_trampoline_0x\num :
323 int $0x\num
324 lretw
325 .endm
326
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500327 IRQ_TRAMPOLINE 02
328 IRQ_TRAMPOLINE 10
329 IRQ_TRAMPOLINE 13
330 IRQ_TRAMPOLINE 15
331 IRQ_TRAMPOLINE 18
332 IRQ_TRAMPOLINE 19
333 IRQ_TRAMPOLINE 1c
334 IRQ_TRAMPOLINE 4a
335
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500336 .org 0xe3fe
337 jmp entry_13
338
339 .org 0xe401
340 // XXX - Fixed Disk Parameter Table
341
342 .org 0xe6f2
343 jmp entry_19
344
345 .org 0xe6f5
346.include "out/cbt.proc.16.s"
347 .text
348
349 .org 0xe729
350 // XXX - Baud Rate Generator Table
351
352 .org 0xe739
353 IRQ_ENTRY 14
354
355 .org 0xe82e
356 IRQ_ENTRY 16
357
358 .org 0xe987
359 IRQ_ENTRY 09
360
361 .org 0xec59
362 IRQ_ENTRY 40
363
364 .org 0xef57
365 IRQ_ENTRY 0e
366
367 .org 0xefc7
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500368.include "out/floppy_dbt.proc.16.s"
369 .text
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500370
371 .org 0xefd2
372 IRQ_ENTRY 17
373
374 .org 0xf045
375 // XXX int 10
376 iretw
377
378 .org 0xf065
379 IRQ_ENTRY 10
380
381 .org 0xf0a4
382 // XXX int 1D
383 iretw
384
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500385 .globl freespace2_start, freespace2_end
386freespace2_start:
387
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500388 .org 0xf841
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500389freespace2_end:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500390 jmp entry_12
391
392 .org 0xf84d
393 jmp entry_11
394
395 .org 0xf859
396 IRQ_ENTRY 15
397
398 .org 0xfa6e
399.include "out/font.proc.16.s"
400 .text
401
402 .org 0xfe6e
403 IRQ_ENTRY 1a
404
405 .org 0xfea5
406 IRQ_ENTRY 08
407
408 .org 0xfef3
409 // XXX - Initial Interrupt Vector Offsets Loaded by POST
410
411 .org 0xff00
412 // XXX - BIOS_COPYRIGHT_STRING
413 .ascii "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
414
415 .org 0xff53
416 .globl dummy_iret_handler
417dummy_iret_handler:
418 iretw
419
420 .org 0xff54
421 IRQ_ENTRY 05
422
423 .org 0xfff0 // Power-up Entry Point
424 ljmpw $0xf000, $post16
425
426 .org 0xfff5
427 // BIOS build date
428 .ascii "06/23/99"
429
430 .org 0xfffe
Kevin O'Connor44c631d2008-03-02 11:24:36 -0500431 .byte CONFIG_MODEL_ID
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500432 .byte 0x00
433
434 .end