blob: 6e31c4edc2ce2f7f7d63cbb11fca5fb304a95b06 [file] [log] [blame]
Kevin O'Connor1f2c3072009-05-06 23:35:59 -04001// Rom layout and bios assembler to C interface.
2//
Kevin O'Connordab0a742013-12-03 11:50:49 -05003// Copyright (C) 2009-2013 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connor1f2c3072009-05-06 23:35:59 -04004//
5// This file may be distributed under the terms of the GNU LGPLv3 license.
6
7
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -05008#include "asm-offsets.h" // BREGS_*
Julian Pidancet7c6509c2011-12-19 05:07:55 +00009#include "config.h" // CONFIG_*
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040010#include "entryfuncs.S" // ENTRY_*
11
12
13/****************************************************************
14 * Rom Header
15 ****************************************************************/
16
17 .section .rom.header
Kevin O'Connor36feea92012-02-11 10:49:45 -050018 .code16gcc
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040019 .global _rom_header, _rom_header_size, _rom_header_checksum
20_rom_header:
21 .word 0xaa55
22_rom_header_size:
23 .byte 0
24_rom_header_entry:
25 jmp _optionrom_entry
26_rom_header_checksum:
Kevin O'Connorc9d3c2d2010-01-01 12:53:32 -050027 .byte 0
28_rom_header_other:
Julian Pidancet7c6509c2011-12-19 05:07:55 +000029 .space 17
30_rom_header_pcidata:
31#if CONFIG_VGA_PCI == 1
32 .word rom_pci_data
33#else
34 .word 0
35#endif
36_rom_header_pnpdata:
37 .word 0
Kevin O'Connor72b5e452011-12-23 23:01:48 -050038_rom_header_other2:
39 .word 0
40_rom_header_signature:
41 .asciz "IBM"
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040042
43
44/****************************************************************
45 * Entry points
46 ****************************************************************/
47
Kevin O'Connor8032b8a2014-02-05 22:47:29 -050048 // Force a fault if found to be running on broken x86emu versions.
49 DECLFUNC x86emu_fault
50x86emu_fault:
511: hlt
52 jmp 1b
53
54 // This macro implements a call while avoiding instructions
55 // that old versions of x86emu have problems with.
56 .macro VGA_CALLL cfunc
57 // Make sure leal instruction works.
58 movl $0x8000, %ecx
59 leal (%ecx, %ecx, 1), %ecx
60 cmpl $0x10000, %ecx
61 jne x86emu_fault
62 // Use callw instead of calll
63 push %ax
64 callw \cfunc
65 .endm
66
67 // This macro is the same as ENTRY_ARG except VGA_CALLL is used.
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050068 .macro ENTRY_ARG_VGA cfunc
69 cli
70 cld
71 PUSHBREGS
72 movw %ss, %ax // Move %ss to %ds
73 movw %ax, %ds
74 movl %esp, %ebx // Backup %esp, then zero high bits
75 movzwl %sp, %esp
76 movl %esp, %eax // First arg is pointer to struct bregs
Kevin O'Connor8032b8a2014-02-05 22:47:29 -050077 VGA_CALLL \cfunc
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050078 movl %ebx, %esp // Restore %esp (including high bits)
79 POPBREGS
80 .endm
81
Kevin O'Connor9961f992012-01-21 11:53:44 -050082 DECLFUNC entry_104f05
83entry_104f05:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050084 ENTRY_ARG_VGA vbe_104f05
Kevin O'Connor9961f992012-01-21 11:53:44 -050085 lretw
86
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040087 DECLFUNC _optionrom_entry
88_optionrom_entry:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050089 ENTRY_ARG_VGA vga_post
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040090 lretw
91
Kevin O'Connor9f193b92009-05-16 23:31:27 -040092 DECLFUNC entry_10
93entry_10:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050094 ENTRY_ARG_VGA handle_10
Kevin O'Connor9f193b92009-05-16 23:31:27 -040095 iretw
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -050096
97 // Entry point using extra stack
98 DECLFUNC entry_10_extrastack
99entry_10_extrastack:
100 cli
101 cld
102 pushw %ds // Set %ds:%eax to space on ExtraStack
103 pushl %eax
Kevin O'Connorfeb02842013-12-09 20:30:30 -0500104 movw %cs:ExtraStackSeg, %ds
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500105 movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
106 popl BREGS_eax(%eax) // Backup registers
107 popw BREGS_ds(%eax)
108 movl %edi, BREGS_edi(%eax)
109 movl %esi, BREGS_esi(%eax)
110 movl %ebp, BREGS_ebp(%eax)
111 movl %ebx, BREGS_ebx(%eax)
112 movl %edx, BREGS_edx(%eax)
113 movl %ecx, BREGS_ecx(%eax)
114 movw %es, BREGS_es(%eax)
115 movl %esp, BREGS_size+0(%eax)
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500116 movw %ss, BREGS_size+4(%eax)
Kevin O'Connor41c60612013-12-09 17:27:54 -0500117 popl BREGS_code(%eax)
118 popw BREGS_flags(%eax)
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500119
120 movw %ds, %dx // Setup %ss/%esp and call function
121 movw %dx, %ss
122 movl %eax, %esp
Kevin O'Connor8032b8a2014-02-05 22:47:29 -0500123 VGA_CALLL handle_10
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500124
125 movl %esp, %eax // Restore registers and return
126 movw BREGS_size+4(%eax), %ss
127 movl BREGS_size+0(%eax), %esp
128 popl %edx
129 popw %dx
130 pushw BREGS_flags(%eax)
131 pushl BREGS_code(%eax)
132 movl BREGS_edi(%eax), %edi
133 movl BREGS_esi(%eax), %esi
134 movl BREGS_ebp(%eax), %ebp
135 movl BREGS_ebx(%eax), %ebx
136 movl BREGS_edx(%eax), %edx
137 movl BREGS_ecx(%eax), %ecx
138 movw BREGS_es(%eax), %es
139 pushw BREGS_ds(%eax)
140 pushl BREGS_eax(%eax)
141 popl %eax
142 popw %ds
143 iretw