xref: /openbsd/sys/arch/i386/i386/mptramp.s (revision 71ce0f95)
1/*	$OpenBSD: mptramp.s,v 1.14 2014/01/05 20:23:57 mlarkin 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 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Copyright (c) 1999 Stefan Grefen
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 *    notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in the
44 *    documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 *    must display the following acknowledgement:
47 *      This product includes software developed by the NetBSD
48 *      Foundation, Inc. and its contributors.
49 * 4. Neither the name of The NetBSD Foundation nor the names of its
50 *    contributors may be used to endorse or promote products derived
51 *    from this software without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
54 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 */
65/*
66 * MP startup ...
67 * the stuff from cpu_spinup_trampoline to mp_startup
68 * is copied into the first 640 KB
69 *
70 * We startup the processors now when the kthreads become ready.
71 * The steps are:
72 *	1) Get the processors running kernel-code from a special
73 *	   page-table and stack page, do chip identification.
74 *	2) halt the processors waiting for them to be enabled
75 *	   by a idle-thread
76 */
77
78#include "assym.h"
79#include <machine/param.h>
80#include <machine/asm.h>
81#include <machine/specialreg.h>
82#include <machine/segments.h>
83#include <machine/gdt.h>
84#include <machine/mpbiosvar.h>
85#include <machine/i82489reg.h>
86
87#define GDTE(a,b)	.byte	0xff,0xff,0x0,0x0,0x0,a,b,0x0
88#define _RELOC(x)	((x) - KERNBASE)
89#define RELOC(x)	_RELOC(_C_LABEL(x))
90
91#define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
92#define _TRMP_OFFSET(a)  a = . - _C_LABEL(cpu_spinup_trampoline)
93
94/*
95 * Debug code to stop aux. processors in various stages based on the
96 * value in cpu_trace.
97 *
98 * %edi points at cpu_trace;  cpu_trace[0] is the "hold point";
99 * cpu_trace[1] is the point which the cpu has reached.
100 * cpu_trace[2] is the last value stored by HALTT.
101 */
102
103
104#ifdef MPDEBUG
105#define HALT(x)	1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi)
106#define HALTT(x,y)	movl y,8(%edi); HALT(x)
107#else
108#define HALT(x)
109#define HALTT(x,y)
110#endif
111
112	.globl	_C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor)
113	.globl	_C_LABEL(cpuid_level),_C_LABEL(cpu_feature)
114
115	.global _C_LABEL(cpu_spinup_trampoline)
116	.global _C_LABEL(cpu_spinup_trampoline_end)
117	.global _C_LABEL(cpu_hatch)
118	.global _C_LABEL(mp_pdirpa)
119	.global _C_LABEL(gdt), _C_LABEL(local_apic)
120
121	.text
122	.align 4,0x0
123	.code16
124_C_LABEL(cpu_spinup_trampoline):
125	cli
126	movw	%cs, %ax
127	movw	%ax, %ds
128	movw	%ax, %es
129	movw	%ax, %ss
130	data32 addr32 lgdt	(gdt_desc)	# load flat descriptor table
131	movl	%cr0, %eax	# get cr0
132	orl	$0x1, %eax	# enable protected mode
133	movl	%eax, %cr0	# doit
134	ljmpl	$0x8, $mp_startup
135
136_TRMP_LABEL(mp_startup)
137	.code32
138
139	movl	$0x10, %eax	# data segment
140	movw	%ax, %ds
141	movw	%ax, %ss
142	movw	%ax, %es
143	movw	%ax, %fs
144	movw	%ax, %gs
145	movl	$(MP_TRAMPOLINE+NBPG-16),%esp	# bootstrap stack end,
146						# with scratch space..
147
148#ifdef MPDEBUG
149	leal	RELOC(cpu_trace),%edi
150#endif
151
152	HALT(0x1)
153	/* First, reset the PSL. */
154	pushl	$PSL_MBO
155	popfl
156
157	movl	RELOC(mp_pdirpa),%ecx
158	HALTT(0x5,%ecx)
159
160	/* Load base of page directory and enable mapping. */
161	movl	%ecx,%cr3		# load ptd addr into mmu
162	movl	%cr0,%eax		# get control word
163					# enable paging & NPX emulation
164	orl	$(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax
165	movl	%eax,%cr0		# and let's page NOW!
166
167#ifdef MPDEBUG
168	leal	_C_LABEL(cpu_trace),%edi
169#endif
170	HALT(0x6)
171
172# ok, we're now running with paging enabled and sharing page tables with cpu0.
173# figure out which processor we really are, what stack we should be on, etc.
174
175	movl	_C_LABEL(local_apic)+LAPIC_ID,%eax
176	shrl	$LAPIC_ID_SHIFT,%eax
177	xorl	%ebx,%ebx
1781:
179	leal	0(,%ebx,4),%ecx
180	incl	%ebx
181	movl	_C_LABEL(cpu_info)(%ecx),%ecx
182	movl	CPU_INFO_APICID(%ecx),%edx
183	cmpl	%eax,%edx
184	jne 1b
185
186	HALTT(0x7, %ecx)
187
188# %ecx points at our cpu_info structure..
189
190	movw	$(MAXGDTSIZ-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
1981:
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_OFFSET(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
222mp_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	/* NOTREACHED */
253
254	.data
255_C_LABEL(mp_pdirpa):
256	.long	0
257#ifdef MPDEBUG
258	.global _C_LABEL(cpu_trace)
259_C_LABEL(cpu_trace):
260	.long	0x40
261	.long	0xff
262	.long	0xff
263#endif
264