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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 06e1e95 was 11675207, checked in by jermar <jermar@…>, 17 years ago

Move everything to kernel/.

  • Property mode set to 100644
File size: 5.9 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 word
32# 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 as much as possible word by word */
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 andl $~((1<<30)|(1<<29)),%edx # clear Cache Disable and not Write Though
110 movl %edx,%cr0
111 jmp 0f
1120:
113 ret
114
115
116## Enable local APIC
117#
118# Enable local APIC in MSR.
119#
120enable_l_apic_in_msr:
121 push %eax
122
123 movl $0x1b, %ecx
124 rdmsr
125 orl $(1<<11),%eax
126 orl $(0xfee00000),%eax
127 wrmsr
128
129 pop %eax
130 ret
131
132# Clear nested flag
133# overwrites %ecx
134.macro CLEAR_NT_FLAG
135 pushfl
136 pop %ecx
137 and $0xffffbfff,%ecx
138 push %ecx
139 popfl
140.endm
141
142## Declare interrupt handlers
143#
144# Declare interrupt handlers for n interrupt
145# vectors starting at vector i.
146#
147# The handlers setup data segment registers
148# and call exc_dispatch().
149#
150#define INTERRUPT_ALIGN 64
151.macro handler i n
152
153.ifeq \i-0x30 # Syscall handler
154 push %ds
155 push %es
156 push %fs
157 push %gs
158
159 # Push arguments on stack
160 push %edi
161 push %esi
162 push %edx
163 push %ecx
164 push %eax
165
166 # we must fill the data segment registers
167 movw $16,%ax
168 movw %ax,%ds
169 movw %ax,%es
170
171 sti
172
173 call syscall_handler # syscall_handler(ax,cx,dx,si,di)
174 cli
175 addl $20, %esp # clean-up of parameters
176
177 pop %gs
178 pop %fs
179 pop %es
180 pop %ds
181
182 CLEAR_NT_FLAG
183 iret
184.else
185 /*
186 * This macro distinguishes between two versions of ia32 exceptions.
187 * One version has error word and the other does not have it.
188 * The latter version fakes the error word on the stack so that the
189 * handlers and istate_t can be the same for both types.
190 */
191 .iflt \i-32
192 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
193 /*
194 * With error word, do nothing
195 */
196 .else
197 /*
198 * Version without error word,
199 */
200 subl $4, %esp
201 .endif
202 .else
203 /*
204 * Version without error word,
205 */
206 subl $4, %esp
207 .endif
208
209 push %ds
210 push %es
211 push %fs
212 push %gs
213
214#ifdef CONFIG_DEBUG_ALLREGS
215 push %ebx
216 push %ebp
217 push %edi
218 push %esi
219#else
220 sub $16, %esp
221#endif
222 push %edx
223 push %ecx
224 push %eax
225
226 # we must fill the data segment registers
227 movw $16,%ax
228 movw %ax,%ds
229 movw %ax,%es
230
231 pushl %esp # *istate
232 pushl $(\i) # intnum
233 call exc_dispatch # excdispatch(intnum, *istate)
234 addl $8,%esp # Clear arguments from stack
235
236 CLEAR_NT_FLAG # Modifies %ecx
237
238 pop %eax
239 pop %ecx
240 pop %edx
241#ifdef CONFIG_DEBUG_ALLREGS
242 pop %esi
243 pop %edi
244 pop %ebp
245 pop %ebx
246#else
247 add $16, %esp
248#endif
249
250 pop %gs
251 pop %fs
252 pop %es
253 pop %ds
254
255 addl $4,%esp # Skip error word, no matter whether real or fake.
256 iret
257.endif
258
259 .align INTERRUPT_ALIGN
260 .if (\n-\i)-1
261 handler "(\i+1)",\n
262 .endif
263.endm
264
265# keep in sync with pm.h !!!
266IDT_ITEMS=64
267.align INTERRUPT_ALIGN
268interrupt_handlers:
269h_start:
270 handler 0 IDT_ITEMS
271h_end:
272
273.data
274.global interrupt_handler_size
275
276interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
Note: See TracBrowser for help on using the repository browser.