xref: /netbsd/sys/arch/i386/i386/mptramp.S (revision c4a72b64)
1/*	$NetBSD: mptramp.S,v 1.1 2002/11/22 15:01:18 fvdl 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 "opt_mpbios.h"		/* for MPDEBUG */
86
87#include "assym.h"
88#include <machine/param.h>
89#include <machine/asm.h>
90#include <machine/specialreg.h>
91#include <machine/segments.h>
92#include <machine/mpbiosvar.h>
93#include <machine/i82489reg.h>
94#include <machine/gdt.h>
95
96#define GDTE(a,b)               .byte   0xff,0xff,0x0,0x0,0x0,a,b,0x0
97#define _RELOC(x)       ((x) - KERNBASE)
98#define RELOC(x)        _RELOC(_C_LABEL(x))
99
100#define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
101
102#ifdef MPDEBUG
103
104/*
105 * Debug code to stop aux. processors in various stages based on the
106 * value in cpu_trace.
107 *
108 * %edi points at cpu_trace;  cpu_trace[0] is the "hold point";
109 * cpu_trace[1] is the point which the cpu has reached.
110 * cpu_trace[2] is the last value stored by HALTT.
111 */
112
113#define HALT(x)	1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi)
114#define HALTT(x,y)	movl y,8(%edi); HALT(x)
115#else
116#define HALT(x)	/**/
117#define HALTT(x,y) /**/
118#endif
119
120        .globl  _C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor)
121	.globl  _C_LABEL(cpuid_level),_C_LABEL(cpu_feature)
122	.globl	_C_LABEL(mpidle)
123
124	.global _C_LABEL(cpu_spinup_trampoline)
125	.global _C_LABEL(cpu_spinup_trampoline_end)
126	.global _C_LABEL(cpu_hatch)
127	.global _C_LABEL(mp_pdirpa)
128	.global _C_LABEL(gdt), _C_LABEL(local_apic)
129
130	.text
131	.align 4,0x0
132	.code16
133_C_LABEL(cpu_spinup_trampoline):
134	cli
135	xorw    %ax,%ax
136	movw    %ax, %ds
137	movw    %ax, %es
138	movw    %ax, %ss
139	data32 addr32 lgdt    (gdt_desc)      # load flat descriptor table
140	movl    %cr0, %eax       # get cr0
141	orl     $0x1, %eax      # enable protected mode
142	movl    %eax, %cr0      # doit
143	movl    $0x10, %eax     # data segment
144	movw    %ax, %ds
145	movw    %ax, %ss
146	movw    %ax, %es
147	movw    %ax, %fs
148	movw    %ax, %gs
149	ljmpl    $0x8, $mp_startup
150	.code32
151
152_TRMP_LABEL(mp_startup)
153	movl    $ (MP_TRAMPOLINE+NBPG-16),%esp       # bootstrap stack end,
154						     # with scratch space..
155
156#ifdef MPDEBUG
157	leal    RELOC(cpu_trace),%edi
158#endif
159
160	HALT(0x1)
161	/* First, reset the PSL. */
162	pushl   $PSL_MBO
163	popfl
164
165	movl	RELOC(mp_pdirpa),%ecx
166	HALTT(0x5,%ecx)
167
168        /* Load base of page directory and enable mapping. */
169        movl    %ecx,%cr3               # load ptd addr into mmu
170        movl    %cr0,%eax               # get control word
171                                        # enable paging & NPX emulation
172        orl     $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax
173        movl    %eax,%cr0               # and let's page NOW!
174
175#ifdef MPDEBUG
176	leal    _C_LABEL(cpu_trace),%edi
177#endif
178	HALT(0x6)
179
180# ok, we're now running with paging enabled and sharing page tables with cpu0.
181# figure out which processor we really are, what stack we should be on, etc.
182
183	movl	_C_LABEL(local_apic)+LAPIC_ID,%ecx
184	shrl	$LAPIC_ID_SHIFT,%ecx
185	leal	0(,%ecx,4),%ecx
186	movl	_C_LABEL(cpu_info)(%ecx),%ecx
187
188	HALTT(0x7, %ecx)
189
190# %ecx points at our cpu_info structure..
191
192	movw    $((MAXGDTSIZ*8) - 1), 6(%esp)	# prepare segment descriptor
193	movl    CPU_INFO_GDT(%ecx), %eax	# for our real gdt
194	movl    %eax, 8(%esp)
195	lgdt	6(%esp)
196	HALT(0x8)
197	jmp	1f
198	nop
1991:
200	HALT(0x12)
201	movl    $GSEL(GDATA_SEL, SEL_KPL),%eax 	#switch to new segment
202	movl    %eax,%ds
203	movl    %eax,%es
204	movl    %eax,%ss
205	HALT(0x13)
206	pushl   $GSEL(GCODE_SEL, SEL_KPL)
207	pushl	$mp_cont
208	HALT(0x14)
209	lret
210	.align 4,0x0
211_TRMP_LABEL(gdt_table)
212	.word   0x0,0x0,0x0,0x0  # null GDTE
213	 GDTE(0x9f,0xcf)         # Kernel text
214	 GDTE(0x93,0xcf)         # Kernel data
215_TRMP_LABEL(gdt_desc)
216	.word   0x17             # limit 3 entries
217	.long   gdt_table        # base of gdt
218
219_C_LABEL(cpu_spinup_trampoline_end):	#end of code copied to MP_TRAMPOLINE
220mp_cont:
221	HALT(0x15)
222
223	movl	CPU_INFO_IDLE_PCB(%ecx),%esi
224
225# %esi now points at our PCB.
226
227	HALTT(0x19, %esi)
228
229	movl	PCB_ESP(%esi),%esp
230	movl	PCB_EBP(%esi),%ebp
231
232	HALT(0x20)
233	/* Switch address space. */
234	movl	PCB_CR3(%esi),%eax
235	HALTT(0x22, %eax)
236	movl	%eax,%cr3
237	HALT(0x25)
238	/* load segment registers. */
239	movl	$GSEL(GCPU_SEL, SEL_KPL),%eax
240	HALTT(0x26,%eax)
241	movl	%eax,%fs
242	xorl	%eax,%eax
243	HALTT(0x27,%eax)
244	movl	%eax,%gs
245	movl    PCB_CR0(%esi),%eax
246	HALTT(0x28,%eax)
247	movl    %eax,%cr0
248	HALTT(0x30,%ecx)
249	pushl	%ecx
250	call	_C_LABEL(cpu_hatch)
251	HALT(0x33)
252	xorl	%esi,%esi
253	jmp	_C_LABEL(mpidle)
254
255	.data
256_C_LABEL(mp_pdirpa):
257	.long	0
258#ifdef MPDEBUG
259	.global _C_LABEL(cpu_trace)
260_C_LABEL(cpu_trace):
261	.long  0x40
262	.long  0xff
263	.long  0xff
264#endif
265