i386 removal, part 11/x: Remove wrong machine/ setup in the boot Makefiles.
[dragonfly.git] / sys / platform / pc32 / i386 / mpboot.s
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 $
35  * $DragonFly: src/sys/platform/pc32/i386/mpboot.s,v 1.11 2006/11/07 06:43:24 dillon Exp $
36  */
37
38 #include <machine/asmacros.h>           /* miscellaneous asm macros */
39 #include <machine_base/apic/apicreg.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 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.
48  *
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.
51  *
52 #define CHECK_POINTS
53  */
54
55 #if defined(CHECK_POINTS)
56
57 #define CMOS_REG        (0x70)
58 #define CMOS_DATA       (0x71)
59
60 #define CHECKPOINT(A,D)         \
61         movb    $A,%al ;        \
62         outb    %al,$CMOS_REG ; \
63         movb    D,%al ;         \
64         outb    %al,$CMOS_DATA
65
66 #else
67
68 #define CHECKPOINT(A,D)
69
70 #endif /* CHECK_POINTS */
71
72
73 /*
74  * The APs enter here from their trampoline code (bootMP, below)
75  * NOTE: %fs is not setup until the call to init_secondary()!
76  */
77         .p2align 4
78
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! */
87
88         movl    bootSTK,%esp                    /* boot stack end loc. */
89         pushl   $mp_begin                       /* jump to high mem */
90         NON_GPROF_RET
91
92         /*
93          * Wait for the booting CPU to signal startup
94          */
95 mp_begin:       /* now running relocated at KERNBASE */
96         CHECKPOINT(0x37, $4)
97         call    init_secondary                  /* load i386 tables */
98         CHECKPOINT(0x38, $5)
99
100         /*
101          * If the [BSP] CPU has support for VME, turn it on.
102          */
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
108 1:
109
110         CHECKPOINT(0x39, $6)
111
112         /*
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!).
120          */
121         movl    PCPU(curthread),%eax
122         movl    %eax,%ebx
123         movl    TD_SP(%eax),%esp
124         ret
125
126 /*
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
133  */
134
135         .data
136         ALIGN_DATA                              /* just to be sure */
137
138 BOOTMP1:
139
140 NON_GPROF_ENTRY(bootMP)
141         .code16         
142         cli
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
151
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
160
161         /* Now load the global descriptor table */
162         lgdt    MP_GDTptr - bootMP
163
164         /* Enable protected mode */
165         movl    %cr0, %eax
166         orl     $CR0_PE, %eax
167         movl    %eax, %cr0 
168
169         /*
170          * make intrasegment jump to flush the processor pipeline and
171          * reload CS register
172          */
173         pushl   $0x18
174         pushl   $(protmode - bootMP)
175         lretl
176
177        .code32          
178 protmode:
179         CHECKPOINT(0x35, $2)
180
181         /*
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.
186          *
187          * SO NOW... for the BIG Jump into kernel's segment
188          * and physical text above 1 Meg.
189          */
190         mov     $0x10, %ebx
191         movw    %bx, %ds
192         movw    %bx, %es
193         movw    %bx, %fs
194         movw    %bx, %gs
195         movw    %bx, %ss
196
197         .globl  bigJump
198 bigJump:
199         /* this will be modified by mpInstallTramp() */
200         ljmp    $0x08, $0                       /* far jmp to MPentry() */
201         
202 dead:   hlt /* We should never get here */
203         jmp     dead
204
205 /*
206  * MP boot strap Global Descriptor Table
207  */
208         .p2align 4
209         .globl  MP_GDT
210         .globl  bootCodeSeg
211         .globl  bootDataSeg
212 MP_GDT:
213
214 nulldesc:               /* offset = 0x0 */
215
216         .word   0x0     
217         .word   0x0     
218         .byte   0x0     
219         .byte   0x0     
220         .byte   0x0     
221         .byte   0x0     
222
223 kernelcode:             /* offset = 0x08 */
224
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 */
231
232 kerneldata:             /* offset = 0x10 */
233
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 */
240
241 bootcode:               /* offset = 0x18 */
242
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 */
250
251 bootdata:               /* offset = 0x20 */
252
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             
260
261 /*
262  * GDT pointer for the lgdt call
263  */
264         .globl  mp_gdtbase
265
266 MP_GDTptr:      
267 mp_gdtlimit:
268         .word   0x0028          
269 mp_gdtbase:             /* this will be modified by mpInstallTramp() */
270         .long   0
271
272         .space  0x100   /* space for boot_stk - 1st temporary stack */
273 boot_stk:
274
275 BOOTMP2:
276         .globl  bootMP_size
277 bootMP_size:
278         .long   BOOTMP2 - BOOTMP1
279