source: mainline/kernel/arch/ia32/src/asm.S@ 71eef11

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

Support for six syscall arguments for ia32.

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