kernel: Move GPL'd kernel files to sys/gnu to have them all in one place.
[dragonfly.git] / sys / platform / pc32 / i386 / mpboot.s
blob0cfab2df21cba8a86fc44b60e35bc14ba104563c
1 /*
2 * Copyright (c) 1995, Jack F. Vogel
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Jack F. Vogel
16 * 4. The name of the developer may be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * mpboot.s: FreeBSD machine support for the Intel MP Spec
32 * multiprocessor systems.
34 * $FreeBSD: src/sys/i386/i386/mpboot.s,v 1.13.2.3 2000/09/07 01:18:26 tegge Exp $
35 * $DragonFly: src/sys/platform/pc32/i386/mpboot.s,v 1.11 2006/11/07 06:43:24 dillon Exp $
38 #include <machine/asmacros.h> /* miscellaneous asm macros */
39 #include <machine_base/apic/apicreg.h>
40 #include <machine/specialreg.h>
42 #include "assym.s"
45 * this code MUST be enabled here and in mp_machdep.c for debugging.
46 * it follows the very early stages of AP boot by placing values in CMOS ram.
47 * it NORMALLY will never be needed and thus the primitive method for enabling.
49 * WARNING! DEFINING THIS OPTION MAY CAUSE THE CMOS CHECKSUM TO FAIL AND THE
50 * BIOS MIGHT COMPLAIN. ENABLE THIS OPTION FOR DEBUGGING THE BOOT PATH ONLY.
52 #define CHECK_POINTS
55 #if defined(CHECK_POINTS)
57 #define CMOS_REG (0x70)
58 #define CMOS_DATA (0x71)
60 #define CHECKPOINT(A,D) \
61 movb $A,%al ; \
62 outb %al,$CMOS_REG ; \
63 movb D,%al ; \
64 outb %al,$CMOS_DATA
66 #else
68 #define CHECKPOINT(A,D)
70 #endif /* CHECK_POINTS */
74 * The APs enter here from their trampoline code (bootMP, below)
75 * NOTE: %fs is not setup until the call to init_secondary()!
77 .p2align 4
79 NON_GPROF_ENTRY(MPentry)
80 CHECKPOINT(0x36, $3)
81 /* Now enable paging mode */
82 movl IdlePTD-KERNBASE, %eax
83 movl %eax,%cr3
84 movl %cr0,%eax
85 orl $CR0_PE|CR0_PG,%eax /* enable paging */
86 movl %eax,%cr0 /* let the games begin! */
88 movl bootSTK,%esp /* boot stack end loc. */
89 pushl $mp_begin /* jump to high mem */
90 NON_GPROF_RET
93 * Wait for the booting CPU to signal startup
95 mp_begin: /* now running relocated at KERNBASE */
96 CHECKPOINT(0x37, $4)
97 call init_secondary /* load i386 tables */
98 CHECKPOINT(0x38, $5)
101 * If the [BSP] CPU has support for VME, turn it on.
103 testl $CPUID_VME, cpu_feature /* XXX WRONG! BSP! */
104 jz 1f
105 movl %cr4, %eax
106 orl $CR4_VME, %eax
107 movl %eax, %cr4
110 CHECKPOINT(0x39, $6)
113 * Execute the context restore function for the idlethread which
114 * has conveniently been set as curthread. Remember, %eax must
115 * contain the target thread and %ebx must contain the originating
116 * thread (which we just set the same since we have no originating
117 * thread). BSP/AP synchronization occurs in ap_init(). We do
118 * not need to mess with the BGL for this because LWKT threads are
119 * self-contained on each cpu (or, at least, the idlethread is!).
121 movl PCPU(curthread),%eax
122 movl %eax,%ebx
123 movl TD_SP(%eax),%esp
127 * This is the embedded trampoline or bootstrap that is
128 * copied into 'real-mode' low memory, it is where the
129 * secondary processor "wakes up". When it is executed
130 * the processor will eventually jump into the routine
131 * MPentry, which resides in normal kernel text above
132 * 1Meg. -jackv
135 .data
136 ALIGN_DATA /* just to be sure */
138 BOOTMP1:
140 NON_GPROF_ENTRY(bootMP)
141 .code16
143 CHECKPOINT(0x34, $1)
144 /* First guarantee a 'clean slate' */
145 xorl %eax, %eax
146 movl %eax, %ebx
147 movl %eax, %ecx
148 movl %eax, %edx
149 movl %eax, %esi
150 movl %eax, %edi
152 /* set up data segments */
153 mov %cs, %ax
154 mov %ax, %ds
155 mov %ax, %es
156 mov %ax, %fs
157 mov %ax, %gs
158 mov %ax, %ss
159 mov $(boot_stk - bootMP), %esp
161 /* Now load the global descriptor table */
162 lgdt MP_GDTptr - bootMP
164 /* Enable protected mode */
165 movl %cr0, %eax
166 orl $CR0_PE, %eax
167 movl %eax, %cr0
170 * make intrasegment jump to flush the processor pipeline and
171 * reload CS register
173 pushl $0x18
174 pushl $(protmode - bootMP)
175 lretl
177 .code32
178 protmode:
179 CHECKPOINT(0x35, $2)
182 * we are NOW running for the first time with %eip
183 * having the full physical address, BUT we still
184 * are using a segment descriptor with the origin
185 * not matching the booting kernel.
187 * SO NOW... for the BIG Jump into kernel's segment
188 * and physical text above 1 Meg.
190 mov $0x10, %ebx
191 movw %bx, %ds
192 movw %bx, %es
193 movw %bx, %fs
194 movw %bx, %gs
195 movw %bx, %ss
197 .globl bigJump
198 bigJump:
199 /* this will be modified by mpInstallTramp() */
200 ljmp $0x08, $0 /* far jmp to MPentry() */
202 dead: hlt /* We should never get here */
203 jmp dead
206 * MP boot strap Global Descriptor Table
208 .p2align 4
209 .globl MP_GDT
210 .globl bootCodeSeg
211 .globl bootDataSeg
212 MP_GDT:
214 nulldesc: /* offset = 0x0 */
216 .word 0x0
217 .word 0x0
218 .byte 0x0
219 .byte 0x0
220 .byte 0x0
221 .byte 0x0
223 kernelcode: /* offset = 0x08 */
225 .word 0xffff /* segment limit 0..15 */
226 .word 0x0000 /* segment base 0..15 */
227 .byte 0x0 /* segment base 16..23; set for 0K */
228 .byte 0x9f /* flags; Type */
229 .byte 0xcf /* flags; Limit */
230 .byte 0x0 /* segment base 24..32 */
232 kerneldata: /* offset = 0x10 */
234 .word 0xffff /* segment limit 0..15 */
235 .word 0x0000 /* segment base 0..15 */
236 .byte 0x0 /* segment base 16..23; set for 0k */
237 .byte 0x93 /* flags; Type */
238 .byte 0xcf /* flags; Limit */
239 .byte 0x0 /* segment base 24..32 */
241 bootcode: /* offset = 0x18 */
243 .word 0xffff /* segment limit 0..15 */
244 bootCodeSeg: /* this will be modified by mpInstallTramp() */
245 .word 0x0000 /* segment base 0..15 */
246 .byte 0x00 /* segment base 16...23; set for 0x000xx000 */
247 .byte 0x9e /* flags; Type */
248 .byte 0xcf /* flags; Limit */
249 .byte 0x0 /*segment base 24..32 */
251 bootdata: /* offset = 0x20 */
253 .word 0xffff
254 bootDataSeg: /* this will be modified by mpInstallTramp() */
255 .word 0x0000 /* segment base 0..15 */
256 .byte 0x00 /* segment base 16...23; set for 0x000xx000 */
257 .byte 0x92
258 .byte 0xcf
259 .byte 0x0
262 * GDT pointer for the lgdt call
264 .globl mp_gdtbase
266 MP_GDTptr:
267 mp_gdtlimit:
268 .word 0x0028
269 mp_gdtbase: /* this will be modified by mpInstallTramp() */
270 .long 0
272 .space 0x100 /* space for boot_stk - 1st temporary stack */
273 boot_stk:
275 BOOTMP2:
276 .globl bootMP_size
277 bootMP_size:
278 .long BOOTMP2 - BOOTMP1