Changes in kernel/arch/ia32/src/asm.S [eee047c:b8230b9] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/asm.S
reee047c rb8230b9 142 142 .macro CLEAR_NT_FLAG 143 143 pushfl 144 andl $0xffffbfff, (%esp) 144 pop %ecx 145 and $0xffffbfff, %ecx 146 push %ecx 145 147 popfl 146 148 .endm … … 161 163 pushl %edi # remember return user address 162 164 163 xorl %ebp, %ebp # stop stack traces here164 165 165 pushl %gs # remember TLS 166 166 … … 188 188 189 189 190 #define ISTATE_OFFSET_EAX 0191 #define ISTATE_OFFSET_EBX 4192 #define ISTATE_OFFSET_ECX 8193 #define ISTATE_OFFSET_EDX 12194 #define ISTATE_OFFSET_EDI 16195 #define ISTATE_OFFSET_ESI 20196 #define ISTATE_OFFSET_EBP 24197 #define ISTATE_OFFSET_EBP_FRAME 28198 #define ISTATE_OFFSET_EIP_FRAME 32199 #define ISTATE_OFFSET_GS 36200 #define ISTATE_OFFSET_FS 40201 #define ISTATE_OFFSET_ES 44202 #define ISTATE_OFFSET_DS 48203 #define ISTATE_OFFSET_ERROR_WORD 52204 #define ISTATE_OFFSET_EIP 56205 #define ISTATE_OFFSET_CS 60206 #define ISTATE_OFFSET_EFLAGS 64207 #define ISTATE_OFFSET_ESP 68208 #define ISTATE_OFFSET_SS 72209 210 /*211 * Size of the istate structure without the hardware-saved part and without the212 * error word.213 */214 #define ISTATE_SOFT_SIZE 52215 216 190 ## Declare interrupt handlers 217 191 # … … 222 196 # and call exc_dispatch(). 223 197 # 224 #define INTERRUPT_ALIGN 256198 #define INTERRUPT_ALIGN 64 225 199 .macro handler i n 226 200 227 .ifeq \i - 0x30 # Syscall handler 228 pushl %ds 229 pushl %es 230 pushl %fs 231 pushl %gs 232 233 # 234 # Push syscall arguments onto the stack 235 # 236 # NOTE: The idea behind the order of arguments passed in registers is to 237 # use all scratch registers first and preserved registers next. 238 # An optimized libc syscall wrapper can make use of this setup. 239 # 240 pushl %eax 241 pushl %ebp 242 pushl %edi 243 pushl %esi 244 pushl %ebx 245 pushl %ecx 246 pushl %edx 247 248 # we must fill the data segment registers 249 movw $16, %ax 250 movw %ax, %ds 251 movw %ax, %es 252 253 xorl %ebp, %ebp 254 255 cld 256 sti 257 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) 258 call syscall_handler 259 cli 260 261 movl 20(%esp), %ebp # restore EBP 262 addl $28, %esp # clean-up of parameters 263 264 popl %gs 265 popl %fs 266 popl %es 267 popl %ds 268 269 CLEAR_NT_FLAG 270 iret 271 .else 272 /* 273 * This macro distinguishes between two versions of ia32 exceptions. 274 * One version has error word and the other does not have it. 275 * The latter version fakes the error word on the stack so that the 276 * handlers and istate_t can be the same for both types. 277 */ 278 .iflt \i - 32 279 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 280 # 281 # Exception with error word: do nothing 282 # 283 .else 284 # 285 # Exception without error word: fake up one 286 # 287 pushl $0 288 .endif 289 .else 290 # 291 # Interrupt: fake up one 292 # 293 pushl $0 294 .endif 295 296 subl $ISTATE_SOFT_SIZE, %esp 297 298 # 299 # Save the general purpose registers. 300 # 301 movl %eax, ISTATE_OFFSET_EAX(%esp) 302 movl %ebx, ISTATE_OFFSET_EBX(%esp) 303 movl %ecx, ISTATE_OFFSET_ECX(%esp) 304 movl %edx, ISTATE_OFFSET_EDX(%esp) 305 movl %edi, ISTATE_OFFSET_EDI(%esp) 306 movl %esi, ISTATE_OFFSET_ESI(%esp) 307 movl %ebp, ISTATE_OFFSET_EBP(%esp) 308 309 # 310 # Save the selector registers. 311 # 312 movl %gs, %eax 313 movl %fs, %ebx 314 movl %es, %ecx 315 movl %ds, %edx 316 317 movl %eax, ISTATE_OFFSET_GS(%esp) 318 movl %ebx, ISTATE_OFFSET_FS(%esp) 319 movl %ecx, ISTATE_OFFSET_ES(%esp) 320 movl %edx, ISTATE_OFFSET_DS(%esp) 321 322 # 323 # Switch to kernel selectors. 324 # 325 movl $16, %eax 326 movl %eax, %ds 327 movl %eax, %es 328 329 # 330 # Imitate a regular stack frame linkage. 331 # Stop stack traces here if we came from userspace. 332 # 333 cmpl $8, ISTATE_OFFSET_CS(%esp) 334 jz 0f 335 xorl %ebp, %ebp 336 0: movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp) 337 movl ISTATE_OFFSET_EIP(%esp), %eax 338 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 339 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 340 341 cld 342 343 pushl %esp # pass istate address 344 pushl $(\i) # pass intnum 345 call exc_dispatch # exc_dispatch(intnum, istate) 346 addl $8, %esp # Clear arguments from the stack 347 348 CLEAR_NT_FLAG 349 350 # 351 # Restore the selector registers. 352 # 353 movl ISTATE_OFFSET_GS(%esp), %eax 354 movl ISTATE_OFFSET_FS(%esp), %ebx 355 movl ISTATE_OFFSET_ES(%esp), %ecx 356 movl ISTATE_OFFSET_DS(%esp), %edx 357 358 movl %eax, %gs 359 movl %ebx, %fs 360 movl %ecx, %es 361 movl %edx, %ds 362 363 # 364 # Restore the scratch registers and the preserved registers the handler 365 # cloberred itself (i.e. EBX and EBP). 366 # 367 movl ISTATE_OFFSET_EAX(%esp), %eax 368 movl ISTATE_OFFSET_EBX(%esp), %ebx 369 movl ISTATE_OFFSET_ECX(%esp), %ecx 370 movl ISTATE_OFFSET_EDX(%esp), %edx 371 movl ISTATE_OFFSET_EBP(%esp), %ebp 372 373 addl $(ISTATE_SOFT_SIZE + 4), %esp 374 iret 375 .endif 376 377 .align INTERRUPT_ALIGN 378 .if (\n- \i) - 1 379 handler "(\i + 1)", \n 380 .endif 201 .ifeq \i - 0x30 # Syscall handler 202 pushl %ds 203 pushl %es 204 pushl %fs 205 pushl %gs 206 207 # 208 # Push syscall arguments onto the stack 209 # 210 # NOTE: The idea behind the order of arguments passed in registers is to 211 # use all scratch registers first and preserved registers next. 212 # An optimized libc syscall wrapper can make use of this setup. 213 # 214 pushl %eax 215 pushl %ebp 216 pushl %edi 217 pushl %esi 218 pushl %ebx 219 pushl %ecx 220 pushl %edx 221 222 # we must fill the data segment registers 223 movw $16, %ax 224 movw %ax, %ds 225 movw %ax, %es 226 227 cld 228 sti 229 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) 230 call syscall_handler 231 cli 232 addl $28, %esp # clean-up of parameters 233 234 popl %gs 235 popl %fs 236 popl %es 237 popl %ds 238 239 CLEAR_NT_FLAG 240 iret 241 .else 242 /* 243 * This macro distinguishes between two versions of ia32 exceptions. 244 * One version has error word and the other does not have it. 245 * The latter version fakes the error word on the stack so that the 246 * handlers and istate_t can be the same for both types. 247 */ 248 .iflt \i - 32 249 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 250 /* 251 * With error word, do nothing 252 */ 253 .else 254 /* 255 * Version without error word 256 */ 257 subl $4, %esp 258 .endif 259 .else 260 /* 261 * Version without error word 262 */ 263 subl $4, %esp 264 .endif 265 266 pushl %ds 267 pushl %es 268 pushl %fs 269 pushl %gs 270 271 pushl %ebp 272 pushl %edx 273 pushl %ecx 274 pushl %eax 275 276 # we must fill the data segment registers 277 278 movw $16, %ax 279 movw %ax, %ds 280 movw %ax, %es 281 282 # stop stack traces here 283 xorl %ebp, %ebp 284 285 pushl %esp # *istate 286 pushl $(\i) # intnum 287 call exc_dispatch # exc_dispatch(intnum, *istate) 288 addl $8, %esp # Clear arguments from stack 289 290 CLEAR_NT_FLAG # Modifies %ecx 291 292 popl %eax 293 popl %ecx 294 popl %edx 295 popl %ebp 296 297 popl %gs 298 popl %fs 299 popl %es 300 popl %ds 301 302 # skip error word, no matter whether real or fake 303 addl $4, %esp 304 iret 305 .endif 306 307 .align INTERRUPT_ALIGN 308 .if (\n- \i) - 1 309 handler "(\i + 1)", \n 310 .endif 381 311 .endm 382 312
Note:
See TracChangeset
for help on using the changeset viewer.