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 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * This file is through cpp before being used as
31 * an inline. It contains support routines used
32 * only by DR for the copy-rename sequence.
33 */
34
35 #if defined(lint)
36 #include <sys/types.h>
37 #include <sys/sbd_ioctl.h>
38 #include <sys/sbdp_priv.h>
39 #else
40 #include "assym.h"
41 #endif /* lint */
42
43 #include <sys/asm_linkage.h>
44 #include <sys/param.h>
45 #include <sys/privregs.h>
46 #include <sys/machasi.h>
47 #include <sys/mmu.h>
48 #include <sys/machthread.h>
49 #include <sys/pte.h>
50 #include <sys/stack.h>
51 #include <sys/vis.h>
52 #include <sys/param.h>
53 #include <sys/errno.h>
54 #include <sys/vtrace.h>
55 #include <sys/clock.h>
56 #include <sys/asi.h>
57 #include <sys/fsr.h>
58 #include <sys/cheetahregs.h>
59 #include <sys/cheetahasm.h>
60
61 #ifndef lint
62
63 /*
64 * Invalidating the E$ tags is only needed on Cheetah following
65 * the manual displacement flush. The internal flush ASI used by
66 * Cheetahplus, Jaguar, and Panther will invalidate the cache lines.
67 *
68 * arg1 = ecache_size
69 * arg2 = ecache_linesize
70 */
71 #define ECACHE_FLUSHTAGS(arg1, arg2, tmp1) \
72 GET_CPU_IMPL(tmp1) ;\
73 srlx arg1, 1, arg1 ;\
74 cmp tmp1, CHEETAH_IMPL ;\
75 bne 1f ;\
76 nop ;\
77 sub arg1, arg2, tmp1 ;\
78 0: ;\
79 stxa %g0, [tmp1]ASI_EC_DIAG ;\
80 membar #Sync ;\
81 cmp %g0, tmp1 ;\
82 bne,pt %icc, 0b ;\
83 sub tmp1, arg2, tmp1 ;\
84 1:
85
86
87 #define SWITCH_STACK(estk) \
88 flushw ;\
89 sub estk, SA(KFPUSIZE+GSR_SIZE), estk ;\
90 andn estk, 0x3f, estk ;\
91 sub estk, SA(MINFRAME) + STACK_BIAS, %sp ;\
92 mov estk, %fp
93
94 /*
95 * Returns icache size and linesize in reg1 and reg2, respectively.
96 * Panther has a larger icache compared to Cheetahplus and Jaguar.
97 */
98 #define GET_ICACHE_PARAMS(reg1, reg2) \
99 GET_CPU_IMPL(reg1) ;\
100 cmp reg1, PANTHER_IMPL ;\
101 bne %xcc, 1f ;\
102 nop ;\
103 set PN_ICACHE_SIZE, reg1 ;\
104 set PN_ICACHE_LSIZE, reg2 ;\
105 ba 2f ;\
106 nop ;\
107 1: ;\
108 set CH_ICACHE_SIZE, reg1 ;\
109 set CH_ICACHE_LSIZE, reg2 ;\
110 2:
111
112 #endif /* !lint */
113
114 #if defined(lint)
115
116 /*ARGSUSED*/
117 void
118 sbdp_shutdown_asm(sbdp_shutdown_t *shutshown)
119 {}
120
121 #else /* lint */
122
123 ENTRY_NP(sbdp_shutdown_asm)
124 ! %o0 = address of sbdp_shutdown_t structure passed in
125 !
126 ! struct sbdp_shutdown {
127 ! uint64_t estack; -> %o0
128 ! uint64_t flushaddr; -> %o1
129 ! uint32_t size; -> %o2
130 ! uint32_t linesize; -> %g1
131 ! uint64_t physaddr; -> %o0
132 ! } sbdp_shutdown_t;
133 !
134 membar #LoadStore
135 mov %o0, %o4
136 ldx [%o4], %o0
137 ldx [%o4 + 8], %o1
138 ld [%o4 + 16], %o2
139 ld [%o4 + 20], %g1
140
141 !
142 ! Switch stack pointer to bbsram
143 !
144 SWITCH_STACK(%o0)
145
146 ldx [%o4 + 24], %o0 !save physaddr in %o0
147 !
148 ! Get some globals
149 !
150 ! ecache_linesize already in %g1
151
152 sethi %hi(dcache_linesize), %g2
153 ld [%g2 + %lo(dcache_linesize)], %g2
154
155 sethi %hi(dcache_size), %g3
156 ld [%g3 + %lo(dcache_size)], %g3
157
158 !
159 ! Save the E$ size
160 !
161 mov %o2, %o5
162 !
163 ! Flush E$
164 !
165 rdpr %pstate, %o3
166 andn %o3, PSTATE_IE | PSTATE_AM, %o4
167 wrpr %g0, %o4, %pstate
168
169 ! Panther needs to flush L2 before L3 cache.
170 PN_L2_FLUSHALL(%o4, %g4, %g5)
171
172 ECACHE_FLUSHALL(%o2, %g1, %o1, %o4)
173
174 wrpr %g0, %o3, %pstate
175
176 !
177 ! Invalidate the E$ tags (Cheetah only).
178 !
179 ECACHE_FLUSHTAGS(%o5, %g1, %o3)
180
181 !
182 ! %o2 & %o3 now available
183 !
184
185 membar #Sync
186
187 !
188 ! Flush D$
189 !
190 CH_DCACHE_FLUSHALL(%g3, %g2, %o3)
191
192 !
193 ! Flush I$
194 !
195 GET_ICACHE_PARAMS(%g5, %g4)
196 CH_ICACHE_FLUSHALL(%g5, %g4, %o3, %o4)
197
198 membar #Sync
199
200 !
201 ! Flush all unlocked dtlb's & itlb's
202 !
203 sethi %hi(FLUSH_ADDR), %g3
204 set DEMAP_ALL_TYPE, %g1
205 stxa %g0, [%g1]ASI_DTLB_DEMAP
206 stxa %g0, [%g1]ASI_ITLB_DEMAP
207 flush %g3
208
209 sir 0
210 SET_SIZE(sbdp_shutdown_asm)
211
212 .global sbdp_shutdown_asm_end
213
214 .skip 2048
215
216 sbdp_shutdown_asm_end:
217
218 #endif /* lint */
219
220
221 #if defined(lint)
222
223 #else /* lint */
224 #include "assym.h"
225 #endif /* lint */
226
227 #define TT_HSM 0x99
228
229 #if defined(lint)
230 /* ARGSUSED */
231 void
232 sgdr_mem_blkcopy(caddr_t src, caddr_t dst, u_int linecount, u_int linesize)
233 {}
234
235 void
236 stdmcdecode(uint64_t physaddr, uint64_t value)
237 {
238 physaddr = physaddr;
239 value = value;
240 }
241
242 #else /* !lint */
243 !
244 ! Move a single cache line of data. Survive UE and CE on the read
245 !
246 ! i0 = src va
247 ! i1 = dst va
248 ! i2 = line count
249 ! i3 = line size
250 ! i4 = cache of fpu state
251 !
252 ENTRY(sgdr_mem_blkcopy)
253
254 ! TODO: can we safely SAVE here
255 save %sp, -SA(MINFRAME + 2*64), %sp
256
257 ! XXX do we need to save the state of the fpu?
258 rd %fprs, %i4
259 btst (FPRS_DU|FPRS_DL|FPRS_FEF), %i4
260
261 ! always enable FPU
262 wr %g0, FPRS_FEF, %fprs
263
264 bz,a 1f
265 nop
266
267 ! save in-use fpregs on stack
268 membar #Sync
269 add %fp, STACK_BIAS - 81, %o2
270 and %o2, -64, %o2
271 stda %d0, [%o2]ASI_BLK_P
272 membar #Sync
273
274 1:
275 brz,pn %i2, 2f ! while (linecount) {
276 nop
277 ldda [%i0]ASI_BLK_P, %d0 ! *dst = *src;
278 membar #Sync
279 stda %d0, [%i1]ASI_BLK_COMMIT_P
280 membar #Sync
281
282 add %i0, %i3, %i0 ! dst++, src++;
283 add %i1, %i3, %i1
284
285 ba 1b ! linecount-- }
286 dec %i2
287
288 2:
289 membar #Sync
290
291 ! restore fp to the way we got it
292 btst (FPRS_DU|FPRS_DL|FPRS_FEF), %i4
293 bz,a 3f
294 nop
295
296 ! restore fpregs from stack
297 add %fp, STACK_BIAS - 81, %o2
298 and %o2, -64, %o2
299 ldda [%o2]ASI_BLK_P, %d0
300 membar #Sync
301
302 3:
303 wr %g0, %i4, %fprs ! fpu back to the way it was
304 ret
305 restore
306 SET_SIZE(sgdr_mem_blkcopy)
307
308 ! Store long word value at mc regs
309 !
310 ! void stdmcdecode(uint64_t physaddr, uint64_t value)
311 !
312 ENTRY(stdmcdecode)
313 /*
314 * disable interrupts, clear Address Mask to access 64 bit physaddr
315 */
316 rdpr %pstate, %o4
317 andn %o4, PSTATE_IE | PSTATE_AM, %o5
318 wrpr %o5, 0, %pstate ! clear IE, AM bits
319 stxa %o1, [%o0]ASI_MC_DECODE
320 membar #Sync
321 retl
322 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
323 SET_SIZE(stdmcdecode)
324
325 #endif /* lint */