Changeset 44c69b66 in mainline


Ignore:
Timestamp:
2010-07-12T15:38:15Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4e91239
Parents:
c15b374
Message:

Make the code in asm.S independent of the interrupt vector used for syscalls.

Location:
kernel/arch/ia32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/include/asm.h

    rc15b374 r44c69b66  
    429429extern void asm_delay_loop(uint32_t);
    430430extern void asm_fake_loop(uint32_t);
     431
     432extern uintptr_t int_syscall;
    431433
    432434extern uintptr_t int_0;
  • kernel/arch/ia32/src/asm.S

    rc15b374 r44c69b66  
    266266        sysexit   /* return to userspace */
    267267
     268/*
     269 * This is the legacy syscall handler using the interrupt mechanism.
     270 */
     271.global int_syscall
     272int_syscall:
     273        subl $(ISTATE_SOFT_SIZE + 4), %esp
     274
     275        /*
     276         * Push syscall arguments onto the stack
     277         *
     278         * NOTE: The idea behind the order of arguments passed
     279         *       in registers is to use all scratch registers
     280         *       first and preserved registers next. An optimized
     281         *       libc syscall wrapper can make use of this setup.
     282         *       The istate structure is arranged in the way to support
     283         *       this idea.
     284         *
     285         */
     286        movl %eax, ISTATE_OFFSET_EAX(%esp)
     287        movl %ebx, ISTATE_OFFSET_EBX(%esp)
     288        movl %ecx, ISTATE_OFFSET_ECX(%esp)
     289        movl %edx, ISTATE_OFFSET_EDX(%esp)
     290        movl %edi, ISTATE_OFFSET_EDI(%esp)
     291        movl %esi, ISTATE_OFFSET_ESI(%esp)
     292        movl %ebp, ISTATE_OFFSET_EBP(%esp)
     293
     294        /*
     295         * Save the selector registers.
     296         */
     297        movl %gs, %ecx
     298        movl %fs, %edx
     299
     300        movl %ecx, ISTATE_OFFSET_GS(%esp)
     301        movl %edx, ISTATE_OFFSET_FS(%esp)
     302
     303        movl %es, %ecx
     304        movl %ds, %edx
     305               
     306        movl %ecx, ISTATE_OFFSET_ES(%esp)
     307        movl %edx, ISTATE_OFFSET_DS(%esp)
     308
     309        /*
     310         * Switch to kernel selectors.
     311         */
     312        movl $16, %eax
     313        movl %eax, %ds
     314        movl %eax, %es
     315               
     316        movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
     317        movl ISTATE_OFFSET_EIP(%esp), %eax
     318        movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
     319        leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
     320               
     321        cld
     322        sti
     323               
     324        /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
     325        call syscall_handler
     326                       
     327        CLEAR_NT_FLAG
     328
     329        /*
     330         * Restore the selector registers.
     331         */
     332        movl ISTATE_OFFSET_GS(%esp), %ecx
     333        movl ISTATE_OFFSET_FS(%esp), %edx
     334
     335        movl %ecx, %gs
     336        movl %edx, %fs
     337
     338        movl ISTATE_OFFSET_ES(%esp), %ecx
     339        movl ISTATE_OFFSET_DS(%esp), %edx
     340                       
     341        movl %ecx, %es
     342        movl %edx, %ds
     343                       
     344        /*
     345         * Restore the preserved registers the handler cloberred itself
     346         * (i.e. EBP).
     347         */
     348        movl ISTATE_OFFSET_EBP(%esp), %ebp
     349                       
     350        addl $(ISTATE_SOFT_SIZE + 4), %esp
     351        iret
     352               
     353
    268354/** Declare interrupt handlers
    269355 *
     
    272358 *
    273359 */
    274 
    275360.macro handler i
    276361.global int_\i
    277362int_\i:
    278         .ifeq \i - 0x30
    279                 /* Syscall handler */
    280                 subl $(ISTATE_SOFT_SIZE + 4), %esp
    281 
     363        /*
     364         * This macro distinguishes between two versions of ia32
     365         * exceptions. One version has error word and the other
     366         * does not have it. The latter version fakes the error
     367         * word on the stack so that the handlers and istate_t
     368         * can be the same for both types.
     369         */
     370        .iflt \i - 32
     371                .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     372                        /*
     373                         * Exception with error word: do nothing
     374                         */
     375                .else
     376                        /*
     377                         * Exception without error word: fake up one
     378                         */
     379                        pushl $0
     380                .endif
     381        .else
    282382                /*
    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                  *
     383                 * Interrupt: fake up one
    292384                 */
    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)
     385                pushl $0
     386        .endif
     387       
     388        subl $ISTATE_SOFT_SIZE, %esp
     389       
     390        /*
     391         * Save the general purpose registers.
     392         */
     393        movl %eax, ISTATE_OFFSET_EAX(%esp)
     394        movl %ebx, ISTATE_OFFSET_EBX(%esp)
     395        movl %ecx, ISTATE_OFFSET_ECX(%esp)
     396        movl %edx, ISTATE_OFFSET_EDX(%esp)
     397        movl %edi, ISTATE_OFFSET_EDI(%esp)
     398        movl %esi, ISTATE_OFFSET_ESI(%esp)
     399        movl %ebp, ISTATE_OFFSET_EBP(%esp)
     400       
     401        /*
     402         * Save the selector registers.
     403         */
     404        movl %gs, %eax
     405        movl %fs, %ebx
     406        movl %es, %ecx
     407        movl %ds, %edx
     408       
     409        movl %eax, ISTATE_OFFSET_GS(%esp)
     410        movl %ebx, ISTATE_OFFSET_FS(%esp)
     411        movl %ecx, ISTATE_OFFSET_ES(%esp)
     412        movl %edx, ISTATE_OFFSET_DS(%esp)
     413       
     414        /*
     415         * Switch to kernel selectors.
     416         */
     417        movl $16, %eax
     418        movl %eax, %ds
     419        movl %eax, %es
     420       
     421        /*
     422         * Imitate a regular stack frame linkage.
     423         * Stop stack traces here if we came from userspace.
     424         */
     425        cmpl $8, ISTATE_OFFSET_CS(%esp)
     426        jz 0f
     427        xorl %ebp, %ebp
     428       
     429        0:
     430       
     431                movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
    324432                movl ISTATE_OFFSET_EIP(%esp), %eax
    325433                movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
     
    327435               
    328436                cld
    329                 sti
    330                
    331                 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
    332                 call syscall_handler
    333                        
     437               
     438                pushl %esp   /* pass istate address */
     439                pushl $(\i)  /* pass intnum */
     440               
     441                /* Call exc_dispatch(intnum, istate) */
     442                call exc_dispatch
     443               
     444                addl $8, %esp  /* clear arguments from the stack */
     445               
    334446                CLEAR_NT_FLAG
    335 
     447               
    336448                /*
    337449                 * Restore the selector registers.
    338450                 */
    339                 movl ISTATE_OFFSET_GS(%esp), %ecx
    340                 movl ISTATE_OFFSET_FS(%esp), %edx
    341 
    342                 movl %ecx, %gs
    343                 movl %edx, %fs
    344 
     451                movl ISTATE_OFFSET_GS(%esp), %eax
     452                movl ISTATE_OFFSET_FS(%esp), %ebx
    345453                movl ISTATE_OFFSET_ES(%esp), %ecx
    346454                movl ISTATE_OFFSET_DS(%esp), %edx
    347                        
     455               
     456                movl %eax, %gs
     457                movl %ebx, %fs
    348458                movl %ecx, %es
    349459                movl %edx, %ds
    350                        
     460               
    351461                /*
    352                  * Restore the preserved registers the handler cloberred itself
    353                  * (i.e. EBP).
     462                 * Restore the scratch registers and the preserved
     463                 * registers the handler cloberred itself
     464                 * (i.e. EBX and EBP).
    354465                 */
     466                movl ISTATE_OFFSET_EAX(%esp), %eax
     467                movl ISTATE_OFFSET_EBX(%esp), %ebx
     468                movl ISTATE_OFFSET_ECX(%esp), %ecx
     469                movl ISTATE_OFFSET_EDX(%esp), %edx
    355470                movl ISTATE_OFFSET_EBP(%esp), %ebp
    356                        
     471               
    357472                addl $(ISTATE_SOFT_SIZE + 4), %esp
    358473                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
    379                 .else
    380                         /*
    381                          * Interrupt: fake up one
    382                          */
    383                         pushl $0
    384                 .endif
    385                
    386                 subl $ISTATE_SOFT_SIZE, %esp
    387                
    388                 /*
    389                  * Save the general purpose registers.
    390                  */
    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                
    473         .endif
    474474.endm
    475475
  • kernel/arch/ia32/src/pm.c

    rc15b374 r44c69b66  
    206206        idt_setoffset(d++, (uintptr_t) &int_62);
    207207        idt_setoffset(d++, (uintptr_t) &int_63);
     208
     209        idt_setoffset(&idt[VECTOR_SYSCALL], (uintptr_t) &int_syscall);
    208210}
    209211
Note: See TracChangeset for help on using the changeset viewer.