Changes in / [62b20f1:22c3444] in mainline


Ignore:
Location:
kernel
Files:
3 edited

Legend:

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

    r62b20f1 r22c3444  
    7272
    7373typedef struct istate {
    74         /*
    75          * The strange order of the GPRs is given by the requirement to use the
    76          * istate structure for both regular interrupts and exceptions as well
    77          * as for syscall handler which use this order as an optimization.
    78          */
     74        uint32_t eax;
     75        uint32_t ebx;
     76        uint32_t ecx;
    7977        uint32_t edx;
    80         uint32_t ecx;
    81         uint32_t ebx;
     78        uint32_t edi;
    8279        uint32_t esi;
    83         uint32_t edi;
    8480        uint32_t ebp;
    85         uint32_t eax;
    8681       
    8782        uint32_t ebp_frame;  /* imitation of frame pointer linkage */
  • kernel/arch/ia32/src/asm.S

    r62b20f1 r22c3444  
    164164.endm
    165165
    166 #define ISTATE_OFFSET_EDX         0
    167 #define ISTATE_OFFSET_ECX         4
    168 #define ISTATE_OFFSET_EBX         8
    169 #define ISTATE_OFFSET_ESI         12
    170 #define ISTATE_OFFSET_EDI         16
    171 #define ISTATE_OFFSET_EBP         20
    172 #define ISTATE_OFFSET_EAX         24
     166/*
     167 * The SYSENTER syscall mechanism can be used for syscalls with
     168 * four or fewer arguments. To pass these four arguments, we
     169 * use four registers: EDX, ECX, EBX, ESI. The syscall number
     170 * is passed in EAX. We use EDI to remember the return address
     171 * and EBP to remember the stack. The INT-based syscall mechanism
     172 * can actually handle six arguments plus the syscall number
     173 * entirely in registers.
     174 */
     175.global sysenter_handler
     176sysenter_handler:
     177        sti
     178        pushl %ebp  /* remember user stack */
     179        pushl %edi  /* remember return user address */
     180       
     181        xorl %ebp, %ebp  /* stop stack traces here */
     182       
     183        pushl %gs  /* remember TLS */
     184       
     185        pushl %eax     /* syscall number */
     186        subl $8, %esp  /* unused sixth and fifth argument */
     187        pushl %esi     /* fourth argument */
     188        pushl %ebx     /* third argument */
     189        pushl %ecx     /* second argument */
     190        pushl %edx     /* first argument */
     191       
     192        movw $16, %ax
     193        movw %ax, %ds
     194        movw %ax, %es
     195       
     196        cld
     197        call syscall_handler
     198        addl $28, %esp  /* remove arguments from stack */
     199       
     200        pop %gs  /* restore TLS */
     201       
     202        pop %edx  /* prepare return EIP for SYSEXIT */
     203        pop %ecx  /* prepare userspace ESP for SYSEXIT */
     204       
     205        sysexit   /* return to userspace */
     206
     207#define ISTATE_OFFSET_EAX         0
     208#define ISTATE_OFFSET_EBX         4
     209#define ISTATE_OFFSET_ECX         8
     210#define ISTATE_OFFSET_EDX         12
     211#define ISTATE_OFFSET_EDI         16
     212#define ISTATE_OFFSET_ESI         20
     213#define ISTATE_OFFSET_EBP         24
    173214#define ISTATE_OFFSET_EBP_FRAME   28
    174215#define ISTATE_OFFSET_EIP_FRAME   32
     
    190231#define ISTATE_SOFT_SIZE  52
    191232
    192 /*
    193  * Size of the entire istate structure including the error word and the
    194  * hardware-saved part.
    195  */
    196 #define ISTATE_REAL_SIZE  (ISTATE_SOFT_SIZE + 24)
    197 
    198 /*
    199  * The SYSENTER syscall mechanism can be used for syscalls with
    200  * four or fewer arguments. To pass these four arguments, we
    201  * use four registers: EDX, ECX, EBX, ESI. The syscall number
    202  * is passed in EAX. We use EDI to remember the return address
    203  * and EBP to remember the stack. The INT-based syscall mechanism
    204  * can actually handle six arguments plus the syscall number
    205  * entirely in registers.
    206  */
    207 .global sysenter_handler
    208 sysenter_handler:
    209         sti
    210         subl $(ISTATE_REAL_SIZE), %esp
    211 
    212         /*
    213          * Save the return address and the userspace stack in the istate
    214          * structure on locations that would normally be taken by them.
    215          */
    216         movl %ebp, ISTATE_OFFSET_ESP(%esp)
    217         movl %edi, ISTATE_OFFSET_EIP(%esp)
    218 
    219         /*
    220          * Push syscall arguments onto the stack
    221          */
    222         movl %eax, ISTATE_OFFSET_EAX(%esp)
    223         movl %ebx, ISTATE_OFFSET_EBX(%esp)
    224         movl %ecx, ISTATE_OFFSET_ECX(%esp)
    225         movl %edx, ISTATE_OFFSET_EDX(%esp)
    226         movl %esi, ISTATE_OFFSET_ESI(%esp)
    227         movl %edi, ISTATE_OFFSET_EDI(%esp)      /* observability; not needed */
    228         movl %ebp, ISTATE_OFFSET_EBP(%esp)      /* observability; not needed */
    229        
    230         /*
    231          * Fake up the stack trace linkage.
    232          */
    233         movl %edi, ISTATE_OFFSET_EIP_FRAME(%esp)
    234         movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
    235         leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
    236 
    237         /*
    238          * Save TLS.
    239          */
    240         movl %gs, %edx
    241         movl %edx, ISTATE_OFFSET_GS(%esp)
    242 
    243         /*
    244          * Switch to kernel selectors.
    245          */
    246         movw $16, %ax
    247         movw %ax, %ds
    248         movw %ax, %es
    249        
    250         cld
    251         call syscall_handler
    252        
    253         /*
    254          * Restore TLS.
    255          */
    256         movl ISTATE_OFFSET_GS(%esp), %edx
    257         movl %edx, %gs
    258        
    259         /*
    260          * Prepare return address and userspace stack for SYSEXIT.
    261          */
    262         movl ISTATE_OFFSET_EIP(%esp), %edx
    263         movl ISTATE_OFFSET_ESP(%esp), %ecx
    264 
    265         addl $(ISTATE_REAL_SIZE), %esp
    266        
    267         sysexit   /* return to userspace */
    268 
    269233/** Declare interrupt handlers
    270234 *
     
    281245        .ifeq \i - 0x30
    282246                /* Syscall handler */
    283                 subl $(ISTATE_SOFT_SIZE + 4), %esp
    284 
     247                pushl %ds
     248                pushl %es
     249                pushl %fs
     250                pushl %gs
     251               
    285252                /*
    286253                 * Push syscall arguments onto the stack
     
    290257                 *       first and preserved registers next. An optimized
    291258                 *       libc syscall wrapper can make use of this setup.
    292                  *       The istate structure is arranged in the way to support
    293                  *       this idea.
    294259                 *
    295260                 */
    296                 movl %eax, ISTATE_OFFSET_EAX(%esp)
    297                 movl %ebx, ISTATE_OFFSET_EBX(%esp)
    298                 movl %ecx, ISTATE_OFFSET_ECX(%esp)
    299                 movl %edx, ISTATE_OFFSET_EDX(%esp)
    300                 movl %edi, ISTATE_OFFSET_EDI(%esp)
    301                 movl %esi, ISTATE_OFFSET_ESI(%esp)
    302                 movl %ebp, ISTATE_OFFSET_EBP(%esp)
    303 
    304                 /*
    305                  * Save the selector registers.
    306                  */
    307                 movl %gs, %ecx
    308                 movl %fs, %edx
    309 
    310                 movl %ecx, ISTATE_OFFSET_GS(%esp)
    311                 movl %edx, ISTATE_OFFSET_FS(%esp)
    312 
    313                 movl %es, %ecx
    314                 movl %ds, %edx
    315                
    316                 movl %ecx, ISTATE_OFFSET_ES(%esp)
    317                 movl %edx, ISTATE_OFFSET_DS(%esp)
    318 
    319                 /*
    320                  * Switch to kernel selectors.
    321                  */
    322                 movl $16, %eax
    323                 movl %eax, %ds
    324                 movl %eax, %es
    325                
    326                 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
    327                 movl ISTATE_OFFSET_EIP(%esp), %eax
    328                 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
    329                 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
     261                pushl %eax
     262                pushl %ebp
     263                pushl %edi
     264                pushl %esi
     265                pushl %ebx
     266                pushl %ecx
     267                pushl %edx
     268               
     269                /* We must fill the data segment registers */
     270                movw $16, %ax
     271                movw %ax, %ds
     272                movw %ax, %es
     273               
     274                xorl %ebp, %ebp
    330275               
    331276                cld
     
    334279                /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
    335280                call syscall_handler
    336                        
     281                cli
     282               
     283                movl 20(%esp), %ebp  /* restore EBP */
     284                addl $28, %esp       /* clean-up of parameters */
     285               
     286                popl %gs
     287                popl %fs
     288                popl %es
     289                popl %ds
     290               
    337291                CLEAR_NT_FLAG
    338 
    339                 /*
    340                  * Restore the selector registers.
    341                  */
    342                 movl ISTATE_OFFSET_GS(%esp), %ecx
    343                 movl ISTATE_OFFSET_FS(%esp), %edx
    344 
    345                 movl %ecx, %gs
    346                 movl %edx, %fs
    347 
    348                 movl ISTATE_OFFSET_ES(%esp), %ecx
    349                 movl ISTATE_OFFSET_DS(%esp), %edx
    350                        
    351                 movl %ecx, %es
    352                 movl %edx, %ds
    353                        
    354                 /*
    355                  * Restore the preserved registers the handler cloberred itself
    356                  * (i.e. EBP).
    357                  */
    358                 movl ISTATE_OFFSET_EBP(%esp), %ebp
    359                        
    360                 addl $(ISTATE_SOFT_SIZE + 4), %esp
    361292                iret
    362                
    363293        .else
    364294                /*
  • kernel/generic/src/interrupt/interrupt.c

    r62b20f1 r22c3444  
    163163{
    164164        fault_if_from_uspace(istate, "Unhandled exception %u.", n);
    165         panic_badtrap(istate, n, "Unhandled exception %u.", n);
     165        panic("Unhandled exception %u.", n);
    166166}
    167167
Note: See TracChangeset for help on using the changeset viewer.