1 /* $OpenBSD: mptramp.s,v 1.8 2007/02/20 21:15:01 tom 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 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * Copyright (c) 1999 Stefan Grefen 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by the NetBSD 55 * Foundation, Inc. and its contributors. 56 * 4. Neither the name of The NetBSD Foundation nor the names of its 57 * contributors may be used to endorse or promote products derived 58 * from this software without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 61 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 */ 72 /* 73 * MP startup ... 74 * the stuff from cpu_spinup_trampoline to mp_startup 75 * is copied into the first 640 KB 76 * 77 * We startup the processors now when the kthreads become ready. 78 * The steps are: 79 * 1) Get the processors running kernel-code from a special 80 * page-table and stack page, do chip identification. 81 * 2) halt the processors waiting for them to be enabled 82 * by a idle-thread 83 */ 84 85 #include "assym.h" 86 #include <machine/param.h> 87 #include <machine/asm.h> 88 #include <machine/specialreg.h> 89 #include <machine/segments.h> 90 #include <machine/gdt.h> 91 #include <machine/mpbiosvar.h> 92 #include <machine/i82489reg.h> 93 94 #define GDTE(a,b) .byte 0xff,0xff,0x0,0x0,0x0,a,b,0x0 95 #define _RELOC(x) ((x) - KERNBASE) 96 #define RELOC(x) _RELOC(_C_LABEL(x)) 97 98 #define _TRMP_LABEL(a) a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE 99 100 /* 101 * Debug code to stop aux. processors in various stages based on the 102 * value in cpu_trace. 103 * 104 * %edi points at cpu_trace; cpu_trace[0] is the "hold point"; 105 * cpu_trace[1] is the point which the cpu has reached. 106 * cpu_trace[2] is the last value stored by HALTT. 107 */ 108 109 110 #ifdef MPDEBUG 111 #define HALT(x) 1: movl (%edi),%ebx;cmpl $ x,%ebx ; jle 1b ; movl $x,4(%edi) 112 #define HALTT(x,y) movl y,8(%edi); HALT(x) 113 #else 114 #define HALT(x) /**/ 115 #define HALTT(x,y) /**/ 116 #endif 117 118 .globl _C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor) 119 .globl _C_LABEL(cpuid_level),_C_LABEL(cpu_feature) 120 121 .global _C_LABEL(cpu_spinup_trampoline) 122 .global _C_LABEL(cpu_spinup_trampoline_end) 123 .global _C_LABEL(cpu_hatch) 124 .global _C_LABEL(mp_pdirpa) 125 .global _C_LABEL(gdt), _C_LABEL(local_apic) 126 127 .text 128 .align 4,0x0 129 .code16 130 _C_LABEL(cpu_spinup_trampoline): 131 cli 132 xorw %ax, %ax 133 movw %ax, %ds 134 movw %ax, %es 135 movw %ax, %ss 136 data32 addr32 lgdt (gdt_desc) # load flat descriptor table 137 movl %cr0, %eax # get cr0 138 orl $0x1, %eax # enable protected mode 139 movl %eax, %cr0 # doit 140 ljmp $0x8, $mp_startup 141 142 _TRMP_LABEL(mp_startup) 143 .code32 144 145 movl $0x10, %eax # data segment 146 movw %ax, %ds 147 movw %ax, %ss 148 movw %ax, %es 149 movw %ax, %fs 150 movw %ax, %gs 151 movl $(MP_TRAMPOLINE+NBPG-16),%esp # bootstrap stack end, 152 # with scratch space.. 153 154 #ifdef MPDEBUG 155 leal RELOC(cpu_trace),%edi 156 #endif 157 158 HALT(0x1) 159 /* First, reset the PSL. */ 160 pushl $PSL_MBO 161 popfl 162 163 movl RELOC(mp_pdirpa),%ecx 164 HALTT(0x5,%ecx) 165 166 /* Load base of page directory and enable mapping. */ 167 movl %ecx,%cr3 # load ptd addr into mmu 168 movl %cr0,%eax # get control word 169 # enable paging & NPX emulation 170 orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_EM|CR0_MP|CR0_WP),%eax 171 movl %eax,%cr0 # and let's page NOW! 172 173 #ifdef MPDEBUG 174 leal _C_LABEL(cpu_trace),%edi 175 #endif 176 HALT(0x6) 177 178 # ok, we're now running with paging enabled and sharing page tables with cpu0. 179 # figure out which processor we really are, what stack we should be on, etc. 180 181 movl _C_LABEL(local_apic)+LAPIC_ID,%ecx 182 shrl $LAPIC_ID_SHIFT,%ecx 183 leal 0(,%ecx,4),%ecx 184 movl _C_LABEL(cpu_info)(%ecx),%ecx 185 186 HALTT(0x7, %ecx) 187 188 # %ecx points at our cpu_info structure.. 189 190 movw $((MAXGDTSIZ*8) - 1), 6(%esp) # prepare segment descriptor 191 movl CPU_INFO_GDT(%ecx), %eax # for real gdt 192 movl %eax, 8(%esp) 193 HALTT(0x8, %eax) 194 lgdt 6(%esp) 195 HALT(0x9) 196 jmp 1f 197 nop 198 1: 199 HALT(0xa) 200 movl $GSEL(GDATA_SEL, SEL_KPL),%eax #switch to new segment 201 HALTT(0x10, %eax) 202 movw %ax,%ds 203 HALT(0x11) 204 movw %ax,%es 205 HALT(0x12) 206 movw %ax,%ss 207 HALT(0x13) 208 pushl $GSEL(GCODE_SEL, SEL_KPL) 209 pushl $mp_cont 210 HALT(0x14) 211 lret 212 .align 4,0x0 213 _TRMP_LABEL(gdt_table) 214 .word 0x0,0x0,0x0,0x0 # null GDTE 215 GDTE(0x9f,0xcf) # Kernel text 216 GDTE(0x93,0xcf) # Kernel data 217 _TRMP_LABEL(gdt_desc) 218 .word 0x17 # limit 3 entries 219 .long gdt_table # where is gdt 220 221 _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE 222 mp_cont: 223 224 movl CPU_INFO_IDLE_PCB(%ecx),%esi 225 226 # %esi now points at our PCB. 227 228 HALTT(0x19, %esi) 229 230 movl PCB_ESP(%esi),%esp 231 movl PCB_EBP(%esi),%ebp 232 233 HALT(0x20) 234 /* Switch address space. */ 235 movl PCB_CR3(%esi),%eax 236 HALTT(0x22, %eax) 237 movl %eax,%cr3 238 HALT(0x25) 239 /* Load segment registers. */ 240 movl $GSEL(GCPU_SEL, SEL_KPL),%eax 241 HALTT(0x26,%eax) 242 movl %eax,%fs 243 xorl %eax,%eax 244 HALTT(0x27,%eax) 245 movl %eax,%gs 246 movl PCB_CR0(%esi),%eax 247 HALTT(0x28,%eax) 248 movl %eax,%cr0 249 HALTT(0x30,%ecx) 250 pushl %ecx 251 call _C_LABEL(cpu_hatch) 252 HALT(0x33) 253 xorl %esi,%esi 254 jmp _C_LABEL(idle_start) 255 256 .data 257 _C_LABEL(mp_pdirpa): 258 .long 0 259 #ifdef MPDEBUG 260 .global _C_LABEL(cpu_trace) 261 _C_LABEL(cpu_trace): 262 .long 0x40 263 .long 0xff 264 .long 0xff 265 #endif