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


Ignore:
Location:
kernel
Files:
3 edited

Legend:

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

    r22c3444 r62b20f1  
    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         */
     79        uint32_t edx;
     80        uint32_t ecx;
     81        uint32_t ebx;
     82        uint32_t esi;
     83        uint32_t edi;
     84        uint32_t ebp;
    7485        uint32_t eax;
    75         uint32_t ebx;
    76         uint32_t ecx;
    77         uint32_t edx;
    78         uint32_t edi;
    79         uint32_t esi;
    80         uint32_t ebp;
    8186       
    8287        uint32_t ebp_frame;  /* imitation of frame pointer linkage */
  • kernel/arch/ia32/src/asm.S

    r22c3444 r62b20f1  
    164164.endm
    165165
    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
    176 sysenter_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
     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
    214173#define ISTATE_OFFSET_EBP_FRAME   28
    215174#define ISTATE_OFFSET_EIP_FRAME   32
     
    231190#define ISTATE_SOFT_SIZE  52
    232191
     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
     208sysenter_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
    233269/** Declare interrupt handlers
    234270 *
     
    245281        .ifeq \i - 0x30
    246282                /* Syscall handler */
    247                 pushl %ds
    248                 pushl %es
    249                 pushl %fs
    250                 pushl %gs
    251                
     283                subl $(ISTATE_SOFT_SIZE + 4), %esp
     284
    252285                /*
    253286                 * Push syscall arguments onto the stack
     
    257290                 *       first and preserved registers next. An optimized
    258291                 *       libc syscall wrapper can make use of this setup.
     292                 *       The istate structure is arranged in the way to support
     293                 *       this idea.
    259294                 *
    260295                 */
    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
     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
    275330               
    276331                cld
     
    279334                /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
    280335                call syscall_handler
    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                
     336                       
    291337                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
    292361                iret
     362               
    293363        .else
    294364                /*
  • kernel/generic/src/interrupt/interrupt.c

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