xref: /titanic_41/usr/src/uts/sun4u/serengeti/ml/sbdp_asm.s (revision 40db2e2b777b79f3dd0d6d9629593a07f86b9c0a)
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				;\
780:								;\
79        stxa    %g0, [tmp1]ASI_EC_DIAG				;\
80        membar  #Sync						;\
81        cmp     %g0, tmp1					;\
82        bne,pt  %icc, 0b					;\
83        sub     tmp1, arg2, tmp1				;\
841:
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							;\
1071:								;\
108	set	CH_ICACHE_SIZE, reg1				;\
109	set	CH_ICACHE_LSIZE, reg2				;\
1102:
111
112#endif  /* !lint */
113
114#if defined(lint)
115
116/*ARGSUSED*/
117void
118sbdp_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
216sbdp_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 */
231void
232sgdr_mem_blkcopy(caddr_t src, caddr_t dst, u_int linecount, u_int linesize)
233{}
234
235void
236stdmcdecode(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
2741:
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
2882:
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
3023:
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 */
326