blob: 0d6af39ee4cae0e28827c80939ae9e789bf2d506 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001// Rom layout and bios assembler to C interface.
2//
Kevin O'Connor36feea92012-02-11 10:49:45 -05003// Copyright (C) 2008-2012 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05004// Copyright (C) 2002 MandrakeSoft S.A.
5//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05006// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05007
Kevin O'Connor3dba4c22011-01-29 11:26:54 -05008#include "asm-offsets.h" // BREGS_*
Kevin O'Connor4ade5232013-09-18 21:41:48 -04009#include "config.h" // CONFIG_*
Kevin O'Connorf8e176c2009-05-06 23:33:32 -040010#include "entryfuncs.S" // ENTRY_*
Kevin O'Connor4ade5232013-09-18 21:41:48 -040011#include "hw/ps2port.h" // PORT_A20
12#include "hw/rtc.h" // CMOS_RESET_CODE
13#include "x86.h" // CR0_*
Kevin O'Connor74534532008-05-12 18:28:58 -040014
Kevin O'Connor1d019512008-03-11 21:21:47 -040015
16/****************************************************************
Kevin O'Connor38aadba2013-09-29 19:25:44 -040017 * 16bit / 32bit call trampolines
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050018 ****************************************************************/
19
20// Place CPU into 32bit mode from 16bit mode.
Kevin O'Connor4057f982010-11-25 08:52:50 -050021// %edx = return location (in 32bit mode)
Kevin O'Connorad901592009-12-13 11:25:25 -050022// Clobbers: ecx, flags, segment registers, cr0, idt/gdt
Kevin O'Connord67a7032009-01-17 19:37:26 -050023 DECLFUNC transition32
Kevin O'Connor36feea92012-02-11 10:49:45 -050024 .code16gcc
Kevin O'Connorf4c511c2014-04-07 19:49:12 -040025transition32_for_smi:
26 movl %eax, %ecx
27 jmp 1f
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050028transition32:
Kevin O'Connorad901592009-12-13 11:25:25 -050029 movl %eax, %ecx
Kevin O'Connor9caf7862009-02-27 20:14:05 -050030
Kevin O'Connorf094ba82009-04-13 19:30:27 -040031 // Disable irqs (and clear direction flag)
32 cli
33 cld
34
35 // Disable nmi
36 movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax
37 outb %al, $PORT_CMOS_INDEX
38 inb $PORT_CMOS_DATA, %al
39
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050040 // enable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050041 inb $PORT_A20, %al
42 orb $A20_ENABLE_BIT, %al
43 outb %al, $PORT_A20
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050044
45 // Set segment descriptors
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400461: lidtw %cs:pmode_IDT_info
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050047 lgdtw %cs:rombios32_gdt_48
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050048
Kevin O'Connor3eac0092008-11-16 09:59:32 -050049 // Enable protected mode
50 movl %cr0, %eax
51 orl $CR0_PE, %eax
52 movl %eax, %cr0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050053
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050054 // start 32bit protected mode code
Kevin O'Connorf4c511c2014-04-07 19:49:12 -040055 ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 2f)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050056
57 .code32
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050058 // init data segments
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400592: movl $SEG32_MODE32_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050060 movw %ax, %ds
61 movw %ax, %es
62 movw %ax, %ss
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050063 movw %ax, %fs
64 movw %ax, %gs
65
Kevin O'Connorad901592009-12-13 11:25:25 -050066 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -050067 jmpl *%edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050068
Kevin O'Connor752151b2009-12-10 21:16:07 -050069// Place CPU into 16bit mode from 32bit mode.
Kevin O'Connor4057f982010-11-25 08:52:50 -050070// %edx = return location (in 16bit mode)
Kevin O'Connorad901592009-12-13 11:25:25 -050071// Clobbers: ecx, flags, segment registers, cr0, idt/gdt
Kevin O'Connor752151b2009-12-10 21:16:07 -050072 DECLFUNC transition16
73 .global transition16big
74transition16:
Kevin O'Connorad901592009-12-13 11:25:25 -050075 movl %eax, %ecx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050076
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050077 // restore data segment limits to 0xffff
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050078 movl $SEG32_MODE16_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050079 movw %ax, %ds
80 movw %ax, %es
81 movw %ax, %ss
82 movw %ax, %fs
83 movw %ax, %gs
84
Kevin O'Connorffb81a42009-04-13 19:44:55 -040085#if CONFIG_DISABLE_A20
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050086 // disable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050087 inb $PORT_A20, %al
88 andb $~A20_ENABLE_BIT, %al
89 outb %al, $PORT_A20
Kevin O'Connorffb81a42009-04-13 19:44:55 -040090#endif
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050091
92 // Jump to 16bit mode
93 ljmpw $SEG32_MODE16_CS, $1f
94
Kevin O'Connor752151b2009-12-10 21:16:07 -050095transition16big:
Kevin O'Connorad901592009-12-13 11:25:25 -050096 movl %eax, %ecx
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050097
98 movl $SEG32_MODE16BIG_DS, %eax
99 movw %ax, %ds
100 movw %ax, %es
101 movw %ax, %ss
102 movw %ax, %fs
103 movw %ax, %gs
104
Kevin O'Connor0f788892010-07-25 14:04:01 -0400105 ljmpw $SEG32_MODE16BIG_CS, $1f
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500106
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -0500107 .code16gcc
1081:
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500109 // Disable protected mode
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500110 movl %cr0, %eax
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500111 andl $~CR0_PE, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500112 movl %eax, %cr0
113
114 // far jump to flush CPU queue after transition to real mode
Kevin O'Connore3677b12008-07-04 15:29:23 -0400115 ljmpw $SEG_BIOS, $2f
Kevin O'Connor21e930b2008-03-01 09:49:37 -0500116
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001172:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500118 // restore IDT to normal real-mode defaults
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500119 lidtw %cs:rmode_IDT_info
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500120
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500121 // Clear segment registers
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500122 xorw %ax, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500123 movw %ax, %fs
124 movw %ax, %gs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500125 movw %ax, %es
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500126 movw %ax, %ds
127 movw %ax, %ss // Assume stack is in segment 0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500128
Kevin O'Connorad901592009-12-13 11:25:25 -0500129 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -0500130 jmpl *%edx
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500131
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400132// Call a 16bit SeaBIOS function from SeaBIOS 32bit C code.
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400133// %ecx = calling function
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400134// Clobbers: %ecx, %edx, flags, segment registers, idt/gdt
135 DECLFUNC __call16
136 .global __call16big
137 .code32
138__call16:
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400139 pushl %edx
140 pushl %ecx
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400141 movl $1f, %edx
142 jmp transition16
143__call16big:
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400144 pushl %edx
145 pushl %ecx
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400146 movl $1f, %edx
147 jmp transition16big
148
149 // Make call.
150 .code16gcc
Kevin O'Connor7acaa3c2013-10-02 20:20:03 -04001511: movl $_zonelow_seg, %edx // Adjust %ds, %ss, and %esp
152 movl %edx, %ds
153 movzwl StackSeg, %edx
154 movl %edx, %ecx
155 shll $4, %ecx
156 movl %edx, %ss
157 subl %ecx, %esp
158 movl %edx, %ds
159
160 popl %ecx // Call function
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400161 popl %edx
162 calll *%ecx
Kevin O'Connor7acaa3c2013-10-02 20:20:03 -0400163
164 movl %ss, %edx // Readjust %esp
165 shll $4, %edx
166 addl %edx, %esp
167
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400168 // Return via transition32
169 movl $(2f + BUILD_BIOS_ADDR), %edx
170 jmp transition32
171 .code32
1722: retl
173
174
175/****************************************************************
176 * External calling trampolines
177 ****************************************************************/
178
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400179// Far call a 16bit function from 16bit mode with a specified cpu register state
Kevin O'Connor2d977562013-09-29 20:21:40 -0400180// %eax = address of struct bregs, %edx = segment of struct bregs
181// Clobbers: %e[bc]x, %e[ds]i, flags
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400182 .code16gcc
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400183 DECLFUNC __farcall16
184__farcall16:
Kevin O'Connor2d977562013-09-29 20:21:40 -0400185 // Save %edx/%eax, %ebp
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500186 pushl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500187 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400188 pushl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500189
190 // Setup for iretw call
Kevin O'Connor2d977562013-09-29 20:21:40 -0400191 movl %edx, %ds
Kevin O'Connor273e8ae2009-01-19 19:56:07 -0500192 pushw %cs
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400193 pushw $1f // return point
Kevin O'Connor2d977562013-09-29 20:21:40 -0400194 pushw BREGS_flags(%eax) // flags
195 pushl BREGS_code(%eax) // CS:IP
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500196
197 // Load calling registers.
Kevin O'Connor2d977562013-09-29 20:21:40 -0400198 movl BREGS_edi(%eax), %edi
199 movl BREGS_esi(%eax), %esi
200 movl BREGS_ebp(%eax), %ebp
201 movl BREGS_ebx(%eax), %ebx
202 movl BREGS_edx(%eax), %edx
203 movl BREGS_ecx(%eax), %ecx
204 movw BREGS_es(%eax), %es
205 pushl BREGS_eax(%eax)
206 movw BREGS_ds(%eax), %ds
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400207 popl %eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500208
209 // Invoke call
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400210 iretw // XXX - just do a lcalll
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05002111:
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400212 // Store flags, es, eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500213 pushfw
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400214 cli
215 cld
Kevin O'Connor2d977562013-09-29 20:21:40 -0400216 pushw %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500217 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400218 movw 0x08(%esp), %ds
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400219 movl 0x0c(%esp), %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400220 popl BREGS_eax(%eax)
221 popw BREGS_es(%eax)
222 popw BREGS_flags(%eax)
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500223
224 // Store remaining registers
Kevin O'Connor2d977562013-09-29 20:21:40 -0400225 movl %edi, BREGS_edi(%eax)
226 movl %esi, BREGS_esi(%eax)
227 movl %ebp, BREGS_ebp(%eax)
228 movl %ebx, BREGS_ebx(%eax)
229 movl %edx, BREGS_edx(%eax)
230 movl %ecx, BREGS_ecx(%eax)
231 movw %es, BREGS_ds(%eax)
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400232 movw %ss, %cx
233 movw %cx, %ds // Restore %ds == %ss
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500234
Kevin O'Connor2d977562013-09-29 20:21:40 -0400235 // Remove %edx/%eax, restore %ebp
236 popl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500237 popl %eax
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500238 popl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500239
240 retl
241
Kevin O'Connor79dde652009-04-13 19:26:43 -0400242// IRQ trampolines
243 .macro IRQ_TRAMPOLINE num
244 DECLFUNC irq_trampoline_0x\num
245 irq_trampoline_0x\num :
246 int $0x\num
247 lretw
248 .endm
249
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400250 IRQ_TRAMPOLINE 02
Kevin O'Connor79dde652009-04-13 19:26:43 -0400251 IRQ_TRAMPOLINE 10
252 IRQ_TRAMPOLINE 13
253 IRQ_TRAMPOLINE 15
254 IRQ_TRAMPOLINE 16
255 IRQ_TRAMPOLINE 18
256 IRQ_TRAMPOLINE 19
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400257 IRQ_TRAMPOLINE 1c
258 IRQ_TRAMPOLINE 4a
Kevin O'Connor79dde652009-04-13 19:26:43 -0400259
260
261/****************************************************************
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400262 * Misc. entry points.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400263 ****************************************************************/
264
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400265// Entry point for QEMU smi interrupts.
266 DECLFUNC entry_smi
267entry_smi:
268 // Transition to 32bit mode.
269 movl $1f + BUILD_BIOS_ADDR, %edx
270 jmp transition32_for_smi
271 .code32
Kevin O'Connor31bcda22014-05-28 13:33:50 -04002721: movl $BUILD_SMM_ADDR + 0x8000, %esp
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400273 calll _cfunc32flat_handle_smi - BUILD_BIOS_ADDR
274 rsm
275 .code16gcc
276
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400277// Resume (and reboot) entry point - called from entry_post
278 DECLFUNC entry_resume
279entry_resume:
Kevin O'Connor79dde652009-04-13 19:26:43 -0400280 // Disable interrupts
281 cli
282 cld
Kevin O'Connor46b82622012-05-13 12:10:30 -0400283 // Use the ExtraStack in low mem.
Kevin O'Connorc9243442013-02-17 13:58:28 -0500284 movl $_zonelow_seg, %eax
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400285 movw %ax, %ds
Kevin O'Connor79dde652009-04-13 19:26:43 -0400286 movw %ax, %ss
Kevin O'Connor46b82622012-05-13 12:10:30 -0400287 movl $ExtraStack + BUILD_EXTRA_STACK_SIZE, %esp
Kevin O'Connor79dde652009-04-13 19:26:43 -0400288 // Call handler.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400289 jmp handle_resume
290
Kevin O'Connore54ee382009-07-26 19:33:13 -0400291// PMM entry point
292 DECLFUNC entry_pmm
293entry_pmm:
294 pushl %esp // Backup %esp, then clear high bits
295 movzwl %sp, %esp
296 pushfl // Save registers clobbered by C code
297 cli
298 cld
299 pushl %eax
300 pushl %ecx
301 pushl %edx
302 pushw %es
303 pushw %ds
304 movw %ss, %cx // Move %ss to %ds
305 movw %cx, %ds
Kevin O'Connor533b6282011-07-16 13:13:12 -0400306 movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
307 leal 28(%esp), %edx // %edx points to start of args
308 movl $-1, %ecx
309 calll call32
Kevin O'Connore54ee382009-07-26 19:33:13 -0400310 movw %ax, 12(%esp) // Modify %ax:%dx to return %eax
311 shrl $16, %eax
312 movw %ax, 4(%esp)
313 popw %ds // Restore saved registers
314 popw %es
315 popl %edx
316 popl %ecx
317 popl %eax
318 popfl
319 popl %esp
320 lretw
321
Kevin O'Connor79dde652009-04-13 19:26:43 -0400322// PnP entry points
Kevin O'Connord67a7032009-01-17 19:37:26 -0500323 DECLFUNC entry_pnp_real
324 .global entry_pnp_prot
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500325entry_pnp_prot:
326 pushl %esp
327 jmp 1f
328entry_pnp_real:
329 pushl %esp // Backup %esp, then clear high bits
330 movzwl %sp, %esp
3311:
332 pushfl // Save registers clobbered by C code
Kevin O'Connore54ee382009-07-26 19:33:13 -0400333 cli
334 cld
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500335 pushl %eax
336 pushl %ecx
337 pushl %edx
338 pushw %es
339 pushw %ds
340 movw %ss, %cx // Move %ss to %ds
341 movw %cx, %ds
Kevin O'Connor752151b2009-12-10 21:16:07 -0500342 leal 28(%esp), %eax // %eax points to start of u16 args
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500343 calll handle_pnp
344 movw %ax, 12(%esp) // Modify %eax to return %ax
345 popw %ds
346 popw %es
347 popl %edx
348 popl %ecx
349 popl %eax
350 popfl
351 popl %esp
352 lretw
353
Kevin O'Connor79dde652009-04-13 19:26:43 -0400354// APM entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400355 DECLFUNC entry_apm16
356entry_apm16:
Kevin O'Connor1d019512008-03-11 21:21:47 -0400357 pushfw // save flags
358 pushl %eax // dummy
Kevin O'Connord3e43672012-05-28 11:37:53 -0400359 ENTRY_ARG handle_apm
Kevin O'Connorb3c28be2008-06-08 13:34:43 -0400360 addw $4, %sp // pop dummy
Kevin O'Connor1d019512008-03-11 21:21:47 -0400361 popfw // restore flags
362 lretw
363
364 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400365 DECLFUNC entry_apm32
366entry_apm32:
Kevin O'Connorc0031482010-01-01 13:03:17 -0500367 pushfl
368 pushl %gs
369 pushl %cs // Move second descriptor after %cs to %gs
370 addl $16, (%esp)
371 popl %gs
Kevin O'Connord3e43672012-05-28 11:37:53 -0400372 ENTRY_ARG_ESP _cfunc32seg_handle_apm
Kevin O'Connorc0031482010-01-01 13:03:17 -0500373 popl %gs
374 popfl
Kevin O'Connor1d019512008-03-11 21:21:47 -0400375 lretl
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400376
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500377// PCI-BIOS entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400378 DECLFUNC entry_pcibios32
379entry_pcibios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500380 pushfl
Kevin O'Connorc0031482010-01-01 13:03:17 -0500381 pushl %gs // Backup %gs and set %gs=%ds
382 pushl %ds
383 popl %gs
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500384 ENTRY_ARG_ESP _cfunc32seg_handle_pcibios
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500385 popl %gs
386 popfl
387 lretl
388
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500389 .code16gcc
390 DECLFUNC entry_pcibios16
391entry_pcibios16:
392 ENTRY_ARG handle_pcibios
393 iretw
394
Kevin O'Connor3fcabf02014-05-08 18:32:32 -0400395// int 1589 entry point
396 DECLFUNC entry_1589
397entry_1589:
398 ENTRY_ARG handle_1589
399 iretw
400
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500401// BIOS32 support
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500402 .code32
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500403 DECLFUNC entry_bios32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400404entry_bios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500405 pushfl
406#if CONFIG_PCIBIOS
407 // Check for PCI-BIOS request
408 cmpl $0x49435024, %eax // $PCI
409 jne 1f
410 movl $BUILD_BIOS_ADDR, %ebx
411 movl $BUILD_BIOS_SIZE, %ecx
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400412 movl $entry_pcibios32, %edx
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500413 xorb %al, %al
414 jmp 2f
415#endif
416 // Unknown request
4171: movb $0x80, %al
418 // Return to caller
4192: popfl
420 lretl
421
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400422// 32bit elf entry point
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400423 EXPORTFUNC entry_elf
424entry_elf:
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400425 cli
426 cld
427 lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
428 lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
Kevin O'Connore0504b02009-04-13 19:32:51 -0400429 movl $SEG32_MODE32_DS, %eax
430 movw %ax, %ds
431 movw %ax, %es
432 movw %ax, %fs
433 movw %ax, %gs
434 movw %ax, %ss
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400435 movl $BUILD_STACK_ADDR, %esp
Kevin O'Connorb1885fc2013-02-08 21:00:46 -0500436 ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400437
Kevin O'Connor1d019512008-03-11 21:21:47 -0400438 .code16gcc
Kevin O'Connor1d019512008-03-11 21:21:47 -0400439
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500440// UEFI Compatibility Support Module (CSM) entry point
David Woodhouse118469a2013-01-25 19:46:25 -0600441 EXPORTFUNC entry_csm
442entry_csm:
443 // Backup register state
444 pushfw
445 cli
446 cld
447 pushl %eax // dummy
448 PUSHBREGS
449
450 // Backup stack location and convert to a "flat pointer"
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000451 movl %ss, %eax
452 movw %ax, BREGS_code+2(%esp) // Store %ss in bregs->code.seg
453 shll $4, %eax
454 addl %esp, %eax
David Woodhouse118469a2013-01-25 19:46:25 -0600455
456 // Change to BUILD_STACK_ADDR stack
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000457 xorl %ebx, %ebx
458 movw %bx, %ss
David Woodhouse118469a2013-01-25 19:46:25 -0600459 movl $BUILD_STACK_ADDR, %esp
460
461 // Jump to 32bit mode and call handle_csm(bregs)
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000462 movl $_cfunc32flat_handle_csm, %edx
David Woodhouse118469a2013-01-25 19:46:25 -0600463 jmp transition32
David Woodhouse118469a2013-01-25 19:46:25 -0600464
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500465 DECLFUNC __csm_return
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500466 .code32
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000467__csm_return:
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500468 movl $1f, %edx
David Woodhouse118469a2013-01-25 19:46:25 -0600469 jmp transition16big
470 .code16gcc
471
472 // Switch back to original stack
Kevin O'Connorbbd04582013-02-18 21:57:26 -05004731: movzwl BREGS_code+2(%eax), %edx
474 movl %edx, %ecx
David Woodhouse118469a2013-01-25 19:46:25 -0600475 shll $4, %ecx
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500476 subl %ecx, %eax
477 movl %edx, %ss
478 movl %eax, %esp
David Woodhouse118469a2013-01-25 19:46:25 -0600479
480 // Restore register state and return.
481 POPBREGS
482 addw $4, %sp // pop dummy
483 popfw
484 lretw
485
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500486
487/****************************************************************
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500488 * Interrupt entry points
489 ****************************************************************/
490
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400491 // Main entry point for interrupts handled on extra stack
492 DECLFUNC irqentry_extrastack
493irqentry_extrastack:
494 cli
495 cld
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400496 pushw %ds // Set %ds:%eax to space on ExtraStack
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400497 pushl %eax
Kevin O'Connorc9243442013-02-17 13:58:28 -0500498 movl $_zonelow_seg, %eax
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400499 movl %eax, %ds
500 movl StackPos, %eax
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400501 subl $24, %eax
502 popl 0(%eax) // Backup %eax, %ds, %es, %ecx, %edx
503 popw 4(%eax)
504 movw %es, 6(%eax)
505 movl %ecx, 8(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400506 popl %ecx
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400507 movl %edx, 12(%eax)
508 movl %esp, 16(%eax)
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400509 movw %ss, 20(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400510
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400511 movw %ds, %dx // Setup %ss/%esp and call function
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400512 movw %dx, %ss
513 movl %eax, %esp
514 calll *%ecx
515
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400516 movl %esp, %eax // Restore registers and return
517 movw 20(%eax), %ss
518 movl 16(%eax), %esp
519 movl 12(%eax), %edx
520 movl 8(%eax), %ecx
521 movw 6(%eax), %es
522 pushw 4(%eax)
523 pushl 0(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400524 popl %eax
525 popw %ds
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400526 iretw
527
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500528 // Main entry point for interrupts handled on extra stack
529 DECLFUNC irqentry_arg_extrastack
530irqentry_arg_extrastack:
531 cli
532 cld
533 pushw %ds // Set %ds:%eax to space on ExtraStack
534 pushl %eax
535 movl $_zonelow_seg, %eax
536 movl %eax, %ds
537 movl StackPos, %eax
538 subl $BREGS_size+8, %eax
539 popl BREGS_eax(%eax) // Backup registers
540 popw BREGS_ds(%eax)
541 movl %edi, BREGS_edi(%eax)
542 movl %esi, BREGS_esi(%eax)
543 movl %ebp, BREGS_ebp(%eax)
544 movl %ebx, BREGS_ebx(%eax)
545 movl %edx, BREGS_edx(%eax)
546 movl %ecx, BREGS_ecx(%eax)
547 popl %ecx
548 movw %es, BREGS_es(%eax)
549 movl %esp, BREGS_size+0(%eax)
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500550 movw %ss, BREGS_size+4(%eax)
Kevin O'Connorfeb02842013-12-09 20:30:30 -0500551 popl BREGS_code(%eax)
552 popw BREGS_flags(%eax)
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500553
554 movw %ds, %dx // Setup %ss/%esp and call function
555 movw %dx, %ss
556 movl %eax, %esp
557 calll *%ecx
558
559 movl %esp, %eax // Restore registers and return
560 movw BREGS_size+4(%eax), %ss
561 movl BREGS_size+0(%eax), %esp
562 popl %edx
563 popw %dx
564 pushw BREGS_flags(%eax)
565 pushl BREGS_code(%eax)
566 movl BREGS_edi(%eax), %edi
567 movl BREGS_esi(%eax), %esi
568 movl BREGS_ebp(%eax), %ebp
569 movl BREGS_ebx(%eax), %ebx
570 movl BREGS_edx(%eax), %edx
571 movl BREGS_ecx(%eax), %ecx
572 movw BREGS_es(%eax), %es
573 pushw BREGS_ds(%eax)
574 pushl BREGS_eax(%eax)
575 popl %eax
576 popw %ds
577 iretw
578
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400579 // Main entry point for interrupts with args
Kevin O'Connoreaec3c22009-05-30 03:40:22 -0400580 DECLFUNC irqentryarg
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400581irqentryarg:
582 ENTRY_ARG_ST
583 iretw
584
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400585 // Define an entry point for hardware interrupts.
Kevin O'Connor812478e2011-01-22 10:53:48 -0500586 .macro IRQ_ENTRY num
587 .global entry_\num
588 entry_\num :
589 pushl $ handle_\num
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400590 jmp irqentry_extrastack
Kevin O'Connor812478e2011-01-22 10:53:48 -0500591 .endm
592
593 .macro DECL_IRQ_ENTRY num
594 DECLFUNC entry_\num
595 IRQ_ENTRY \num
596 .endm
597
598 // Define an entry point for an interrupt (can read/modify args).
599 .macro IRQ_ENTRY_ARG num
600 .global entry_\num
601 entry_\num :
602 pushl $ handle_\num
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500603#if CONFIG_ENTRY_EXTRASTACK
604 jmp irqentry_arg_extrastack
605#else
Kevin O'Connor812478e2011-01-22 10:53:48 -0500606 jmp irqentryarg
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500607#endif
Kevin O'Connor812478e2011-01-22 10:53:48 -0500608 .endm
609
610 .macro DECL_IRQ_ENTRY_ARG num
611 DECLFUNC entry_\num
612 IRQ_ENTRY_ARG \num
613 .endm
614
615 // Various entry points (that don't require a fixed location).
Kevin O'Connord67a7032009-01-17 19:37:26 -0500616 DECL_IRQ_ENTRY_ARG 13
Kevin O'Connord67a7032009-01-17 19:37:26 -0500617 DECL_IRQ_ENTRY 76
Kevin O'Connord67a7032009-01-17 19:37:26 -0500618 DECL_IRQ_ENTRY 70
619 DECL_IRQ_ENTRY 74
620 DECL_IRQ_ENTRY 75
621 DECL_IRQ_ENTRY hwpic1
622 DECL_IRQ_ENTRY hwpic2
623
Kevin O'Connor4ebc0b72009-03-01 12:31:57 -0500624 // int 18/19 are special - they reset stack and call into 32bit mode.
Kevin O'Connord67a7032009-01-17 19:37:26 -0500625 DECLFUNC entry_19
626entry_19:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500627 ENTRY_INTO32 _cfunc32flat_handle_19
Kevin O'Connord67a7032009-01-17 19:37:26 -0500628
629 DECLFUNC entry_18
630entry_18:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500631 ENTRY_INTO32 _cfunc32flat_handle_18
Kevin O'Connord67a7032009-01-17 19:37:26 -0500632
633
634/****************************************************************
635 * Fixed position entry points
636 ****************************************************************/
637
638 // Specify a location in the fixed part of bios area.
639 .macro ORG addr
640 .section .fixedaddr.\addr
641 .endm
642
643 ORG 0xe05b
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400644entry_post:
645 cmpl $0, %cs:HaveRunPost // Check for resume/reboot
646 jnz entry_resume
647 ENTRY_INTO32 _cfunc32flat_handle_post // Normal entry point
Kevin O'Connord67a7032009-01-17 19:37:26 -0500648
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500649 ORG 0xe2c3
Kevin O'Connor75f49b32009-03-07 00:07:24 -0500650 IRQ_ENTRY 02
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500651
Kevin O'Connor74534532008-05-12 18:28:58 -0400652 ORG 0xe3fe
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500653 .global entry_13_official
654entry_13_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500655 jmp entry_13
656
Kevin O'Connor30853762009-01-17 18:49:20 -0500657 // 0xe401 - OldFDPT in disk.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500658
Kevin O'Connor74534532008-05-12 18:28:58 -0400659 ORG 0xe6f2
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500660 .global entry_19_official
661entry_19_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500662 jmp entry_19
663
Kevin O'Connor30853762009-01-17 18:49:20 -0500664 // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500665
Kevin O'Connor30853762009-01-17 18:49:20 -0500666 // 0xe729 - BaudTable in serial.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500667
Kevin O'Connor74534532008-05-12 18:28:58 -0400668 ORG 0xe739
Kevin O'Connored128492008-03-11 11:14:59 -0400669 IRQ_ENTRY_ARG 14
670
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500671 ORG 0xe82e
672 IRQ_ENTRY_ARG 16
673
674 ORG 0xe987
675 IRQ_ENTRY 09
676
677 ORG 0xec59
678 IRQ_ENTRY_ARG 40
679
680 ORG 0xef57
681 IRQ_ENTRY 0e
682
Kevin O'Connor30853762009-01-17 18:49:20 -0500683 // 0xefc7 - diskette_param_table in floppy.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500684
685 ORG 0xefd2
686 IRQ_ENTRY_ARG 17
687
688 ORG 0xf045
Kevin O'Connord67a7032009-01-17 19:37:26 -0500689entry_10_0x0f:
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500690 // XXX - INT 10 Functions 0-Fh Entry Point
691 iretw
692
693 ORG 0xf065
694 IRQ_ENTRY_ARG 10
695
Kevin O'Connor30853762009-01-17 18:49:20 -0500696 // 0xf0a4 - VideoParams in misc.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500697
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500698 ORG 0xf841
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400699 IRQ_ENTRY_ARG 12
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500700
701 ORG 0xf84d
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400702 IRQ_ENTRY_ARG 11
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500703
704 ORG 0xf859
Kevin O'Connor3fcabf02014-05-08 18:32:32 -0400705 .global entry_15_official
706entry_15_official:
707 cmpb $0x89, %ah
708 je entry_1589 // 1589 calls return in protected mode
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500709 IRQ_ENTRY_ARG 15
710
Kevin O'Connor30853762009-01-17 18:49:20 -0500711 // 0xfa6e - vgafont8 in font.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500712
Kevin O'Connor74534532008-05-12 18:28:58 -0400713 ORG 0xfe6e
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500714 .global entry_1a_official
715entry_1a_official:
716 cmpb $0xb1, %ah
717 je entry_pcibios16 // PCIBIOS calls can be in protected mode
Kevin O'Connored128492008-03-11 11:14:59 -0400718 IRQ_ENTRY_ARG 1a
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500719
Kevin O'Connor74534532008-05-12 18:28:58 -0400720 ORG 0xfea5
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500721 IRQ_ENTRY 08
722
Kevin O'Connor30853762009-01-17 18:49:20 -0500723 // 0xfef3 - InitVectors in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500724
Kevin O'Connor30853762009-01-17 18:49:20 -0500725 // 0xff00 - BiosCopyright in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500726
Kevin O'Connor74534532008-05-12 18:28:58 -0400727 ORG 0xff53
Kevin O'Connord67a7032009-01-17 19:37:26 -0500728 .global entry_iret_official
729entry_iret_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500730 iretw
731
Kevin O'Connor74534532008-05-12 18:28:58 -0400732 ORG 0xff54
Kevin O'Connored128492008-03-11 11:14:59 -0400733 IRQ_ENTRY_ARG 05
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500734
Kevin O'Connor74534532008-05-12 18:28:58 -0400735 ORG 0xfff0 // Power-up Entry Point
Kevin O'Connor3f168b62008-11-29 13:22:29 -0500736 .global reset_vector
737reset_vector:
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400738 ljmpw $SEG_BIOS, $entry_post
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500739
Kevin O'Connor30853762009-01-17 18:49:20 -0500740 // 0xfff5 - BiosDate in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500741
Kevin O'Connor30853762009-01-17 18:49:20 -0500742 // 0xfffe - BiosModelId in misc.c
Kevin O'Connore3677b12008-07-04 15:29:23 -0400743
Kevin O'Connor30853762009-01-17 18:49:20 -0500744 // 0xffff - BiosChecksum in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500745
746 .end