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*/
66void
67bcopy32_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*/
107void
108flush_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)
1283:
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*/
138void
139stphysio_il(uint64_t physaddr, u_int value)
140{}
141
142/*ARGSUSED*/
143u_int
144ldphysio_il(uint64_t physaddr)
145{ return(0); }
146
147uint64_t
148lddphys_il(uint64_t physaddr)
149{ return (0x0ull); }
150
151uint64_t
152ldxasi_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*/
225void
226sbdp_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
2400:					/* 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
2491:
250	ldx	[%o0], %o1
251	brz,pn	%o1, 5f
252	ld	[%o0 + 16], %o2
253	wr	%o2, 0, %asi
254	b	3f
255	nop
2562:
257	b	4f			/* cache it */
258	nop
2593:
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 */
2664:
267	b	1b			/* caching done */
268	nop
2695:
270	retl
271	wrpr	%g0, %o4, %pstate	/* restore the PSTATE */
272	SET_SIZE(sbdp_exec_script_il)
273
274#endif /* lint */
275