Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


5983a4a7b1c615e64acba65d30674078a8fedb0e
[palacios.git] / bios / seabios / src / romlayout.S
1 // Rom layout and bios assembler to C interface.
2 //
3 // Copyright (C) 2008,2009  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 LGPLv3 license.
7
8
9 /****************************************************************
10  * Include of 16bit C code
11  ****************************************************************/
12
13         .code16gcc
14 #include "ccode.16.s"
15
16 #include "config.h" // CONFIG_*
17 #include "ioport.h" // PORT_A20
18 #include "bregs.h" // CR0_*
19 #include "cmos.h" // CMOS_RESET_CODE
20 #include "asm-offsets.h" // BREGS_*
21 #include "entryfuncs.S" // ENTRY_*
22
23
24 /****************************************************************
25  * Call trampolines
26  ****************************************************************/
27
28 // Place CPU into 32bit mode from 16bit mode.
29 // %edx = return location (in 32bit mode)
30 // Clobbers: ecx, flags, segment registers, cr0, idt/gdt
31         DECLFUNC transition32
32 transition32:
33         movl %eax, %ecx
34
35         // Disable irqs (and clear direction flag)
36         cli
37         cld
38
39         // Disable nmi
40         movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax
41         outb %al, $PORT_CMOS_INDEX
42         inb $PORT_CMOS_DATA, %al
43
44         // enable a20
45         inb $PORT_A20, %al
46         orb $A20_ENABLE_BIT, %al
47         outb %al, $PORT_A20
48
49         // Set segment descriptors
50         lidtw %cs:pmode_IDT_info
51         lgdtw %cs:rombios32_gdt_48
52
53         // Enable protected mode
54         movl %cr0, %eax
55         orl $CR0_PE, %eax
56         movl %eax, %cr0
57
58         // start 32bit protected mode code
59         ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 1f)
60
61         .code32
62 1:
63         // init data segments
64         movl $SEG32_MODE32_DS, %eax
65         movw %ax, %ds
66         movw %ax, %es
67         movw %ax, %ss
68         movw %ax, %fs
69         movw %ax, %gs
70
71         movl %ecx, %eax
72         jmpl *%edx
73
74 // Place CPU into 16bit mode from 32bit mode.
75 // %edx = return location (in 16bit mode)
76 // Clobbers: ecx, flags, segment registers, cr0, idt/gdt
77         DECLFUNC transition16
78         .global transition16big
79 transition16:
80         movl %eax, %ecx
81
82         // restore data segment limits to 0xffff
83         movl $SEG32_MODE16_DS, %eax
84         movw %ax, %ds
85         movw %ax, %es
86         movw %ax, %ss
87         movw %ax, %fs
88         movw %ax, %gs
89
90 #if CONFIG_DISABLE_A20
91         // disable a20
92         inb $PORT_A20, %al
93         andb $~A20_ENABLE_BIT, %al
94         outb %al, $PORT_A20
95 #endif
96
97         // Jump to 16bit mode
98         ljmpw $SEG32_MODE16_CS, $1f
99
100 transition16big:
101         movl %eax, %ecx
102
103         movl $SEG32_MODE16BIG_DS, %eax
104         movw %ax, %ds
105         movw %ax, %es
106         movw %ax, %ss
107         movw %ax, %fs
108         movw %ax, %gs
109
110         ljmpw $SEG32_MODE16BIG_CS, $1f
111
112         .code16gcc
113 1:
114         // Disable protected mode
115         movl %cr0, %eax
116         andl $~CR0_PE, %eax
117         movl %eax, %cr0
118
119         // far jump to flush CPU queue after transition to real mode
120         ljmpw $SEG_BIOS, $2f
121
122 2:
123         // restore IDT to normal real-mode defaults
124         lidtw %cs:rmode_IDT_info
125
126         // Clear segment registers
127         xorw %ax, %ax
128         movw %ax, %fs
129         movw %ax, %gs
130         movw %ax, %es
131         movw %ax, %ds
132         movw %ax, %ss  // Assume stack is in segment 0
133
134         movl %ecx, %eax
135         jmpl *%edx
136
137 // Call a 16bit function from 16bit mode with a specified cpu register state
138 // %eax = address of struct bregs
139 // Clobbers: %e[bcd]x, %e[ds]i, flags
140         DECLFUNC __call16
141 __call16:
142         // Save %eax, %ebp
143         pushl %ebp
144         pushl %eax
145
146         // Setup for iretw call
147         pushw %cs
148         pushw $1f               // return point
149         pushw BREGS_flags(%eax) // flags
150         pushl BREGS_code(%eax)  // CS:IP
151
152         // Load calling registers.
153         movl BREGS_edi(%eax), %edi
154         movl BREGS_esi(%eax), %esi
155         movl BREGS_ebp(%eax), %ebp
156         movl BREGS_ebx(%eax), %ebx
157         movl BREGS_edx(%eax), %edx
158         movl BREGS_ecx(%eax), %ecx
159         movw BREGS_es(%eax), %es
160         movw BREGS_ds(%eax), %ds
161         movl %ss:BREGS_eax(%eax), %eax
162
163         // Invoke call
164         iretw                   // XXX - just do a lcalll
165 1:
166         // Store flags, eax, ecx
167         pushfw
168         pushl %eax
169         movl 0x06(%esp), %eax
170         movl %ecx, %ss:BREGS_ecx(%eax)
171         movw %ds, %ss:BREGS_ds(%eax)
172         movw %ss, %cx
173         movw %cx, %ds           // Restore %ds == %ss
174         popl %ecx
175         movl %ecx, BREGS_eax(%eax)
176         popw %cx
177         movw %cx, BREGS_flags(%eax)
178
179         // Store remaining registers
180         movw %es, BREGS_es(%eax)
181         movl %edi, BREGS_edi(%eax)
182         movl %esi, BREGS_esi(%eax)
183         movl %ebp, BREGS_ebp(%eax)
184         movl %ebx, BREGS_ebx(%eax)
185         movl %edx, BREGS_edx(%eax)
186
187         // Remove %eax, restore %ebp
188         popl %eax
189         popl %ebp
190
191         retl
192
193 // Call a 16bit function from 32bit mode.
194 // %eax = address of struct bregs
195 // Clobbers: %e[bcd]x, %e[ds]i, flags, segment registers, idt/gdt
196         DECLFUNC __call16_from32
197         .global __call16big_from32
198         .code32
199 __call16_from32:
200         movl $1f, %edx
201         jmp transition16
202 __call16big_from32:
203         movl $1f, %edx
204         jmp transition16big
205
206         // Make call.
207         .code16gcc
208 1:      calll __call16
209         // Return via transition32
210         movl $(2f + BUILD_BIOS_ADDR), %edx
211         jmp transition32
212         .code32
213 2:      retl
214
215         .code16gcc
216 // IRQ trampolines
217         .macro IRQ_TRAMPOLINE num
218         DECLFUNC irq_trampoline_0x\num
219         irq_trampoline_0x\num :
220         int $0x\num
221         lretw
222         .endm
223
224         IRQ_TRAMPOLINE 10
225         IRQ_TRAMPOLINE 13
226         IRQ_TRAMPOLINE 15
227         IRQ_TRAMPOLINE 16
228         IRQ_TRAMPOLINE 18
229         IRQ_TRAMPOLINE 19
230
231
232 /****************************************************************
233  * Misc. entry points.
234  ****************************************************************/
235
236 // Resume (and reboot) entry point - called from entry_post
237         DECLFUNC entry_resume
238 entry_resume:
239         // Disable interrupts
240         cli
241         cld
242         // Use a stack in EBDA
243         movw $SEG_BDA, %ax
244         movw %ax, %ds
245         movw BDA_ebda_seg, %ax
246         movw %ax, %ds
247         movw %ax, %ss
248         movl $EBDA_OFFSET_TOP_STACK, %esp
249         // Call handler.
250         jmp handle_resume
251
252 // PMM entry point
253         DECLFUNC entry_pmm
254 entry_pmm:
255         pushl %esp              // Backup %esp, then clear high bits
256         movzwl %sp, %esp
257         pushfl                  // Save registers clobbered by C code
258         cli
259         cld
260         pushl %eax
261         pushl %ecx
262         pushl %edx
263         pushw %es
264         pushw %ds
265         movw %ss, %cx           // Move %ss to %ds
266         movw %cx, %ds
267         movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
268         leal 28(%esp), %edx     // %edx points to start of args
269         movl $-1, %ecx
270         calll call32
271         movw %ax, 12(%esp)      // Modify %ax:%dx to return %eax
272         shrl $16, %eax
273         movw %ax, 4(%esp)
274         popw %ds                // Restore saved registers
275         popw %es
276         popl %edx
277         popl %ecx
278         popl %eax
279         popfl
280         popl %esp
281         lretw
282
283 // PnP entry points
284         DECLFUNC entry_pnp_real
285         .global entry_pnp_prot
286 entry_pnp_prot:
287         pushl %esp
288         jmp 1f
289 entry_pnp_real:
290         pushl %esp              // Backup %esp, then clear high bits
291         movzwl %sp, %esp
292 1:
293         pushfl                  // Save registers clobbered by C code
294         cli
295         cld
296         pushl %eax
297         pushl %ecx
298         pushl %edx
299         pushw %es
300         pushw %ds
301         movw %ss, %cx           // Move %ss to %ds
302         movw %cx, %ds
303         leal 28(%esp), %eax     // %eax points to start of u16 args
304         calll handle_pnp
305         movw %ax, 12(%esp)      // Modify %eax to return %ax
306         popw %ds
307         popw %es
308         popl %edx
309         popl %ecx
310         popl %eax
311         popfl
312         popl %esp
313         lretw
314
315 // APM entry points
316         DECLFUNC entry_apm16
317 entry_apm16:
318         pushfw          // save flags
319         pushl %eax      // dummy
320         ENTRY_ARG handle_apm16
321         addw $4, %sp    // pop dummy
322         popfw           // restore flags
323         lretw
324
325         .code32
326         DECLFUNC entry_apm32
327 entry_apm32:
328         pushfl
329         pushl %gs
330         pushl %cs               // Move second descriptor after %cs to %gs
331         addl $16, (%esp)
332         popl %gs
333         ENTRY_ARG_ESP _cfunc32seg_handle_apm32
334         popl %gs
335         popfl
336         lretl
337
338 // PCI-BIOS 32bit entry point
339         DECLFUNC entry_pcibios32
340 entry_pcibios32:
341         pushfl
342         pushl %gs               // Backup %gs and set %gs=%ds
343         pushl %ds
344         popl %gs
345         ENTRY_ARG_ESP _cfunc32seg_handle_pcibios32
346         popl %gs
347         popfl
348         lretl
349
350 // BIOS32 support
351         EXPORTFUNC entry_bios32
352 entry_bios32:
353         pushfl
354 #if CONFIG_PCIBIOS
355         // Check for PCI-BIOS request
356         cmpl $0x49435024, %eax // $PCI
357         jne 1f
358         movl $BUILD_BIOS_ADDR, %ebx
359         movl $BUILD_BIOS_SIZE, %ecx
360         movl $entry_pcibios32, %edx
361         xorb %al, %al
362         jmp 2f
363 #endif
364         // Unknown request
365 1:      movb $0x80, %al
366         // Return to caller
367 2:      popfl
368         lretl
369
370 // 32bit elf entry point
371         EXPORTFUNC entry_elf
372 entry_elf:
373         cli
374         cld
375         lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
376         lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
377         movl $SEG32_MODE32_DS, %eax
378         movw %ax, %ds
379         movw %ax, %es
380         movw %ax, %fs
381         movw %ax, %gs
382         movw %ax, %ss
383         movl $BUILD_STACK_ADDR, %esp
384         ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
385
386         .code16gcc
387
388
389 /****************************************************************
390  * Interrupt entry points
391  ****************************************************************/
392
393         // Main entry point for interrupts without args
394         DECLFUNC irqentry
395 irqentry:
396         ENTRY_ST
397         iretw
398
399         // Main entry point for interrupts with args
400         DECLFUNC irqentryarg
401 irqentryarg:
402         ENTRY_ARG_ST
403         iretw
404
405         // Define an entry point for an interrupt (no args passed).
406         .macro IRQ_ENTRY num
407         .global entry_\num
408         entry_\num :
409         pushl $ handle_\num
410         jmp irqentry
411         .endm
412
413         .macro DECL_IRQ_ENTRY num
414         DECLFUNC entry_\num
415         IRQ_ENTRY \num
416         .endm
417
418         // Define an entry point for an interrupt (can read/modify args).
419         .macro IRQ_ENTRY_ARG num
420         .global entry_\num
421         entry_\num :
422         pushl $ handle_\num
423         jmp irqentryarg
424         .endm
425
426         .macro DECL_IRQ_ENTRY_ARG num
427         DECLFUNC entry_\num
428         IRQ_ENTRY_ARG \num
429         .endm
430
431         // Various entry points (that don't require a fixed location).
432         DECL_IRQ_ENTRY_ARG 13
433         DECL_IRQ_ENTRY 76
434         DECL_IRQ_ENTRY 70
435         DECL_IRQ_ENTRY 74
436         DECL_IRQ_ENTRY 75
437         DECL_IRQ_ENTRY hwpic1
438         DECL_IRQ_ENTRY hwpic2
439
440         // int 18/19 are special - they reset stack and call into 32bit mode.
441         DECLFUNC entry_19
442 entry_19:
443         ENTRY_INTO32 _cfunc32flat_handle_19
444
445         DECLFUNC entry_18
446 entry_18:
447         ENTRY_INTO32 _cfunc32flat_handle_18
448
449
450 /****************************************************************
451  * Fixed position entry points
452  ****************************************************************/
453
454         // Specify a location in the fixed part of bios area.
455         .macro ORG addr
456         .section .fixedaddr.\addr
457         .endm
458
459         ORG 0xe05b
460 entry_post:
461         cmpl $0, %cs:HaveRunPost                // Check for resume/reboot
462         jnz entry_resume
463         ENTRY_INTO32 _cfunc32flat_handle_post   // Normal entry point
464
465         ORG 0xe2c3
466         IRQ_ENTRY 02
467
468         ORG 0xe3fe
469         .global entry_13_official
470 entry_13_official:
471         jmp entry_13
472
473         // 0xe401 - OldFDPT in disk.c
474
475         ORG 0xe6f2
476         .global entry_19_official
477 entry_19_official:
478         jmp entry_19
479
480         // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c
481
482         // 0xe729 - BaudTable in serial.c
483
484         ORG 0xe739
485         IRQ_ENTRY_ARG 14
486
487         ORG 0xe82e
488         IRQ_ENTRY_ARG 16
489
490         ORG 0xe987
491         IRQ_ENTRY 09
492
493         ORG 0xec59
494         IRQ_ENTRY_ARG 40
495
496         ORG 0xef57
497         IRQ_ENTRY 0e
498
499         // 0xefc7 - diskette_param_table in floppy.c
500
501         ORG 0xefd2
502         IRQ_ENTRY_ARG 17
503
504         ORG 0xf045
505 entry_10_0x0f:
506         // XXX - INT 10 Functions 0-Fh Entry Point
507         iretw
508
509         ORG 0xf065
510         IRQ_ENTRY_ARG 10
511
512         // 0xf0a4 - VideoParams in misc.c
513
514         ORG 0xf841
515         IRQ_ENTRY_ARG 12
516
517         ORG 0xf84d
518         IRQ_ENTRY_ARG 11
519
520         ORG 0xf859
521         IRQ_ENTRY_ARG 15
522
523         // 0xfa6e - vgafont8 in font.c
524
525         ORG 0xfe6e
526         IRQ_ENTRY_ARG 1a
527
528         ORG 0xfea5
529         IRQ_ENTRY 08
530
531         // 0xfef3 - InitVectors in misc.c
532
533         // 0xff00 - BiosCopyright in misc.c
534
535         ORG 0xff53
536         .global entry_iret_official
537 entry_iret_official:
538         iretw
539
540         ORG 0xff54
541         IRQ_ENTRY_ARG 05
542
543         ORG 0xfff0 // Power-up Entry Point
544         .global reset_vector
545 reset_vector:
546         ljmpw $SEG_BIOS, $entry_post
547
548         // 0xfff5 - BiosDate in misc.c
549
550         // 0xfffe - BiosModelId in misc.c
551
552         // 0xffff - BiosChecksum in misc.c
553
554         .end