kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / i386 / i386 / mpboot.s
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1995, Jack F. Vogel
3 * All rights reserved.
4 *
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.
18 *
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.
30 *
31 * mpboot.s: FreeBSD machine support for the Intel MP Spec
32 * multiprocessor systems.
33 *
34 * $FreeBSD: src/sys/i386/i386/mpboot.s,v 1.13.2.3 2000/09/07 01:18:26 tegge Exp $
d9eea1a5 35 * $DragonFly: src/sys/i386/i386/Attic/mpboot.s,v 1.5 2003/07/11 17:42:08 dillon Exp $
984263bc
MD
36 */
37
38#include <machine/asmacros.h> /* miscellaneous asm macros */
39#include <machine/apic.h>
40#include <machine/specialreg.h>
41
42#include "assym.s"
43
44/*
45 * this code MUST be enabled here and in mp_machdep.c
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.
48 *
984263bc
MD
49 */
50
8a8d5d85 51#define CHECK_POINTS
984263bc
MD
52#if defined(CHECK_POINTS) && !defined(PC98)
53
54#define CMOS_REG (0x70)
55#define CMOS_DATA (0x71)
56
57#define CHECKPOINT(A,D) \
8a8d5d85 58 movb $A,%al ; \
984263bc 59 outb %al,$CMOS_REG ; \
8a8d5d85 60 movb D,%al ; \
984263bc
MD
61 outb %al,$CMOS_DATA
62
63#else
64
65#define CHECKPOINT(A,D)
66
67#endif /* CHECK_POINTS */
68
69
70/*
8a8d5d85
MD
71 * The APs enter here from their trampoline code (bootMP, below)
72 * NOTE: %fs is not setup until the call to init_secondary()!
984263bc
MD
73 */
74 .p2align 4
75
76NON_GPROF_ENTRY(MPentry)
8a8d5d85 77 CHECKPOINT(0x36, $3)
984263bc 78 /* Now enable paging mode */
2954c92f 79 movl IdlePTD-KERNBASE, %eax
984263bc
MD
80 movl %eax,%cr3
81 movl %cr0,%eax
82 orl $CR0_PE|CR0_PG,%eax /* enable paging */
83 movl %eax,%cr0 /* let the games begin! */
984263bc 84
8a8d5d85 85 movl bootSTK,%esp /* boot stack end loc. */
984263bc 86 pushl $mp_begin /* jump to high mem */
8a8d5d85 87 NON_GPROF_RET
984263bc
MD
88
89 /*
90 * Wait for the booting CPU to signal startup
91 */
92mp_begin: /* now running relocated at KERNBASE */
8a8d5d85 93 CHECKPOINT(0x37, $4)
2954c92f 94 call init_secondary /* load i386 tables */
8a8d5d85 95 CHECKPOINT(0x38, $5)
984263bc
MD
96
97 /*
98 * If the [BSP] CPU has support for VME, turn it on.
99 */
2954c92f 100 testl $CPUID_VME, cpu_feature /* XXX WRONG! BSP! */
984263bc
MD
101 jz 1f
102 movl %cr4, %eax
103 orl $CR4_VME, %eax
104 movl %eax, %cr4
1051:
106
107 /* disable the APIC, just to be SURE */
108 movl lapic_svr, %eax /* get spurious vector reg. */
109 andl $~APIC_SVR_SWEN, %eax /* clear software enable bit */
110 movl %eax, lapic_svr
111
8a8d5d85 112 /* data returned to BSP */
984263bc 113 movl lapic_ver, %eax /* our version reg contents */
2954c92f 114 movl %eax, cpu_apic_versions /* into [ 0 ] */
8a8d5d85
MD
115
116 CHECKPOINT(0x39, $6)
117
118 /*
119 * Execute the context restore function for the idlethread which
120 * has conveniently been set as curthread. Remember, %eax must
d9eea1a5
MD
121 * contain the target thread and %ebx must contain the originating
122 * thread (which we just set the same since we have no originating
123 * thread). BSP/AP synchronization occurs in ap_init(). We do
124 * not need to mess with the BGL for this because LWKT threads are
125 * self-contained on each cpu (or, at least, the idlethread is!).
8a8d5d85
MD
126 */
127 movl PCPU(curthread),%eax
d9eea1a5 128 movl %eax,%ebx
8a8d5d85 129 movl TD_SP(%eax),%esp
984263bc 130 ret
984263bc
MD
131
132/*
133 * This is the embedded trampoline or bootstrap that is
134 * copied into 'real-mode' low memory, it is where the
135 * secondary processor "wakes up". When it is executed
136 * the processor will eventually jump into the routine
137 * MPentry, which resides in normal kernel text above
138 * 1Meg. -jackv
139 */
140
141 .data
142 ALIGN_DATA /* just to be sure */
143
144BOOTMP1:
145
146NON_GPROF_ENTRY(bootMP)
147 .code16
148 cli
8a8d5d85 149 CHECKPOINT(0x34, $1)
984263bc
MD
150 /* First guarantee a 'clean slate' */
151 xorl %eax, %eax
152 movl %eax, %ebx
153 movl %eax, %ecx
154 movl %eax, %edx
155 movl %eax, %esi
156 movl %eax, %edi
157
158 /* set up data segments */
159 mov %cs, %ax
160 mov %ax, %ds
161 mov %ax, %es
162 mov %ax, %fs
163 mov %ax, %gs
164 mov %ax, %ss
2954c92f 165 mov $(boot_stk - bootMP), %esp
984263bc
MD
166
167 /* Now load the global descriptor table */
2954c92f 168 lgdt MP_GDTptr - bootMP
984263bc
MD
169
170 /* Enable protected mode */
171 movl %cr0, %eax
172 orl $CR0_PE, %eax
173 movl %eax, %cr0
174
175 /*
176 * make intrasegment jump to flush the processor pipeline and
177 * reload CS register
178 */
179 pushl $0x18
2954c92f 180 pushl $(protmode - bootMP)
984263bc
MD
181 lretl
182
183 .code32
184protmode:
8a8d5d85 185 CHECKPOINT(0x35, $2)
984263bc
MD
186
187 /*
188 * we are NOW running for the first time with %eip
189 * having the full physical address, BUT we still
190 * are using a segment descriptor with the origin
191 * not matching the booting kernel.
192 *
193 * SO NOW... for the BIG Jump into kernel's segment
194 * and physical text above 1 Meg.
195 */
196 mov $0x10, %ebx
197 movw %bx, %ds
198 movw %bx, %es
199 movw %bx, %fs
200 movw %bx, %gs
201 movw %bx, %ss
202
2954c92f
MD
203 .globl bigJump
204bigJump:
984263bc
MD
205 /* this will be modified by mpInstallTramp() */
206 ljmp $0x08, $0 /* far jmp to MPentry() */
207
208dead: hlt /* We should never get here */
209 jmp dead
210
211/*
212 * MP boot strap Global Descriptor Table
213 */
214 .p2align 4
2954c92f
MD
215 .globl MP_GDT
216 .globl bootCodeSeg
217 .globl bootDataSeg
218MP_GDT:
984263bc
MD
219
220nulldesc: /* offset = 0x0 */
221
222 .word 0x0
223 .word 0x0
224 .byte 0x0
225 .byte 0x0
226 .byte 0x0
227 .byte 0x0
228
229kernelcode: /* offset = 0x08 */
230
231 .word 0xffff /* segment limit 0..15 */
232 .word 0x0000 /* segment base 0..15 */
233 .byte 0x0 /* segment base 16..23; set for 0K */
234 .byte 0x9f /* flags; Type */
235 .byte 0xcf /* flags; Limit */
236 .byte 0x0 /* segment base 24..32 */
237
238kerneldata: /* offset = 0x10 */
239
240 .word 0xffff /* segment limit 0..15 */
241 .word 0x0000 /* segment base 0..15 */
242 .byte 0x0 /* segment base 16..23; set for 0k */
243 .byte 0x93 /* flags; Type */
244 .byte 0xcf /* flags; Limit */
245 .byte 0x0 /* segment base 24..32 */
246
247bootcode: /* offset = 0x18 */
248
249 .word 0xffff /* segment limit 0..15 */
2954c92f 250bootCodeSeg: /* this will be modified by mpInstallTramp() */
984263bc
MD
251 .word 0x0000 /* segment base 0..15 */
252 .byte 0x00 /* segment base 16...23; set for 0x000xx000 */
253 .byte 0x9e /* flags; Type */
254 .byte 0xcf /* flags; Limit */
255 .byte 0x0 /*segment base 24..32 */
256
257bootdata: /* offset = 0x20 */
258
259 .word 0xffff
2954c92f 260bootDataSeg: /* this will be modified by mpInstallTramp() */
984263bc
MD
261 .word 0x0000 /* segment base 0..15 */
262 .byte 0x00 /* segment base 16...23; set for 0x000xx000 */
263 .byte 0x92
264 .byte 0xcf
265 .byte 0x0
266
267/*
268 * GDT pointer for the lgdt call
269 */
2954c92f 270 .globl mp_gdtbase
984263bc
MD
271
272MP_GDTptr:
2954c92f 273mp_gdtlimit:
984263bc 274 .word 0x0028
2954c92f 275mp_gdtbase: /* this will be modified by mpInstallTramp() */
984263bc
MD
276 .long 0
277
278 .space 0x100 /* space for boot_stk - 1st temporary stack */
279boot_stk:
280
281BOOTMP2:
2954c92f
MD
282 .globl bootMP_size
283bootMP_size:
984263bc 284 .long BOOTMP2 - BOOTMP1
2954c92f 285