Subversion Repositories HelenOS

Rev

Rev 1829 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1829 Rev 1831
1
#
1
#
2
# Copyright (C) 2001-2004 Jakub Jermar
2
# Copyright (C) 2001-2004 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
## very low and hardware-level functions
29
## very low and hardware-level functions
30
 
30
 
31
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
31
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
32
# and 1 means interrupt with error word
32
# and 1 means interrupt with error word
33
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
33
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
34
 
34
 
35
.text
35
.text
36
 
36
 
37
.global xen_callback
37
.global xen_callback
38
.global xen_failsafe_callback
38
.global xen_failsafe_callback
39
.global enable_l_apic_in_msr
39
.global enable_l_apic_in_msr
40
.global interrupt_handlers
-
 
41
.global memcpy
40
.global memcpy
42
.global memcpy_from_uspace
41
.global memcpy_from_uspace
43
.global memcpy_from_uspace_failover_address
42
.global memcpy_from_uspace_failover_address
44
.global memcpy_to_uspace
43
.global memcpy_to_uspace
45
.global memcpy_to_uspace_failover_address
44
.global memcpy_to_uspace_failover_address
46
 
45
 
47
 
46
 
48
xen_callback:
47
xen_callback:
49
	iret
48
	iret
50
 
49
 
51
xen_failsafe_callback:
50
xen_failsafe_callback:
52
	iret
51
	iret
53
 
52
 
54
 
53
 
55
#define MEMCPY_DST	4
54
#define MEMCPY_DST	4
56
#define MEMCPY_SRC	8
55
#define MEMCPY_SRC	8
57
#define MEMCPY_SIZE	12
56
#define MEMCPY_SIZE	12
58
 
57
 
59
/** Copy memory to/from userspace.
58
/** Copy memory to/from userspace.
60
 *
59
 *
61
 * This is almost conventional memcpy().
60
 * This is almost conventional memcpy().
62
 * The difference is that there is a failover part
61
 * The difference is that there is a failover part
63
 * to where control is returned from a page fault
62
 * to where control is returned from a page fault
64
 * if the page fault occurs during copy_from_uspace()
63
 * if the page fault occurs during copy_from_uspace()
65
 * or copy_to_uspace().
64
 * or copy_to_uspace().
66
 *
65
 *
67
 * @param MEMCPY_DST(%esp)	Destination address.
66
 * @param MEMCPY_DST(%esp)	Destination address.
68
 * @param MEMCPY_SRC(%esp)	Source address.
67
 * @param MEMCPY_SRC(%esp)	Source address.
69
 * @param MEMCPY_SIZE(%esp)	Size.
68
 * @param MEMCPY_SIZE(%esp)	Size.
70
 *
69
 *
71
 * @return MEMCPY_SRC(%esp) on success and 0 on failure.
70
 * @return MEMCPY_SRC(%esp) on success and 0 on failure.
72
 */
71
 */
73
memcpy:
72
memcpy:
74
memcpy_from_uspace:
73
memcpy_from_uspace:
75
memcpy_to_uspace:
74
memcpy_to_uspace:
76
	movl %edi, %edx				/* save %edi */
75
	movl %edi, %edx				/* save %edi */
77
	movl %esi, %eax				/* save %esi */
76
	movl %esi, %eax				/* save %esi */
78
	
77
	
79
	movl MEMCPY_SIZE(%esp), %ecx
78
	movl MEMCPY_SIZE(%esp), %ecx
80
	shrl $2, %ecx				/* size / 4 */
79
	shrl $2, %ecx				/* size / 4 */
81
	
80
	
82
	movl MEMCPY_DST(%esp), %edi
81
	movl MEMCPY_DST(%esp), %edi
83
	movl MEMCPY_SRC(%esp), %esi
82
	movl MEMCPY_SRC(%esp), %esi
84
	
83
	
85
	rep movsl				/* copy as much as possible word by word */
84
	rep movsl				/* copy as much as possible word by word */
86
 
85
 
87
	movl MEMCPY_SIZE(%esp), %ecx
86
	movl MEMCPY_SIZE(%esp), %ecx
88
	andl $3, %ecx				/* size % 4 */
87
	andl $3, %ecx				/* size % 4 */
89
	jz 0f
88
	jz 0f
90
	
89
	
91
	rep movsb				/* copy the rest byte by byte */
90
	rep movsb				/* copy the rest byte by byte */
92
 
91
 
93
0:
92
0:
94
	movl %edx, %edi
93
	movl %edx, %edi
95
	movl %eax, %esi
94
	movl %eax, %esi
96
	movl MEMCPY_SRC(%esp), %eax		/* MEMCPY_SRC(%esp), success */
95
	movl MEMCPY_SRC(%esp), %eax		/* MEMCPY_SRC(%esp), success */
97
	ret
96
	ret
98
	
97
	
99
/*
98
/*
100
 * We got here from as_page_fault() after the memory operations
99
 * We got here from as_page_fault() after the memory operations
101
 * above had caused a page fault.
100
 * above had caused a page fault.
102
 */
101
 */
103
memcpy_from_uspace_failover_address:
102
memcpy_from_uspace_failover_address:
104
memcpy_to_uspace_failover_address:
103
memcpy_to_uspace_failover_address:
105
	movl %edx, %edi
104
	movl %edx, %edi
106
	movl %eax, %esi
105
	movl %eax, %esi
107
	xorl %eax, %eax				/* return 0, failure */
106
	xorl %eax, %eax				/* return 0, failure */
108
	ret
107
	ret
109
 
108
 
110
 
109
 
111
## Enable local APIC
110
## Enable local APIC
112
#
111
#
113
# Enable local APIC in MSR.
112
# Enable local APIC in MSR.
114
#
113
#
115
enable_l_apic_in_msr:
114
enable_l_apic_in_msr:
116
	push %eax
115
	push %eax
117
 
116
 
118
	movl $0x1b, %ecx
117
	movl $0x1b, %ecx
119
	rdmsr
118
	rdmsr
120
	orl $(1<<11),%eax
119
	orl $(1<<11),%eax
121
	orl $(0xfee00000),%eax
120
	orl $(0xfee00000),%eax
122
	wrmsr
121
	wrmsr
123
 
122
 
124
	pop %eax
123
	pop %eax
125
	ret
124
	ret
126
 
-
 
127
# Clear nested flag
-
 
128
# overwrites %ecx
-
 
129
.macro CLEAR_NT_FLAG
-
 
130
	pushfl
-
 
131
	pop %ecx
-
 
132
	and $0xffffbfff,%ecx
-
 
133
	push %ecx
-
 
134
	popfl
-
 
135
.endm	
-
 
136
 
-
 
137
## Declare interrupt handlers
-
 
138
#
-
 
139
# Declare interrupt handlers for n interrupt
-
 
140
# vectors starting at vector i.
-
 
141
#
-
 
142
# The handlers setup data segment registers
-
 
143
# and call exc_dispatch().
-
 
144
#
-
 
145
#define INTERRUPT_ALIGN 64
-
 
146
.macro handler i n
-
 
147
 
-
 
148
.ifeq \i-0x30     # Syscall handler
-
 
149
	push %ds
-
 
150
	push %es
-
 
151
	push %fs
-
 
152
	push %gs
-
 
153
 
-
 
154
	# Push arguments on stack
-
 
155
	push %edi
-
 
156
	push %esi
-
 
157
	push %edx
-
 
158
	push %ecx
-
 
159
	push %eax
-
 
160
	
-
 
161
	# we must fill the data segment registers
-
 
162
	movw $16,%ax
-
 
163
	movw %ax,%ds
-
 
164
	movw %ax,%es
-
 
165
	
-
 
166
	sti
-
 
167
	
-
 
168
	call syscall_handler   # syscall_handler(ax,cx,dx,si,di)
-
 
169
	cli
-
 
170
	addl $20, %esp         # clean-up of parameters
-
 
171
	
-
 
172
	pop %gs
-
 
173
	pop %fs
-
 
174
	pop %es
-
 
175
	pop %ds
-
 
176
	
-
 
177
	CLEAR_NT_FLAG
-
 
178
	iret
-
 
179
.else	
-
 
180
	/*
-
 
181
	 * This macro distinguishes between two versions of ia32 exceptions.
-
 
182
	 * One version has error word and the other does not have it.
-
 
183
	 * The latter version fakes the error word on the stack so that the
-
 
184
	 * handlers and istate_t can be the same for both types.
-
 
185
	 */
-
 
186
	.iflt \i-32
-
 
187
		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
-
 
188
			/* 
-
 
189
			 * With error word, do nothing
-
 
190
			 */
-
 
191
                .else
-
 
192
                        /*
-
 
193
                         * Version without error word,
-
 
194
                         */
-
 
195
			subl $4, %esp
-
 
196
                .endif
-
 
197
        .else
-
 
198
                /*
-
 
199
                 * Version without error word,
-
 
200
                 */
-
 
201
		subl $4, %esp
-
 
202
	.endif
-
 
203
	
-
 
204
	push %ds
-
 
205
	push %es
-
 
206
	push %fs
-
 
207
	push %gs
-
 
208
 
-
 
209
#ifdef CONFIG_DEBUG_ALLREGS
-
 
210
	push %ebx
-
 
211
	push %ebp
-
 
212
	push %edi
-
 
213
	push %esi
-
 
214
#else
-
 
215
	sub $16, %esp
-
 
216
#endif
-
 
217
	push %edx
-
 
218
	push %ecx
-
 
219
	push %eax
-
 
220
	
-
 
221
	# we must fill the data segment registers
-
 
222
	movw $16,%ax
-
 
223
	movw %ax,%ds
-
 
224
	movw %ax,%es
-
 
225
 
-
 
226
	pushl %esp          # *istate
-
 
227
	pushl $(\i)         # intnum
-
 
228
	call exc_dispatch   # excdispatch(intnum, *istate)
-
 
229
	addl $8,%esp        # Clear arguments from stack
-
 
230
 
-
 
231
	CLEAR_NT_FLAG # Modifies %ecx
-
 
232
	
-
 
233
	pop %eax
-
 
234
	pop %ecx
-
 
235
	pop %edx
-
 
236
#ifdef CONFIG_DEBUG_ALLREGS
-
 
237
	pop %esi
-
 
238
	pop %edi
-
 
239
	pop %ebp
-
 
240
	pop %ebx
-
 
241
#else
-
 
242
	add $16, %esp
-
 
243
#endif	
-
 
244
	
-
 
245
	pop %gs
-
 
246
	pop %fs
-
 
247
	pop %es
-
 
248
	pop %ds
-
 
249
 
-
 
250
	addl $4,%esp	# Skip error word, no matter whether real or fake.
-
 
251
	iret
-
 
252
.endif
-
 
253
 
-
 
254
	.align INTERRUPT_ALIGN
-
 
255
	.if (\n-\i)-1
-
 
256
	handler "(\i+1)",\n
-
 
257
	.endif
-
 
258
.endm
-
 
259
 
-
 
260
# keep in sync with pm.h !!!
-
 
261
IDT_ITEMS=64
-
 
262
.align INTERRUPT_ALIGN
-
 
263
interrupt_handlers:
-
 
264
h_start:
-
 
265
	handler 0 IDT_ITEMS
-
 
266
h_end:
-
 
267
 
-
 
268
.data
-
 
269
.global interrupt_handler_size
-
 
270
 
-
 
271
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
-
 
272
 
125