Changeset 4003861 in mainline for kernel/arch/amd64/src/asm.S


Ignore:
Timestamp:
2010-07-14T13:11:59Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
074c9bd, aa0d227
Parents:
6b1a85c (diff), f77e591 (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 from lp:~jakub/helenos/upa

File:
1 edited

Legend:

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

    r6b1a85c r4003861  
    192192#define ERROR_WORD_INTERRUPT_LIST  0x00027D00
    193193
    194 #define INTERRUPT_ALIGN         256
    195 
    196 /** Declare interrupt handlers
    197  *
    198  * Declare interrupt handlers for n interrupt
    199  * vectors starting at vector i.
    200  *
    201  * The handlers call exc_dispatch().
    202  *
    203  */
    204 .macro handler i n
    205        
     194.macro handler i
     195.global int_\i
     196int_\i:
     197
    206198        /*
    207199         * Choose between version with error code and version without error
    208          * code. Both versions have to be of the same size. amd64 assembly is,
    209          * however, a little bit tricky. For instance, subq $0x80, %rsp and
    210          * subq $0x78, %rsp can result in two instructions with different
    211          * op-code lengths.
    212          * Therefore we align the interrupt handlers.
     200         * code.
    213201         */
    214202       
     
    290278        addq $(ISTATE_SOFT_SIZE + 8), %rsp
    291279        iretq
    292        
    293         .align INTERRUPT_ALIGN
    294         .if (\n - \i) - 1
    295                 handler "(\i + 1)", \n
    296         .endif
    297280.endm
    298281
    299 .align INTERRUPT_ALIGN
     282#define LIST_0_63 \
     283        0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
     284        28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\
     285        53,54,55,56,57,58,59,60,61,62,63
     286
    300287interrupt_handlers:
    301         h_start:
    302                 handler 0 IDT_ITEMS
    303         h_end:
     288.irp cnt, LIST_0_63
     289        handler \cnt
     290.endr
    304291
    305292/** Low-level syscall handler
     
    334321        movq %gs:8, %rsp  /* set this thread's kernel RSP */
    335322       
    336         /* Switch back to remain consistent */
     323        /*
     324         * Note that the space needed for the imitated istate structure has been
     325         * preallocated for us in thread_create_arch() and set in
     326         * before_thread_runs_arch().
     327         */
     328
     329        /*
     330         * Save the general purpose registers and push the 7th argument (syscall
     331         * number) onto the stack. Note that the istate structure has a layout
     332         * which supports this.
     333         */
     334        movq %rax, ISTATE_OFFSET_RAX(%rsp)  /* 7th argument, passed on stack */
     335        movq %rbx, ISTATE_OFFSET_RBX(%rsp)  /* observability */
     336        movq %rcx, ISTATE_OFFSET_RCX(%rsp)  /* userspace RIP */
     337        movq %rdx, ISTATE_OFFSET_RDX(%rsp)  /* 3rd argument, observability */
     338        movq %rsi, ISTATE_OFFSET_RSI(%rsp)  /* 2nd argument, observability */
     339        movq %rdi, ISTATE_OFFSET_RDI(%rsp)  /* 1st argument, observability */
     340        movq %rbp, ISTATE_OFFSET_RBP(%rsp)  /* need to preserve userspace RBP */
     341        movq %r8, ISTATE_OFFSET_R8(%rsp)    /* 5th argument, observability */
     342        movq %r9, ISTATE_OFFSET_R9(%rsp)    /* 6th argument, observability */
     343        movq %r10, ISTATE_OFFSET_R10(%rsp)  /* 4th argument, observability */
     344        movq %r11, ISTATE_OFFSET_R11(%rsp)  /* low 32 bits userspace RFLAGS */
     345        movq %r12, ISTATE_OFFSET_R12(%rsp)  /* observability */
     346        movq %r13, ISTATE_OFFSET_R13(%rsp)  /* observability */
     347        movq %r14, ISTATE_OFFSET_R14(%rsp)  /* observability */
     348        movq %r15, ISTATE_OFFSET_R15(%rsp)  /* observability */
     349
     350        /*
     351         * Save the return address and the userspace stack on locations that
     352         * would normally be taken by them.
     353         */
     354        movq %gs:0, %rax
     355        movq %rax, ISTATE_OFFSET_RSP(%rsp)
     356        movq %rcx, ISTATE_OFFSET_RIP(%rsp)
     357
     358        /*
     359         * Imitate a regular stack frame linkage.
     360         */
     361        movq $0, ISTATE_OFFSET_RBP_FRAME(%rsp)
     362        movq %rcx, ISTATE_OFFSET_RIP_FRAME(%rsp)
     363        leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp
     364
     365        /* Switch back to normal %gs */
    337366        swapgs
    338367        sti
    339368       
    340         pushq %rcx
    341         pushq %r11
    342         pushq %rbp
    343        
    344         xorq %rbp, %rbp  /* stop the stack traces here */
    345        
    346369        /* Copy the 4th argument where it is expected  */
    347370        movq %r10, %rcx
    348         pushq %rax
    349        
     371
     372        /*
     373         * Call syscall_handler() with the 7th argument passed on stack.
     374         */
    350375        call syscall_handler
    351376       
    352         addq $8, %rsp
    353        
    354         popq %rbp
    355         popq %r11
    356         popq %rcx
    357        
    358377        cli
    359         swapgs
    360        
    361         /* Restore the user RSP */
    362         movq %gs:0, %rsp
    363         swapgs
    364        
     378       
     379        /*
     380         * Restore registers needed for return via the SYSRET instruction and
     381         * the clobbered preserved registers (i.e. RBP).
     382         */
     383        movq ISTATE_OFFSET_RBP(%rsp), %rbp
     384        movq ISTATE_OFFSET_RCX(%rsp), %rcx
     385        movq ISTATE_OFFSET_R11(%rsp), %r11
     386        movq ISTATE_OFFSET_RSP(%rsp), %rsp
     387
    365388        sysretq
    366389
     
    509532        ret
    510533
    511 .data
    512 .global interrupt_handler_size
    513 
    514 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
Note: See TracChangeset for help on using the changeset viewer.