Ignore:
File:
1 edited

Legend:

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

    rb8230b9 reee047c  
    142142.macro CLEAR_NT_FLAG
    143143        pushfl
    144         pop %ecx
    145         and $0xffffbfff, %ecx
    146         push %ecx
     144        andl $0xffffbfff, (%esp)
    147145        popfl
    148146.endm   
     
    163161        pushl %edi      # remember return user address
    164162
     163        xorl %ebp, %ebp # stop stack traces here
     164
    165165        pushl %gs       # remember TLS
    166166
     
    188188
    189189
     190#define ISTATE_OFFSET_EAX               0
     191#define ISTATE_OFFSET_EBX               4
     192#define ISTATE_OFFSET_ECX               8
     193#define ISTATE_OFFSET_EDX               12
     194#define ISTATE_OFFSET_EDI               16
     195#define ISTATE_OFFSET_ESI               20
     196#define ISTATE_OFFSET_EBP               24
     197#define ISTATE_OFFSET_EBP_FRAME         28
     198#define ISTATE_OFFSET_EIP_FRAME         32
     199#define ISTATE_OFFSET_GS                36
     200#define ISTATE_OFFSET_FS                40
     201#define ISTATE_OFFSET_ES                44
     202#define ISTATE_OFFSET_DS                48
     203#define ISTATE_OFFSET_ERROR_WORD        52
     204#define ISTATE_OFFSET_EIP               56
     205#define ISTATE_OFFSET_CS                60
     206#define ISTATE_OFFSET_EFLAGS            64
     207#define ISTATE_OFFSET_ESP               68
     208#define ISTATE_OFFSET_SS                72
     209
     210/*
     211 * Size of the istate structure without the hardware-saved part and without the
     212 * error word.
     213 */
     214#define ISTATE_SOFT_SIZE                52
     215
    190216## Declare interrupt handlers
    191217#
     
    196222# and call exc_dispatch().
    197223#
    198 #define INTERRUPT_ALIGN 64
     224#define INTERRUPT_ALIGN 256
    199225.macro handler i n
    200226       
    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
     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
     3360:      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
    311381.endm
    312382
Note: See TracChangeset for help on using the changeset viewer.