Subversion Repositories HelenOS

Rev

Rev 1821 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1821 decky 1
#
2
# Copyright (C) 2001-2004 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
## very low and hardware-level functions
30
 
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
33
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
34
 
35
.text
36
 
1829 decky 37
.global xen_callback
38
.global xen_failsafe_callback
1821 decky 39
.global enable_l_apic_in_msr
40
.global interrupt_handlers
41
.global memcpy
42
.global memcpy_from_uspace
43
.global memcpy_from_uspace_failover_address
44
.global memcpy_to_uspace
45
.global memcpy_to_uspace_failover_address
46
 
47
 
1829 decky 48
xen_callback:
49
	iret
50
 
51
xen_failsafe_callback:
52
	iret
53
 
54
 
1821 decky 55
#define MEMCPY_DST	4
56
#define MEMCPY_SRC	8
57
#define MEMCPY_SIZE	12
58
 
59
/** Copy memory to/from userspace.
60
 *
61
 * This is almost conventional memcpy().
62
 * The difference is that there is a failover part
63
 * to where control is returned from a page fault
64
 * if the page fault occurs during copy_from_uspace()
65
 * or copy_to_uspace().
66
 *
67
 * @param MEMCPY_DST(%esp)	Destination address.
68
 * @param MEMCPY_SRC(%esp)	Source address.
69
 * @param MEMCPY_SIZE(%esp)	Size.
70
 *
71
 * @return MEMCPY_SRC(%esp) on success and 0 on failure.
72
 */
73
memcpy:
74
memcpy_from_uspace:
75
memcpy_to_uspace:
76
	movl %edi, %edx				/* save %edi */
77
	movl %esi, %eax				/* save %esi */
78
 
79
	movl MEMCPY_SIZE(%esp), %ecx
80
	shrl $2, %ecx				/* size / 4 */
81
 
82
	movl MEMCPY_DST(%esp), %edi
83
	movl MEMCPY_SRC(%esp), %esi
84
 
85
	rep movsl				/* copy as much as possible word by word */
86
 
87
	movl MEMCPY_SIZE(%esp), %ecx
88
	andl $3, %ecx				/* size % 4 */
89
	jz 0f
90
 
91
	rep movsb				/* copy the rest byte by byte */
92
 
93
0:
94
	movl %edx, %edi
95
	movl %eax, %esi
96
	movl MEMCPY_SRC(%esp), %eax		/* MEMCPY_SRC(%esp), success */
97
	ret
98
 
99
/*
100
 * We got here from as_page_fault() after the memory operations
101
 * above had caused a page fault.
102
 */
103
memcpy_from_uspace_failover_address:
104
memcpy_to_uspace_failover_address:
105
	movl %edx, %edi
106
	movl %eax, %esi
107
	xorl %eax, %eax				/* return 0, failure */
108
	ret
109
 
110
 
111
## Enable local APIC
112
#
113
# Enable local APIC in MSR.
114
#
115
enable_l_apic_in_msr:
116
	push %eax
117
 
118
	movl $0x1b, %ecx
119
	rdmsr
120
	orl $(1<<11),%eax
121
	orl $(0xfee00000),%eax
122
	wrmsr
123
 
124
	pop %eax
125
	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