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