Changeset 5f83634 in mainline for kernel/arch/ia32/src/asm.S


Ignore:
Timestamp:
2010-07-12T16:45:05Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
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.
Message:

Merge from lp:~jakub/helenos/upa

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/asm.S

    rbee2d4c r5f83634  
    3030 *
    3131 */
    32 
    33 /**
    34  * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
    35  * has no error word  and 1 means interrupt with error word
    36  *
    37  */
    38 #define ERROR_WORD_INTERRUPT_LIST  0x00027d00
    3932
    4033#include <arch/pm.h>
     
    153146        wrmsr
    154147        ret
    155 
    156 /** Clear nested flag
    157  *
    158  */
    159 .macro CLEAR_NT_FLAG
    160         pushfl
    161         andl $0xffffbfff, (%esp)
    162         popfl
    163 .endm
    164148
    165149#define ISTATE_OFFSET_EDX         0
     
    266250        sysexit   /* return to userspace */
    267251
     252/*
     253 * This is the legacy syscall handler using the interrupt mechanism.
     254 */
     255.global int_syscall
     256int_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
    268341/** Declare interrupt handlers
    269342 *
     
    272345 *
    273346 */
    274 
    275347.macro handler i
    276348.global int_\i
    277349int_\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                         */
    379362                .else
    380363                        /*
    381                          * Interrupt: fake up one
     364                         * Exception without error word: fake up one
    382365                         */
    383366                        pushl $0
    384367                .endif
    385                
    386                 subl $ISTATE_SOFT_SIZE, %esp
    387                
     368        .else
    388369                /*
    389                  * Save the general purpose registers.
     370                 * Interrupt: fake up one
    390371                 */
    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
    473373        .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
    474460.endm
    475461
Note: See TracChangeset for help on using the changeset viewer.