xref: /netbsd/sys/arch/i386/i386/mptramp.S (revision bf301517)
1/*	$NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $	*/
2
3/*
4 * Copyright (c) 2000, 2016 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. (Author: Bill Sommerfeld), and Maxime Villard.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Copyright (c) 1999 Stefan Grefen
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 *    must display the following acknowledgement:
45 *      This product includes software developed by the NetBSD
46 *      Foundation, Inc. and its contributors.
47 * 4. Neither the name of The NetBSD Foundation nor the names of its
48 *    contributors may be used to endorse or promote products derived
49 *    from this software without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 */
63
64/*
65 * MP startup ...
66 * the stuff from cpu_spinup_trampoline to mp_startup is copied into the
67 * first 640 KB.
68 *
69 * We startup the processors now when the kthreads become ready.
70 * The steps are:
71 *     1) Get the processors running kernel-code from a special
72 *        page-table and stack page, do chip identification.
73 *     2) halt the processors waiting for them to be enabled
74 *        by a idle-thread
75 */
76
77#include <machine/asm.h>
78__KERNEL_RCSID(0, "$NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $");
79
80#include "assym.h"
81#include <machine/specialreg.h>
82#include <machine/segments.h>
83#include <machine/mpbiosvar.h>
84#include <machine/i82489reg.h>
85#include <machine/gdt.h>
86
87#define GDTE(a,b)	.byte   0xff,0xff,0x0,0x0,0x0,a,b,0x0
88
89#define _TRMP_LABEL(a)	a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
90
91/*
92 * A smp_data structure is packed at the end of the trampoline page. The stack
93 * is right below this structure.
94 */
95#define SMP_DATA	(MP_TRAMPOLINE + PAGE_SIZE - 3 * 4)
96#define SMP_DATA_STACK	(SMP_DATA + 0 * 4)
97#define SMP_DATA_LARGE	(SMP_DATA + 0 * 4)
98#define SMP_DATA_NOX	(SMP_DATA + 1 * 4)
99#define SMP_DATA_PDIR	(SMP_DATA + 2 * 4)
100
101	.global _C_LABEL(cpu_spinup_trampoline)
102	.global _C_LABEL(cpu_spinup_trampoline_end)
103
104	.text
105	.align 4,0x0
106	.code16
107/* XXX ENTRY() */
108LABEL(cpu_spinup_trampoline)
109	cli
110	xorw	%ax,%ax
111	movw	%ax,%ds
112	movw	%ax,%es
113	movw	%ax,%ss
114
115	/* load flat descriptor table */
116#ifdef __clang__
117	lgdt (gdt_desc)
118#else
119	data32 addr32 lgdt (gdt_desc)
120#endif
121
122	/* enable protected mode */
123	movl	%cr0,%eax
124	orl	$CR0_PE,%eax
125	movl	%eax,%cr0
126	ljmpl	$0x8,$mp_startup
127
128_TRMP_LABEL(mp_startup)
129	.code32
130
131	movl	$0x10,%eax	/* data segment */
132	movw	%ax,%ds
133	movw	%ax,%ss
134	movw	%ax,%es
135	movw	%ax,%fs
136	movw	%ax,%gs
137
138	/* bootstrap stack end */
139	movl	$SMP_DATA_STACK,%esp
140
141	/* First, reset the PSL. */
142	pushl	$PSL_MBO
143	popfl
144
145	/* Enable PSE if available */
146	movl	$SMP_DATA_LARGE,%eax
147	movl	(%eax),%eax
148	orl	%eax,%eax
149	jz	no_PSE
150	movl	%cr4,%eax
151	orl	$CR4_PSE,%eax
152	movl	%eax,%cr4
153no_PSE:
154
155#ifdef PAE
156	/* Enable PAE */
157	movl	%cr4,%eax
158	or	$CR4_PAE,%eax
159	movl	%eax,%cr4
160#endif
161
162	/*
163	 * Set NOX in EFER, if available.
164	 */
165	movl	$SMP_DATA_NOX,%ebx
166	movl	(%ebx),%ebx
167	cmpl	$0,%ebx
168	je 	no_NOX
169	movl	$MSR_EFER,%ecx
170	rdmsr
171	xorl	%eax,%eax
172	orl	$(EFER_NXE),%eax
173	wrmsr
174no_NOX:
175
176	/* Load %cr3. */
177	movl	$SMP_DATA_PDIR,%ecx
178	movl	(%ecx),%ecx
179	movl	%ecx,%cr3		/* load PTD addr into MMU */
180
181	/* Enable paging and the rest of it. */
182	movl	%cr0,%eax
183	orl	$(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM),%eax
184	movl	%eax,%cr0
185
186	/* Wait until BP has done init sequence. */
1871:
188	movl	_C_LABEL(cpu_starting),%ecx
189	pause
190	testl	%ecx,%ecx
191	jz	1b
192
193	movw	$(MAXGDTSIZ-1),6(%esp)	/* prepare segment descriptor */
194	movl	CPU_INFO_GDT(%ecx),%eax	/* for our real gdt */
195	movl	%eax,8(%esp)
196	lgdt	6(%esp)
197	jmp	1f
198	nop
1991:
200	movl	$GSEL(GDATA_SEL, SEL_KPL),%eax 	/* switch to new segment */
201	movl	%eax,%ds
202	movl	%eax,%es
203	movl	%eax,%ss
204	pushl	$GSEL(GCODE_SEL, SEL_KPL)
205	pushl	$mp_cont
206	lret
207	.align	4,0x0
208
209_TRMP_LABEL(gdt_table)
210	.word	0x0,0x0,0x0,0x0	/* null gdte */
211	GDTE(0x9f,0xcf)		/* Kernel text */
212	GDTE(0x93,0xcf)		/* Kernel data */
213_TRMP_LABEL(gdt_desc)
214	.word	0x17		/* limit 3 entries */
215	.long	gdt_table	/* base of gdt */
216
217_C_LABEL(cpu_spinup_trampoline_end):	/* end of code copied to MP_TRAMPOLINE */
218
219mp_cont:
220	movl	CPU_INFO_IDLELWP(%ecx),%esi
221	movl	L_PCB(%esi),%esi
222
223	movl	PCB_ESP(%esi),%esp
224	movl	PCB_EBP(%esi),%ebp
225
226	/* Switch address space. */
227	movl	PCB_CR3(%esi),%eax
228	movl	%eax,%cr3
229
230	/* load segment registers. */
231	movl	$GSEL(GCPU_SEL, SEL_KPL),%eax
232	movl	%eax,%fs
233	xorl	%eax,%eax
234	movl	%eax,%gs
235
236	movl	PCB_CR0(%esi),%eax
237	movl	%eax,%cr0
238	pushl	%ecx
239
240	call	_C_LABEL(cpu_hatch)
241END(cpu_spinup_trampoline)
242
243