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 */