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 2004 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 #endif /* lint */
38 
39 #ifndef	INLINE
40 
41 #include <sys/asm_linkage.h>
42 
43 #else /* INLINE */
44 
45 #define	ENTRY_NP(x)	.inline	x,0
46 #define	retl		/* nop */
47 #define	SET_SIZE(x)	.end
48 
49 #endif /* INLINE */
50 
51 #include <sys/privregs.h>
52 #include <sys/sun4asi.h>
53 #include <sys/machparam.h>
54 #include <sys/machthread.h>
55 #include <sys/cheetahregs.h>
56 #include <sys/cheetahasm.h>
57 
58 /*
59  * Bcopy routine used by DR to copy
60  * between physical addresses.
61  * Borrowed from Starfire DR 2.6.
62  */
63 #if defined(lint)
64 
65 /*ARGSUSED*/
66 void
bcopy32_il(uint64_t paddr1,uint64_t paddr2)67 bcopy32_il(uint64_t paddr1, uint64_t paddr2)
68 {}
69 
70 #else /* lint */
71 
72 	ENTRY_NP(bcopy32_il)
73 	.register %g2, #scratch
74 	.register %g3, #scratch
75         rdpr    %pstate, %o4
76         andn    %o4, PSTATE_IE | PSTATE_AM, %g3		! clear IE, AM bits
77         wrpr    %g0, %g3, %pstate
78 
79         ldxa    [%o0]ASI_MEM, %o2
80 	add	%o0, 8, %o0
81         ldxa    [%o0]ASI_MEM, %o3
82 	add	%o0, 8, %o0
83         ldxa    [%o0]ASI_MEM, %g1
84 	add	%o0, 8, %o0
85         ldxa    [%o0]ASI_MEM, %g2
86 
87 	stxa    %o2, [%o1]ASI_MEM
88 	add	%o1, 8, %o1
89 	stxa    %o3, [%o1]ASI_MEM
90 	add	%o1, 8, %o1
91 	stxa    %g1, [%o1]ASI_MEM
92 	add	%o1, 8, %o1
93 	stxa    %g2, [%o1]ASI_MEM
94 
95 	stxa	%g0, [%o1]ASI_DC_INVAL	/* flush line from dcache */
96 	membar	#Sync
97 
98 	retl
99         wrpr    %g0, %o4, %pstate       ! restore earlier pstate register value
100 	SET_SIZE(bcopy32_il)
101 
102 #endif /* lint */
103 
104 #if defined(lint)
105 
106 /*ARGSUSED*/
107 void
108 flush_ecache_il(uint64_t physaddr, uint_t size, uint_t linesize)
109 {}
110 
111 #else /* lint */
112 
113 	ENTRY_NP(flush_ecache_il)
114 	rdpr	%pstate, %o3
115 	andn	%o3, PSTATE_IE | PSTATE_AM, %o4
116 	wrpr	%g0, %o4, %pstate	! clear AM to access 64 bit physaddr
117 	GET_CPU_IMPL(%o4)
118 	cmp	%o4, PANTHER_IMPL
119 	bne	%xcc, 3f
120 	  nop
121 	! Panther needs to flush L2 before L3.
122 	!
123 	! We need to free up a temp reg for the L2 flush macro (register usage
124 	! convention for inlines allows %o0-%o5, %f0-%f31 as temporaries.)
125 	! Since physaddr is only used for Cheetah, Panther can use %o0 for
126 	! the L2 flush.
127 	PN_L2_FLUSHALL(%o0, %o4, %o5)
128 3:
129 	ECACHE_FLUSHALL(%o1, %o2, %o0, %o4)
130 	wrpr	%g0, %o3, %pstate	! restore earlier pstate
131 	SET_SIZE(flush_ecache_il)
132 
133 #endif /* lint */
134 
135 #if defined(lint)
136 
137 /*ARGUSED*/
138 void
stphysio_il(uint64_t physaddr,u_int value)139 stphysio_il(uint64_t physaddr, u_int value)
140 {}
141 
142 /*ARGSUSED*/
143 u_int
ldphysio_il(uint64_t physaddr)144 ldphysio_il(uint64_t physaddr)
145 { return(0); }
146 
147 uint64_t
lddphys_il(uint64_t physaddr)148 lddphys_il(uint64_t physaddr)
149 { return (0x0ull); }
150 
151 uint64_t
ldxasi_il(uint64_t physaddr,uint_t asi)152 ldxasi_il(uint64_t physaddr, uint_t asi)
153 { return (0x0ull); }
154 
155 #else /* lint */
156 
157 	ENTRY_NP(stphysio_il)
158 	rdpr	%pstate, %o2		/* read PSTATE reg */
159 	andn	%o2, PSTATE_IE | PSTATE_AM, %o3
160 	wrpr	%g0, %o3, %pstate
161 	stwa	%o1, [%o0]ASI_IO        /* store value via bypass ASI */
162 	retl
163 	wrpr	%g0, %o2, %pstate		/* restore the PSTATE */
164 	SET_SIZE(stphysio_il)
165 
166 	!
167 	! load value at physical address in I/O space
168 	!
169 	! u_int   ldphysio_il(uint64_t physaddr)
170 	!
171 	ENTRY_NP(ldphysio_il)
172 	rdpr	%pstate, %o2		/* read PSTATE reg */
173 	andn	%o2, PSTATE_IE | PSTATE_AM, %o3
174 	wrpr	%g0, %o3, %pstate
175 	lduwa	[%o0]ASI_IO, %o0	/* load value via bypass ASI */
176 	retl
177 	wrpr	%g0, %o2, %pstate	/* restore pstate */
178 	SET_SIZE(ldphysio_il)
179 
180         !
181         ! Load long word value at physical address
182         !
183         ! uint64_t lddphys_il(uint64_t physaddr)
184         !
185         ENTRY_NP(lddphys_il)
186         rdpr    %pstate, %o4
187         andn    %o4, PSTATE_IE | PSTATE_AM, %o5
188         wrpr    %o5, 0, %pstate
189         ldxa    [%o0]ASI_MEM, %o0
190         retl
191         wrpr    %g0, %o4, %pstate       /* restore earlier pstate register value */
192         SET_SIZE(lddphys_il)
193 
194         !
195         ! Load long word value from designated asi.
196         !
197         ! uint64_t ldxasi_il(uint64_t physaddr, uint_t asi)
198         !
199         ENTRY_NP(ldxasi_il)
200         rdpr    %pstate, %o4
201         andn    %o4, PSTATE_IE | PSTATE_AM, %o5
202         wrpr    %o5, 0, %pstate
203 	wr	%o1, 0, %asi
204         ldxa    [%o0]%asi, %o0
205         retl
206         wrpr    %g0, %o4, %pstate       /* restore earlier pstate register value */
207         SET_SIZE(ldxasi_il)
208 
209 #endif /* lint */
210 
211 #if defined(lint)
212 
213 /*
214  * Argument to sbdp_exec_script_il is a pointer to:
215  *
216  * typedef struct {
217  *	uint64_t	masr_addr;
218  *	uint64_t	masr;
219  *	uint_t	asi;
220  *	uint_t		_filler;
221  * } sbdp_rename_script_t;
222  */
223 
224 /*ARGUSED*/
225 void
226 sbdp_exec_script_il(void *sp)
227 {}
228 
229 #else /* lint */
230 
231 	ENTRY_NP(sbdp_exec_script_il)
232 	mov	%o0, %o2
233 
234 	rdpr	%pstate, %o4		/* read PSTATE reg */
235 	andn	%o4, PSTATE_IE | PSTATE_AM, %o1
236 	wrpr	%g0, %o1, %pstate
237 
238 	membar #Sync
239 
240 0:					/* cache script */
241 	ldx	[%o2], %o1
242 	ldx	[%o2 + 16], %o1
243 	cmp	%g0, %o1
244 	bnz,pt	%xcc, 0b
245 	add	%o2, 24, %o2
246 
247 	b	2f			/* cache it */
248 	nop
249 1:
250 	ldx	[%o0], %o1
251 	brz,pn	%o1, 5f
252 	ld	[%o0 + 16], %o2
253 	wr	%o2, 0, %asi
254 	b	3f
255 	nop
256 2:
257 	b	4f			/* cache it */
258 	nop
259 3:
260 	ldx	[%o0 + 8], %o2
261 	stxa	%o2, [%o1]%asi
262 	membar	#Sync
263 	add	%o0, 24, %o0
264 	b	1b
265 	ldxa	[%o1]%asi, %g0	/* read back to insure written */
266 4:
267 	b	1b			/* caching done */
268 	nop
269 5:
270 	retl
271 	wrpr	%g0, %o4, %pstate	/* restore the PSTATE */
272 	SET_SIZE(sbdp_exec_script_il)
273 
274 #endif /* lint */
275