blob: 9de91a2e5a9f45e795f6b34ffba9d88930874947 [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'Connorf076a3e2008-02-25 22:25:15 -050025transition32:
Kevin O'Connorad901592009-12-13 11:25:25 -050026 movl %eax, %ecx
Kevin O'Connor9caf7862009-02-27 20:14:05 -050027
Kevin O'Connorf094ba82009-04-13 19:30:27 -040028 // Disable irqs (and clear direction flag)
29 cli
30 cld
31
32 // Disable nmi
33 movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax
34 outb %al, $PORT_CMOS_INDEX
35 inb $PORT_CMOS_DATA, %al
36
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050037 // enable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050038 inb $PORT_A20, %al
39 orb $A20_ENABLE_BIT, %al
40 outb %al, $PORT_A20
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050041
42 // Set segment descriptors
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050043 lidtw %cs:pmode_IDT_info
44 lgdtw %cs:rombios32_gdt_48
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050045
Kevin O'Connor3eac0092008-11-16 09:59:32 -050046 // Enable protected mode
47 movl %cr0, %eax
48 orl $CR0_PE, %eax
49 movl %eax, %cr0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050050
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050051 // start 32bit protected mode code
Kevin O'Connor14927082008-11-08 19:07:49 -050052 ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 1f)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050053
54 .code32
551:
56 // init data segments
Kevin O'Connor14927082008-11-08 19:07:49 -050057 movl $SEG32_MODE32_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050058 movw %ax, %ds
59 movw %ax, %es
60 movw %ax, %ss
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050061 movw %ax, %fs
62 movw %ax, %gs
63
Kevin O'Connorad901592009-12-13 11:25:25 -050064 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -050065 jmpl *%edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050066
Kevin O'Connor752151b2009-12-10 21:16:07 -050067// Place CPU into 16bit mode from 32bit mode.
Kevin O'Connor4057f982010-11-25 08:52:50 -050068// %edx = return location (in 16bit mode)
Kevin O'Connorad901592009-12-13 11:25:25 -050069// Clobbers: ecx, flags, segment registers, cr0, idt/gdt
Kevin O'Connor752151b2009-12-10 21:16:07 -050070 DECLFUNC transition16
71 .global transition16big
72transition16:
Kevin O'Connorad901592009-12-13 11:25:25 -050073 movl %eax, %ecx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -050074
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050075 // restore data segment limits to 0xffff
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050076 movl $SEG32_MODE16_DS, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050077 movw %ax, %ds
78 movw %ax, %es
79 movw %ax, %ss
80 movw %ax, %fs
81 movw %ax, %gs
82
Kevin O'Connorffb81a42009-04-13 19:44:55 -040083#if CONFIG_DISABLE_A20
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050084 // disable a20
Kevin O'Connord9a8b2d2008-11-16 09:17:02 -050085 inb $PORT_A20, %al
86 andb $~A20_ENABLE_BIT, %al
87 outb %al, $PORT_A20
Kevin O'Connorffb81a42009-04-13 19:44:55 -040088#endif
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -050089
90 // Jump to 16bit mode
91 ljmpw $SEG32_MODE16_CS, $1f
92
Kevin O'Connor752151b2009-12-10 21:16:07 -050093transition16big:
Kevin O'Connorad901592009-12-13 11:25:25 -050094 movl %eax, %ecx
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -050095
96 movl $SEG32_MODE16BIG_DS, %eax
97 movw %ax, %ds
98 movw %ax, %es
99 movw %ax, %ss
100 movw %ax, %fs
101 movw %ax, %gs
102
Kevin O'Connor0f788892010-07-25 14:04:01 -0400103 ljmpw $SEG32_MODE16BIG_CS, $1f
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500104
Kevin O'Connor1a72e2e2008-11-11 22:03:55 -0500105 .code16gcc
1061:
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500107 // Disable protected mode
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500108 movl %cr0, %eax
Kevin O'Connor3eac0092008-11-16 09:59:32 -0500109 andl $~CR0_PE, %eax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500110 movl %eax, %cr0
111
112 // far jump to flush CPU queue after transition to real mode
Kevin O'Connore3677b12008-07-04 15:29:23 -0400113 ljmpw $SEG_BIOS, $2f
Kevin O'Connor21e930b2008-03-01 09:49:37 -0500114
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05001152:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500116 // restore IDT to normal real-mode defaults
Kevin O'Connor6e5b4a42008-12-06 13:03:52 -0500117 lidtw %cs:rmode_IDT_info
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500118
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500119 // Clear segment registers
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500120 xorw %ax, %ax
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500121 movw %ax, %fs
122 movw %ax, %gs
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500123 movw %ax, %es
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500124 movw %ax, %ds
125 movw %ax, %ss // Assume stack is in segment 0
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500126
Kevin O'Connorad901592009-12-13 11:25:25 -0500127 movl %ecx, %eax
Kevin O'Connor4057f982010-11-25 08:52:50 -0500128 jmpl *%edx
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500129
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400130// Call a 16bit SeaBIOS function from SeaBIOS 32bit C code.
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400131// %ecx = calling function
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400132// Clobbers: %ecx, %edx, flags, segment registers, idt/gdt
133 DECLFUNC __call16
134 .global __call16big
135 .code32
136__call16:
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400137 pushl %edx
138 pushl %ecx
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400139 movl $1f, %edx
140 jmp transition16
141__call16big:
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400142 pushl %edx
143 pushl %ecx
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400144 movl $1f, %edx
145 jmp transition16big
146
147 // Make call.
148 .code16gcc
Kevin O'Connor7acaa3c2013-10-02 20:20:03 -04001491: movl $_zonelow_seg, %edx // Adjust %ds, %ss, and %esp
150 movl %edx, %ds
151 movzwl StackSeg, %edx
152 movl %edx, %ecx
153 shll $4, %ecx
154 movl %edx, %ss
155 subl %ecx, %esp
156 movl %edx, %ds
157
158 popl %ecx // Call function
Kevin O'Connor9e75b082013-09-29 19:58:09 -0400159 popl %edx
160 calll *%ecx
Kevin O'Connor7acaa3c2013-10-02 20:20:03 -0400161
162 movl %ss, %edx // Readjust %esp
163 shll $4, %edx
164 addl %edx, %esp
165
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400166 // Return via transition32
167 movl $(2f + BUILD_BIOS_ADDR), %edx
168 jmp transition32
169 .code32
1702: retl
171
172
173/****************************************************************
174 * External calling trampolines
175 ****************************************************************/
176
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400177// Far call a 16bit function from 16bit mode with a specified cpu register state
Kevin O'Connor2d977562013-09-29 20:21:40 -0400178// %eax = address of struct bregs, %edx = segment of struct bregs
179// Clobbers: %e[bc]x, %e[ds]i, flags
Kevin O'Connor38aadba2013-09-29 19:25:44 -0400180 .code16gcc
Kevin O'Connorc7ffbac2012-03-25 11:04:10 -0400181 DECLFUNC __farcall16
182__farcall16:
Kevin O'Connor2d977562013-09-29 20:21:40 -0400183 // Save %edx/%eax, %ebp
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500184 pushl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500185 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400186 pushl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500187
188 // Setup for iretw call
Kevin O'Connor2d977562013-09-29 20:21:40 -0400189 movl %edx, %ds
Kevin O'Connor273e8ae2009-01-19 19:56:07 -0500190 pushw %cs
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400191 pushw $1f // return point
Kevin O'Connor2d977562013-09-29 20:21:40 -0400192 pushw BREGS_flags(%eax) // flags
193 pushl BREGS_code(%eax) // CS:IP
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500194
195 // Load calling registers.
Kevin O'Connor2d977562013-09-29 20:21:40 -0400196 movl BREGS_edi(%eax), %edi
197 movl BREGS_esi(%eax), %esi
198 movl BREGS_ebp(%eax), %ebp
199 movl BREGS_ebx(%eax), %ebx
200 movl BREGS_edx(%eax), %edx
201 movl BREGS_ecx(%eax), %ecx
202 movw BREGS_es(%eax), %es
203 pushl BREGS_eax(%eax)
204 movw BREGS_ds(%eax), %ds
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400205 popl %eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500206
207 // Invoke call
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400208 iretw // XXX - just do a lcalll
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -05002091:
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400210 // Store flags, es, eax
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500211 pushfw
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400212 cli
213 cld
Kevin O'Connor2d977562013-09-29 20:21:40 -0400214 pushw %ds
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500215 pushl %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400216 movw 0x08(%esp), %ds
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400217 movl 0x0c(%esp), %eax
Kevin O'Connor2d977562013-09-29 20:21:40 -0400218 popl BREGS_eax(%eax)
219 popw BREGS_es(%eax)
220 popw BREGS_flags(%eax)
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500221
222 // Store remaining registers
Kevin O'Connor2d977562013-09-29 20:21:40 -0400223 movl %edi, BREGS_edi(%eax)
224 movl %esi, BREGS_esi(%eax)
225 movl %ebp, BREGS_ebp(%eax)
226 movl %ebx, BREGS_ebx(%eax)
227 movl %edx, BREGS_edx(%eax)
228 movl %ecx, BREGS_ecx(%eax)
229 movw %es, BREGS_ds(%eax)
Kevin O'Connorbeeabd62012-05-28 13:59:07 -0400230 movw %ss, %cx
231 movw %cx, %ds // Restore %ds == %ss
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500232
Kevin O'Connor2d977562013-09-29 20:21:40 -0400233 // Remove %edx/%eax, restore %ebp
234 popl %edx
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500235 popl %eax
Kevin O'Connor9caf7862009-02-27 20:14:05 -0500236 popl %ebp
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500237
238 retl
239
Kevin O'Connor79dde652009-04-13 19:26:43 -0400240// IRQ trampolines
241 .macro IRQ_TRAMPOLINE num
242 DECLFUNC irq_trampoline_0x\num
243 irq_trampoline_0x\num :
244 int $0x\num
245 lretw
246 .endm
247
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400248 IRQ_TRAMPOLINE 02
Kevin O'Connor79dde652009-04-13 19:26:43 -0400249 IRQ_TRAMPOLINE 10
250 IRQ_TRAMPOLINE 13
251 IRQ_TRAMPOLINE 15
252 IRQ_TRAMPOLINE 16
253 IRQ_TRAMPOLINE 18
254 IRQ_TRAMPOLINE 19
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400255 IRQ_TRAMPOLINE 1c
256 IRQ_TRAMPOLINE 4a
Kevin O'Connor79dde652009-04-13 19:26:43 -0400257
258
259/****************************************************************
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400260 * Misc. entry points.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400261 ****************************************************************/
262
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400263// Resume (and reboot) entry point - called from entry_post
264 DECLFUNC entry_resume
265entry_resume:
Kevin O'Connor79dde652009-04-13 19:26:43 -0400266 // Disable interrupts
267 cli
268 cld
Kevin O'Connor46b82622012-05-13 12:10:30 -0400269 // Use the ExtraStack in low mem.
Kevin O'Connorc9243442013-02-17 13:58:28 -0500270 movl $_zonelow_seg, %eax
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400271 movw %ax, %ds
Kevin O'Connor79dde652009-04-13 19:26:43 -0400272 movw %ax, %ss
Kevin O'Connor46b82622012-05-13 12:10:30 -0400273 movl $ExtraStack + BUILD_EXTRA_STACK_SIZE, %esp
Kevin O'Connor79dde652009-04-13 19:26:43 -0400274 // Call handler.
Kevin O'Connor79dde652009-04-13 19:26:43 -0400275 jmp handle_resume
276
Kevin O'Connore54ee382009-07-26 19:33:13 -0400277// PMM entry point
278 DECLFUNC entry_pmm
279entry_pmm:
280 pushl %esp // Backup %esp, then clear high bits
281 movzwl %sp, %esp
282 pushfl // Save registers clobbered by C code
283 cli
284 cld
285 pushl %eax
286 pushl %ecx
287 pushl %edx
288 pushw %es
289 pushw %ds
290 movw %ss, %cx // Move %ss to %ds
291 movw %cx, %ds
Kevin O'Connor533b6282011-07-16 13:13:12 -0400292 movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
293 leal 28(%esp), %edx // %edx points to start of args
294 movl $-1, %ecx
295 calll call32
Kevin O'Connore54ee382009-07-26 19:33:13 -0400296 movw %ax, 12(%esp) // Modify %ax:%dx to return %eax
297 shrl $16, %eax
298 movw %ax, 4(%esp)
299 popw %ds // Restore saved registers
300 popw %es
301 popl %edx
302 popl %ecx
303 popl %eax
304 popfl
305 popl %esp
306 lretw
307
Kevin O'Connor79dde652009-04-13 19:26:43 -0400308// PnP entry points
Kevin O'Connord67a7032009-01-17 19:37:26 -0500309 DECLFUNC entry_pnp_real
310 .global entry_pnp_prot
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500311entry_pnp_prot:
312 pushl %esp
313 jmp 1f
314entry_pnp_real:
315 pushl %esp // Backup %esp, then clear high bits
316 movzwl %sp, %esp
3171:
318 pushfl // Save registers clobbered by C code
Kevin O'Connore54ee382009-07-26 19:33:13 -0400319 cli
320 cld
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500321 pushl %eax
322 pushl %ecx
323 pushl %edx
324 pushw %es
325 pushw %ds
326 movw %ss, %cx // Move %ss to %ds
327 movw %cx, %ds
Kevin O'Connor752151b2009-12-10 21:16:07 -0500328 leal 28(%esp), %eax // %eax points to start of u16 args
Kevin O'Connor0c3068d2008-12-21 17:51:36 -0500329 calll handle_pnp
330 movw %ax, 12(%esp) // Modify %eax to return %ax
331 popw %ds
332 popw %es
333 popl %edx
334 popl %ecx
335 popl %eax
336 popfl
337 popl %esp
338 lretw
339
Kevin O'Connor79dde652009-04-13 19:26:43 -0400340// APM entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400341 DECLFUNC entry_apm16
342entry_apm16:
Kevin O'Connor1d019512008-03-11 21:21:47 -0400343 pushfw // save flags
344 pushl %eax // dummy
Kevin O'Connord3e43672012-05-28 11:37:53 -0400345 ENTRY_ARG handle_apm
Kevin O'Connorb3c28be2008-06-08 13:34:43 -0400346 addw $4, %sp // pop dummy
Kevin O'Connor1d019512008-03-11 21:21:47 -0400347 popfw // restore flags
348 lretw
349
350 .code32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400351 DECLFUNC entry_apm32
352entry_apm32:
Kevin O'Connorc0031482010-01-01 13:03:17 -0500353 pushfl
354 pushl %gs
355 pushl %cs // Move second descriptor after %cs to %gs
356 addl $16, (%esp)
357 popl %gs
Kevin O'Connord3e43672012-05-28 11:37:53 -0400358 ENTRY_ARG_ESP _cfunc32seg_handle_apm
Kevin O'Connorc0031482010-01-01 13:03:17 -0500359 popl %gs
360 popfl
Kevin O'Connor1d019512008-03-11 21:21:47 -0400361 lretl
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400362
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500363// PCI-BIOS entry points
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400364 DECLFUNC entry_pcibios32
365entry_pcibios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500366 pushfl
Kevin O'Connorc0031482010-01-01 13:03:17 -0500367 pushl %gs // Backup %gs and set %gs=%ds
368 pushl %ds
369 popl %gs
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500370 ENTRY_ARG_ESP _cfunc32seg_handle_pcibios
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500371 popl %gs
372 popfl
373 lretl
374
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500375 .code16gcc
376 DECLFUNC entry_pcibios16
377entry_pcibios16:
378 ENTRY_ARG handle_pcibios
379 iretw
380
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500381// BIOS32 support
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500382 .code32
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500383 DECLFUNC entry_bios32
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400384entry_bios32:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500385 pushfl
386#if CONFIG_PCIBIOS
387 // Check for PCI-BIOS request
388 cmpl $0x49435024, %eax // $PCI
389 jne 1f
390 movl $BUILD_BIOS_ADDR, %ebx
391 movl $BUILD_BIOS_SIZE, %ecx
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400392 movl $entry_pcibios32, %edx
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500393 xorb %al, %al
394 jmp 2f
395#endif
396 // Unknown request
3971: movb $0x80, %al
398 // Return to caller
3992: popfl
400 lretl
401
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400402// 32bit elf entry point
Kevin O'Connor47c8e312011-07-10 22:57:32 -0400403 EXPORTFUNC entry_elf
404entry_elf:
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400405 cli
406 cld
407 lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
408 lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
Kevin O'Connore0504b02009-04-13 19:32:51 -0400409 movl $SEG32_MODE32_DS, %eax
410 movw %ax, %ds
411 movw %ax, %es
412 movw %ax, %fs
413 movw %ax, %gs
414 movw %ax, %ss
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400415 movl $BUILD_STACK_ADDR, %esp
Kevin O'Connorb1885fc2013-02-08 21:00:46 -0500416 ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
Kevin O'Connoree4f9ff2008-07-05 21:19:10 -0400417
Kevin O'Connor1d019512008-03-11 21:21:47 -0400418 .code16gcc
Kevin O'Connor1d019512008-03-11 21:21:47 -0400419
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500420// UEFI Compatibility Support Module (CSM) entry point
David Woodhouse118469a2013-01-25 19:46:25 -0600421 EXPORTFUNC entry_csm
422entry_csm:
423 // Backup register state
424 pushfw
425 cli
426 cld
427 pushl %eax // dummy
428 PUSHBREGS
429
430 // Backup stack location and convert to a "flat pointer"
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000431 movl %ss, %eax
432 movw %ax, BREGS_code+2(%esp) // Store %ss in bregs->code.seg
433 shll $4, %eax
434 addl %esp, %eax
David Woodhouse118469a2013-01-25 19:46:25 -0600435
436 // Change to BUILD_STACK_ADDR stack
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000437 xorl %ebx, %ebx
438 movw %bx, %ss
David Woodhouse118469a2013-01-25 19:46:25 -0600439 movl $BUILD_STACK_ADDR, %esp
440
441 // Jump to 32bit mode and call handle_csm(bregs)
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000442 movl $_cfunc32flat_handle_csm, %edx
David Woodhouse118469a2013-01-25 19:46:25 -0600443 jmp transition32
David Woodhouse118469a2013-01-25 19:46:25 -0600444
Kevin O'Connor3e86d6b2013-02-18 21:50:57 -0500445 DECLFUNC __csm_return
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500446 .code32
David Woodhouse4b1d2be2013-02-10 00:51:56 +0000447__csm_return:
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500448 movl $1f, %edx
David Woodhouse118469a2013-01-25 19:46:25 -0600449 jmp transition16big
450 .code16gcc
451
452 // Switch back to original stack
Kevin O'Connorbbd04582013-02-18 21:57:26 -05004531: movzwl BREGS_code+2(%eax), %edx
454 movl %edx, %ecx
David Woodhouse118469a2013-01-25 19:46:25 -0600455 shll $4, %ecx
Kevin O'Connorbbd04582013-02-18 21:57:26 -0500456 subl %ecx, %eax
457 movl %edx, %ss
458 movl %eax, %esp
David Woodhouse118469a2013-01-25 19:46:25 -0600459
460 // Restore register state and return.
461 POPBREGS
462 addw $4, %sp // pop dummy
463 popfw
464 lretw
465
Kevin O'Connor38fcbfe2008-02-25 22:30:47 -0500466
467/****************************************************************
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500468 * Interrupt entry points
469 ****************************************************************/
470
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400471 // Main entry point for interrupts handled on extra stack
472 DECLFUNC irqentry_extrastack
473irqentry_extrastack:
474 cli
475 cld
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400476 pushw %ds // Set %ds:%eax to space on ExtraStack
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400477 pushl %eax
Kevin O'Connorc9243442013-02-17 13:58:28 -0500478 movl $_zonelow_seg, %eax
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400479 movl %eax, %ds
480 movl StackPos, %eax
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400481 subl $24, %eax
482 popl 0(%eax) // Backup %eax, %ds, %es, %ecx, %edx
483 popw 4(%eax)
484 movw %es, 6(%eax)
485 movl %ecx, 8(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400486 popl %ecx
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400487 movl %edx, 12(%eax)
488 movl %esp, 16(%eax)
489 movzwl %sp, %esp
490 movw %ss, 20(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400491
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400492 movw %ds, %dx // Setup %ss/%esp and call function
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400493 movw %dx, %ss
494 movl %eax, %esp
495 calll *%ecx
496
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400497 movl %esp, %eax // Restore registers and return
498 movw 20(%eax), %ss
499 movl 16(%eax), %esp
500 movl 12(%eax), %edx
501 movl 8(%eax), %ecx
502 movw 6(%eax), %es
503 pushw 4(%eax)
504 pushl 0(%eax)
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400505 popl %eax
506 popw %ds
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400507 iretw
508
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500509 // Main entry point for interrupts handled on extra stack
510 DECLFUNC irqentry_arg_extrastack
511irqentry_arg_extrastack:
512 cli
513 cld
514 pushw %ds // Set %ds:%eax to space on ExtraStack
515 pushl %eax
516 movl $_zonelow_seg, %eax
517 movl %eax, %ds
518 movl StackPos, %eax
519 subl $BREGS_size+8, %eax
520 popl BREGS_eax(%eax) // Backup registers
521 popw BREGS_ds(%eax)
522 movl %edi, BREGS_edi(%eax)
523 movl %esi, BREGS_esi(%eax)
524 movl %ebp, BREGS_ebp(%eax)
525 movl %ebx, BREGS_ebx(%eax)
526 movl %edx, BREGS_edx(%eax)
527 movl %ecx, BREGS_ecx(%eax)
528 popl %ecx
529 movw %es, BREGS_es(%eax)
530 movl %esp, BREGS_size+0(%eax)
531 movzwl %sp, %esp
532 movw %ss, BREGS_size+4(%eax)
533 movl (%esp), %edx
534 movl %edx, BREGS_code(%eax)
535 movw 4(%esp), %dx
536 movw %dx, BREGS_flags(%eax)
537
538 movw %ds, %dx // Setup %ss/%esp and call function
539 movw %dx, %ss
540 movl %eax, %esp
541 calll *%ecx
542
543 movl %esp, %eax // Restore registers and return
544 movw BREGS_size+4(%eax), %ss
545 movl BREGS_size+0(%eax), %esp
546 popl %edx
547 popw %dx
548 pushw BREGS_flags(%eax)
549 pushl BREGS_code(%eax)
550 movl BREGS_edi(%eax), %edi
551 movl BREGS_esi(%eax), %esi
552 movl BREGS_ebp(%eax), %ebp
553 movl BREGS_ebx(%eax), %ebx
554 movl BREGS_edx(%eax), %edx
555 movl BREGS_ecx(%eax), %ecx
556 movw BREGS_es(%eax), %es
557 pushw BREGS_ds(%eax)
558 pushl BREGS_eax(%eax)
559 popl %eax
560 popw %ds
561 iretw
562
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400563 // Main entry point for interrupts with args
Kevin O'Connoreaec3c22009-05-30 03:40:22 -0400564 DECLFUNC irqentryarg
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400565irqentryarg:
566 ENTRY_ARG_ST
567 iretw
568
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400569 // Define an entry point for hardware interrupts.
Kevin O'Connor812478e2011-01-22 10:53:48 -0500570 .macro IRQ_ENTRY num
571 .global entry_\num
572 entry_\num :
573 pushl $ handle_\num
Kevin O'Connorecdc6552012-05-28 14:25:15 -0400574 jmp irqentry_extrastack
Kevin O'Connor812478e2011-01-22 10:53:48 -0500575 .endm
576
577 .macro DECL_IRQ_ENTRY num
578 DECLFUNC entry_\num
579 IRQ_ENTRY \num
580 .endm
581
582 // Define an entry point for an interrupt (can read/modify args).
583 .macro IRQ_ENTRY_ARG num
584 .global entry_\num
585 entry_\num :
586 pushl $ handle_\num
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500587#if CONFIG_ENTRY_EXTRASTACK
588 jmp irqentry_arg_extrastack
589#else
Kevin O'Connor812478e2011-01-22 10:53:48 -0500590 jmp irqentryarg
Kevin O'Connorf0d75a02013-03-02 18:14:35 -0500591#endif
Kevin O'Connor812478e2011-01-22 10:53:48 -0500592 .endm
593
594 .macro DECL_IRQ_ENTRY_ARG num
595 DECLFUNC entry_\num
596 IRQ_ENTRY_ARG \num
597 .endm
598
599 // Various entry points (that don't require a fixed location).
Kevin O'Connord67a7032009-01-17 19:37:26 -0500600 DECL_IRQ_ENTRY_ARG 13
Kevin O'Connord67a7032009-01-17 19:37:26 -0500601 DECL_IRQ_ENTRY 76
Kevin O'Connord67a7032009-01-17 19:37:26 -0500602 DECL_IRQ_ENTRY 70
603 DECL_IRQ_ENTRY 74
604 DECL_IRQ_ENTRY 75
605 DECL_IRQ_ENTRY hwpic1
606 DECL_IRQ_ENTRY hwpic2
607
Kevin O'Connor4ebc0b72009-03-01 12:31:57 -0500608 // int 18/19 are special - they reset stack and call into 32bit mode.
Kevin O'Connord67a7032009-01-17 19:37:26 -0500609 DECLFUNC entry_19
610entry_19:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500611 ENTRY_INTO32 _cfunc32flat_handle_19
Kevin O'Connord67a7032009-01-17 19:37:26 -0500612
613 DECLFUNC entry_18
614entry_18:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500615 ENTRY_INTO32 _cfunc32flat_handle_18
Kevin O'Connord67a7032009-01-17 19:37:26 -0500616
617
618/****************************************************************
619 * Fixed position entry points
620 ****************************************************************/
621
622 // Specify a location in the fixed part of bios area.
623 .macro ORG addr
624 .section .fixedaddr.\addr
625 .endm
626
627 ORG 0xe05b
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400628entry_post:
629 cmpl $0, %cs:HaveRunPost // Check for resume/reboot
630 jnz entry_resume
631 ENTRY_INTO32 _cfunc32flat_handle_post // Normal entry point
Kevin O'Connord67a7032009-01-17 19:37:26 -0500632
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500633 ORG 0xe2c3
Kevin O'Connor75f49b32009-03-07 00:07:24 -0500634 IRQ_ENTRY 02
Kevin O'Connorc5b50362008-12-18 21:56:41 -0500635
Kevin O'Connor74534532008-05-12 18:28:58 -0400636 ORG 0xe3fe
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500637 .global entry_13_official
638entry_13_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500639 jmp entry_13
640
Kevin O'Connor30853762009-01-17 18:49:20 -0500641 // 0xe401 - OldFDPT in disk.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500642
Kevin O'Connor74534532008-05-12 18:28:58 -0400643 ORG 0xe6f2
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500644 .global entry_19_official
645entry_19_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500646 jmp entry_19
647
Kevin O'Connor30853762009-01-17 18:49:20 -0500648 // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500649
Kevin O'Connor30853762009-01-17 18:49:20 -0500650 // 0xe729 - BaudTable in serial.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500651
Kevin O'Connor74534532008-05-12 18:28:58 -0400652 ORG 0xe739
Kevin O'Connored128492008-03-11 11:14:59 -0400653 IRQ_ENTRY_ARG 14
654
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500655 ORG 0xe82e
656 IRQ_ENTRY_ARG 16
657
658 ORG 0xe987
659 IRQ_ENTRY 09
660
661 ORG 0xec59
662 IRQ_ENTRY_ARG 40
663
664 ORG 0xef57
665 IRQ_ENTRY 0e
666
Kevin O'Connor30853762009-01-17 18:49:20 -0500667 // 0xefc7 - diskette_param_table in floppy.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500668
669 ORG 0xefd2
670 IRQ_ENTRY_ARG 17
671
672 ORG 0xf045
Kevin O'Connord67a7032009-01-17 19:37:26 -0500673entry_10_0x0f:
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500674 // XXX - INT 10 Functions 0-Fh Entry Point
675 iretw
676
677 ORG 0xf065
678 IRQ_ENTRY_ARG 10
679
Kevin O'Connor30853762009-01-17 18:49:20 -0500680 // 0xf0a4 - VideoParams in misc.c
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500681
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500682 ORG 0xf841
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400683 IRQ_ENTRY_ARG 12
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500684
685 ORG 0xf84d
Kevin O'Connor9f193b92009-05-16 23:31:27 -0400686 IRQ_ENTRY_ARG 11
Kevin O'Connorb4f0e892008-12-13 18:33:05 -0500687
688 ORG 0xf859
689 IRQ_ENTRY_ARG 15
690
Kevin O'Connor30853762009-01-17 18:49:20 -0500691 // 0xfa6e - vgafont8 in font.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500692
Kevin O'Connor74534532008-05-12 18:28:58 -0400693 ORG 0xfe6e
Kevin O'Connor922aa1b2013-03-02 04:02:11 -0500694 .global entry_1a_official
695entry_1a_official:
696 cmpb $0xb1, %ah
697 je entry_pcibios16 // PCIBIOS calls can be in protected mode
Kevin O'Connored128492008-03-11 11:14:59 -0400698 IRQ_ENTRY_ARG 1a
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500699
Kevin O'Connor74534532008-05-12 18:28:58 -0400700 ORG 0xfea5
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500701 IRQ_ENTRY 08
702
Kevin O'Connor30853762009-01-17 18:49:20 -0500703 // 0xfef3 - InitVectors in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500704
Kevin O'Connor30853762009-01-17 18:49:20 -0500705 // 0xff00 - BiosCopyright in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500706
Kevin O'Connor74534532008-05-12 18:28:58 -0400707 ORG 0xff53
Kevin O'Connord67a7032009-01-17 19:37:26 -0500708 .global entry_iret_official
709entry_iret_official:
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500710 iretw
711
Kevin O'Connor74534532008-05-12 18:28:58 -0400712 ORG 0xff54
Kevin O'Connored128492008-03-11 11:14:59 -0400713 IRQ_ENTRY_ARG 05
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500714
Kevin O'Connor74534532008-05-12 18:28:58 -0400715 ORG 0xfff0 // Power-up Entry Point
Kevin O'Connor3f168b62008-11-29 13:22:29 -0500716 .global reset_vector
717reset_vector:
Kevin O'Connor87b533b2011-07-10 22:35:07 -0400718 ljmpw $SEG_BIOS, $entry_post
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500719
Kevin O'Connor30853762009-01-17 18:49:20 -0500720 // 0xfff5 - BiosDate in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500721
Kevin O'Connor30853762009-01-17 18:49:20 -0500722 // 0xfffe - BiosModelId in misc.c
Kevin O'Connore3677b12008-07-04 15:29:23 -0400723
Kevin O'Connor30853762009-01-17 18:49:20 -0500724 // 0xffff - BiosChecksum in misc.c
Kevin O'Connorf076a3e2008-02-25 22:25:15 -0500725
726 .end