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