source: mainline/kernel/arch/sparc64/src/asm.S@ f1d1f5d3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f1d1f5d3 was 6eabb6e6, checked in by Jakub Jermar <jakub@…>, 19 years ago

Support for sparc64 FPU context.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1#
2# Copyright (C) 2005 Jakub Jermar
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# - Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14# - The name of the author may not be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29#include <arch/arch.h>
30#include <arch/stack.h>
31#include <arch/regdef.h>
32#include <arch/mm/mmu.h>
33
34.text
35
36.register %g2, #scratch
37.register %g3, #scratch
38
39/*
40 * This is the assembly language version of our _memcpy() generated by gcc.
41 */
42.global memcpy
43memcpy:
44 add %o1, 7, %g1
45 and %g1, -8, %g1
46 cmp %o1, %g1
47 be,pn %xcc, 3f
48 add %o0, 7, %g1
49 mov 0, %g3
500:
51 brz,pn %o2, 2f
52 mov 0, %g2
531:
54 ldub [%g3 + %o1], %g1
55 add %g2, 1, %g2
56 cmp %o2, %g2
57 stb %g1, [%g3 + %o0]
58 bne,pt %xcc, 1b
59 mov %g2, %g3
602:
61 jmp %o7 + 8 ! exit point
62 mov %o1, %o0
633:
64 and %g1, -8, %g1
65 cmp %o0, %g1
66 bne,pt %xcc, 0b
67 mov 0, %g3
68 srlx %o2, 3, %g4
69 brz,pn %g4, 5f
70 mov 0, %g5
714:
72 sllx %g3, 3, %g2
73 add %g5, 1, %g3
74 ldx [%o1 + %g2], %g1
75 mov %g3, %g5
76 cmp %g4, %g3
77 bne,pt %xcc, 4b
78 stx %g1, [%o0 + %g2]
795:
80 and %o2, 7, %o2
81 brz,pn %o2, 2b
82 sllx %g4, 3, %g1
83 mov 0, %g2
84 add %g1, %o0, %o0
85 add %g1, %o1, %g4
86 mov 0, %g3
876:
88 ldub [%g2 + %g4], %g1
89 stb %g1, [%g2 + %o0]
90 add %g3, 1, %g2
91 cmp %o2, %g2
92 bne,pt %xcc, 6b
93 mov %g2, %g3
94
95 jmp %o7 + 8 ! exit point
96 mov %o1, %o0
97
98/*
99 * Almost the same as memcpy() except the loads are from userspace.
100 */
101.global memcpy_from_uspace
102memcpy_from_uspace:
103 add %o1, 7, %g1
104 and %g1, -8, %g1
105 cmp %o1, %g1
106 be,pn %xcc, 3f
107 add %o0, 7, %g1
108 mov 0, %g3
1090:
110 brz,pn %o2, 2f
111 mov 0, %g2
1121:
113 lduba [%g3 + %o1] ASI_AIUS, %g1
114 add %g2, 1, %g2
115 cmp %o2, %g2
116 stb %g1, [%g3 + %o0]
117 bne,pt %xcc, 1b
118 mov %g2, %g3
1192:
120 jmp %o7 + 8 ! exit point
121 mov %o1, %o0
1223:
123 and %g1, -8, %g1
124 cmp %o0, %g1
125 bne,pt %xcc, 0b
126 mov 0, %g3
127 srlx %o2, 3, %g4
128 brz,pn %g4, 5f
129 mov 0, %g5
1304:
131 sllx %g3, 3, %g2
132 add %g5, 1, %g3
133 ldxa [%o1 + %g2] ASI_AIUS, %g1
134 mov %g3, %g5
135 cmp %g4, %g3
136 bne,pt %xcc, 4b
137 stx %g1, [%o0 + %g2]
1385:
139 and %o2, 7, %o2
140 brz,pn %o2, 2b
141 sllx %g4, 3, %g1
142 mov 0, %g2
143 add %g1, %o0, %o0
144 add %g1, %o1, %g4
145 mov 0, %g3
1466:
147 lduba [%g2 + %g4] ASI_AIUS, %g1
148 stb %g1, [%g2 + %o0]
149 add %g3, 1, %g2
150 cmp %o2, %g2
151 bne,pt %xcc, 6b
152 mov %g2, %g3
153
154 jmp %o7 + 8 ! exit point
155 mov %o1, %o0
156
157/*
158 * Almost the same as memcpy() except the stores are to userspace.
159 */
160.global memcpy_to_uspace
161memcpy_to_uspace:
162 add %o1, 7, %g1
163 and %g1, -8, %g1
164 cmp %o1, %g1
165 be,pn %xcc, 3f
166 add %o0, 7, %g1
167 mov 0, %g3
1680:
169 brz,pn %o2, 2f
170 mov 0, %g2
1711:
172 ldub [%g3 + %o1], %g1
173 add %g2, 1, %g2
174 cmp %o2, %g2
175 stba %g1, [%g3 + %o0] ASI_AIUS
176 bne,pt %xcc, 1b
177 mov %g2, %g3
1782:
179 jmp %o7 + 8 ! exit point
180 mov %o1, %o0
1813:
182 and %g1, -8, %g1
183 cmp %o0, %g1
184 bne,pt %xcc, 0b
185 mov 0, %g3
186 srlx %o2, 3, %g4
187 brz,pn %g4, 5f
188 mov 0, %g5
1894:
190 sllx %g3, 3, %g2
191 add %g5, 1, %g3
192 ldx [%o1 + %g2], %g1
193 mov %g3, %g5
194 cmp %g4, %g3
195 bne,pt %xcc, 4b
196 stxa %g1, [%o0 + %g2] ASI_AIUS
1975:
198 and %o2, 7, %o2
199 brz,pn %o2, 2b
200 sllx %g4, 3, %g1
201 mov 0, %g2
202 add %g1, %o0, %o0
203 add %g1, %o1, %g4
204 mov 0, %g3
2056:
206 ldub [%g2 + %g4], %g1
207 stba %g1, [%g2 + %o0] ASI_AIUS
208 add %g3, 1, %g2
209 cmp %o2, %g2
210 bne,pt %xcc, 6b
211 mov %g2, %g3
212
213 jmp %o7 + 8 ! exit point
214 mov %o1, %o0
215
216.global memcpy_from_uspace_failover_address
217.global memcpy_to_uspace_failover_address
218memcpy_from_uspace_failover_address:
219memcpy_to_uspace_failover_address:
220 jmp %o7 + 8 ! exit point
221 mov %g0, %o0 ! return 0 on failure
222
223.global memsetb
224memsetb:
225 b _memsetb
226 nop
227
228
229.macro WRITE_ALTERNATE_REGISTER reg, bit
230 rdpr %pstate, %g1 ! save PSTATE.PEF
231 wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
232 mov %o0, \reg
233 wrpr %g0, PSTATE_PRIV_BIT, %pstate
234 retl
235 wrpr %g1, 0, %pstate ! restore PSTATE.PEF
236.endm
237
238.macro READ_ALTERNATE_REGISTER reg, bit
239 rdpr %pstate, %g1 ! save PSTATE.PEF
240 wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
241 mov \reg, %o0
242 wrpr %g0, PSTATE_PRIV_BIT, %pstate
243 retl
244 wrpr %g1, 0, %pstate ! restore PSTATE.PEF
245.endm
246
247.global write_to_ag_g6
248write_to_ag_g6:
249 WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
250
251.global write_to_ag_g7
252write_to_ag_g7:
253 WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
254
255.global write_to_ig_g6
256write_to_ig_g6:
257 WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
258
259.global read_from_ag_g7
260read_from_ag_g7:
261 READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
262
263
264/** Switch to userspace.
265 *
266 * %o0 Userspace entry address.
267 * %o1 Userspace stack pointer address.
268 * %o2 Userspace address of uarg structure.
269 */
270.global switch_to_userspace
271switch_to_userspace:
272 save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
273 flushw
274 wrpr %g0, 0, %cleanwin ! avoid information leak
275
276 mov %i3, %o0 ! uarg
277
278 clr %i2
279 clr %i3
280 clr %i4
281 clr %i5
282 clr %i6
283
284 wrpr %g0, 1, %tl ! enforce mapping via nucleus
285
286 rdpr %cwp, %g1
287 wrpr %g1, TSTATE_IE_BIT, %tstate
288 wrpr %i0, 0, %tnpc
289
290 /*
291 * Set primary context according to secondary context.
292 * Secondary context has been already installed by
293 * higher-level functions.
294 */
295 wr %g0, ASI_DMMU, %asi
296 ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
297 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
298 flush %i7
299
300 /*
301 * Spills and fills will be handled by the userspace handlers.
302 */
303 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
304
305 done ! jump to userspace
306
Note: See TracBrowser for help on using the repository browser.