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