8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / uts / sun4u / sys / machthread.h
blob7b844bea44637825453f1d3dbeeadbac331e0518
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_MACHTHREAD_H
27 #define _SYS_MACHTHREAD_H
29 #pragma ident "%Z%%M% %I% %E% SMI"
31 #include <sys/asi.h>
32 #include <sys/sun4asi.h>
33 #include <sys/machasi.h>
34 #include <sys/bitmap.h>
35 #include <sys/opl_olympus_regs.h>
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
41 #ifdef _ASM
43 #define THREAD_REG %g7 /* pointer to current thread data */
46 * Get the processor implementation from the version register.
48 #define GET_CPU_IMPL(out) \
49 rdpr %ver, out; \
50 srlx out, 32, out; \
51 sll out, 16, out; \
52 srl out, 16, out;
54 #ifdef _STARFIRE
56 * CPU_INDEX(r, scr)
57 * Returns cpu id in r.
58 * On Starfire, this is read from the Port Controller's Port ID
59 * register in local space.
61 * Need to load the 64 bit address of the PC's PortID reg
62 * using only one register. Kludge the 41 bits address constant to
63 * be 32bits by shifting it 12 bits to the right first.
65 #define LOCAL_PC_PORTID_ADDR_SRL12 0x1FFF4000
66 #define PC_PORT_ID 0xD0
68 #define CPU_INDEX(r, scr) \
69 rdpr %pstate, scr; \
70 andn scr, PSTATE_IE | PSTATE_AM, r; \
71 wrpr r, 0, %pstate; \
72 set LOCAL_PC_PORTID_ADDR_SRL12, r; \
73 sllx r, 12, r; \
74 or r, PC_PORT_ID, r; \
75 lduwa [r]ASI_IO, r; \
76 wrpr scr, 0, %pstate
78 #elif defined(_OPL)
80 * For OPL platform, we get CPU_INDEX from ASI_EIDR.
82 #define CPU_INDEX(r, scr) \
83 ldxa [%g0]ASI_EIDR, r; \
84 and r, 0xfff, r
87 #else /* _STARFIRE */
90 * UPA supports up to 32 devices while Safari supports up to
91 * 1024 devices (utilizing the SSM protocol). Based upon the
92 * value of NCPU, a 5- or 10-bit mask will be needed for
93 * extracting the cpu id.
95 #if NCPU > 32
96 #define CPU_MASK 0x3ff
97 #else
98 #define CPU_MASK 0x1f
99 #endif /* NCPU > 32 */
102 * CPU_INDEX(r, scr)
103 * Returns cpu id in r.
104 * For UPA based systems, the cpu id corresponds to the mid field in
105 * the UPA config register. For Safari based machines, the cpu id
106 * corresponds to the aid field in the Safari config register.
108 * XXX - scr reg is not used here.
110 #define CPU_INDEX(r, scr) \
111 ldxa [%g0]ASI_UPA_CONFIG, r; \
112 srlx r, 17, r; \
113 and r, CPU_MASK, r
115 #endif /* _STARFIRE */
118 * Given a cpu id extract the appropriate word
119 * in the cpuset mask for this cpu id.
121 #if CPUSET_SIZE > CLONGSIZE
122 #define CPU_INDEXTOSET(base, index, scr) \
123 srl index, BT_ULSHIFT, scr; \
124 and index, BT_ULMASK, index; \
125 sll scr, CLONGSHIFT, scr; \
126 add base, scr, base
127 #else
128 #define CPU_INDEXTOSET(base, index, scr)
129 #endif /* CPUSET_SIZE */
133 * Assembly macro to find address of the current CPU.
134 * Used when coming in from a user trap - cannot use THREAD_REG.
135 * Args are destination register and one scratch register.
137 #define CPU_ADDR(reg, scr) \
138 .global cpu; \
139 CPU_INDEX(scr, reg); \
140 sll scr, CPTRSHIFT, scr; \
141 set cpu, reg; \
142 ldn [reg + scr], reg
144 #define CINT64SHIFT 3
147 * Assembly macro to find the physical address of the current CPU.
148 * All memory references using VA must be limited to nucleus
149 * memory to avoid any MMU side effect.
151 #define CPU_PADDR(reg, scr) \
152 .global cpu_pa; \
153 CPU_INDEX(scr, reg); \
154 sll scr, CINT64SHIFT, scr; \
155 set cpu_pa, reg; \
156 ldx [reg + scr], reg
158 #endif /* _ASM */
161 * If a high level trap handler decides to call sys_trap() to execute some
162 * base level code, context and other registers must be set to proper
163 * values to run kernel. This is true for most part of the kernel, except
164 * for user_rtt, a substantial part of which is executed with registers
165 * ready to run user code. The following macro may be used to detect this
166 * condition and handle it. Please note that, in general, we can't restart
167 * arbitrary piece of code running at tl > 0; user_rtt is a special case
168 * that can be handled.
170 * Entry condition:
172 * %tl = 2
173 * pstate.ag = 1
175 * Register usage:
177 * scr1, scr2 - destroyed
178 * normal %g5 and %g6 - destroyed
181 /* BEGIN CSTYLED */
182 #define RESET_USER_RTT_REGS(scr1, scr2, label) \
183 /* \
184 * do nothing if %tl != 2. this an attempt to stop this \
185 * piece of code from executing more than once before going \
186 * back to TL=0. more specifically, the changes we are doing \
187 * to %wstate, %canrestore and %otherwin can't be done more \
188 * than once before going to TL=0. note that it is okay to \
189 * execute this more than once if we restart at user_rtt and \
190 * come back from there. \
191 */ \
192 rdpr %tl, scr1; \
193 cmp scr1, 2; \
194 bne,a,pn %xcc, label; \
195 nop; \
196 /* \
197 * read tstate[2].%tpc. do nothing if it is not \
198 * between rtt_ctx_start and rtt_ctx_end. \
199 */ \
200 rdpr %tpc, scr1; \
201 set rtt_ctx_end, scr2; \
202 cmp scr1, scr2; \
203 bgu,a,pt %xcc, label; \
204 nop; \
205 set rtt_ctx_start, scr2; \
206 cmp scr1, scr2; \
207 blu,a,pt %xcc, label; \
208 nop; \
209 /* \
210 * pickup tstate[2].cwp \
211 */ \
212 rdpr %tstate, scr1; \
213 and scr1, TSTATE_CWP, scr1; \
214 /* \
215 * set tstate[1].cwp to tstate[2].cwp. fudge \
216 * tstate[1].tpc and tstate[1].tnpc to restart \
217 * user_rtt. \
218 */ \
219 wrpr %g0, 1, %tl; \
220 set TSTATE_KERN | TSTATE_IE, scr2; \
221 or scr1, scr2, scr2; \
222 wrpr %g0, scr2, %tstate; \
223 set user_rtt, scr1; \
224 wrpr %g0, scr1, %tpc; \
225 add scr1, 4, scr1; \
226 wrpr %g0, scr1, %tnpc; \
227 /* \
228 * restore %tl \
229 */ \
230 wrpr %g0, 2, %tl; \
231 /* \
232 * set %wstate \
233 */ \
234 rdpr %wstate, scr1; \
235 sllx scr1, WSTATE_SHIFT, scr1; \
236 wrpr scr1, WSTATE_K64, %wstate; \
237 /* \
238 * setup window registers \
239 * %cleanwin <-- nwin - 1 \
240 * %otherwin <-- %canrestore \
241 * %canrestore <-- 0 \
242 */ \
243 sethi %hi(nwin_minus_one), scr1; \
244 ld [scr1 + %lo(nwin_minus_one)], scr1; \
245 wrpr %g0, scr1, %cleanwin; \
246 rdpr %canrestore, scr1; \
247 wrpr %g0, scr1, %otherwin; \
248 wrpr %g0, 0, %canrestore; \
249 /* \
250 * set THREAD_REG, as we have restored user \
251 * registers in user_rtt. we trash %g5 and %g6 \
252 * in the process. \
253 */ \
254 rdpr %pstate, scr1; \
255 wrpr scr1, PSTATE_AG, %pstate; \
256 /* \
257 * using normal globals now \
258 */ \
259 CPU_ADDR(%g5, %g6); \
260 ldn [%g5 + CPU_THREAD], %g6; \
261 mov %g6, THREAD_REG; \
262 rdpr %pstate, %g5; \
263 wrpr %g5, PSTATE_AG, %pstate; \
264 /* \
265 * back to alternate globals. \
266 * set PCONTEXT to run kernel. \
267 * A demap of I/DTLB is required if the nucleus bits differ \
268 * from kcontextreg. \
269 */ \
270 mov MMU_PCONTEXT, scr1; \
271 sethi %hi(kcontextreg), scr2; \
272 ldx [scr2 + %lo(kcontextreg)], scr2; \
273 ldxa [scr1]ASI_MMU_CTX, scr1; \
274 xor scr2, scr1, scr1; \
275 srlx scr1, CTXREG_NEXT_SHIFT, scr1; \
276 /* \
277 * If N_pgsz0/1 changed, need to demap. \
278 */ \
279 brz scr1, label/**/_0; \
280 nop; \
281 mov DEMAP_ALL_TYPE, scr1; \
282 stxa %g0, [scr1]ASI_DTLB_DEMAP; \
283 stxa %g0, [scr1]ASI_ITLB_DEMAP; \
284 label/**/_0: \
285 mov MMU_PCONTEXT, scr1; \
286 stxa scr2, [scr1]ASI_MMU_CTX; \
287 sethi %hi(FLUSH_ADDR), scr1; \
288 flush scr1
290 /* END CSTYLED */
292 #ifdef __cplusplus
294 #endif
296 #endif /* _SYS_MACHTHREAD_H */