Ignore:
File:
1 edited

Legend:

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

    rf77e591d rc0e9f3f  
    192192#define ERROR_WORD_INTERRUPT_LIST  0x00027D00
    193193
    194 .macro handler i
    195 .global int_\i
    196 int_\i:
    197 
     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       
    198206        /*
    199207         * Choose between version with error code and version without error
    200          * code.
     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.
    201213         */
    202214       
     
    278290        addq $(ISTATE_SOFT_SIZE + 8), %rsp
    279291        iretq
     292       
     293        .align INTERRUPT_ALIGN
     294        .if (\n - \i) - 1
     295                handler "(\i + 1)", \n
     296        .endif
    280297.endm
    281298
    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 
     299.align INTERRUPT_ALIGN
    287300interrupt_handlers:
    288 .irp cnt, LIST_0_63
    289         handler \cnt
    290 .endr
     301        h_start:
     302                handler 0 IDT_ITEMS
     303        h_end:
    291304
    292305/** Low-level syscall handler
     
    321334        movq %gs:8, %rsp  /* set this thread's kernel RSP */
    322335       
    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 */
     336        /* Switch back to remain consistent */
    366337        swapgs
    367338        sti
    368339       
     340        pushq %rcx
     341        pushq %r11
     342        pushq %rbp
     343       
     344        xorq %rbp, %rbp  /* stop the stack traces here */
     345       
    369346        /* Copy the 4th argument where it is expected  */
    370347        movq %r10, %rcx
    371 
    372         /*
    373          * Call syscall_handler() with the 7th argument passed on stack.
    374          */
     348        pushq %rax
     349       
    375350        call syscall_handler
    376351       
     352        addq $8, %rsp
     353       
     354        popq %rbp
     355        popq %r11
     356        popq %rcx
     357       
    377358        cli
    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 
     359        swapgs
     360       
     361        /* Restore the user RSP */
     362        movq %gs:0, %rsp
     363        swapgs
     364       
    388365        sysretq
    389366
     
    532509        ret
    533510
     511.data
     512.global interrupt_handler_size
     513
     514interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
Note: See TracChangeset for help on using the changeset viewer.