1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #if defined(lint) 27 #include <sys/types.h> 28 #else /* lint */ 29 #include "assym.h" 30 #endif /* lint */ 31 32 #include <sys/asm_linkage.h> 33 #include <sys/machthread.h> 34 #include <sys/param.h> 35 #include <sys/vm_machparam.h> 36 #include <sys/privregs.h> 37 #include <sys/intreg.h> 38 #include <sys/vis.h> 39 #include <sys/clock.h> 40 #include <vm/hat_sfmmu.h> 41 42 #if !defined(lint) 43 .weak cpu_feature_init 44 .type cpu_feature_init, #function 45 #endif /* lint */ 46 47 #if !defined(lint) 48 .weak cpu_early_feature_init 49 .type cpu_early_feature_init, #function 50 #endif /* lint */ 51 52 /* 53 * Processor initialization 54 * 55 * This is the kernel entry point for other cpus except the first one. 56 * When the prom jumps to this location we are still executing with the 57 * prom's trap table. It expects the cpuid as its first parameter. 58 */ 59 60 #if defined(lint) 61 62 /* ARGSUSED */ 63 void 64 cpu_startup(int cpuid) 65 {} 66 67 #else /* lint */ 68 69 ! allocate a temporary stack to run on while we figure who and 70 ! what we are. 71 .seg ".data" 72 .align 8 73 etmpstk: 74 .skip 2048 75 tmpstk: 76 .word 0 77 78 ENTRY_NP(cpu_startup) 79 ! 80 ! Initialize CPU state registers 81 ! 82 ! The boot cpu and other cpus are different. The boot cpu has gone 83 ! through boot, and its state might be affected as a result. The 84 ! other cpus' states come directly from the prom. 85 ! 86 wrpr %g0, PSTATE_KERN, %pstate 87 wr %g0, %g0, %fprs ! clear fprs 88 CLEARTICKNPT ! allow user rdtick 89 90 ! 91 ! Set up temporary stack 92 ! 93 set tmpstk, %g1 94 sub %g1, SA(KFPUSIZE+GSR_SIZE), %g2 95 and %g2, 0x3F, %g3 96 sub %g2, %g3, %o2 97 sub %o2, SA(MINFRAME) + STACK_BIAS, %sp 98 99 mov %o0, %l1 ! save cpuid 100 101 call sfmmu_mp_startup 102 sub %g0, 1, THREAD_REG ! catch any curthread acceses 103 104 ! On OPL platforms, context page size TLB programming must be enabled in 105 ! ASI_MEMCNTL. To avoid Olympus-C and Jupiter sTLB errata (strands with 106 ! different TLB page size settings), this must be done here before any 107 ! reference to non-nucleus memory. An early hook is added to perform 108 ! cpu specific initialization. 109 ! 110 sethi %hi(cpu_early_feature_init), %o0 111 or %o0, %lo(cpu_early_feature_init), %o0 112 brz %o0, 0f 113 nop 114 call %o0 115 nop 116 117 0: 118 ! SET_KCONTEXTREG(reg0, reg1, reg2, reg3, reg4, label1, label2, label3) 119 SET_KCONTEXTREG(%o0, %g1, %g2, %g3, %l3, l1, l2, l3) 120 121 ! We are now running on the kernel's trap table. 122 ! 123 ! It is very important to have a thread pointer and a cpu struct 124 ! *before* calling into C routines . 125 ! Otherwise, overflow/underflow handlers, etc. can get very upset! 126 ! 127 ! 128 ! We don't want to simply increment 129 ! ncpus right now because it is in the cache, and 130 ! we don't have the cache on yet for this CPU. 131 ! 132 set cpu, %l3 133 sll %l1, CPTRSHIFT, %l2 ! offset into CPU vector. 134 ldn [%l3 + %l2], %l3 ! pointer to CPU struct 135 ldn [%l3 + CPU_THREAD], THREAD_REG ! set thread pointer (%g7) 136 137 ! 138 ! Set up any required cpu feature 139 ! 140 sethi %hi(cpu_feature_init), %o0 141 or %o0, %lo(cpu_feature_init), %o0 142 brz %o0, 1f 143 nop 144 call %o0 145 nop 146 147 1: 148 ! 149 ! Resume the thread allocated for the CPU. 150 ! 151 ldn [THREAD_REG + T_PC], %i7 152 ldn [THREAD_REG + T_SP], %fp 153 ret ! "return" into the thread 154 restore ! WILL cause underflow 155 SET_SIZE(cpu_startup) 156 157 #endif /* lint */