Changeset 5f83634 in mainline for kernel/arch/ia32/src/asm.S
- Timestamp:
- 2010-07-12T16:45:05Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6b1a85c
- Parents:
- bee2d4c (diff), 8078180 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/asm.S
rbee2d4c r5f83634 30 30 * 31 31 */ 32 33 /**34 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int35 * has no error word and 1 means interrupt with error word36 *37 */38 #define ERROR_WORD_INTERRUPT_LIST 0x00027d0039 32 40 33 #include <arch/pm.h> … … 153 146 wrmsr 154 147 ret 155 156 /** Clear nested flag157 *158 */159 .macro CLEAR_NT_FLAG160 pushfl161 andl $0xffffbfff, (%esp)162 popfl163 .endm164 148 165 149 #define ISTATE_OFFSET_EDX 0 … … 266 250 sysexit /* return to userspace */ 267 251 252 /* 253 * This is the legacy syscall handler using the interrupt mechanism. 254 */ 255 .global int_syscall 256 int_syscall: 257 subl $(ISTATE_SOFT_SIZE + 4), %esp 258 259 /* 260 * Push syscall arguments onto the stack 261 * 262 * NOTE: The idea behind the order of arguments passed 263 * in registers is to use all scratch registers 264 * first and preserved registers next. An optimized 265 * libc syscall wrapper can make use of this setup. 266 * The istate structure is arranged in the way to support 267 * this idea. 268 * 269 */ 270 movl %eax, ISTATE_OFFSET_EAX(%esp) 271 movl %ebx, ISTATE_OFFSET_EBX(%esp) 272 movl %ecx, ISTATE_OFFSET_ECX(%esp) 273 movl %edx, ISTATE_OFFSET_EDX(%esp) 274 movl %edi, ISTATE_OFFSET_EDI(%esp) 275 movl %esi, ISTATE_OFFSET_ESI(%esp) 276 movl %ebp, ISTATE_OFFSET_EBP(%esp) 277 278 /* 279 * Save the selector registers. 280 */ 281 movl %gs, %ecx 282 movl %fs, %edx 283 284 movl %ecx, ISTATE_OFFSET_GS(%esp) 285 movl %edx, ISTATE_OFFSET_FS(%esp) 286 287 movl %es, %ecx 288 movl %ds, %edx 289 290 movl %ecx, ISTATE_OFFSET_ES(%esp) 291 movl %edx, ISTATE_OFFSET_DS(%esp) 292 293 /* 294 * Switch to kernel selectors. 295 */ 296 movl $16, %eax 297 movl %eax, %ds 298 movl %eax, %es 299 300 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 301 movl ISTATE_OFFSET_EIP(%esp), %eax 302 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 303 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 304 305 cld 306 307 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */ 308 call syscall_handler 309 310 /* 311 * Restore the selector registers. 312 */ 313 movl ISTATE_OFFSET_GS(%esp), %ecx 314 movl ISTATE_OFFSET_FS(%esp), %edx 315 316 movl %ecx, %gs 317 movl %edx, %fs 318 319 movl ISTATE_OFFSET_ES(%esp), %ecx 320 movl ISTATE_OFFSET_DS(%esp), %edx 321 322 movl %ecx, %es 323 movl %edx, %ds 324 325 /* 326 * Restore the preserved registers the handler cloberred itself 327 * (i.e. EBP). 328 */ 329 movl ISTATE_OFFSET_EBP(%esp), %ebp 330 331 addl $(ISTATE_SOFT_SIZE + 4), %esp 332 iret 333 334 /** 335 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int 336 * has no error word and 1 means interrupt with error word 337 * 338 */ 339 #define ERROR_WORD_INTERRUPT_LIST 0x00027d00 340 268 341 /** Declare interrupt handlers 269 342 * … … 272 345 * 273 346 */ 274 275 347 .macro handler i 276 348 .global int_\i 277 349 int_\i: 278 .ifeq \i - 0x30 279 /* Syscall handler */ 280 subl $(ISTATE_SOFT_SIZE + 4), %esp 281 282 /* 283 * Push syscall arguments onto the stack 284 * 285 * NOTE: The idea behind the order of arguments passed 286 * in registers is to use all scratch registers 287 * first and preserved registers next. An optimized 288 * libc syscall wrapper can make use of this setup. 289 * The istate structure is arranged in the way to support 290 * this idea. 291 * 292 */ 293 movl %eax, ISTATE_OFFSET_EAX(%esp) 294 movl %ebx, ISTATE_OFFSET_EBX(%esp) 295 movl %ecx, ISTATE_OFFSET_ECX(%esp) 296 movl %edx, ISTATE_OFFSET_EDX(%esp) 297 movl %edi, ISTATE_OFFSET_EDI(%esp) 298 movl %esi, ISTATE_OFFSET_ESI(%esp) 299 movl %ebp, ISTATE_OFFSET_EBP(%esp) 300 301 /* 302 * Save the selector registers. 303 */ 304 movl %gs, %ecx 305 movl %fs, %edx 306 307 movl %ecx, ISTATE_OFFSET_GS(%esp) 308 movl %edx, ISTATE_OFFSET_FS(%esp) 309 310 movl %es, %ecx 311 movl %ds, %edx 312 313 movl %ecx, ISTATE_OFFSET_ES(%esp) 314 movl %edx, ISTATE_OFFSET_DS(%esp) 315 316 /* 317 * Switch to kernel selectors. 318 */ 319 movl $16, %eax 320 movl %eax, %ds 321 movl %eax, %es 322 323 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 324 movl ISTATE_OFFSET_EIP(%esp), %eax 325 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 326 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 327 328 cld 329 sti 330 331 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */ 332 call syscall_handler 333 334 CLEAR_NT_FLAG 335 336 /* 337 * Restore the selector registers. 338 */ 339 movl ISTATE_OFFSET_GS(%esp), %ecx 340 movl ISTATE_OFFSET_FS(%esp), %edx 341 342 movl %ecx, %gs 343 movl %edx, %fs 344 345 movl ISTATE_OFFSET_ES(%esp), %ecx 346 movl ISTATE_OFFSET_DS(%esp), %edx 347 348 movl %ecx, %es 349 movl %edx, %ds 350 351 /* 352 * Restore the preserved registers the handler cloberred itself 353 * (i.e. EBP). 354 */ 355 movl ISTATE_OFFSET_EBP(%esp), %ebp 356 357 addl $(ISTATE_SOFT_SIZE + 4), %esp 358 iret 359 360 .else 361 /* 362 * This macro distinguishes between two versions of ia32 363 * exceptions. One version has error word and the other 364 * does not have it. The latter version fakes the error 365 * word on the stack so that the handlers and istate_t 366 * can be the same for both types. 367 */ 368 .iflt \i - 32 369 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 370 /* 371 * Exception with error word: do nothing 372 */ 373 .else 374 /* 375 * Exception without error word: fake up one 376 */ 377 pushl $0 378 .endif 350 /* 351 * This macro distinguishes between two versions of ia32 352 * exceptions. One version has error word and the other 353 * does not have it. The latter version fakes the error 354 * word on the stack so that the handlers and istate_t 355 * can be the same for both types. 356 */ 357 .iflt \i - 32 358 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST 359 /* 360 * Exception with error word: do nothing 361 */ 379 362 .else 380 363 /* 381 * Interrupt: fake up one364 * Exception without error word: fake up one 382 365 */ 383 366 pushl $0 384 367 .endif 385 386 subl $ISTATE_SOFT_SIZE, %esp 387 368 .else 388 369 /* 389 * Save the general purpose registers.370 * Interrupt: fake up one 390 371 */ 391 movl %eax, ISTATE_OFFSET_EAX(%esp) 392 movl %ebx, ISTATE_OFFSET_EBX(%esp) 393 movl %ecx, ISTATE_OFFSET_ECX(%esp) 394 movl %edx, ISTATE_OFFSET_EDX(%esp) 395 movl %edi, ISTATE_OFFSET_EDI(%esp) 396 movl %esi, ISTATE_OFFSET_ESI(%esp) 397 movl %ebp, ISTATE_OFFSET_EBP(%esp) 398 399 /* 400 * Save the selector registers. 401 */ 402 movl %gs, %eax 403 movl %fs, %ebx 404 movl %es, %ecx 405 movl %ds, %edx 406 407 movl %eax, ISTATE_OFFSET_GS(%esp) 408 movl %ebx, ISTATE_OFFSET_FS(%esp) 409 movl %ecx, ISTATE_OFFSET_ES(%esp) 410 movl %edx, ISTATE_OFFSET_DS(%esp) 411 412 /* 413 * Switch to kernel selectors. 414 */ 415 movl $16, %eax 416 movl %eax, %ds 417 movl %eax, %es 418 419 /* 420 * Imitate a regular stack frame linkage. 421 * Stop stack traces here if we came from userspace. 422 */ 423 cmpl $8, ISTATE_OFFSET_CS(%esp) 424 jz 0f 425 xorl %ebp, %ebp 426 427 0: 428 429 movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp) 430 movl ISTATE_OFFSET_EIP(%esp), %eax 431 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 432 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 433 434 cld 435 436 pushl %esp /* pass istate address */ 437 pushl $(\i) /* pass intnum */ 438 439 /* Call exc_dispatch(intnum, istate) */ 440 call exc_dispatch 441 442 addl $8, %esp /* clear arguments from the stack */ 443 444 CLEAR_NT_FLAG 445 446 /* 447 * Restore the selector registers. 448 */ 449 movl ISTATE_OFFSET_GS(%esp), %eax 450 movl ISTATE_OFFSET_FS(%esp), %ebx 451 movl ISTATE_OFFSET_ES(%esp), %ecx 452 movl ISTATE_OFFSET_DS(%esp), %edx 453 454 movl %eax, %gs 455 movl %ebx, %fs 456 movl %ecx, %es 457 movl %edx, %ds 458 459 /* 460 * Restore the scratch registers and the preserved 461 * registers the handler cloberred itself 462 * (i.e. EBX and EBP). 463 */ 464 movl ISTATE_OFFSET_EAX(%esp), %eax 465 movl ISTATE_OFFSET_EBX(%esp), %ebx 466 movl ISTATE_OFFSET_ECX(%esp), %ecx 467 movl ISTATE_OFFSET_EDX(%esp), %edx 468 movl ISTATE_OFFSET_EBP(%esp), %ebp 469 470 addl $(ISTATE_SOFT_SIZE + 4), %esp 471 iret 472 372 pushl $0 473 373 .endif 374 375 subl $ISTATE_SOFT_SIZE, %esp 376 377 /* 378 * Save the general purpose registers. 379 */ 380 movl %eax, ISTATE_OFFSET_EAX(%esp) 381 movl %ebx, ISTATE_OFFSET_EBX(%esp) 382 movl %ecx, ISTATE_OFFSET_ECX(%esp) 383 movl %edx, ISTATE_OFFSET_EDX(%esp) 384 movl %edi, ISTATE_OFFSET_EDI(%esp) 385 movl %esi, ISTATE_OFFSET_ESI(%esp) 386 movl %ebp, ISTATE_OFFSET_EBP(%esp) 387 388 /* 389 * Save the selector registers. 390 */ 391 movl %gs, %ecx 392 movl %fs, %edx 393 394 movl %ecx, ISTATE_OFFSET_GS(%esp) 395 movl %edx, ISTATE_OFFSET_FS(%esp) 396 397 movl %es, %ecx 398 movl %ds, %edx 399 400 movl %ecx, ISTATE_OFFSET_ES(%esp) 401 movl %edx, ISTATE_OFFSET_DS(%esp) 402 403 /* 404 * Switch to kernel selectors. 405 */ 406 movl $16, %eax 407 movl %eax, %ds 408 movl %eax, %es 409 410 /* 411 * Imitate a regular stack frame linkage. 412 * Stop stack traces here if we came from userspace. 413 */ 414 xorl %eax, %eax 415 cmpl $8, ISTATE_OFFSET_CS(%esp) 416 cmovl %eax, %ebp 417 418 movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp) 419 movl ISTATE_OFFSET_EIP(%esp), %eax 420 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 421 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 422 423 cld 424 425 pushl %esp /* pass istate address */ 426 pushl $(\i) /* pass intnum */ 427 428 /* Call exc_dispatch(intnum, istate) */ 429 call exc_dispatch 430 431 addl $8, %esp /* clear arguments from the stack */ 432 433 /* 434 * Restore the selector registers. 435 */ 436 movl ISTATE_OFFSET_GS(%esp), %ecx 437 movl ISTATE_OFFSET_FS(%esp), %edx 438 439 movl %ecx, %gs 440 movl %edx, %fs 441 442 movl ISTATE_OFFSET_ES(%esp), %ecx 443 movl ISTATE_OFFSET_DS(%esp), %edx 444 445 movl %ecx, %es 446 movl %edx, %ds 447 448 /* 449 * Restore the scratch registers and the preserved 450 * registers the handler cloberred itself 451 * (i.e. EBP). 452 */ 453 movl ISTATE_OFFSET_EAX(%esp), %eax 454 movl ISTATE_OFFSET_ECX(%esp), %ecx 455 movl ISTATE_OFFSET_EDX(%esp), %edx 456 movl ISTATE_OFFSET_EBP(%esp), %ebp 457 458 addl $(ISTATE_SOFT_SIZE + 4), %esp 459 iret 474 460 .endm 475 461
Note:
See TracChangeset
for help on using the changeset viewer.