1*03831d35Sstevel /*
2*03831d35Sstevel  * CDDL HEADER START
3*03831d35Sstevel  *
4*03831d35Sstevel  * The contents of this file are subject to the terms of the
5*03831d35Sstevel  * Common Development and Distribution License (the "License").
6*03831d35Sstevel  * You may not use this file except in compliance with the License.
7*03831d35Sstevel  *
8*03831d35Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*03831d35Sstevel  * or http://www.opensolaris.org/os/licensing.
10*03831d35Sstevel  * See the License for the specific language governing permissions
11*03831d35Sstevel  * and limitations under the License.
12*03831d35Sstevel  *
13*03831d35Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
14*03831d35Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*03831d35Sstevel  * If applicable, add the following below this CDDL HEADER, with the
16*03831d35Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
17*03831d35Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
18*03831d35Sstevel  *
19*03831d35Sstevel  * CDDL HEADER END
20*03831d35Sstevel  */
21*03831d35Sstevel 
22*03831d35Sstevel /*
23*03831d35Sstevel  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*03831d35Sstevel  * Use is subject to license terms.
25*03831d35Sstevel  */
26*03831d35Sstevel 
27*03831d35Sstevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*03831d35Sstevel 
29*03831d35Sstevel /*
30*03831d35Sstevel  * This file is through cpp before being used as
31*03831d35Sstevel  * an inline.  It contains support routines used
32*03831d35Sstevel  * only by DR for the copy-rename sequence.
33*03831d35Sstevel  */
34*03831d35Sstevel 
35*03831d35Sstevel #if defined(lint)
36*03831d35Sstevel #include <sys/types.h>
37*03831d35Sstevel #endif /* lint */
38*03831d35Sstevel 
39*03831d35Sstevel #ifndef	INLINE
40*03831d35Sstevel 
41*03831d35Sstevel #include <sys/asm_linkage.h>
42*03831d35Sstevel 
43*03831d35Sstevel #else /* INLINE */
44*03831d35Sstevel 
45*03831d35Sstevel #define	ENTRY_NP(x)	.inline	x,0
46*03831d35Sstevel #define	retl		/* nop */
47*03831d35Sstevel #define	SET_SIZE(x)	.end
48*03831d35Sstevel 
49*03831d35Sstevel #endif /* INLINE */
50*03831d35Sstevel 
51*03831d35Sstevel #include <sys/privregs.h>
52*03831d35Sstevel #include <sys/sun4asi.h>
53*03831d35Sstevel #include <sys/machparam.h>
54*03831d35Sstevel #include <sys/machthread.h>
55*03831d35Sstevel #include <sys/cheetahregs.h>
56*03831d35Sstevel #include <sys/cheetahasm.h>
57*03831d35Sstevel 
58*03831d35Sstevel /*
59*03831d35Sstevel  * Bcopy routine used by DR to copy
60*03831d35Sstevel  * between physical addresses.
61*03831d35Sstevel  * Borrowed from Starfire DR 2.6.
62*03831d35Sstevel  */
63*03831d35Sstevel #if defined(lint)
64*03831d35Sstevel 
65*03831d35Sstevel /*ARGSUSED*/
66*03831d35Sstevel void
bcopy32_il(uint64_t paddr1,uint64_t paddr2)67*03831d35Sstevel bcopy32_il(uint64_t paddr1, uint64_t paddr2)
68*03831d35Sstevel {}
69*03831d35Sstevel 
70*03831d35Sstevel #else /* lint */
71*03831d35Sstevel 
72*03831d35Sstevel 	ENTRY_NP(bcopy32_il)
73*03831d35Sstevel 	.register %g2, #scratch
74*03831d35Sstevel 	.register %g3, #scratch
75*03831d35Sstevel         rdpr    %pstate, %o4
76*03831d35Sstevel         andn    %o4, PSTATE_IE | PSTATE_AM, %g3		! clear IE, AM bits
77*03831d35Sstevel         wrpr    %g0, %g3, %pstate
78*03831d35Sstevel 
79*03831d35Sstevel         ldxa    [%o0]ASI_MEM, %o2
80*03831d35Sstevel 	add	%o0, 8, %o0
81*03831d35Sstevel         ldxa    [%o0]ASI_MEM, %o3
82*03831d35Sstevel 	add	%o0, 8, %o0
83*03831d35Sstevel         ldxa    [%o0]ASI_MEM, %g1
84*03831d35Sstevel 	add	%o0, 8, %o0
85*03831d35Sstevel         ldxa    [%o0]ASI_MEM, %g2
86*03831d35Sstevel 
87*03831d35Sstevel 	stxa    %o2, [%o1]ASI_MEM
88*03831d35Sstevel 	add	%o1, 8, %o1
89*03831d35Sstevel 	stxa    %o3, [%o1]ASI_MEM
90*03831d35Sstevel 	add	%o1, 8, %o1
91*03831d35Sstevel 	stxa    %g1, [%o1]ASI_MEM
92*03831d35Sstevel 	add	%o1, 8, %o1
93*03831d35Sstevel 	stxa    %g2, [%o1]ASI_MEM
94*03831d35Sstevel 
95*03831d35Sstevel 	stxa	%g0, [%o1]ASI_DC_INVAL	/* flush line from dcache */
96*03831d35Sstevel 	membar	#Sync
97*03831d35Sstevel 
98*03831d35Sstevel 	retl
99*03831d35Sstevel         wrpr    %g0, %o4, %pstate       ! restore earlier pstate register value
100*03831d35Sstevel 	SET_SIZE(bcopy32_il)
101*03831d35Sstevel 
102*03831d35Sstevel #endif /* lint */
103*03831d35Sstevel 
104*03831d35Sstevel #if defined(lint)
105*03831d35Sstevel 
106*03831d35Sstevel /*ARGSUSED*/
107*03831d35Sstevel void
108*03831d35Sstevel flush_ecache_il(uint64_t physaddr, uint_t size, uint_t linesize)
109*03831d35Sstevel {}
110*03831d35Sstevel 
111*03831d35Sstevel #else /* lint */
112*03831d35Sstevel 
113*03831d35Sstevel 	ENTRY_NP(flush_ecache_il)
114*03831d35Sstevel 	rdpr	%pstate, %o3
115*03831d35Sstevel 	andn	%o3, PSTATE_IE | PSTATE_AM, %o4
116*03831d35Sstevel 	wrpr	%g0, %o4, %pstate	! clear AM to access 64 bit physaddr
117*03831d35Sstevel 	GET_CPU_IMPL(%o4)
118*03831d35Sstevel 	cmp	%o4, PANTHER_IMPL
119*03831d35Sstevel 	bne	%xcc, 3f
120*03831d35Sstevel 	  nop
121*03831d35Sstevel 	! Panther needs to flush L2 before L3.
122*03831d35Sstevel 	!
123*03831d35Sstevel 	! We need to free up a temp reg for the L2 flush macro (register usage
124*03831d35Sstevel 	! convention for inlines allows %o0-%o5, %f0-%f31 as temporaries.)
125*03831d35Sstevel 	! Since physaddr is only used for Cheetah, Panther can use %o0 for
126*03831d35Sstevel 	! the L2 flush.
127*03831d35Sstevel 	PN_L2_FLUSHALL(%o0, %o4, %o5)
128*03831d35Sstevel 3:
129*03831d35Sstevel 	ECACHE_FLUSHALL(%o1, %o2, %o0, %o4)
130*03831d35Sstevel 	wrpr	%g0, %o3, %pstate	! restore earlier pstate
131*03831d35Sstevel 	SET_SIZE(flush_ecache_il)
132*03831d35Sstevel 
133*03831d35Sstevel #endif /* lint */
134*03831d35Sstevel 
135*03831d35Sstevel #if defined(lint)
136*03831d35Sstevel 
137*03831d35Sstevel /*ARGUSED*/
138*03831d35Sstevel void
stphysio_il(uint64_t physaddr,u_int value)139*03831d35Sstevel stphysio_il(uint64_t physaddr, u_int value)
140*03831d35Sstevel {}
141*03831d35Sstevel 
142*03831d35Sstevel /*ARGSUSED*/
143*03831d35Sstevel u_int
ldphysio_il(uint64_t physaddr)144*03831d35Sstevel ldphysio_il(uint64_t physaddr)
145*03831d35Sstevel { return(0); }
146*03831d35Sstevel 
147*03831d35Sstevel uint64_t
lddphys_il(uint64_t physaddr)148*03831d35Sstevel lddphys_il(uint64_t physaddr)
149*03831d35Sstevel { return (0x0ull); }
150*03831d35Sstevel 
151*03831d35Sstevel uint64_t
ldxasi_il(uint64_t physaddr,uint_t asi)152*03831d35Sstevel ldxasi_il(uint64_t physaddr, uint_t asi)
153*03831d35Sstevel { return (0x0ull); }
154*03831d35Sstevel 
155*03831d35Sstevel #else /* lint */
156*03831d35Sstevel 
157*03831d35Sstevel 	ENTRY_NP(stphysio_il)
158*03831d35Sstevel 	rdpr	%pstate, %o2		/* read PSTATE reg */
159*03831d35Sstevel 	andn	%o2, PSTATE_IE | PSTATE_AM, %o3
160*03831d35Sstevel 	wrpr	%g0, %o3, %pstate
161*03831d35Sstevel 	stwa	%o1, [%o0]ASI_IO        /* store value via bypass ASI */
162*03831d35Sstevel 	retl
163*03831d35Sstevel 	wrpr	%g0, %o2, %pstate		/* restore the PSTATE */
164*03831d35Sstevel 	SET_SIZE(stphysio_il)
165*03831d35Sstevel 
166*03831d35Sstevel 	!
167*03831d35Sstevel 	! load value at physical address in I/O space
168*03831d35Sstevel 	!
169*03831d35Sstevel 	! u_int   ldphysio_il(uint64_t physaddr)
170*03831d35Sstevel 	!
171*03831d35Sstevel 	ENTRY_NP(ldphysio_il)
172*03831d35Sstevel 	rdpr	%pstate, %o2		/* read PSTATE reg */
173*03831d35Sstevel 	andn	%o2, PSTATE_IE | PSTATE_AM, %o3
174*03831d35Sstevel 	wrpr	%g0, %o3, %pstate
175*03831d35Sstevel 	lduwa	[%o0]ASI_IO, %o0	/* load value via bypass ASI */
176*03831d35Sstevel 	retl
177*03831d35Sstevel 	wrpr	%g0, %o2, %pstate	/* restore pstate */
178*03831d35Sstevel 	SET_SIZE(ldphysio_il)
179*03831d35Sstevel 
180*03831d35Sstevel         !
181*03831d35Sstevel         ! Load long word value at physical address
182*03831d35Sstevel         !
183*03831d35Sstevel         ! uint64_t lddphys_il(uint64_t physaddr)
184*03831d35Sstevel         !
185*03831d35Sstevel         ENTRY_NP(lddphys_il)
186*03831d35Sstevel         rdpr    %pstate, %o4
187*03831d35Sstevel         andn    %o4, PSTATE_IE | PSTATE_AM, %o5
188*03831d35Sstevel         wrpr    %o5, 0, %pstate
189*03831d35Sstevel         ldxa    [%o0]ASI_MEM, %o0
190*03831d35Sstevel         retl
191*03831d35Sstevel         wrpr    %g0, %o4, %pstate       /* restore earlier pstate register value */
192*03831d35Sstevel         SET_SIZE(lddphys_il)
193*03831d35Sstevel 
194*03831d35Sstevel         !
195*03831d35Sstevel         ! Load long word value from designated asi.
196*03831d35Sstevel         !
197*03831d35Sstevel         ! uint64_t ldxasi_il(uint64_t physaddr, uint_t asi)
198*03831d35Sstevel         !
199*03831d35Sstevel         ENTRY_NP(ldxasi_il)
200*03831d35Sstevel         rdpr    %pstate, %o4
201*03831d35Sstevel         andn    %o4, PSTATE_IE | PSTATE_AM, %o5
202*03831d35Sstevel         wrpr    %o5, 0, %pstate
203*03831d35Sstevel 	wr	%o1, 0, %asi
204*03831d35Sstevel         ldxa    [%o0]%asi, %o0
205*03831d35Sstevel         retl
206*03831d35Sstevel         wrpr    %g0, %o4, %pstate       /* restore earlier pstate register value */
207*03831d35Sstevel         SET_SIZE(ldxasi_il)
208*03831d35Sstevel 
209*03831d35Sstevel #endif /* lint */
210*03831d35Sstevel 
211*03831d35Sstevel #if defined(lint)
212*03831d35Sstevel 
213*03831d35Sstevel /*
214*03831d35Sstevel  * Argument to sbdp_exec_script_il is a pointer to:
215*03831d35Sstevel  *
216*03831d35Sstevel  * typedef struct {
217*03831d35Sstevel  *	uint64_t	masr_addr;
218*03831d35Sstevel  *	uint64_t	masr;
219*03831d35Sstevel  *	uint_t	asi;
220*03831d35Sstevel  *	uint_t		_filler;
221*03831d35Sstevel  * } sbdp_rename_script_t;
222*03831d35Sstevel  */
223*03831d35Sstevel 
224*03831d35Sstevel /*ARGUSED*/
225*03831d35Sstevel void
226*03831d35Sstevel sbdp_exec_script_il(void *sp)
227*03831d35Sstevel {}
228*03831d35Sstevel 
229*03831d35Sstevel #else /* lint */
230*03831d35Sstevel 
231*03831d35Sstevel 	ENTRY_NP(sbdp_exec_script_il)
232*03831d35Sstevel 	mov	%o0, %o2
233*03831d35Sstevel 
234*03831d35Sstevel 	rdpr	%pstate, %o4		/* read PSTATE reg */
235*03831d35Sstevel 	andn	%o4, PSTATE_IE | PSTATE_AM, %o1
236*03831d35Sstevel 	wrpr	%g0, %o1, %pstate
237*03831d35Sstevel 
238*03831d35Sstevel 	membar #Sync
239*03831d35Sstevel 
240*03831d35Sstevel 0:					/* cache script */
241*03831d35Sstevel 	ldx	[%o2], %o1
242*03831d35Sstevel 	ldx	[%o2 + 16], %o1
243*03831d35Sstevel 	cmp	%g0, %o1
244*03831d35Sstevel 	bnz,pt	%xcc, 0b
245*03831d35Sstevel 	add	%o2, 24, %o2
246*03831d35Sstevel 
247*03831d35Sstevel 	b	2f			/* cache it */
248*03831d35Sstevel 	nop
249*03831d35Sstevel 1:
250*03831d35Sstevel 	ldx	[%o0], %o1
251*03831d35Sstevel 	brz,pn	%o1, 5f
252*03831d35Sstevel 	ld	[%o0 + 16], %o2
253*03831d35Sstevel 	wr	%o2, 0, %asi
254*03831d35Sstevel 	b	3f
255*03831d35Sstevel 	nop
256*03831d35Sstevel 2:
257*03831d35Sstevel 	b	4f			/* cache it */
258*03831d35Sstevel 	nop
259*03831d35Sstevel 3:
260*03831d35Sstevel 	ldx	[%o0 + 8], %o2
261*03831d35Sstevel 	stxa	%o2, [%o1]%asi
262*03831d35Sstevel 	membar	#Sync
263*03831d35Sstevel 	add	%o0, 24, %o0
264*03831d35Sstevel 	b	1b
265*03831d35Sstevel 	ldxa	[%o1]%asi, %g0	/* read back to insure written */
266*03831d35Sstevel 4:
267*03831d35Sstevel 	b	1b			/* caching done */
268*03831d35Sstevel 	nop
269*03831d35Sstevel 5:
270*03831d35Sstevel 	retl
271*03831d35Sstevel 	wrpr	%g0, %o4, %pstate	/* restore the PSTATE */
272*03831d35Sstevel 	SET_SIZE(sbdp_exec_script_il)
273*03831d35Sstevel 
274*03831d35Sstevel #endif /* lint */
275