~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/arch/sparc64/src/asm.S

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
43
memcpy:
 
44
        mov     %o0, %o3                ! save dst
 
45
        add     %o1, 7, %g1
 
46
        and     %g1, -8, %g1
 
47
        cmp     %o1, %g1
 
48
        be,pn   %xcc, 3f
 
49
        add     %o0, 7, %g1
 
50
        mov     0, %g3
 
51
0:
 
52
        brz,pn  %o2, 2f
 
53
        mov     0, %g2
 
54
1:
 
55
        ldub    [%g3 + %o1], %g1
 
56
        add     %g2, 1, %g2
 
57
        cmp     %o2, %g2
 
58
        stb     %g1, [%g3 + %o0]
 
59
        bne,pt  %xcc, 1b
 
60
        mov     %g2, %g3
 
61
2:
 
62
        jmp     %o7 + 8                 ! exit point
 
63
        mov     %o3, %o0
 
64
3:
 
65
        and     %g1, -8, %g1
 
66
        cmp     %o0, %g1
 
67
        bne,pt  %xcc, 0b
 
68
        mov     0, %g3
 
69
        srlx    %o2, 3, %g4
 
70
        brz,pn  %g4, 5f
 
71
        mov     0, %g5
 
72
4:
 
73
        sllx    %g3, 3, %g2
 
74
        add     %g5, 1, %g3
 
75
        ldx     [%o1 + %g2], %g1
 
76
        mov     %g3, %g5
 
77
        cmp     %g4, %g3
 
78
        bne,pt  %xcc, 4b
 
79
        stx     %g1, [%o0 + %g2]
 
80
5:
 
81
        and     %o2, 7, %o2
 
82
        brz,pn  %o2, 2b
 
83
        sllx    %g4, 3, %g1
 
84
        mov     0, %g2
 
85
        add     %g1, %o0, %o0
 
86
        add     %g1, %o1, %g4
 
87
        mov     0, %g3
 
88
6:
 
89
        ldub    [%g2 + %g4], %g1
 
90
        stb     %g1, [%g2 + %o0]
 
91
        add     %g3, 1, %g2
 
92
        cmp     %o2, %g2
 
93
        bne,pt  %xcc, 6b
 
94
        mov     %g2, %g3
 
95
 
 
96
        jmp     %o7 + 8                 ! exit point
 
97
        mov     %o3, %o0
 
98
 
 
99
/*
 
100
 * Almost the same as memcpy() except the loads are from userspace.
 
101
 */
 
102
.global memcpy_from_uspace
 
103
memcpy_from_uspace:
 
104
        mov     %o0, %o3                ! save dst
 
105
        add     %o1, 7, %g1
 
106
        and     %g1, -8, %g1
 
107
        cmp     %o1, %g1
 
108
        be,pn   %xcc, 3f
 
109
        add     %o0, 7, %g1
 
110
        mov     0, %g3
 
111
0:
 
112
        brz,pn  %o2, 2f
 
113
        mov     0, %g2
 
114
1:
 
115
        lduba   [%g3 + %o1] ASI_AIUS, %g1
 
116
        add     %g2, 1, %g2
 
117
        cmp     %o2, %g2
 
118
        stb     %g1, [%g3 + %o0]
 
119
        bne,pt  %xcc, 1b
 
120
        mov     %g2, %g3
 
121
2:
 
122
        jmp     %o7 + 8                 ! exit point
 
123
        mov     %o3, %o0
 
124
3:
 
125
        and     %g1, -8, %g1
 
126
        cmp     %o0, %g1
 
127
        bne,pt  %xcc, 0b
 
128
        mov     0, %g3
 
129
        srlx    %o2, 3, %g4
 
130
        brz,pn  %g4, 5f
 
131
        mov     0, %g5
 
132
4:
 
133
        sllx    %g3, 3, %g2
 
134
        add     %g5, 1, %g3
 
135
        ldxa    [%o1 + %g2] ASI_AIUS, %g1
 
136
        mov     %g3, %g5
 
137
        cmp     %g4, %g3
 
138
        bne,pt  %xcc, 4b
 
139
        stx     %g1, [%o0 + %g2]
 
140
5:
 
141
        and     %o2, 7, %o2
 
142
        brz,pn  %o2, 2b
 
143
        sllx    %g4, 3, %g1
 
144
        mov     0, %g2
 
145
        add     %g1, %o0, %o0
 
146
        add     %g1, %o1, %g4
 
147
        mov     0, %g3
 
148
6:
 
149
        lduba   [%g2 + %g4] ASI_AIUS, %g1
 
150
        stb     %g1, [%g2 + %o0]
 
151
        add     %g3, 1, %g2
 
152
        cmp     %o2, %g2
 
153
        bne,pt  %xcc, 6b
 
154
        mov     %g2, %g3
 
155
 
 
156
        jmp     %o7 + 8                 ! exit point
 
157
        mov     %o3, %o0
 
158
 
 
159
/*
 
160
 * Almost the same as memcpy() except the stores are to userspace.
 
161
 */
 
162
.global memcpy_to_uspace
 
163
memcpy_to_uspace:
 
164
        mov     %o0, %o3                ! save dst
 
165
        add     %o1, 7, %g1
 
166
        and     %g1, -8, %g1
 
167
        cmp     %o1, %g1
 
168
        be,pn   %xcc, 3f
 
169
        add     %o0, 7, %g1
 
170
        mov     0, %g3
 
171
0:
 
172
        brz,pn  %o2, 2f
 
173
        mov     0, %g2
 
174
1:
 
175
        ldub    [%g3 + %o1], %g1
 
176
        add     %g2, 1, %g2
 
177
        cmp     %o2, %g2
 
178
        stba    %g1, [%g3 + %o0] ASI_AIUS
 
179
        bne,pt  %xcc, 1b
 
180
        mov     %g2, %g3
 
181
2:
 
182
        jmp     %o7 + 8                 ! exit point
 
183
        mov     %o3, %o0
 
184
3:
 
185
        and     %g1, -8, %g1
 
186
        cmp     %o0, %g1
 
187
        bne,pt  %xcc, 0b
 
188
        mov     0, %g3
 
189
        srlx    %o2, 3, %g4
 
190
        brz,pn  %g4, 5f
 
191
        mov     0, %g5
 
192
4:
 
193
        sllx    %g3, 3, %g2
 
194
        add     %g5, 1, %g3
 
195
        ldx     [%o1 + %g2], %g1
 
196
        mov     %g3, %g5
 
197
        cmp     %g4, %g3
 
198
        bne,pt  %xcc, 4b
 
199
        stxa    %g1, [%o0 + %g2] ASI_AIUS
 
200
5:
 
201
        and     %o2, 7, %o2
 
202
        brz,pn  %o2, 2b
 
203
        sllx    %g4, 3, %g1
 
204
        mov     0, %g2
 
205
        add     %g1, %o0, %o0
 
206
        add     %g1, %o1, %g4
 
207
        mov     0, %g3
 
208
6:
 
209
        ldub    [%g2 + %g4], %g1
 
210
        stba    %g1, [%g2 + %o0] ASI_AIUS
 
211
        add     %g3, 1, %g2
 
212
        cmp     %o2, %g2
 
213
        bne,pt  %xcc, 6b
 
214
        mov     %g2, %g3
 
215
 
 
216
        jmp     %o7 + 8                 ! exit point
 
217
        mov     %o3, %o0
 
218
 
 
219
.global memcpy_from_uspace_failover_address
 
220
.global memcpy_to_uspace_failover_address
 
221
memcpy_from_uspace_failover_address:
 
222
memcpy_to_uspace_failover_address:
 
223
        jmp     %o7 + 8                 ! exit point
 
224
        mov     %g0, %o0                ! return 0 on failure
 
225
 
 
226
.global memsetb
 
227
memsetb:
 
228
        ba %xcc, _memsetb
 
229
        nop
 
230
 
 
231
.global memsetw
 
232
memsetw:
 
233
        ba %xcc, _memsetw
 
234
        nop
 
235
 
 
236
 
 
237
.macro WRITE_ALTERNATE_REGISTER reg, bit
 
238
        rdpr %pstate, %g1                               ! save PSTATE.PEF
 
239
        wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
 
240
        mov %o0, \reg
 
241
        wrpr %g0, PSTATE_PRIV_BIT, %pstate
 
242
        retl
 
243
        wrpr %g1, 0, %pstate                            ! restore PSTATE.PEF
 
244
.endm
 
245
 
 
246
.macro READ_ALTERNATE_REGISTER reg, bit
 
247
        rdpr %pstate, %g1                               ! save PSTATE.PEF
 
248
        wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
 
249
        mov \reg, %o0
 
250
        wrpr %g0, PSTATE_PRIV_BIT, %pstate
 
251
        retl
 
252
        wrpr %g1, 0, %pstate                            ! restore PSTATE.PEF
 
253
.endm
 
254
 
 
255
.global write_to_ag_g6
 
256
write_to_ag_g6:
 
257
        WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
 
258
 
 
259
.global write_to_ag_g7
 
260
write_to_ag_g7:
 
261
        WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
 
262
 
 
263
.global write_to_ig_g6
 
264
write_to_ig_g6:
 
265
        WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
 
266
 
 
267
.global read_from_ag_g7
 
268
read_from_ag_g7:
 
269
        READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
 
270
 
 
271
 
 
272
/** Switch to userspace.
 
273
 *
 
274
 * %o0  Userspace entry address.
 
275
 * %o1  Userspace stack pointer address.
 
276
 * %o2  Userspace address of uarg structure.
 
277
 */
 
278
.global switch_to_userspace
 
279
switch_to_userspace:
 
280
        save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
 
281
        flushw
 
282
        wrpr %g0, 0, %cleanwin          ! avoid information leak
 
283
 
 
284
        mov %i2, %o0                    ! uarg
 
285
        xor %o1, %o1, %o1               ! %o1 is defined to hold pcb_ptr
 
286
                                        ! set it to 0
 
287
 
 
288
        clr %i2
 
289
        clr %i3
 
290
        clr %i4
 
291
        clr %i5
 
292
        clr %i6
 
293
 
 
294
        wrpr %g0, 1, %tl                ! enforce mapping via nucleus
 
295
 
 
296
        rdpr %cwp, %g1
 
297
        wrpr %g1, TSTATE_IE_BIT, %tstate
 
298
        wrpr %i0, 0, %tnpc
 
299
        
 
300
        /*
 
301
         * Set primary context according to secondary context.
 
302
         * Secondary context has been already installed by
 
303
         * higher-level functions.
 
304
         */
 
305
        wr %g0, ASI_DMMU, %asi
 
306
        ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
 
307
        stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
 
308
        flush %i7
 
309
 
 
310
        /*
 
311
         * Spills and fills will be handled by the userspace handlers.
 
312
         */
 
313
        wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
 
314
        
 
315
        done                            ! jump to userspace
 
316