Subversion Repositories HelenOS

Rev

Rev 1882 | Rev 2228 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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