Changeset 90ed058 in mainline


Ignore:
Timestamp:
2010-07-01T16:33:58Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
49ace23
Parents:
873c681 (diff), eee047c (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 ia32 interrupt handler and trap frame improvements.

Location:
kernel
Files:
4 edited

Legend:

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

    r873c681 r90ed058  
    7272typedef struct istate {
    7373        uint32_t eax;
     74        uint32_t ebx;
    7475        uint32_t ecx;
    7576        uint32_t edx;
     77        uint32_t edi;
     78        uint32_t esi;
    7679        uint32_t ebp;
     80       
     81        uint32_t ebp_frame;     /* imitation of frame pointer linkage */
     82        uint32_t eip_frame;     /* imitation of return address linkage */
    7783
    7884        uint32_t gs;
     
    8187        uint32_t ds;
    8288
    83         uint32_t error_word;
     89        uint32_t error_word;    /* real or fake error word */
    8490        uint32_t eip;
    8591        uint32_t cs;
    8692        uint32_t eflags;
    87         uint32_t stack[];
     93        uint32_t esp;           /* only if istate_t is from uspace */
     94        uint32_t ss;            /* only if istate_t is from uspace */
    8895} istate_t;
    8996
  • kernel/arch/ia32/src/asm.S

    r873c681 r90ed058  
    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   
     
    190188
    191189
     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
    192216## Declare interrupt handlers
    193217#
     
    198222# and call exc_dispatch().
    199223#
    200 #define INTERRUPT_ALIGN 128
     224#define INTERRUPT_ALIGN 256
    201225.macro handler i n
    202226       
    203         .ifeq \i - 0x30     # Syscall handler
    204                 pushl %ds
    205                 pushl %es
    206                 pushl %fs
    207                 pushl %gs
    208                
    209                 #
    210                 # Push syscall arguments onto the stack
    211                 #
    212                 # NOTE: The idea behind the order of arguments passed in registers is to
    213                 #       use all scratch registers first and preserved registers next.
    214                 #       An optimized libc syscall wrapper can make use of this setup.
    215                 #
    216                 pushl %eax
    217                 pushl %ebp
    218                 pushl %edi
    219                 pushl %esi
    220                 pushl %ebx
    221                 pushl %ecx
    222                 pushl %edx
    223                
    224                 # we must fill the data segment registers
    225                 movw $16, %ax
    226                 movw %ax, %ds
    227                 movw %ax, %es
    228        
    229                 xorl %ebp, %ebp
    230 
    231                 cld
    232                 sti
    233                 # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
    234                 call syscall_handler
    235                 cli
    236 
    237                 movl 20(%esp), %ebp     # restore EBP
    238                 addl $28, %esp          # clean-up of parameters
    239                
    240                 popl %gs
    241                 popl %fs
    242                 popl %es
    243                 popl %ds
    244                
    245                 CLEAR_NT_FLAG
    246                 iret
    247         .else
    248                 /*
    249                  * This macro distinguishes between two versions of ia32 exceptions.
    250                  * One version has error word and the other does not have it.
    251                  * The latter version fakes the error word on the stack so that the
    252                  * handlers and istate_t can be the same for both types.
    253                  */
    254                 .iflt \i - 32
    255                         .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
    256                                 /*
    257                                  * With error word, do nothing
    258                                  */
    259                         .else
    260                                 /*
    261                                  * Version without error word
    262                                  */
    263                                 subl $4, %esp
    264                         .endif
    265                 .else
    266                         /*
    267                          * Version without error word
    268                          */
    269                         subl $4, %esp
    270                 .endif
    271                
    272                 pushl %ds
    273                 pushl %es
    274                 pushl %fs
    275                 pushl %gs
    276                
    277                 pushl %ebp
    278                 pushl %edx
    279                 pushl %ecx
    280                 pushl %eax
    281                
    282                 # we must fill the data segment registers
    283                
    284                 movw $16, %ax
    285                 movw %ax, %ds
    286                 movw %ax, %es
    287                
    288                 # stop stack traces here if we came from userspace
    289                 cmpl $8, 40(%esp)
    290                 jz 0f
    291                 xorl %ebp, %ebp
    292 
    293 0:             
    294                 pushl %esp          # *istate
    295                 pushl $(\i)         # intnum
    296                 call exc_dispatch   # exc_dispatch(intnum, *istate)
    297                 addl $8, %esp       # Clear arguments from stack
    298                
    299                 CLEAR_NT_FLAG # Modifies %ecx
    300                
    301                 popl %eax
    302                 popl %ecx
    303                 popl %edx
    304                 popl %ebp
    305                
    306                 popl %gs
    307                 popl %fs
    308                 popl %es
    309                 popl %ds
    310                
    311                 # skip error word, no matter whether real or fake
    312                 addl $4, %esp
    313                 iret
    314         .endif
    315        
    316         .align INTERRUPT_ALIGN
    317         .if (\n- \i) - 1
    318                 handler "(\i + 1)", \n
    319         .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
    320381.endm
    321382
  • kernel/arch/ia32/src/interrupt.c

    r873c681 r90ed058  
    6565void istate_decode(istate_t *istate)
    6666{
    67         printf("error_word=%#lx\n", istate->error_word);
    68         printf("cs =%#0.8lx\teflags=%#0.8lx\n", istate->cs, istate->eflags);
    69         printf("eax=%#0.8lx\tecx=%#0.8lx\tedx=%#0.8lx\n",
    70             istate->eax, istate->ecx, istate->edx);
     67        printf("error_word=%p\n", istate->error_word);
     68        printf("eflags=%p\n", istate->eflags);
     69
     70        printf("cs =%p\tds =%p\tes =%p\n", istate->cs, istate->ds, istate->es);
     71        printf("fs =%p\tgs =%p", istate->fs, istate->gs);
     72        if (istate_from_uspace(istate))
     73                printf("\tss =%p\n", istate->ss);
     74        else
     75                printf("\n");
     76
     77        printf("eax=%p\tebx=%p\tecx=%p\n", istate->eax, istate->ebx,
     78            istate->ecx);
     79        printf("edx=%p\tedi=%p\tesi=%p\n", istate->edx, istate->edi,
     80            istate->esi);
     81        printf("ebp=%p\tesp=%p\teip=%p\n", istate->ebp,
     82            istate_from_uspace(istate) ? istate->esp : (uintptr_t) &istate->esp,
     83            istate->eip);
    7184}
    7285
  • kernel/generic/src/debug/stacktrace.c

    r873c681 r90ed058  
    5252                    ops->symbol_resolve(pc, &symbol, &offset)) {
    5353                        if (offset)
    54                                 printf("%p: %s+%p()\n", fp, symbol, offset);
     54                                printf("%p: %s+%lx()\n", fp, symbol, offset);
    5555                        else
    5656                                printf("%p: %s()\n", fp, symbol);
Note: See TracChangeset for help on using the changeset viewer.