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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f4c2b6a was 3d6c468, checked in by Jakub Jermar <jakub@…>, 17 years ago

Some inline functions in memstr.h seem to be of uncertain origin (ia32).
Replace either with built-in functions or with generic functions.

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