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
RevLine 
[f761f1eb]1#
[df4ed85]2# Copyright (c) 2001-2004 Jakub Jermar
[f761f1eb]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
[da585a52]29## very low and hardware-level functions
[f761f1eb]30
[6c383b0]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
[59532eb]34
[f761f1eb]35.text
36
37.global paging_on
38.global enable_l_apic_in_msr
39.global interrupt_handlers
[e3c762cd]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:
[6c383b0]68 movl %edi, %edx /* save %edi */
69 movl %esi, %eax /* save %esi */
[e3c762cd]70
71 movl MEMCPY_SIZE(%esp), %ecx
[6c383b0]72 shrl $2, %ecx /* size / 4 */
[e3c762cd]73
74 movl MEMCPY_DST(%esp), %edi
75 movl MEMCPY_SRC(%esp), %esi
76
[6c383b0]77 rep movsl /* copy whole words */
[e3c762cd]78
79 movl MEMCPY_SIZE(%esp), %ecx
[6c383b0]80 andl $3, %ecx /* size % 4 */
[e3c762cd]81 jz 0f
82
[6c383b0]83 rep movsb /* copy the rest byte by byte */
[e3c762cd]84
850:
86 movl %edx, %edi
87 movl %eax, %esi
[6c383b0]88 movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */
[e3c762cd]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
[6c383b0]99 xorl %eax, %eax /* return 0, failure */
[e3c762cd]100 ret
[da585a52]101
102## Turn paging on
103#
104# Enable paging and write-back caching in CR0.
105#
[f761f1eb]106paging_on:
[6c383b0]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
[24bd23a]111 movl %edx,%cr0
[f761f1eb]112 jmp 0f
1130:
114 ret
115
[da585a52]116
117## Enable local APIC
118#
119# Enable local APIC in MSR.
120#
[f761f1eb]121enable_l_apic_in_msr:
122 movl $0x1b, %ecx
123 rdmsr
[6c383b0]124 orl $(1 << 11), %eax
125 orl $(0xfee00000), %eax
[f761f1eb]126 wrmsr
127 ret
128
[53f9821]129# Clear nested flag
130# overwrites %ecx
131.macro CLEAR_NT_FLAG
132 pushfl
133 pop %ecx
[6c383b0]134 and $0xffffbfff, %ecx
[53f9821]135 push %ecx
136 popfl
137.endm
[da585a52]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
[fcfac420]145# and call exc_dispatch().
[da585a52]146#
[738ad2e]147#define INTERRUPT_ALIGN 64
[f761f1eb]148.macro handler i n
[25d7709]149
[6c383b0]150.ifeq \i - 0x30 # Syscall handler
151 pushl %ds
152 pushl %es
153 pushl %fs
154 pushl %gs
[53f9821]155
[6c383b0]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
[53f9821]170
171 # we must fill the data segment registers
[6c383b0]172 movw $16, %ax
173 movw %ax, %ds
174 movw %ax, %es
[53f9821]175
176 sti
[6c383b0]177 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
178 call syscall_handler
[53f9821]179 cli
[6c383b0]180 addl $28, %esp # clean-up of parameters
[53f9821]181
[6c383b0]182 popl %gs
183 popl %fs
184 popl %es
185 popl %ds
[53f9821]186
187 CLEAR_NT_FLAG
188 iret
189.else
[25d7709]190 /*
[8e0eb63]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.
[25d7709]195 */
[6c383b0]196 .iflt \i - 32
[8e0eb63]197 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
[53f9821]198 /*
199 * With error word, do nothing
[8e0eb63]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
[53f9821]212 .endif
213
[6c383b0]214 pushl %ds
215 pushl %es
216 pushl %fs
217 pushl %gs
[76cec1e]218
[53f9821]219#ifdef CONFIG_DEBUG_ALLREGS
[6c383b0]220 pushl %ebx
221 pushl %ebp
222 pushl %edi
223 pushl %esi
[53f9821]224#else
[6c383b0]225 subl $16, %esp
[53f9821]226#endif
[6c383b0]227 pushl %edx
228 pushl %ecx
229 pushl %eax
[53f9821]230
[f761f1eb]231 # we must fill the data segment registers
[6c383b0]232 movw $16, %ax
233 movw %ax, %ds
234 movw %ax, %es
[76cec1e]235
[53f9821]236 pushl %esp # *istate
237 pushl $(\i) # intnum
238 call exc_dispatch # excdispatch(intnum, *istate)
[6c383b0]239 addl $8, %esp # Clear arguments from stack
[f761f1eb]240
[53f9821]241 CLEAR_NT_FLAG # Modifies %ecx
242
[6c383b0]243 popl %eax
244 popl %ecx
245 popl %edx
[53f9821]246#ifdef CONFIG_DEBUG_ALLREGS
[6c383b0]247 popl %esi
248 popl %edi
249 popl %ebp
250 popl %ebx
[53f9821]251#else
[6c383b0]252 addl $16, %esp
[53f9821]253#endif
254
[6c383b0]255 popl %gs
256 popl %fs
257 popl %es
258 popl %ds
[f07bba5]259
[6c383b0]260 addl $4, %esp # Skip error word, no matter whether real or fake.
[76cec1e]261 iret
[53f9821]262.endif
[76cec1e]263
[53f9821]264 .align INTERRUPT_ALIGN
[6c383b0]265 .if (\n- \i) - 1
266 handler "(\i + 1)", \n
[f761f1eb]267 .endif
268.endm
269
270# keep in sync with pm.h !!!
[6c383b0]271IDT_ITEMS = 64
[53f9821]272.align INTERRUPT_ALIGN
[f761f1eb]273interrupt_handlers:
274h_start:
[53f9821]275 handler 0 IDT_ITEMS
[f761f1eb]276h_end:
277
278.data
279.global interrupt_handler_size
280
[6c383b0]281interrupt_handler_size: .long (h_end - h_start) / IDT_ITEMS
Note: See TracBrowser for help on using the repository browser.