blob: 93b6874e71610ed050fc9601fe81f8720fff3f0b [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/rtc.h" // CMOS_RESET_CODE
12#include "x86.h" // CR0_*
Kevin O'Connor74534532008-05-12 18:28:58 -040013
Kevin O'Connor56b252e2014-12-03 12:22:14 -050014 .code16
15
Kevin O'Connor1d019512008-03-11 21:21:47 -040016
17/****************************************************************
Kevin O'Connor38aadba2013-09-29 19:25:44 -040018 * 16bit / 32bit call trampolines
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050019 ****************************************************************/
20
21// Place CPU into 32bit mode from 16bit mode.
Kevin O'Connor4057f982010-11-25 08:52:50 -050022// %edx = return location (in 32bit mode)
Kevin O'Connorad901592009-12-13 11:25:25 -050023// Clobbers: ecx, flags, segment registers, cr0, idt/gdt
Kevin O'Connord67a7032009-01-17 19:37:26 -050024 DECLFUNC transition32
Kevin O'Connor5ae3dd62015-03-11 17:45:47 -040025transition32_nmi_off:
26 // transition32 when NMI and A20 are already initialized
Kevin O'Connorf4c511c2014-04-07 19:49:12 -040027 movl %eax, %ecx
28 jmp 1f
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050029transition32:
Kevin O'Connorad901592009-12-13 11:25:25 -050030 movl %eax, %ecx
Kevin O'Connor9caf7862009-02-27 20:14:05 -050031
Kevin O'Connorf094ba82009-04-13 19:30:27 -040032 // Disable irqs (and clear direction flag)
33 cli
34 cld
35
36 // Disable nmi
37 movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax
38 outb %al, $PORT_CMOS_INDEX
39 inb $PORT_CMOS_DATA, %al
40
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050041 // enable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050042 inb $PORT_A20, %al
43 orb $A20_ENABLE_BIT, %al
44 outb %al, $PORT_A20
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050045
46 // Set segment descriptors
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400471: lidtw %cs:pmode_IDT_info
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050048 lgdtw %cs:rombios32_gdt_48
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050049
Kevin O'Connor3eac0092008-11-16 09:59:32 -050050 // Enable protected mode
51 movl %cr0, %eax
52 orl $CR0_PE, %eax
53 movl %eax, %cr0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050054
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050055 // start 32bit protected mode code
Kevin O'Connorf4c511c2014-04-07 19:49:12 -040056 ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 2f)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050057
58 .code32
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050059 // init data segments
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400602: movl $SEG32_MODE32_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050061 movw %ax, %ds
62 movw %ax, %es
63 movw %ax, %ss
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050064 movw %ax, %fs
65 movw %ax, %gs
66
Kevin O'Connorad901592009-12-13 11:25:25 -050067 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -050068 jmpl *%edx
Kevin O'Connor56b252e2014-12-03 12:22:14 -050069 .code16
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050070
Kevin O'Connor752151b2009-12-10 21:16:07 -050071// Place CPU into 16bit mode from 32bit mode.
Kevin O'Connor4057f982010-11-25 08:52:50 -050072// %edx = return location (in 16bit mode)
Kevin O'Connorad901592009-12-13 11:25:25 -050073// Clobbers: ecx, flags, segment registers, cr0, idt/gdt
Kevin O'Connor752151b2009-12-10 21:16:07 -050074 DECLFUNC transition16
75 .global transition16big
Kevin O'Connor56b252e2014-12-03 12:22:14 -050076 .code32
Kevin O'Connor752151b2009-12-10 21:16:07 -050077transition16:
Kevin O'Connorad901592009-12-13 11:25:25 -050078 movl %eax, %ecx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050079
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050080 // restore data segment limits to 0xffff
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050081 movl $SEG32_MODE16_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050082 movw %ax, %ds
83 movw %ax, %es
84 movw %ax, %ss
85 movw %ax, %fs
86 movw %ax, %gs
87
Kevin O'Connorffb81a42009-04-13 19:44:55 -040088#if CONFIG_DISABLE_A20
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050089 // disable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050090 inb $PORT_A20, %al
91 andb $~A20_ENABLE_BIT, %al
92 outb %al, $PORT_A20
Kevin O'Connorffb81a42009-04-13 19:44:55 -040093#endif
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050094
95 // Jump to 16bit mode
96 ljmpw $SEG32_MODE16_CS, $1f
97
Kevin O'Connor752151b2009-12-10 21:16:07 -050098transition16big:
Kevin O'Connorad901592009-12-13 11:25:25 -050099 movl %eax, %ecx
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500100
101 movl $SEG32_MODE16BIG_DS, %eax
102 movw %ax, %ds
103 movw %ax, %es
104 movw %ax, %ss
105 movw %ax, %fs
106 movw %ax, %gs
107
Kevin O'Connor0f788892010-07-25 14:04:01 -0400108 ljmpw $SEG32_MODE16BIG_CS, $1f
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500109
David Woodhouse5b22d932014-06-03 17:28:49 +0100110 .code16
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -05001111:
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500112 // Disable protected mode
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500113 movl %cr0, %eax
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500114 andl $~CR0_PE, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500115 movl %eax, %cr0
116
117 // far jump to flush CPU queue after transition to real mode
Kevin O'Connore3677b12008-07-04 15:29:23 -0400118 ljmpw $SEG_BIOS, $2f
Kevin O'Connor21e930b2008-03-01 09:49:37 -0500119
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001202:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500121 // restore IDT to normal real-mode defaults
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500122 lidtw %cs:rmode_IDT_info
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500123
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500124 // Clear segment registers
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500125 xorw %ax, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500126 movw %ax, %fs
127 movw %ax, %gs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500128 movw %ax, %es
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500129 movw %ax, %ds
130 movw %ax, %ss // Assume stack is in segment 0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500131
Kevin O'Connorad901592009-12-13 11:25:25 -0500132 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -0500133 jmpl *%edx
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500134
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400135
136/****************************************************************
137 * External calling trampolines
138 ****************************************************************/
139
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400140// Far call a 16bit function from 16bit mode with a specified cpu register state
Kevin O'Connor2d977562013-09-29 20:21:40 -0400141// %eax = address of struct bregs, %edx = segment of struct bregs
142// Clobbers: %e[bc]x, %e[ds]i, flags
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400143 DECLFUNC __farcall16
144__farcall16:
Kevin O'Connor2d977562013-09-29 20:21:40 -0400145 // Save %edx/%eax, %ebp
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500146 pushl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500147 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400148 pushl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500149
150 // Setup for iretw call
Kevin O'Connor2d977562013-09-29 20:21:40 -0400151 movl %edx, %ds
Kevin O'Connor273e8ae2009-01-19 19:56:07 -0500152 pushw %cs
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400153 pushw $1f // return point
Kevin O'Connor2d977562013-09-29 20:21:40 -0400154 pushw BREGS_flags(%eax) // flags
155 pushl BREGS_code(%eax) // CS:IP
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500156
Kevin O'Connor46000f52014-10-21 02:23:02 -0400157 // Load calling registers and invoke call
158 RESTOREBREGS_DSEAX
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400159 iretw // XXX - just do a lcalll
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001601:
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400161 // Store flags, es, eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500162 pushfw
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400163 cli
164 cld
Kevin O'Connor2d977562013-09-29 20:21:40 -0400165 pushw %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500166 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400167 movw 0x08(%esp), %ds
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400168 movl 0x0c(%esp), %eax
Kevin O'Connor46000f52014-10-21 02:23:02 -0400169 SAVEBREGS_POP_DSEAX
Kevin O'Connor2d977562013-09-29 20:21:40 -0400170 popw BREGS_flags(%eax)
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400171 movw %ss, %cx
172 movw %cx, %ds // Restore %ds == %ss
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500173
Kevin O'Connor2d977562013-09-29 20:21:40 -0400174 // Remove %edx/%eax, restore %ebp
175 popl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500176 popl %eax
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500177 popl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500178
179 retl
180
Kevin O'Connor79dde652009-04-13 19:26:43 -0400181// IRQ trampolines
182 .macro IRQ_TRAMPOLINE num
183 DECLFUNC irq_trampoline_0x\num
184 irq_trampoline_0x\num :
185 int $0x\num
186 lretw
187 .endm
188
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400189 IRQ_TRAMPOLINE 02
Kevin O'Connor79dde652009-04-13 19:26:43 -0400190 IRQ_TRAMPOLINE 10
191 IRQ_TRAMPOLINE 13
192 IRQ_TRAMPOLINE 15
193 IRQ_TRAMPOLINE 16
194 IRQ_TRAMPOLINE 18
195 IRQ_TRAMPOLINE 19
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400196 IRQ_TRAMPOLINE 1c
197 IRQ_TRAMPOLINE 4a
Kevin O'Connor79dde652009-04-13 19:26:43 -0400198
199
200/****************************************************************
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400201 * Misc. entry points.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400202 ****************************************************************/
203
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400204// Entry point for QEMU smi interrupts.
205 DECLFUNC entry_smi
206entry_smi:
207 // Transition to 32bit mode.
208 movl $1f + BUILD_BIOS_ADDR, %edx
Kevin O'Connor5ae3dd62015-03-11 17:45:47 -0400209 jmp transition32_nmi_off
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400210 .code32
Kevin O'Connor31bcda22014-05-28 13:33:50 -04002111: movl $BUILD_SMM_ADDR + 0x8000, %esp
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400212 calll _cfunc32flat_handle_smi - BUILD_BIOS_ADDR
213 rsm
David Woodhouse5b22d932014-06-03 17:28:49 +0100214 .code16
Kevin O'Connorf4c511c2014-04-07 19:49:12 -0400215
Kevin O'Connor0673b782014-05-24 10:49:50 -0400216// Entry point for QEMU smp sipi interrupts.
217 DECLFUNC entry_smp
218entry_smp:
219 // Transition to 32bit mode.
Kevin O'Connor5ae3dd62015-03-11 17:45:47 -0400220 cli
221 cld
Kevin O'Connor0673b782014-05-24 10:49:50 -0400222 movl $2f + BUILD_BIOS_ADDR, %edx
Kevin O'Connor5ae3dd62015-03-11 17:45:47 -0400223 jmp transition32_nmi_off
Kevin O'Connor0673b782014-05-24 10:49:50 -0400224 .code32
225 // Acquire lock and take ownership of shared stack
Ian Campbell68354a62014-06-30 14:10:02 +01002261: rep ; nop
Kevin O'Connor0673b782014-05-24 10:49:50 -04002272: lock btsl $0, SMPLock
228 jc 1b
229 movl SMPStack, %esp
230 // Call handle_smp
231 calll _cfunc32flat_handle_smp - BUILD_BIOS_ADDR
232 // Release lock and halt processor.
233 movl $0, SMPLock
2343: hlt
235 jmp 3b
David Woodhouse5b22d932014-06-03 17:28:49 +0100236 .code16
Kevin O'Connor0673b782014-05-24 10:49:50 -0400237
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400238// Resume (and reboot) entry point - called from entry_post
239 DECLFUNC entry_resume
240entry_resume:
Kevin O'Connor79dde652009-04-13 19:26:43 -0400241 // Disable interrupts
242 cli
243 cld
Kevin O'Connor46b82622012-05-13 12:10:30 -0400244 // Use the ExtraStack in low mem.
Kevin O'Connorc9243442013-02-17 13:58:28 -0500245 movl $_zonelow_seg, %eax
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400246 movw %ax, %ds
Kevin O'Connor79dde652009-04-13 19:26:43 -0400247 movw %ax, %ss
Kevin O'Connor46b82622012-05-13 12:10:30 -0400248 movl $ExtraStack + BUILD_EXTRA_STACK_SIZE, %esp
Kevin O'Connor79dde652009-04-13 19:26:43 -0400249 // Call handler.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400250 jmp handle_resume
251
Kevin O'Connore54ee382009-07-26 19:33:13 -0400252// PMM entry point
253 DECLFUNC entry_pmm
254entry_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
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400260 PUSHBREGS
Kevin O'Connord5c61742014-09-30 09:37:26 -0400261 movl %ss, %ecx // Move %ss to %ds
Kevin O'Connore54ee382009-07-26 19:33:13 -0400262 movw %cx, %ds
Kevin O'Connord5c61742014-09-30 09:37:26 -0400263 shll $4, %ecx
Kevin O'Connor533b6282011-07-16 13:13:12 -0400264 movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500265 leal PUSHBREGS_size+12(%esp, %ecx), %edx // %edx points to start of args
Kevin O'Connor533b6282011-07-16 13:13:12 -0400266 movl $-1, %ecx
267 calll call32
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400268 movw %ax, BREGS_eax(%esp) // Modify %ax:%dx to return %eax
Kevin O'Connore54ee382009-07-26 19:33:13 -0400269 shrl $16, %eax
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400270 movw %ax, BREGS_edx(%esp)
271 POPBREGS
Kevin O'Connore54ee382009-07-26 19:33:13 -0400272 popfl
273 popl %esp
274 lretw
275
Kevin O'Connor79dde652009-04-13 19:26:43 -0400276// PnP entry points
Kevin O'Connord67a7032009-01-17 19:37:26 -0500277 DECLFUNC entry_pnp_real
278 .global entry_pnp_prot
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500279entry_pnp_prot:
280 pushl %esp
281 jmp 1f
282entry_pnp_real:
283 pushl %esp // Backup %esp, then clear high bits
284 movzwl %sp, %esp
2851:
286 pushfl // Save registers clobbered by C code
Kevin O'Connore54ee382009-07-26 19:33:13 -0400287 cli
288 cld
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400289 PUSHBREGS
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500290 movw %ss, %cx // Move %ss to %ds
291 movw %cx, %ds
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500292 leal PUSHBREGS_size+12(%esp), %eax // %eax points to start of u16 args
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500293 calll handle_pnp
Kevin O'Connor85230162014-11-03 09:45:51 -0500294 movw %ax, BREGS_eax(%esp) // Modify %eax to return %ax
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400295 POPBREGS
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500296 popfl
297 popl %esp
298 lretw
299
Kevin O'Connor79dde652009-04-13 19:26:43 -0400300// APM entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400301 DECLFUNC entry_apm16
302entry_apm16:
Kevin O'Connor1d019512008-03-11 21:21:47 -0400303 pushfw // save flags
304 pushl %eax // dummy
Kevin O'Connord3e43672012-05-28 11:37:53 -0400305 ENTRY_ARG handle_apm
Kevin O'Connorb3c28be2008-06-08 13:34:43 -0400306 addw $4, %sp // pop dummy
Kevin O'Connor1d019512008-03-11 21:21:47 -0400307 popfw // restore flags
308 lretw
309
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400310 DECLFUNC entry_apm32
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500311 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400312entry_apm32:
Kevin O'Connorc0031482010-01-01 13:03:17 -0500313 pushfl
314 pushl %gs
315 pushl %cs // Move second descriptor after %cs to %gs
316 addl $16, (%esp)
317 popl %gs
Kevin O'Connord3e43672012-05-28 11:37:53 -0400318 ENTRY_ARG_ESP _cfunc32seg_handle_apm
Kevin O'Connorc0031482010-01-01 13:03:17 -0500319 popl %gs
320 popfl
Kevin O'Connor1d019512008-03-11 21:21:47 -0400321 lretl
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500322 .code16
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400323
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500324// PCI-BIOS entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400325 DECLFUNC entry_pcibios32
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500326 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400327entry_pcibios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500328 pushfl
Kevin O'Connorc0031482010-01-01 13:03:17 -0500329 pushl %gs // Backup %gs and set %gs=%ds
330 pushl %ds
331 popl %gs
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500332 ENTRY_ARG_ESP _cfunc32seg_handle_pcibios
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500333 popl %gs
334 popfl
335 lretl
David Woodhouse5b22d932014-06-03 17:28:49 +0100336 .code16
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500337
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500338 DECLFUNC entry_pcibios16
339entry_pcibios16:
340 ENTRY_ARG handle_pcibios
341 iretw
342
Kevin O'Connor3fcabf02014-05-08 18:32:32 -0400343// int 1589 entry point
344 DECLFUNC entry_1589
345entry_1589:
346 ENTRY_ARG handle_1589
347 iretw
348
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500349// BIOS32 support
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500350 DECLFUNC entry_bios32
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500351 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400352entry_bios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500353 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
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400360 movl $entry_pcibios32, %edx
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500361 xorb %al, %al
362 jmp 2f
363#endif
364 // Unknown request
3651: movb $0x80, %al
366 // Return to caller
3672: popfl
368 lretl
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500369 .code16
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500370
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400371// 32bit elf entry point
Kevin O'Connoree952532014-06-09 14:37:23 -0400372 DECLFUNC entry_elf
Kevin O'Connor56b252e2014-12-03 12:22:14 -0500373 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400374entry_elf:
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400375 cli
376 cld
377 lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
378 lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
Kevin O'Connore0504b02009-04-13 19:32:51 -0400379 movl $SEG32_MODE32_DS, %eax
380 movw %ax, %ds
381 movw %ax, %es
382 movw %ax, %fs
383 movw %ax, %gs
384 movw %ax, %ss
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400385 movl $BUILD_STACK_ADDR, %esp
Kevin O'Connorb1885fc2013-02-08 21:00:46 -0500386 ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
David Woodhouse5b22d932014-06-03 17:28:49 +0100387 .code16
Kevin O'Connor1d019512008-03-11 21:21:47 -0400388
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500389// UEFI Compatibility Support Module (CSM) entry point
Kevin O'Connoree952532014-06-09 14:37:23 -0400390 DECLFUNC entry_csm
David Woodhouse118469a2013-01-25 19:46:25 -0600391entry_csm:
392 // Backup register state
393 pushfw
394 cli
395 cld
396 pushl %eax // dummy
397 PUSHBREGS
398
399 // Backup stack location and convert to a "flat pointer"
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000400 movl %ss, %eax
401 movw %ax, BREGS_code+2(%esp) // Store %ss in bregs->code.seg
402 shll $4, %eax
403 addl %esp, %eax
David Woodhouse118469a2013-01-25 19:46:25 -0600404
Kevin O'Connor283ae1f2014-10-21 03:19:55 -0400405 // Change to BUILD_STACK_ADDR stack and call handle_csm(bregs)
406 ENTRY_INTO32 _cfunc32flat_handle_csm
David Woodhouse118469a2013-01-25 19:46:25 -0600407
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500408 DECLFUNC __csm_return
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500409 .code32
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000410__csm_return:
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500411 movl $1f, %edx
David Woodhouse118469a2013-01-25 19:46:25 -0600412 jmp transition16big
David Woodhouse5b22d932014-06-03 17:28:49 +0100413 .code16
David Woodhouse118469a2013-01-25 19:46:25 -0600414
415 // Switch back to original stack
Kevin O'Connorbbd04582013-02-18 21:57:26 -05004161: movzwl BREGS_code+2(%eax), %edx
417 movl %edx, %ecx
David Woodhouse118469a2013-01-25 19:46:25 -0600418 shll $4, %ecx
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500419 subl %ecx, %eax
420 movl %edx, %ss
421 movl %eax, %esp
David Woodhouse118469a2013-01-25 19:46:25 -0600422
423 // Restore register state and return.
424 POPBREGS
425 addw $4, %sp // pop dummy
426 popfw
427 lretw
428
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500429
430/****************************************************************
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500431 * Interrupt entry points
432 ****************************************************************/
433
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500434 // Main entry point for hardware interrupts handled on extra stack
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400435 DECLFUNC irqentry_extrastack
436irqentry_extrastack:
437 cli
438 cld
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400439 pushw %ds // Set %ds:%eax to space on ExtraStack
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400440 pushl %eax
Kevin O'Connorc9243442013-02-17 13:58:28 -0500441 movl $_zonelow_seg, %eax
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400442 movl %eax, %ds
443 movl StackPos, %eax
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500444 subl $PUSHBREGS_size+8, %eax
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400445 SAVEBREGS_POP_DSEAX
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400446 popl %ecx
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500447 movl %esp, PUSHBREGS_size(%eax)
448 movw %ss, PUSHBREGS_size+4(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400449
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400450 movw %ds, %dx // Setup %ss/%esp and call function
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400451 movw %dx, %ss
452 movl %eax, %esp
453 calll *%ecx
454
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400455 movl %esp, %eax // Restore registers and return
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500456 movw PUSHBREGS_size+4(%eax), %ss
457 movl PUSHBREGS_size(%eax), %esp
Kevin O'Connor99cb8f32014-10-21 14:34:06 -0400458 RESTOREBREGS_DSEAX
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400459 iretw
460
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500461 // Main entry point for software interrupts handled on extra stack
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500462 DECLFUNC irqentry_arg_extrastack
463irqentry_arg_extrastack:
464 cli
465 cld
466 pushw %ds // Set %ds:%eax to space on ExtraStack
467 pushl %eax
468 movl $_zonelow_seg, %eax
469 movl %eax, %ds
470 movl StackPos, %eax
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500471 subl $PUSHBREGS_size+16, %eax
Kevin O'Connor46000f52014-10-21 02:23:02 -0400472 SAVEBREGS_POP_DSEAX // Save registers on extra stack
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500473 popl %ecx
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500474 movl %esp, PUSHBREGS_size+8(%eax)
475 movw %ss, PUSHBREGS_size+12(%eax)
Kevin O'Connorfeb02842013-12-09 20:30:30 -0500476 popl BREGS_code(%eax)
477 popw BREGS_flags(%eax)
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500478
479 movw %ds, %dx // Setup %ss/%esp and call function
480 movw %dx, %ss
481 movl %eax, %esp
482 calll *%ecx
483
484 movl %esp, %eax // Restore registers and return
Kevin O'Connoraa66d652014-11-05 09:05:36 -0500485 movw PUSHBREGS_size+12(%eax), %ss
486 movl PUSHBREGS_size+8(%eax), %esp
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500487 popl %edx
488 popw %dx
489 pushw BREGS_flags(%eax)
490 pushl BREGS_code(%eax)
Kevin O'Connor46000f52014-10-21 02:23:02 -0400491 RESTOREBREGS_DSEAX
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500492 iretw
493
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500494 // Main entry point for software interrupts (using caller's stack)
495 DECLFUNC irqentry_arg
496irqentry_arg:
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400497 ENTRY_ARG_ST
498 iretw
499
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500500 // Helper macros for hardware interrupt declaration
Kevin O'Connor812478e2011-01-22 10:53:48 -0500501 .macro IRQ_ENTRY num
502 .global entry_\num
503 entry_\num :
504 pushl $ handle_\num
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400505 jmp irqentry_extrastack
Kevin O'Connor812478e2011-01-22 10:53:48 -0500506 .endm
507
508 .macro DECL_IRQ_ENTRY num
509 DECLFUNC entry_\num
510 IRQ_ENTRY \num
511 .endm
512
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500513 // Helper macros for software interrupt declaration
Kevin O'Connor812478e2011-01-22 10:53:48 -0500514 .macro IRQ_ENTRY_ARG num
515 .global entry_\num
516 entry_\num :
517 pushl $ handle_\num
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500518#if CONFIG_ENTRY_EXTRASTACK
519 jmp irqentry_arg_extrastack
520#else
Kevin O'Connorb0d42bd2014-11-05 12:04:53 -0500521 jmp irqentry_arg
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500522#endif
Kevin O'Connor812478e2011-01-22 10:53:48 -0500523 .endm
524
525 .macro DECL_IRQ_ENTRY_ARG num
526 DECLFUNC entry_\num
527 IRQ_ENTRY_ARG \num
528 .endm
529
530 // Various entry points (that don't require a fixed location).
Kevin O'Connord67a7032009-01-17 19:37:26 -0500531 DECL_IRQ_ENTRY_ARG 13
Kevin O'Connord67a7032009-01-17 19:37:26 -0500532 DECL_IRQ_ENTRY 76
Kevin O'Connord67a7032009-01-17 19:37:26 -0500533 DECL_IRQ_ENTRY 70
534 DECL_IRQ_ENTRY 74
535 DECL_IRQ_ENTRY 75
536 DECL_IRQ_ENTRY hwpic1
537 DECL_IRQ_ENTRY hwpic2
538
Kevin O'Connor4ebc0b72009-03-01 12:31:57 -0500539 // int 18/19 are special - they reset stack and call into 32bit mode.
Kevin O'Connord67a7032009-01-17 19:37:26 -0500540 DECLFUNC entry_19
541entry_19:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500542 ENTRY_INTO32 _cfunc32flat_handle_19
Kevin O'Connord67a7032009-01-17 19:37:26 -0500543
544 DECLFUNC entry_18
545entry_18:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500546 ENTRY_INTO32 _cfunc32flat_handle_18
Kevin O'Connord67a7032009-01-17 19:37:26 -0500547
548
549/****************************************************************
550 * Fixed position entry points
551 ****************************************************************/
552
553 // Specify a location in the fixed part of bios area.
554 .macro ORG addr
555 .section .fixedaddr.\addr
556 .endm
557
558 ORG 0xe05b
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400559entry_post:
560 cmpl $0, %cs:HaveRunPost // Check for resume/reboot
561 jnz entry_resume
562 ENTRY_INTO32 _cfunc32flat_handle_post // Normal entry point
Kevin O'Connord67a7032009-01-17 19:37:26 -0500563
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500564 ORG 0xe2c3
Kevin O'Connor75f49b32009-03-07 00:07:24 -0500565 IRQ_ENTRY 02
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500566
Kevin O'Connor74534532008-05-12 18:28:58 -0400567 ORG 0xe3fe
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500568 .global entry_13_official
569entry_13_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500570 jmp entry_13
571
Kevin O'Connorca34ce52014-05-24 10:40:35 -0400572 // 0xe401 - OldFDPT in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500573
Kevin O'Connor74534532008-05-12 18:28:58 -0400574 ORG 0xe6f2
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500575 .global entry_19_official
576entry_19_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500577 jmp entry_19
578
Kevin O'Connor30853762009-01-17 18:49:20 -0500579 // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500580
Kevin O'Connorca34ce52014-05-24 10:40:35 -0400581 // 0xe729 - BaudTable in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500582
Kevin O'Connor74534532008-05-12 18:28:58 -0400583 ORG 0xe739
Kevin O'Connored128492008-03-11 11:14:59 -0400584 IRQ_ENTRY_ARG 14
585
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500586 ORG 0xe82e
587 IRQ_ENTRY_ARG 16
588
589 ORG 0xe987
590 IRQ_ENTRY 09
591
592 ORG 0xec59
593 IRQ_ENTRY_ARG 40
594
595 ORG 0xef57
596 IRQ_ENTRY 0e
597
Kevin O'Connorca34ce52014-05-24 10:40:35 -0400598 // 0xefc7 - diskette_param_table in misc.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500599
600 ORG 0xefd2
601 IRQ_ENTRY_ARG 17
602
603 ORG 0xf045
Kevin O'Connord67a7032009-01-17 19:37:26 -0500604entry_10_0x0f:
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500605 // XXX - INT 10 Functions 0-Fh Entry Point
606 iretw
607
608 ORG 0xf065
609 IRQ_ENTRY_ARG 10
610
Kevin O'Connor30853762009-01-17 18:49:20 -0500611 // 0xf0a4 - VideoParams in misc.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500612
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500613 ORG 0xf841
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400614 IRQ_ENTRY_ARG 12
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500615
616 ORG 0xf84d
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400617 IRQ_ENTRY_ARG 11
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500618
619 ORG 0xf859
Kevin O'Connor3fcabf02014-05-08 18:32:32 -0400620 .global entry_15_official
621entry_15_official:
622 cmpb $0x89, %ah
623 je entry_1589 // 1589 calls return in protected mode
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500624 IRQ_ENTRY_ARG 15
625
Kevin O'Connor30853762009-01-17 18:49:20 -0500626 // 0xfa6e - vgafont8 in font.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500627
Kevin O'Connor74534532008-05-12 18:28:58 -0400628 ORG 0xfe6e
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500629 .global entry_1a_official
630entry_1a_official:
631 cmpb $0xb1, %ah
632 je entry_pcibios16 // PCIBIOS calls can be in protected mode
Kevin O'Connored128492008-03-11 11:14:59 -0400633 IRQ_ENTRY_ARG 1a
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500634
Kevin O'Connor74534532008-05-12 18:28:58 -0400635 ORG 0xfea5
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500636 IRQ_ENTRY 08
637
Kevin O'Connor30853762009-01-17 18:49:20 -0500638 // 0xfef3 - InitVectors in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500639
Kevin O'Connor74534532008-05-12 18:28:58 -0400640 ORG 0xff53
Kevin O'Connord67a7032009-01-17 19:37:26 -0500641 .global entry_iret_official
642entry_iret_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500643 iretw
644
Kevin O'Connor74534532008-05-12 18:28:58 -0400645 ORG 0xff54
Kevin O'Connored128492008-03-11 11:14:59 -0400646 IRQ_ENTRY_ARG 05
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500647
Kevin O'Connor74534532008-05-12 18:28:58 -0400648 ORG 0xfff0 // Power-up Entry Point
Kevin O'Connor3f168b62008-11-29 13:22:29 -0500649 .global reset_vector
650reset_vector:
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400651 ljmpw $SEG_BIOS, $entry_post
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500652
Kevin O'Connor30853762009-01-17 18:49:20 -0500653 // 0xfff5 - BiosDate in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500654
Kevin O'Connor30853762009-01-17 18:49:20 -0500655 // 0xfffe - BiosModelId in misc.c
Kevin O'Connore3677b12008-07-04 15:29:23 -0400656
Kevin O'Connor30853762009-01-17 18:49:20 -0500657 // 0xffff - BiosChecksum in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500658
659 .end