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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2001,2003 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
55 /*
56 * Bcopy routine used by DR to copy
57 * between physical addresses.
58 * Borrowed from Starfire DR 2.6.
59 */
60 #if defined(lint)
61
62 /*ARGSUSED*/
63 void
bcopy32_il(uint64_t paddr1,uint64_t paddr2)64 bcopy32_il(uint64_t paddr1, uint64_t paddr2)
65 {}
66
67 #else /* lint */
68
69 ENTRY_NP(bcopy32_il)
70 .register %g2, #scratch
71 .register %g3, #scratch
72 rdpr %pstate, %o4
73 andn %o4, PSTATE_IE | PSTATE_AM, %g3 ! clear IE, AM bits
74 wrpr %g0, %g3, %pstate
75
76 ldxa [%o0]ASI_MEM, %o2
77 add %o0, 8, %o0
78 ldxa [%o0]ASI_MEM, %o3
79 add %o0, 8, %o0
80 ldxa [%o0]ASI_MEM, %g1
81 add %o0, 8, %o0
82 ldxa [%o0]ASI_MEM, %g2
83
84 stxa %o2, [%o1]ASI_MEM
85 add %o1, 8, %o1
86 stxa %o3, [%o1]ASI_MEM
87 add %o1, 8, %o1
88 stxa %g1, [%o1]ASI_MEM
89 add %o1, 8, %o1
90 stxa %g2, [%o1]ASI_MEM
91
92 retl
93 wrpr %g0, %o4, %pstate ! restore earlier pstate register value
94 SET_SIZE(bcopy32_il)
95
96 #endif /* lint */
97
98 #if defined(lint)
99
100 /*ARGSUSED*/
101 void
102 flush_ecache_il(uint64_t physaddr, uint_t size, uint_t linesize)
103 {}
104
105 #else /* lint */
106
107 ENTRY_NP(flush_ecache_il)
108 srl %o1, 0, %o1 ! clear upper 32 bits
109 srl %o2, 0, %o2 ! clear upper 32 bits
110 rdpr %pstate, %o3
111 andn %o3, PSTATE_IE | PSTATE_AM, %o4
112 wrpr %g0, %o4, %pstate ! clear AM to access 64 bit physaddr
113 b 2f
114 nop
115 1:
116 ldxa [%o0 + %o1]ASI_MEM, %g0 ! start reading from physaddr + size
117 2:
118 subcc %o1, %o2, %o1
119 bgeu,a 1b
120 nop
121
122 ! retl
123 wrpr %g0, %o3, %pstate ! restore earlier pstate
124 SET_SIZE(flush_ecache_il)
125
126 #endif /* lint */
127
128 #if defined(lint)
129
130 /*ARGUSED*/
131 void
stphysio_il(uint64_t physaddr,u_int value)132 stphysio_il(uint64_t physaddr, u_int value)
133 {}
134
135 /*ARGSUSED*/
136 u_int
ldphysio_il(uint64_t physaddr)137 ldphysio_il(uint64_t physaddr)
138 { return(0); }
139
140 #else /* lint */
141
142 ENTRY_NP(stphysio_il)
143 rdpr %pstate, %o2 /* read PSTATE reg */
144 andn %o2, PSTATE_IE | PSTATE_AM, %o3
145 wrpr %g0, %o3, %pstate
146 stwa %o1, [%o0]ASI_IO /* store value via bypass ASI */
147 retl
148 wrpr %g0, %o2, %pstate /* restore the PSTATE */
149 SET_SIZE(stphysio_il)
150
151 !
152 ! load value at physical address in I/O space
153 !
154 ! u_int ldphysio_il(uint64_t physaddr)
155 !
156 ENTRY_NP(ldphysio_il)
157 rdpr %pstate, %o2 /* read PSTATE reg */
158 andn %o2, PSTATE_IE | PSTATE_AM, %o3
159 wrpr %g0, %o3, %pstate
160 lduwa [%o0]ASI_IO, %o0 /* load value via bypass ASI */
161 retl
162 wrpr %g0, %o2, %pstate /* restore pstate */
163 SET_SIZE(ldphysio_il)
164
165 #endif /* lint */
166
167 #if defined(lint)
168
169 /*
170 * Argument to drmach_exec_script_il is a pointer to:
171 *
172 * typedef struct {
173 * uint64_t masr_addr;
174 * uint_t masr;
175 * uint_t _filler;
176 * } drmach_rename_script_t;
177 */
178
179 /*ARGUSED*/
180 void
181 drmach_exec_script_il(void *sp)
182 {}
183
184 #else /* lint */
185
186 ENTRY_NP(drmach_exec_script_il)
187 mov %o0, %o2
188 0: /* cache script */
189 ldx [%o2], %o1
190 cmp %g0, %o1
191 bnz,pt %xcc, 0b
192 add %o2, 16, %o2
193
194 rdpr %pstate, %o4 /* read PSTATE reg */
195 andn %o4, PSTATE_IE | PSTATE_AM, %o1
196 wrpr %g0, %o1, %pstate
197
198 b 2f /* cache it */
199 nop
200 1:
201 ldx [%o0], %o1
202 cmp %g0, %o1
203 bz,pn %xcc, 5f
204 ld [%o0 + 8], %o2
205 b 3f
206 stwa %o2, [%o1]ASI_IO
207 2:
208 b 4f /* cache it */
209 nop
210 3:
211 add %o0, 16, %o0
212 b 1b
213 lduwa [%o1]ASI_IO, %g0 /* read back to insure written */
214 4:
215 b 1b /* caching done */
216 nop
217 5:
218 retl
219 wrpr %g0, %o4, %pstate /* restore the PSTATE */
220 SET_SIZE(drmach_exec_script_il)
221
222 #endif /* lint */
223