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