1 /* $OpenBSD: mptramp.s,v 1.8 2007/02/20 21:15:01 tom Exp $ */
2
3 /*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by RedBack Networks Inc.
9 *
10 * Author: Bill Sommerfeld
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*
42 * Copyright (c) 1999 Stefan Grefen
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the NetBSD
55 * Foundation, Inc. and its contributors.
56 * 4. Neither the name of The NetBSD Foundation nor the names of its
57 * contributors may be used to endorse or promote products derived
58 * from this software without specific prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
61 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE.
71 */
72 /*
73 * MP startup ...
74 * the stuff from cpu_spinup_trampoline to mp_startup
75 * is copied into the first 640 KB
76 *
77 * We startup the processors now when the kthreads become ready.
78 * The steps are:
79 * 1) Get the processors running kernel-code from a special
80 * page-table and stack page, do chip identification.
81 * 2) halt the processors waiting for them to be enabled
82 * by a idle-thread
83 */
84
85 #include "assym.h"
86 #include <machine/param.h>
87 #include <machine/asm.h>
88 #include <machine/specialreg.h>
89 #include <machine/segments.h>
90 #include <machine/gdt.h>
91 #include <machine/mpbiosvar.h>
92 #include <machine/i82489reg.h>
93
94 #define GDTE(a,b) .byte 0xff,0xff,0x0,0x0,0x0,a,b,0x0
95 #define _RELOC(x) ((x) - KERNBASE)
96 #define RELOC(x) _RELOC(_C_LABEL(x))
97
98 #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
99
100 /*
101 * Debug code to stop aux. processors in various stages based on the
102 * value in cpu_trace.
103 *
104 * %edi points at cpu_trace; cpu_trace[0] is the "hold point";
105 * cpu_trace[1] is the point which the cpu has reached.
106 * cpu_trace[2] is the last value stored by HALTT.
107 */
108
109
110 #ifdef MPDEBUG
111 #define HALT(x) 1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi)
112 #define HALTT(x,y) movl y,8(%edi); HALT(x)
113 #else
114 #define HALT(x) /**/
115 #define HALTT(x,y) /**/
116 #endif
117
118 .globl _C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor)
119 .globl _C_LABEL(cpuid_level),_C_LABEL(cpu_feature)
120
121 .global _C_LABEL(cpu_spinup_trampoline)
122 .global _C_LABEL(cpu_spinup_trampoline_end)
123 .global _C_LABEL(cpu_hatch)
124 .global _C_LABEL(mp_pdirpa)
125 .global _C_LABEL(gdt), _C_LABEL(local_apic)
126
127 .text
128 .align 4,0x0
129 .code16
130 _C_LABEL(cpu_spinup_trampoline):
131 cli
132 xorw %ax, %ax
133 movw %ax, %ds
134 movw %ax, %es
135 movw %ax, %ss
136 data32 addr32 lgdt (gdt_desc) # load flat descriptor table
137 movl %cr0, %eax # get cr0
138 orl $0x1, %eax # enable protected mode
139 movl %eax, %cr0 # doit
140 ljmp $0x8, $mp_startup
141
142 _TRMP_LABEL(mp_startup)
143 .code32
144
145 movl $0x10, %eax # data segment
146 movw %ax, %ds
147 movw %ax, %ss
148 movw %ax, %es
149 movw %ax, %fs
150 movw %ax, %gs
151 movl $(MP_TRAMPOLINE+NBPG-16),%esp # bootstrap stack end,
152 # with scratch space..
153
154 #ifdef MPDEBUG
155 leal RELOC(cpu_trace),%edi
156 #endif
157
158 HALT(0x1)
159 /* First, reset the PSL. */
160 pushl $PSL_MBO
161 popfl
162
163 movl RELOC(mp_pdirpa),%ecx
164 HALTT(0x5,%ecx)
165
166 /* Load base of page directory and enable mapping. */
167 movl %ecx,%cr3 # load ptd addr into mmu
168 movl %cr0,%eax # get control word
169 # enable paging & NPX emulation
170 orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax
171 movl %eax,%cr0 # and let's page NOW!
172
173 #ifdef MPDEBUG
174 leal _C_LABEL(cpu_trace),%edi
175 #endif
176 HALT(0x6)
177
178 # ok, we're now running with paging enabled and sharing page tables with cpu0.
179 # figure out which processor we really are, what stack we should be on, etc.
180
181 movl _C_LABEL(local_apic)+LAPIC_ID,%ecx
182 shrl $LAPIC_ID_SHIFT,%ecx
183 leal 0(,%ecx,4),%ecx
184 movl _C_LABEL(cpu_info)(%ecx),%ecx
185
186 HALTT(0x7, %ecx)
187
188 # %ecx points at our cpu_info structure..
189
190 movw $((MAXGDTSIZ*8) - 1), 6(%esp) # prepare segment descriptor
191 movl CPU_INFO_GDT(%ecx), %eax # for real gdt
192 movl %eax, 8(%esp)
193 HALTT(0x8, %eax)
194 lgdt 6(%esp)
195 HALT(0x9)
196 jmp 1f
197 nop
198 1:
199 HALT(0xa)
200 movl $GSEL(GDATA_SEL, SEL_KPL),%eax #switch to new segment
201 HALTT(0x10, %eax)
202 movw %ax,%ds
203 HALT(0x11)
204 movw %ax,%es
205 HALT(0x12)
206 movw %ax,%ss
207 HALT(0x13)
208 pushl $GSEL(GCODE_SEL, SEL_KPL)
209 pushl $mp_cont
210 HALT(0x14)
211 lret
212 .align 4,0x0
213 _TRMP_LABEL(gdt_table)
214 .word 0x0,0x0,0x0,0x0 # null GDTE
215 GDTE(0x9f,0xcf) # Kernel text
216 GDTE(0x93,0xcf) # Kernel data
217 _TRMP_LABEL(gdt_desc)
218 .word 0x17 # limit 3 entries
219 .long gdt_table # where is gdt
220
221 _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE
222 mp_cont:
223
224 movl CPU_INFO_IDLE_PCB(%ecx),%esi
225
226 # %esi now points at our PCB.
227
228 HALTT(0x19, %esi)
229
230 movl PCB_ESP(%esi),%esp
231 movl PCB_EBP(%esi),%ebp
232
233 HALT(0x20)
234 /* Switch address space. */
235 movl PCB_CR3(%esi),%eax
236 HALTT(0x22, %eax)
237 movl %eax,%cr3
238 HALT(0x25)
239 /* Load segment registers. */
240 movl $GSEL(GCPU_SEL, SEL_KPL),%eax
241 HALTT(0x26,%eax)
242 movl %eax,%fs
243 xorl %eax,%eax
244 HALTT(0x27,%eax)
245 movl %eax,%gs
246 movl PCB_CR0(%esi),%eax
247 HALTT(0x28,%eax)
248 movl %eax,%cr0
249 HALTT(0x30,%ecx)
250 pushl %ecx
251 call _C_LABEL(cpu_hatch)
252 HALT(0x33)
253 xorl %esi,%esi
254 jmp _C_LABEL(idle_start)
255
256 .data
257 _C_LABEL(mp_pdirpa):
258 .long 0
259 #ifdef MPDEBUG
260 .global _C_LABEL(cpu_trace)
261 _C_LABEL(cpu_trace):
262 .long 0x40
263 .long 0xff
264 .long 0xff
265 #endif