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