1/* $OpenBSD: mptramp.S,v 1.23 2024/07/12 13:10:58 deraadt Exp $ */ 2/* $NetBSD: mptramp.S,v 1.1 2003/04/26 18:39:30 fvdl Exp $ */ 3 4/*- 5 * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by RedBack Networks Inc. 10 * 11 * Author: Bill Sommerfeld 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/* 36 * Copyright (c) 1999 Stefan Grefen 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by the NetBSD 49 * Foundation, Inc. and its contributors. 50 * 4. Neither the name of The NetBSD Foundation nor the names of its 51 * contributors may be used to endorse or promote products derived 52 * from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 55 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 */ 66/* 67 * MP startup ... 68 * the stuff from cpu_spinup_trampoline to mp_startup 69 * is copied into the first 640 KB 70 * 71 * We startup the processors now when the kthreads become ready. 72 * The steps are: 73 * 1) Get the processors running kernel-code from a special 74 * page-table and stack page, do chip identification. 75 * 2) halt the processors waiting for them to be enabled 76 * by a idle-thread 77 */ 78 79#include "assym.h" 80#include <machine/param.h> 81#include <machine/asm.h> 82#include <machine/specialreg.h> 83#include <machine/segments.h> 84#include <machine/mpbiosvar.h> 85#include <machine/i82489reg.h> 86 87#ifdef __clang__ 88#define addr32 89#endif 90 91#define _TRMP_LABEL(a) a = . - cpu_spinup_trampoline + MP_TRAMPOLINE 92#define _TRMP_OFFSET(a) a = . - cpu_spinup_trampoline 93 94#define _TRMP_DATA_LABEL(a) a = . - mp_tramp_data_start + MP_TRAMP_DATA 95#define _TRMP_DATA_OFFSET(a) a = . - mp_tramp_data_start 96 97 .global cpu_spinup_trampoline_end 98 .global mp_tramp_data_start 99 .global mp_tramp_data_end 100 101 /* 102 * Initial copy of this code gets placed in .rodata, kernel 103 * makes RX copy of it in the MP trampoline page. 104 */ 105 .section .rodata 106 .align 4, 0xcc 107 .code16 108GENTRY(cpu_spinup_trampoline) 109 cli 110 movw $(MP_TRAMP_DATA >> 4), %ax 111 movw %ax, %ds 112 movw %cs, %ax 113 movw %ax, %es 114 movw %ax, %ss 115 addr32 lgdtl (.Lmptramp_gdt32_desc) # load flat descriptor table 116 movl %cr0, %eax # get cr0 117 orl $CR0_PE, %eax # enable protected mode 118 movl %eax, %cr0 # doit 119 ljmpl $0x8, $.Lmp_startup 120 121_TRMP_LABEL(.Lmp_startup) 122 .code32 123 124 movl $0x10, %eax # data segment 125 movw %ax, %ds 126 movw %ax, %ss 127 movw %ax, %es 128 movw %ax, %fs 129 movw %ax, %gs 130 131 movl $(MP_TRAMP_DATA + NBPG - 16),%esp # bootstrap stack end, 132 # with scratch space.. 133 134 /* First, reset the PSL. */ 135 pushl $PSL_MBO 136 popfl 137 138 movl %cr4,%eax 139 orl $(CR4_DEFAULT),%eax 140 movl %eax,%cr4 141 142 movl $MSR_EFER,%ecx 143 rdmsr 144 movl %edx, %edi # %edx is needed by wrmsr below 145 146 # Check if we need to enable NXE 147 movl $0x80000001, %eax 148 cpuid 149 andl $CPUID_NXE, %edx 150 xorl %eax,%eax 151 testl %edx, %edx 152 jz 1f 153 orl $EFER_NXE, %eax 1541: 155 orl $(EFER_LME|EFER_SCE), %eax 156 157 movl %edi, %edx # Restore saved %edx 158 movl $MSR_EFER,%ecx 159 wrmsr 160 161 movl $mp_pdirpa, %ecx 162 movl (%ecx), %ecx 163 movl %ecx,%cr3 # load ptd addr into mmu 164 165 movl $GSEL(GDATA_SEL, SEL_KPL),%eax #switch to new segment 166 movl %eax,%ds 167 movl %eax,%es 168 movl %eax,%ss 169 170 movl $.Lmptramp_gdt64_desc,%eax 171 lgdt (%eax) 172 173 xorw %ax, %ax 174 movw %ax, %fs 175 176 movl $.Lmptramp_jmp64,%eax 177 178 movl %cr0,%ecx # get control word 179 orl $CR0_DEFAULT,%ecx 180 movl %ecx, %cr0 181 182 ljmp *(%eax) 183 184_TRMP_LABEL(.Lmptramp_longmode) 185 .code64 186 movabsq $cpu_spinup_finish,%rax 187 jmp *%rax 188 189 .type cpu_spinup_trampoline_end,@object 190cpu_spinup_trampoline_end: #end of code copied to MP_TRAMPOLINE 191END(cpu_spinup_trampoline) 192 193 .text 194GENTRY(cpu_spinup_finish) 195 movl x2apic_enabled,%eax 196 testl %eax,%eax 197 jz 1f 198 199 mov $MSR_APICBASE,%ecx 200 mov $0,%edx 201 rdmsr 202 orl $APICBASE_ENABLE_X2APIC,%eax 203 wrmsr 204 mov $MSR_X2APIC_ID,%ecx 205 rdmsr 206 andl $X2APIC_ID_MASK,%eax 207 jmp 2f 2081: 209 movl local_apic+LAPIC_ID,%eax 210 shrl $LAPIC_ID_SHIFT,%eax 2112: 212 xorq %rcx,%rcx 2133: 214 movq cpu_info(,%rcx,8),%rdi 215 incq %rcx 216 movl CPU_INFO_APICID(%rdi),%edx 217 cmpl %eax,%edx 218 jne 3b 219 220 movq CPU_INFO_IDLE_PCB(%rdi),%rsi 221 222 movq PCB_RSP(%rsi),%rsp 223 movq PCB_RBP(%rsi),%rbp 224 225 movq CPU_INFO_GDT(%rdi),%rax 226 movw $(GDT_SIZE-1),-10(%rsp) 227 movq %rax,-8(%rsp) 228 lgdt -10(%rsp) 229 230 /* Switch address space. */ 231 movq PCB_CR3(%rsi),%rax 232 movq %rax,%cr3 233 movl $CR0_DEFAULT,%eax 234 movq %rax,%cr0 235 call cpu_hatch 236 movq $0,-8(%rsp) 237END(cpu_spinup_finish) 238 /* NOTREACHED */ 239 240 .section .rodata 241 .type mp_tramp_data_start,@object 242mp_tramp_data_start: 243_TRMP_DATA_LABEL(.Lmptramp_jmp64) 244 .long .Lmptramp_longmode 245 .word GSEL(GCODE_SEL, SEL_KPL) 246 247 .global mp_pdirpa 248 .type mp_pdirpa,@object 249_TRMP_DATA_LABEL(mp_pdirpa) 250 .long 0 251 .size mp_pdirpa,4 252 253 254_TRMP_DATA_LABEL(.Lmptramp_gdt32) 255 .quad 0x0000000000000000 256 .quad 0x00cf9f000000ffff 257 .quad 0x00cf93000000ffff 258_TRMP_DATA_OFFSET(.Lmptramp_gdt32_desc) 259 .word 0x17 260 .long .Lmptramp_gdt32 261 262_TRMP_DATA_LABEL(.Lmptramp_gdt64) 263 .quad 0x0000000000000000 264 .quad 0x00af9a000000ffff 265 .quad 0x00cf92000000ffff 266_TRMP_DATA_LABEL(.Lmptramp_gdt64_desc) 267 .word 0x17 268 .long .Lmptramp_gdt64 269 270 .type mp_tramp_data_end,@object 271mp_tramp_data_end: 272END(mp_tramp_data_start) 273