blob: e0ab9547c471aefee1b17bd0edb688a371291ce0 [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
David Woodhouse67fd42c2014-06-03 17:28:58 +010018 .code16
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
Kevin O'Connor3c37cdb2014-05-12 01:26:26 -040050msg: .ascii "SeaVGABIOS: x86emu leal trap!\n"
Kevin O'Connor8032b8a2014-02-05 22:47:29 -050051x86emu_fault:
Kevin O'Connor3c37cdb2014-05-12 01:26:26 -040052#if CONFIG_DEBUG_IO
53 movw %cs:DebugOutputPort, %dx
54 movw $msg, %si
551: movb %cs:(%si), %al
56 outb %al, (%dx)
57 incw %si
58 cmpw $x86emu_fault, %si
59 jl 1b
60#endif
Kevin O'Connor8032b8a2014-02-05 22:47:29 -0500611: hlt
62 jmp 1b
63
64 // This macro implements a call while avoiding instructions
65 // that old versions of x86emu have problems with.
66 .macro VGA_CALLL cfunc
67 // Make sure leal instruction works.
68 movl $0x8000, %ecx
69 leal (%ecx, %ecx, 1), %ecx
70 cmpl $0x10000, %ecx
71 jne x86emu_fault
72 // Use callw instead of calll
73 push %ax
74 callw \cfunc
75 .endm
76
77 // This macro is the same as ENTRY_ARG except VGA_CALLL is used.
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050078 .macro ENTRY_ARG_VGA cfunc
79 cli
80 cld
81 PUSHBREGS
82 movw %ss, %ax // Move %ss to %ds
83 movw %ax, %ds
84 movl %esp, %ebx // Backup %esp, then zero high bits
85 movzwl %sp, %esp
86 movl %esp, %eax // First arg is pointer to struct bregs
Kevin O'Connor8032b8a2014-02-05 22:47:29 -050087 VGA_CALLL \cfunc
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050088 movl %ebx, %esp // Restore %esp (including high bits)
89 POPBREGS
90 .endm
91
Kevin O'Connor9961f992012-01-21 11:53:44 -050092 DECLFUNC entry_104f05
93entry_104f05:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050094 ENTRY_ARG_VGA vbe_104f05
Kevin O'Connor9961f992012-01-21 11:53:44 -050095 lretw
96
Kevin O'Connor1f2c3072009-05-06 23:35:59 -040097 DECLFUNC _optionrom_entry
98_optionrom_entry:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -050099 ENTRY_ARG_VGA vga_post
Kevin O'Connor1f2c3072009-05-06 23:35:59 -0400100 lretw
101
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400102 DECLFUNC entry_10
103entry_10:
Kevin O'Connor9332f9b2013-11-30 12:52:44 -0500104 ENTRY_ARG_VGA handle_10
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400105 iretw
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500106
Kevin O'Connor251e2632015-03-17 11:37:25 -0400107#define VGA_CUSTOM_BDA_FLAGS 0xb9
108#define BF_EXTRA_STACK 0x40
109
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500110 // Entry point using extra stack
111 DECLFUNC entry_10_extrastack
112entry_10_extrastack:
113 cli
114 cld
Kevin O'Connor251e2632015-03-17 11:37:25 -0400115 pushw %ds
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500116 pushl %eax
Kevin O'Connor251e2632015-03-17 11:37:25 -0400117
118 movw $SEG_BDA, %ax // Check if extra stack is enabled
119 movw %ax, %ds
120 testb $BF_EXTRA_STACK, VGA_CUSTOM_BDA_FLAGS
121 jz 1f
122
123 movw %cs:ExtraStackSeg, %ds // Set %ds:%eax to space on ExtraStack
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500124 movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax
Kevin O'Connor46000f52014-10-21 02:23:02 -0400125 SAVEBREGS_POP_DSEAX // Save registers on extra stack
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500126 movl %esp, PUSHBREGS_size+8(%eax)
127 movw %ss, PUSHBREGS_size+12(%eax)
Kevin O'Connor41c60612013-12-09 17:27:54 -0500128 popl BREGS_code(%eax)
129 popw BREGS_flags(%eax)
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500130
131 movw %ds, %dx // Setup %ss/%esp and call function
132 movw %dx, %ss
133 movl %eax, %esp
Kevin O'Connor8032b8a2014-02-05 22:47:29 -0500134 VGA_CALLL handle_10
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500135
136 movl %esp, %eax // Restore registers and return
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500137 movw PUSHBREGS_size+12(%eax), %ss
138 movl PUSHBREGS_size+8(%eax), %esp
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500139 popl %edx
140 popw %dx
141 pushw BREGS_flags(%eax)
142 pushl BREGS_code(%eax)
Kevin O'Connor46000f52014-10-21 02:23:02 -0400143 RESTOREBREGS_DSEAX
Kevin O'Connor4a8b58c2013-11-30 19:16:15 -0500144 iretw
Kevin O'Connorb4eb6fc2014-10-17 22:15:42 -0400145
Kevin O'Connor251e2632015-03-17 11:37:25 -04001461: // Use regular entry point if the extra stack is disabled
147 popl %eax
148 popw %ds
149 jmp entry_10
150
Kevin O'Connorb4eb6fc2014-10-17 22:15:42 -0400151 // Timer irq handling
152 DECLFUNC entry_timer_hook
153entry_timer_hook:
154 ENTRY handle_timer_hook
155 ljmpw *%cs:Timer_Hook_Resume
156
157 // Timer irq handling on extra stack
158 DECLFUNC entry_timer_hook_extrastack
159entry_timer_hook_extrastack:
160 cli
161 cld
162 pushw %ds // Set %ds:%eax to space on ExtraStack
163 pushl %eax
164 movw %cs:ExtraStackSeg, %ds
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500165 movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax
Kevin O'Connorb4eb6fc2014-10-17 22:15:42 -0400166 SAVEBREGS_POP_DSEAX
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500167 movl %esp, PUSHBREGS_size(%eax)
168 movw %ss, PUSHBREGS_size+4(%eax)
Kevin O'Connorb4eb6fc2014-10-17 22:15:42 -0400169
170 movw %ds, %dx // Setup %ss/%esp and call function
171 movw %dx, %ss
172 movl %eax, %esp
173 calll handle_timer_hook
174
175 movl %esp, %eax // Restore registers and return
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500176 movw PUSHBREGS_size+4(%eax), %ss
177 movl PUSHBREGS_size(%eax), %esp
Kevin O'Connorb4eb6fc2014-10-17 22:15:42 -0400178 RESTOREBREGS_DSEAX
179 ljmpw *%cs:Timer_Hook_Resume