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				;\
680:								;\
69        stxa    %g0, [tmp1]ASI_EC_DIAG				;\
70        membar  #Sync						;\
71        cmp     %g0, tmp1					;\
72        bne,pt  %icc, 0b					;\
73        sub     tmp1, arg2, tmp1				;\
741:
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							;\
971:								;\
98	set	CH_ICACHE_SIZE, reg1				;\
99	set	CH_ICACHE_LSIZE, reg2				;\
1002:
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
195sbdp_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
2331:
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
2472:
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
2613:
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
284