1*bf301517Smaxv/* $NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $ */ 2c4031162Sfvdl 3a1ad52c3Smaxv/* 4a1ad52c3Smaxv * Copyright (c) 2000, 2016 The NetBSD Foundation, Inc. 5c4031162Sfvdl * All rights reserved. 6c4031162Sfvdl * 7c4031162Sfvdl * This code is derived from software contributed to The NetBSD Foundation 8a1ad52c3Smaxv * by RedBack Networks Inc. (Author: Bill Sommerfeld), and Maxime Villard. 9c4031162Sfvdl * 10c4031162Sfvdl * Redistribution and use in source and binary forms, with or without 11c4031162Sfvdl * modification, are permitted provided that the following conditions 12c4031162Sfvdl * are met: 13c4031162Sfvdl * 1. Redistributions of source code must retain the above copyright 14c4031162Sfvdl * notice, this list of conditions and the following disclaimer. 15c4031162Sfvdl * 2. Redistributions in binary form must reproduce the above copyright 16c4031162Sfvdl * notice, this list of conditions and the following disclaimer in the 17c4031162Sfvdl * documentation and/or other materials provided with the distribution. 18c4031162Sfvdl * 19c4031162Sfvdl * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20c4031162Sfvdl * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21c4031162Sfvdl * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22c4031162Sfvdl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23c4031162Sfvdl * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24c4031162Sfvdl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25c4031162Sfvdl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26c4031162Sfvdl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27c4031162Sfvdl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28c4031162Sfvdl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29c4031162Sfvdl * POSSIBILITY OF SUCH DAMAGE. 30c4031162Sfvdl */ 31c4031162Sfvdl 32c4031162Sfvdl/* 33c4031162Sfvdl * Copyright (c) 1999 Stefan Grefen 34c4031162Sfvdl * 35c4031162Sfvdl * Redistribution and use in source and binary forms, with or without 36c4031162Sfvdl * modification, are permitted provided that the following conditions 37c4031162Sfvdl * are met: 38c4031162Sfvdl * 1. Redistributions of source code must retain the above copyright 39c4031162Sfvdl * notice, this list of conditions and the following disclaimer. 40c4031162Sfvdl * 2. Redistributions in binary form must reproduce the above copyright 41c4031162Sfvdl * notice, this list of conditions and the following disclaimer in the 42c4031162Sfvdl * documentation and/or other materials provided with the distribution. 43c4031162Sfvdl * 3. All advertising materials mentioning features or use of this software 44c4031162Sfvdl * must display the following acknowledgement: 45c4031162Sfvdl * This product includes software developed by the NetBSD 46c4031162Sfvdl * Foundation, Inc. and its contributors. 47c4031162Sfvdl * 4. Neither the name of The NetBSD Foundation nor the names of its 48c4031162Sfvdl * contributors may be used to endorse or promote products derived 49c4031162Sfvdl * from this software without specific prior written permission. 50c4031162Sfvdl * 51c4031162Sfvdl * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 52c4031162Sfvdl * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53c4031162Sfvdl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54c4031162Sfvdl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 55c4031162Sfvdl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56c4031162Sfvdl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57c4031162Sfvdl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58c4031162Sfvdl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59c4031162Sfvdl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60c4031162Sfvdl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61c4031162Sfvdl * SUCH DAMAGE. 62c4031162Sfvdl */ 63a1ad52c3Smaxv 64c4031162Sfvdl/* 65c4031162Sfvdl * MP startup ... 66a1ad52c3Smaxv * the stuff from cpu_spinup_trampoline to mp_startup is copied into the 67a1ad52c3Smaxv * first 640 KB. 68c4031162Sfvdl * 69c4031162Sfvdl * We startup the processors now when the kthreads become ready. 70c4031162Sfvdl * The steps are: 71c4031162Sfvdl * 1) Get the processors running kernel-code from a special 72c4031162Sfvdl * page-table and stack page, do chip identification. 73c4031162Sfvdl * 2) halt the processors waiting for them to be enabled 74c4031162Sfvdl * by a idle-thread 75c4031162Sfvdl */ 76c4031162Sfvdl 77a4914dc7Slukem#include <machine/asm.h> 78*bf301517Smaxv__KERNEL_RCSID(0, "$NetBSD: mptramp.S,v 1.32 2017/09/28 17:48:20 maxv Exp $"); 79c4031162Sfvdl 80c4031162Sfvdl#include "assym.h" 81c4031162Sfvdl#include <machine/specialreg.h> 82c4031162Sfvdl#include <machine/segments.h> 83c4031162Sfvdl#include <machine/mpbiosvar.h> 84c4031162Sfvdl#include <machine/i82489reg.h> 85c4031162Sfvdl#include <machine/gdt.h> 86c4031162Sfvdl 87c4031162Sfvdl#define GDTE(a,b) .byte 0xff,0xff,0x0,0x0,0x0,a,b,0x0 88c4031162Sfvdl 89c4031162Sfvdl#define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE 90c4031162Sfvdl 91*bf301517Smaxv/* 92*bf301517Smaxv * A smp_data structure is packed at the end of the trampoline page. The stack 93*bf301517Smaxv * is right below this structure. 94*bf301517Smaxv */ 95*bf301517Smaxv#define SMP_DATA (MP_TRAMPOLINE + PAGE_SIZE - 3 * 4) 96*bf301517Smaxv#define SMP_DATA_STACK (SMP_DATA + 0 * 4) 97*bf301517Smaxv#define SMP_DATA_LARGE (SMP_DATA + 0 * 4) 98*bf301517Smaxv#define SMP_DATA_NOX (SMP_DATA + 1 * 4) 99*bf301517Smaxv#define SMP_DATA_PDIR (SMP_DATA + 2 * 4) 100*bf301517Smaxv 101c4031162Sfvdl .global _C_LABEL(cpu_spinup_trampoline) 102c4031162Sfvdl .global _C_LABEL(cpu_spinup_trampoline_end) 103c4031162Sfvdl 104c4031162Sfvdl .text 105c4031162Sfvdl .align 4,0x0 106c4031162Sfvdl .code16 107ed55ab9bSuebayasi/* XXX ENTRY() */ 108ed55ab9bSuebayasiLABEL(cpu_spinup_trampoline) 109c4031162Sfvdl cli 110c4031162Sfvdl xorw %ax,%ax 111c4031162Sfvdl movw %ax,%ds 112c4031162Sfvdl movw %ax,%es 113c4031162Sfvdl movw %ax,%ss 114087b90f6Smaxv 115087b90f6Smaxv /* load flat descriptor table */ 116e491fe87Sjoerg#ifdef __clang__ 117087b90f6Smaxv lgdt (gdt_desc) 118e491fe87Sjoerg#else 119087b90f6Smaxv data32 addr32 lgdt (gdt_desc) 120e491fe87Sjoerg#endif 121087b90f6Smaxv 122087b90f6Smaxv /* enable protected mode */ 123087b90f6Smaxv movl %cr0,%eax 124087b90f6Smaxv orl $CR0_PE,%eax 125087b90f6Smaxv movl %eax,%cr0 126de9139c6Sfvdl ljmpl $0x8,$mp_startup 127de9139c6Sfvdl 128de9139c6Sfvdl_TRMP_LABEL(mp_startup) 129de9139c6Sfvdl .code32 130de9139c6Sfvdl 131a1ad52c3Smaxv movl $0x10,%eax /* data segment */ 132c4031162Sfvdl movw %ax,%ds 133c4031162Sfvdl movw %ax,%ss 134c4031162Sfvdl movw %ax,%es 135c4031162Sfvdl movw %ax,%fs 136c4031162Sfvdl movw %ax,%gs 137c4031162Sfvdl 138*bf301517Smaxv /* bootstrap stack end */ 139*bf301517Smaxv movl $SMP_DATA_STACK,%esp 140c4031162Sfvdl 141c4031162Sfvdl /* First, reset the PSL. */ 142c4031162Sfvdl pushl $PSL_MBO 143c4031162Sfvdl popfl 144c4031162Sfvdl 145a1ad52c3Smaxv /* Enable PSE if available */ 146*bf301517Smaxv movl $SMP_DATA_LARGE,%eax 147*bf301517Smaxv movl (%eax),%eax 14824a1632cSyamt orl %eax,%eax 149a1ad52c3Smaxv jz no_PSE 15024a1632cSyamt movl %cr4,%eax 15124a1632cSyamt orl $CR4_PSE,%eax 15224a1632cSyamt movl %eax,%cr4 153a1ad52c3Smaxvno_PSE: 154a511dc06Sjym 155a1ad52c3Smaxv#ifdef PAE 156a1ad52c3Smaxv /* Enable PAE */ 157d9474223Sjym movl %cr4,%eax 158d9474223Sjym or $CR4_PAE,%eax 159d9474223Sjym movl %eax,%cr4 160d9474223Sjym#endif 161d9474223Sjym 16287ffcc85Smaxv /* 16387ffcc85Smaxv * Set NOX in EFER, if available. 16487ffcc85Smaxv */ 165*bf301517Smaxv movl $SMP_DATA_NOX,%ebx 166*bf301517Smaxv movl (%ebx),%ebx 16787ffcc85Smaxv cmpl $0,%ebx 16887ffcc85Smaxv je no_NOX 16987ffcc85Smaxv movl $MSR_EFER,%ecx 17087ffcc85Smaxv rdmsr 17187ffcc85Smaxv xorl %eax,%eax 17287ffcc85Smaxv orl $(EFER_NXE),%eax 17387ffcc85Smaxv wrmsr 17487ffcc85Smaxvno_NOX: 17587ffcc85Smaxv 17687ffcc85Smaxv /* Load %cr3. */ 177*bf301517Smaxv movl $SMP_DATA_PDIR,%ecx 178*bf301517Smaxv movl (%ecx),%ecx 179a1ad52c3Smaxv movl %ecx,%cr3 /* load PTD addr into MMU */ 18087ffcc85Smaxv 18187ffcc85Smaxv /* Enable paging and the rest of it. */ 182a1ad52c3Smaxv movl %cr0,%eax 183df71dee7Sdsl orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM),%eax 184a1ad52c3Smaxv movl %eax,%cr0 185c4031162Sfvdl 186087b90f6Smaxv /* Wait until BP has done init sequence. */ 1875d1d928fSad1: 18831c3804aSad movl _C_LABEL(cpu_starting),%ecx 1895d1d928fSad pause 1905d1d928fSad testl %ecx,%ecx 1915d1d928fSad jz 1b 192c4031162Sfvdl 19352f55fdaSmaxv movw $(MAXGDTSIZ-1),6(%esp) /* prepare segment descriptor */ 194a1ad52c3Smaxv movl CPU_INFO_GDT(%ecx),%eax /* for our real gdt */ 195c4031162Sfvdl movl %eax,8(%esp) 196c4031162Sfvdl lgdt 6(%esp) 197c4031162Sfvdl jmp 1f 198c4031162Sfvdl nop 199c4031162Sfvdl1: 200a1ad52c3Smaxv movl $GSEL(GDATA_SEL, SEL_KPL),%eax /* switch to new segment */ 201c4031162Sfvdl movl %eax,%ds 202c4031162Sfvdl movl %eax,%es 203c4031162Sfvdl movl %eax,%ss 204c4031162Sfvdl pushl $GSEL(GCODE_SEL, SEL_KPL) 205c4031162Sfvdl pushl $mp_cont 206c4031162Sfvdl lret 207c4031162Sfvdl .align 4,0x0 208c4031162Sfvdl 209a1ad52c3Smaxv_TRMP_LABEL(gdt_table) 210a1ad52c3Smaxv .word 0x0,0x0,0x0,0x0 /* null gdte */ 211a1ad52c3Smaxv GDTE(0x9f,0xcf) /* Kernel text */ 212a1ad52c3Smaxv GDTE(0x93,0xcf) /* Kernel data */ 213a1ad52c3Smaxv_TRMP_LABEL(gdt_desc) 214a1ad52c3Smaxv .word 0x17 /* limit 3 entries */ 215a1ad52c3Smaxv .long gdt_table /* base of gdt */ 216a1ad52c3Smaxv 217a1ad52c3Smaxv_C_LABEL(cpu_spinup_trampoline_end): /* end of code copied to MP_TRAMPOLINE */ 218a1ad52c3Smaxv 219c4031162Sfvdlmp_cont: 220f0301095Syamt movl CPU_INFO_IDLELWP(%ecx),%esi 2213f18fe81Srmind movl L_PCB(%esi),%esi 222c4031162Sfvdl 223c4031162Sfvdl movl PCB_ESP(%esi),%esp 224c4031162Sfvdl movl PCB_EBP(%esi),%ebp 225c4031162Sfvdl 226c4031162Sfvdl /* Switch address space. */ 227c4031162Sfvdl movl PCB_CR3(%esi),%eax 228c4031162Sfvdl movl %eax,%cr3 229087b90f6Smaxv 230c4031162Sfvdl /* load segment registers. */ 231c4031162Sfvdl movl $GSEL(GCPU_SEL, SEL_KPL),%eax 232c4031162Sfvdl movl %eax,%fs 233c4031162Sfvdl xorl %eax,%eax 234c4031162Sfvdl movl %eax,%gs 235087b90f6Smaxv 236c4031162Sfvdl movl PCB_CR0(%esi),%eax 237c4031162Sfvdl movl %eax,%cr0 238c4031162Sfvdl pushl %ecx 239087b90f6Smaxv 240c4031162Sfvdl call _C_LABEL(cpu_hatch) 241ed55ab9bSuebayasiEND(cpu_spinup_trampoline) 242c4031162Sfvdl 243