xref: /openbsd-src/sys/arch/i386/i386/mptramp.s (revision 8162193374858e8d7dceca506657f13b21b8be44)
1/*	$OpenBSD: mptramp.s,v 1.27 2022/12/08 01:25:44 guenther 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#ifdef __clang__
88#define addr32
89#endif
90
91#define GDTE(a,b)	.byte	0xff,0xff,0x0,0x0,0x0,a,b,0x0
92#define _RELOC(x)	((x) - KERNBASE)
93#define RELOC(x)	_RELOC(x)
94
95#define _TRMP_LABEL(a)	a = . - cpu_spinup_trampoline + MP_TRAMPOLINE
96#define _TRMP_OFFSET(a)	a = . - cpu_spinup_trampoline
97#define _TRMP_DATA_LABEL(a)	a = . - mp_tramp_data_start + MP_TRAMP_DATA
98#define _TRMP_DATA_OFFSET(a)	a = . - mp_tramp_data_start
99
100	.globl	cpu_id,cpu_vendor
101	.globl	cpuid_level,cpu_feature
102
103	.global cpu_spinup_trampoline
104	.global cpu_spinup_trampoline_end
105	.global cpu_hatch
106	.global mp_pdirpa
107	.global mp_tramp_data_start
108	.global mp_tramp_data_end
109	.global gdt, local_apic
110
111	.text
112	.align 4, 0xcc
113	.code16
114cpu_spinup_trampoline:
115	cli
116	movw	$(MP_TRAMP_DATA >> 4), %ax
117	movw	%ax, %ds
118	movw	%cs, %ax
119	movw	%ax, %es
120	movw	%ax, %ss
121	addr32 lgdtl (.Lgdt_desc)	# load flat descriptor table
122	movl	%cr0, %eax	# get cr0
123	orl	$0x1, %eax	# enable protected mode
124	movl	%eax, %cr0	# doit
125	ljmpl	$0x8, $.Lmp_startup
126
127_TRMP_LABEL(.Lmp_startup)
128	.code32
129
130	movl	$0x10, %eax	# data segment
131	movw	%ax, %ds
132	movw	%ax, %ss
133	movw	%ax, %es
134	movw	%ax, %fs
135	movw	%ax, %gs
136	movl	$(MP_TRAMP_DATA+NBPG-16),%esp	# bootstrap stack end,
137						# with scratch space..
138
139	/* First, reset the PSL. */
140	pushl	$PSL_MBO
141	popfl
142
143	movl	RELOC(mp_pdirpa),%ecx
144
145	/* Load base of page directory and enable mapping. */
146	movl	%ecx,%cr3		# load ptd addr into mmu
147#ifndef SMALL_KERNEL
148	testl	$0x1, RELOC(cpu_pae)
149	jz	nopae
150
151	movl	%cr4,%eax
152	orl	$CR4_PAE,%eax
153	movl	%eax, %cr4
154
155	movl	$MSR_EFER,%ecx
156	rdmsr
157	orl	$EFER_NXE, %eax
158	wrmsr
159
160nopae:
161#endif
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# ok, we're now running with paging enabled and sharing page tables with cpu0.
168# figure out which processor we really are, what stack we should be on, etc.
169
170	movl	local_apic+LAPIC_ID,%eax
171	shrl	$LAPIC_ID_SHIFT,%eax
172	xorl	%ebx,%ebx
1731:
174	leal	0(,%ebx,4),%ecx
175	incl	%ebx
176	movl	cpu_info(%ecx),%ecx
177	movl	CPU_INFO_APICID(%ecx),%edx
178	cmpl	%eax,%edx
179	jne 1b
180
181# %ecx points at our cpu_info structure..
182
183	movw	$(GDT_SIZE-1), 6(%esp)		# prepare segment descriptor
184	movl	CPU_INFO_GDT(%ecx), %eax	# for real gdt
185	movl	%eax, 8(%esp)
186	lgdt	6(%esp)
187	jmp	1f
188	nop
1891:
190	movl	$GSEL(GDATA_SEL, SEL_KPL),%eax	#switch to new segment
191	movw	%ax,%ds
192	movw	%ax,%es
193	movw	%ax,%ss
194	pushl	$GSEL(GCODE_SEL, SEL_KPL)
195	pushl	$mp_cont
196	lret
197
198cpu_spinup_trampoline_end:		#end of code copied to MP_TRAMPOLINE
199mp_cont:
200
201	movl	CPU_INFO_IDLE_PCB(%ecx),%esi
202
203# %esi now points at our PCB.
204
205	movl	PCB_ESP(%esi),%esp
206	movl	PCB_EBP(%esi),%ebp
207
208	/* Switch address space. */
209	movl	PCB_CR3(%esi),%eax
210	movl	%eax,%cr3
211	/* Load segment registers. */
212	movl	$GSEL(GCPU_SEL, SEL_KPL),%eax
213	movl	%eax,%fs
214	xorl	%eax,%eax
215	movl	%eax,%gs
216	movl	PCB_CR0(%esi),%eax
217	movl	%eax,%cr0
218	pushl	%ecx
219	call	cpu_hatch
220	/* NOTREACHED */
221
222	.section .rodata
223mp_tramp_data_start:
224_TRMP_DATA_LABEL(.Lgdt_table)
225	.word	0x0,0x0,0x0,0x0			# null GDTE
226	 GDTE(0x9f,0xcf)			# Kernel text
227	 GDTE(0x93,0xcf)			# Kernel data
228_TRMP_DATA_OFFSET(.Lgdt_desc)
229	.word	0x17				# limit 3 entries
230	.long	.Lgdt_table			# where is gdt
231mp_tramp_data_end:
232