Changeset 6473d41 in mainline


Ignore:
Timestamp:
2010-06-29T20:19:09Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c9eb31c2
Parents:
f56e897f
Message:

Alter the ia32 istate_t so that the stack trace printed upon a panic shows the
faulting instruction and modify the exception/interrupt handlers accordingly.
With this change, the ia32 istate_t contains all GPRs again.

Location:
kernel/arch/ia32
Files:
2 edited

Legend:

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

    rf56e897f r6473d41  
    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

    rf56e897f r6473d41  
    190190
    191191
     192#define ISTATE_OFFSET_EAX               0
     193#define ISTATE_OFFSET_EBX               4
     194#define ISTATE_OFFSET_ECX               8
     195#define ISTATE_OFFSET_EDX               12
     196#define ISTATE_OFFSET_EDI               16
     197#define ISTATE_OFFSET_ESI               20
     198#define ISTATE_OFFSET_EBP               24
     199#define ISTATE_OFFSET_EBP_FRAME         28
     200#define ISTATE_OFFSET_EIP_FRAME         32
     201#define ISTATE_OFFSET_GS                36
     202#define ISTATE_OFFSET_FS                40
     203#define ISTATE_OFFSET_ES                44
     204#define ISTATE_OFFSET_DS                48
     205#define ISTATE_OFFSET_ERROR_WORD        52
     206#define ISTATE_OFFSET_EIP               56
     207#define ISTATE_OFFSET_CS                60
     208#define ISTATE_OFFSET_EFLAGS            64
     209#define ISTATE_OFFSET_ESP               68
     210#define ISTATE_OFFSET_SS                72
     211
     212/*
     213 * Size of the istate structure without the hardware-saved part and without the
     214 * error word.
     215 */
     216#define ISTATE_SOFT_SIZE                52
     217
    192218## Declare interrupt handlers
    193219#
     
    201227.macro handler i n
    202228       
    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
     229.ifeq \i - 0x30     # Syscall handler
     230        pushl %ds
     231        pushl %es
     232        pushl %fs
     233        pushl %gs
     234               
     235        #
     236        # Push syscall arguments onto the stack
     237        #
     238        # NOTE: The idea behind the order of arguments passed in registers is to
     239        #       use all scratch registers first and preserved registers next.
     240        #       An optimized libc syscall wrapper can make use of this setup.
     241        #
     242        pushl %eax
     243        pushl %ebp
     244        pushl %edi
     245        pushl %esi
     246        pushl %ebx
     247        pushl %ecx
     248        pushl %edx
     249               
     250        # we must fill the data segment registers
     251        movw $16, %ax
     252        movw %ax, %ds
     253        movw %ax, %es
     254       
     255        xorl %ebp, %ebp
     256
     257        cld
     258        sti
     259        # syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
     260        call syscall_handler
     261        cli
     262
     263        movl 20(%esp), %ebp     # restore EBP
     264        addl $28, %esp          # clean-up of parameters
     265               
     266        popl %gs
     267        popl %fs
     268        popl %es
     269        popl %ds
     270               
     271        CLEAR_NT_FLAG
     272        iret
     273.else
     274        /*
     275         * This macro distinguishes between two versions of ia32 exceptions.
     276         * One version has error word and the other does not have it.
     277         * The latter version fakes the error word on the stack so that the
     278         * handlers and istate_t can be the same for both types.
     279         */
     280.iflt \i - 32
     281.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
     282        #
     283        # Exception with error word: do nothing
     284        #
     285.else
     286        #
     287        # Exception without error word: fake up one
     288        #
     289        pushl $0
     290.endif
     291.else
     292        #
     293        # Interrupt: fake up one
     294        #
     295        pushl $0
     296.endif
     297               
     298        subl $ISTATE_SOFT_SIZE, %esp
     299
     300        #
     301        # Save the general purpose registers.
     302        #
     303        movl %eax, ISTATE_OFFSET_EAX(%esp)
     304        movl %ebx, ISTATE_OFFSET_EBX(%esp)
     305        movl %ecx, ISTATE_OFFSET_ECX(%esp)
     306        movl %edx, ISTATE_OFFSET_EDX(%esp)
     307        movl %edi, ISTATE_OFFSET_EDI(%esp)
     308        movl %esi, ISTATE_OFFSET_ESI(%esp)
     309        movl %ebp, ISTATE_OFFSET_EBP(%esp)
     310       
     311        #
     312        # Save the selector registers.
     313        #
     314        movl %gs, %eax
     315        movl %fs, %ebx
     316        movl %es, %ecx
     317        movl %ds, %edx
     318
     319        movl %eax, ISTATE_OFFSET_GS(%esp)
     320        movl %ebx, ISTATE_OFFSET_FS(%esp)
     321        movl %ecx, ISTATE_OFFSET_ES(%esp)
     322        movl %edx, ISTATE_OFFSET_DS(%esp)
     323
     324        #
     325        # Switch to kernel selectors.
     326        #
     327        movl $16, %eax
     328        movl %eax, %ds
     329        movl %eax, %es
     330               
     331        #
     332        # Imitate a regular stack frame linkage.
     333        # Stop stack traces here if we came from userspace.
     334        #
     335        cmpl $8, ISTATE_OFFSET_CS(%esp)
     336        jz 0f
     337        xorl %ebp, %ebp
     3380:      movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
     339        movl ISTATE_OFFSET_EIP(%esp), %eax
     340        movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
     341        leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
     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
Note: See TracChangeset for help on using the changeset viewer.