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 2005 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 #include <sys/param.h>
30 #include <sys/errno.h>
31 #include <sys/asm_linkage.h>
32 #include <sys/vtrace.h>
33 #include <sys/machthread.h>
34 #include <sys/clock.h>
35 #include <sys/asi.h>
36 #include <sys/fsr.h>
37 #include <sys/privregs.h>
38
39 #if !defined(lint)
40 #include "assym.h"
41 #endif /* lint */
42
43 #define FP_USED 1
44 #define LOFAULT_SET 2
45
46 /*
47 * Error barrier:
48 * We use membar sync to establish an error barrier for
49 * deferred errors. Membar syncs are added before any update
50 * to t_lofault to ensure that deferred errors from earlier
51 * accesses will not be reported after the membar. This error
52 * isolation is important when we try to recover from async
53 * errors which tries to distinguish kernel accesses to user
54 * data.
55 */
56
57 /*
58 * Zero a block of storage.
59 *
60 * uzero is used by the kernel to zero a block in user address space.
61 */
62
63 #if defined(lint)
64
65 /* ARGSUSED */
66 int
67 kzero(void *addr, size_t count)
68 { return(0); }
69
70 /* ARGSUSED */
71 void
72 uzero(void *addr, size_t count)
73 {}
74
75 #else /* lint */
76
77 ENTRY(uzero)
78 !
79 ! Set a new lo_fault handler only if we came in with one
80 ! already specified.
81 !
82 wr %g0, ASI_USER, %asi
83 ldn [THREAD_REG + T_LOFAULT], %o5
84 tst %o5
85 bz,pt %ncc, .do_zero
86 sethi %hi(.zeroerr), %o2
87 or %o2, %lo(.zeroerr), %o2
88 membar #Sync
89 ba,pt %ncc, .do_zero
90 stn %o2, [THREAD_REG + T_LOFAULT]
91
92 ENTRY(kzero)
93 !
94 ! Always set a lo_fault handler
95 !
96 wr %g0, ASI_P, %asi
137 ! Old handler was zero. Just return the error.
138 !
139 retl ! return
140 mov %g1, %o0 ! error code from %g1
141 3:
142 !
143 ! We're here because %o5 was non-zero. It was non-zero
144 ! because either LOFAULT_SET was present, a previous fault
145 ! handler was present or both. In all cases we need to reset
146 ! T_LOFAULT to the value of %o5 after clearing LOFAULT_SET
147 ! before we either simply return the error or we invoke the
148 ! previously specified handler.
149 !
150 be %ncc, 2b
151 stn %o5, [THREAD_REG + T_LOFAULT]
152 jmp %o5 ! goto real handler
153 nop
154 SET_SIZE(kzero)
155 SET_SIZE(uzero)
156
157 #endif /* lint */
158
159 /*
160 * Zero a block of storage.
161 */
162
163 #if defined(lint)
164
165 /* ARGSUSED */
166 void
167 bzero(void *addr, size_t count)
168 {}
169
170 #else /* lint */
171
172 ENTRY(bzero)
173 wr %g0, ASI_P, %asi
174
175 ldn [THREAD_REG + T_LOFAULT], %o5 ! save old vector
176 tst %o5
177 bz,pt %ncc, .do_zero
178 sethi %hi(.zeroerr), %o2
179 or %o2, %lo(.zeroerr), %o2
180 membar #Sync ! sync error barrier
181 stn %o2, [THREAD_REG + T_LOFAULT] ! install new vector
182
183 .do_zero:
184 cmp %o1, 15 ! check for small counts
185 blu,pn %ncc, .byteclr ! just clear bytes
186 nop
187
188 cmp %o1, 192 ! check for large counts
189 blu %ncc, .bzero_small
190 nop
191
457 ! We're just concerned with whether t_lofault was set
458 ! when we came in. We end up here from either kzero()
459 ! or bzero(). kzero() *always* sets a lofault handler.
460 ! It ors LOFAULT_SET into %o5 to indicate it has done
461 ! this even if the value of %o5 is otherwise zero.
462 ! bzero() sets a lofault handler *only* if one was
463 ! previously set. Accordingly we need to examine
464 ! %o5 and if it is non-zero be sure to clear LOFAULT_SET
465 ! before resetting the error handler.
466 !
467 tst %o5
468 bz %ncc, 1f
469 andn %o5, LOFAULT_SET, %o5
470 membar #Sync ! sync error barrier
471 stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault
472 1:
473 retl
474 clr %o0 ! return (0)
475
476 SET_SIZE(bzero)
477 #endif /* lint */
|
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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <sys/param.h>
28 #include <sys/errno.h>
29 #include <sys/asm_linkage.h>
30 #include <sys/vtrace.h>
31 #include <sys/machthread.h>
32 #include <sys/clock.h>
33 #include <sys/asi.h>
34 #include <sys/fsr.h>
35 #include <sys/privregs.h>
36
37 #include "assym.h"
38
39 #define FP_USED 1
40 #define LOFAULT_SET 2
41
42 /*
43 * Error barrier:
44 * We use membar sync to establish an error barrier for
45 * deferred errors. Membar syncs are added before any update
46 * to t_lofault to ensure that deferred errors from earlier
47 * accesses will not be reported after the membar. This error
48 * isolation is important when we try to recover from async
49 * errors which tries to distinguish kernel accesses to user
50 * data.
51 */
52
53 /*
54 * Zero a block of storage.
55 *
56 * uzero is used by the kernel to zero a block in user address space.
57 */
58
59 ENTRY(uzero)
60 !
61 ! Set a new lo_fault handler only if we came in with one
62 ! already specified.
63 !
64 wr %g0, ASI_USER, %asi
65 ldn [THREAD_REG + T_LOFAULT], %o5
66 tst %o5
67 bz,pt %ncc, .do_zero
68 sethi %hi(.zeroerr), %o2
69 or %o2, %lo(.zeroerr), %o2
70 membar #Sync
71 ba,pt %ncc, .do_zero
72 stn %o2, [THREAD_REG + T_LOFAULT]
73
74 ENTRY(kzero)
75 !
76 ! Always set a lo_fault handler
77 !
78 wr %g0, ASI_P, %asi
119 ! Old handler was zero. Just return the error.
120 !
121 retl ! return
122 mov %g1, %o0 ! error code from %g1
123 3:
124 !
125 ! We're here because %o5 was non-zero. It was non-zero
126 ! because either LOFAULT_SET was present, a previous fault
127 ! handler was present or both. In all cases we need to reset
128 ! T_LOFAULT to the value of %o5 after clearing LOFAULT_SET
129 ! before we either simply return the error or we invoke the
130 ! previously specified handler.
131 !
132 be %ncc, 2b
133 stn %o5, [THREAD_REG + T_LOFAULT]
134 jmp %o5 ! goto real handler
135 nop
136 SET_SIZE(kzero)
137 SET_SIZE(uzero)
138
139 /*
140 * Zero a block of storage.
141 */
142
143 ENTRY(bzero)
144 wr %g0, ASI_P, %asi
145
146 ldn [THREAD_REG + T_LOFAULT], %o5 ! save old vector
147 tst %o5
148 bz,pt %ncc, .do_zero
149 sethi %hi(.zeroerr), %o2
150 or %o2, %lo(.zeroerr), %o2
151 membar #Sync ! sync error barrier
152 stn %o2, [THREAD_REG + T_LOFAULT] ! install new vector
153
154 .do_zero:
155 cmp %o1, 15 ! check for small counts
156 blu,pn %ncc, .byteclr ! just clear bytes
157 nop
158
159 cmp %o1, 192 ! check for large counts
160 blu %ncc, .bzero_small
161 nop
162
428 ! We're just concerned with whether t_lofault was set
429 ! when we came in. We end up here from either kzero()
430 ! or bzero(). kzero() *always* sets a lofault handler.
431 ! It ors LOFAULT_SET into %o5 to indicate it has done
432 ! this even if the value of %o5 is otherwise zero.
433 ! bzero() sets a lofault handler *only* if one was
434 ! previously set. Accordingly we need to examine
435 ! %o5 and if it is non-zero be sure to clear LOFAULT_SET
436 ! before resetting the error handler.
437 !
438 tst %o5
439 bz %ncc, 1f
440 andn %o5, LOFAULT_SET, %o5
441 membar #Sync ! sync error barrier
442 stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault
443 1:
444 retl
445 clr %o0 ! return (0)
446
447 SET_SIZE(bzero)
|