Changes in / [4003861:6b1a85c] in mainline


Ignore:
Location:
kernel/arch
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/asm.h

    r4003861 r6b1a85c  
    435435GEN_WRITE_REG(dr7)
    436436
     437extern size_t interrupt_handler_size;
     438extern void interrupt_handlers(void);
     439
    437440extern void asm_delay_loop(uint32_t);
    438441extern void asm_fake_loop(uint32_t);
    439442
    440 extern uintptr_t int_0;
    441 extern uintptr_t int_1;
    442 extern uintptr_t int_2;
    443 extern uintptr_t int_3;
    444 extern uintptr_t int_4;
    445 extern uintptr_t int_5;
    446 extern uintptr_t int_6;
    447 extern uintptr_t int_7;
    448 extern uintptr_t int_8;
    449 extern uintptr_t int_9;
    450 extern uintptr_t int_10;
    451 extern uintptr_t int_11;
    452 extern uintptr_t int_12;
    453 extern uintptr_t int_13;
    454 extern uintptr_t int_14;
    455 extern uintptr_t int_15;
    456 extern uintptr_t int_16;
    457 extern uintptr_t int_17;
    458 extern uintptr_t int_18;
    459 extern uintptr_t int_19;
    460 extern uintptr_t int_20;
    461 extern uintptr_t int_21;
    462 extern uintptr_t int_22;
    463 extern uintptr_t int_23;
    464 extern uintptr_t int_24;
    465 extern uintptr_t int_25;
    466 extern uintptr_t int_26;
    467 extern uintptr_t int_27;
    468 extern uintptr_t int_28;
    469 extern uintptr_t int_29;
    470 extern uintptr_t int_30;
    471 extern uintptr_t int_31;
    472 extern uintptr_t int_32;
    473 extern uintptr_t int_33;
    474 extern uintptr_t int_34;
    475 extern uintptr_t int_35;
    476 extern uintptr_t int_36;
    477 extern uintptr_t int_37;
    478 extern uintptr_t int_38;
    479 extern uintptr_t int_39;
    480 extern uintptr_t int_40;
    481 extern uintptr_t int_41;
    482 extern uintptr_t int_42;
    483 extern uintptr_t int_43;
    484 extern uintptr_t int_44;
    485 extern uintptr_t int_45;
    486 extern uintptr_t int_46;
    487 extern uintptr_t int_47;
    488 extern uintptr_t int_48;
    489 extern uintptr_t int_49;
    490 extern uintptr_t int_50;
    491 extern uintptr_t int_51;
    492 extern uintptr_t int_52;
    493 extern uintptr_t int_53;
    494 extern uintptr_t int_54;
    495 extern uintptr_t int_55;
    496 extern uintptr_t int_56;
    497 extern uintptr_t int_57;
    498 extern uintptr_t int_58;
    499 extern uintptr_t int_59;
    500 extern uintptr_t int_60;
    501 extern uintptr_t int_61;
    502 extern uintptr_t int_62;
    503 extern uintptr_t int_63;
    504 
    505443#endif
    506444
  • kernel/arch/amd64/src/asm.S

    r4003861 r6b1a85c  
    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
  • kernel/arch/amd64/src/interrupt.c

    r4003861 r6b1a85c  
    6565void istate_decode(istate_t *istate)
    6666{
    67         printf("cs =%p\trip=%p\trfl=%p\terr=%p\n",
    68             istate->cs, istate->rip, istate->rflags, istate->error_word);
    69 
    70         if (istate_from_uspace(istate))
    71                 printf("ss =%p\n", istate->ss);
    72        
    73         printf("rax=%p\trbx=%p\trcx=%p\trdx=%p\n",
    74             istate->rax, istate->rbx, istate->rcx, istate->rdx);
    75         printf("rsi=%p\trdi=%p\trbp=%p\trsp=%p\n",
    76             istate->rsi, istate->rdi, istate->rbp,
    77             istate_from_uspace(istate) ? istate->rsp : (uintptr_t)&istate->rsp);
    78         printf("r8 =%p\tr9 =%p\tr10=%p\tr11=%p\n",
    79             istate->r8, istate->r9, istate->r10, istate->r11);
    80         printf("r12=%p\tr13=%p\tr14=%p\tr15=%p\n",
    81             istate->r12, istate->r13, istate->r14, istate->r15);
     67        printf("error_word=%#llx\n", istate->error_word);
     68        printf("cs =%#0.16llx\trflags=%#0.16llx\n", istate->cs,
     69            istate->rflags);
     70        printf("rax=%#0.16llx\trbx=%#0.16llx\trcx=%#0.16llx\n", istate->rax,
     71            istate->rcx, istate->rdx);
     72        printf("rsi=%#0.16llx\trdi=%#0.16llx\tr8 =%#0.16llx\n", istate->rsi,
     73            istate->rdi, istate->r8);
     74        printf("r9 =%#0.16llx\tr10=%#0.16llx\tr11=%#0.16llx\n", istate->r9,
     75            istate->r10, istate->r11);
    8276}
    8377
  • kernel/arch/amd64/src/pm.c

    r4003861 r6b1a85c  
    175175                d->present = 1;
    176176                d->type = AR_INTERRUPT; /* masking interrupt */
     177
     178                idt_setoffset(d, ((uintptr_t) interrupt_handlers) +
     179                    i * interrupt_handler_size);
    177180        }
    178 
    179         d = &idt[0];
    180         idt_setoffset(d++, (uintptr_t) &int_0);
    181         idt_setoffset(d++, (uintptr_t) &int_1);
    182         idt_setoffset(d++, (uintptr_t) &int_2);
    183         idt_setoffset(d++, (uintptr_t) &int_3);
    184         idt_setoffset(d++, (uintptr_t) &int_4);
    185         idt_setoffset(d++, (uintptr_t) &int_5);
    186         idt_setoffset(d++, (uintptr_t) &int_6);
    187         idt_setoffset(d++, (uintptr_t) &int_7);
    188         idt_setoffset(d++, (uintptr_t) &int_8);
    189         idt_setoffset(d++, (uintptr_t) &int_9);
    190         idt_setoffset(d++, (uintptr_t) &int_10);
    191         idt_setoffset(d++, (uintptr_t) &int_11);
    192         idt_setoffset(d++, (uintptr_t) &int_12);
    193         idt_setoffset(d++, (uintptr_t) &int_13);
    194         idt_setoffset(d++, (uintptr_t) &int_14);
    195         idt_setoffset(d++, (uintptr_t) &int_15);
    196         idt_setoffset(d++, (uintptr_t) &int_16);
    197         idt_setoffset(d++, (uintptr_t) &int_17);
    198         idt_setoffset(d++, (uintptr_t) &int_18);
    199         idt_setoffset(d++, (uintptr_t) &int_19);
    200         idt_setoffset(d++, (uintptr_t) &int_20);
    201         idt_setoffset(d++, (uintptr_t) &int_21);
    202         idt_setoffset(d++, (uintptr_t) &int_22);
    203         idt_setoffset(d++, (uintptr_t) &int_23);
    204         idt_setoffset(d++, (uintptr_t) &int_24);
    205         idt_setoffset(d++, (uintptr_t) &int_25);
    206         idt_setoffset(d++, (uintptr_t) &int_26);
    207         idt_setoffset(d++, (uintptr_t) &int_27);
    208         idt_setoffset(d++, (uintptr_t) &int_28);
    209         idt_setoffset(d++, (uintptr_t) &int_29);
    210         idt_setoffset(d++, (uintptr_t) &int_30);
    211         idt_setoffset(d++, (uintptr_t) &int_31);
    212         idt_setoffset(d++, (uintptr_t) &int_32);
    213         idt_setoffset(d++, (uintptr_t) &int_33);
    214         idt_setoffset(d++, (uintptr_t) &int_34);
    215         idt_setoffset(d++, (uintptr_t) &int_35);
    216         idt_setoffset(d++, (uintptr_t) &int_36);
    217         idt_setoffset(d++, (uintptr_t) &int_37);
    218         idt_setoffset(d++, (uintptr_t) &int_38);
    219         idt_setoffset(d++, (uintptr_t) &int_39);
    220         idt_setoffset(d++, (uintptr_t) &int_40);
    221         idt_setoffset(d++, (uintptr_t) &int_41);
    222         idt_setoffset(d++, (uintptr_t) &int_42);
    223         idt_setoffset(d++, (uintptr_t) &int_43);
    224         idt_setoffset(d++, (uintptr_t) &int_44);
    225         idt_setoffset(d++, (uintptr_t) &int_45);
    226         idt_setoffset(d++, (uintptr_t) &int_46);
    227         idt_setoffset(d++, (uintptr_t) &int_47);
    228         idt_setoffset(d++, (uintptr_t) &int_48);
    229         idt_setoffset(d++, (uintptr_t) &int_49);
    230         idt_setoffset(d++, (uintptr_t) &int_50);
    231         idt_setoffset(d++, (uintptr_t) &int_51);
    232         idt_setoffset(d++, (uintptr_t) &int_52);
    233         idt_setoffset(d++, (uintptr_t) &int_53);
    234         idt_setoffset(d++, (uintptr_t) &int_54);
    235         idt_setoffset(d++, (uintptr_t) &int_55);
    236         idt_setoffset(d++, (uintptr_t) &int_56);
    237         idt_setoffset(d++, (uintptr_t) &int_57);
    238         idt_setoffset(d++, (uintptr_t) &int_58);
    239         idt_setoffset(d++, (uintptr_t) &int_59);
    240         idt_setoffset(d++, (uintptr_t) &int_60);
    241         idt_setoffset(d++, (uintptr_t) &int_61);
    242         idt_setoffset(d++, (uintptr_t) &int_62);
    243         idt_setoffset(d++, (uintptr_t) &int_63);
    244181}
    245182
  • kernel/arch/amd64/src/proc/scheduler.c

    r4003861 r6b1a85c  
    3838#include <proc/thread.h>
    3939#include <arch.h>
     40#include <arch/context.h>
    4041#include <arch/asm.h>
    4142#include <print.h>
     
    5657{
    5758        CPU->arch.tss->rsp0 =
    58             (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
     59            (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
    5960       
    6061        /*
  • kernel/arch/amd64/src/proc/thread.c

    r4003861 r6b1a85c  
    3434
    3535#include <proc/thread.h>
    36 #include <arch/interrupt.h>
    3736
    3837/** Perform amd64 specific thread initialization.
     
    5049         */
    5150        thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =
    52             (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)];
     51            (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(uint64_t)];
    5352}
    5453
  • kernel/arch/ia32/include/asm.h

    r4003861 r6b1a85c  
    4242#include <config.h>
    4343#include <trace.h>
     44
     45extern uint32_t interrupt_handler_size;
    4446
    4547/** Halt CPU
  • kernel/arch/ia32/src/asm.S

    r4003861 r6b1a85c  
    175175
    176176/*
     177 * Size of the entire istate structure including the error word and the
     178 * hardware-saved part.
     179 */
     180#define ISTATE_REAL_SIZE  (ISTATE_SOFT_SIZE + 24)
     181
     182/*
    177183 * The SYSENTER syscall mechanism can be used for syscalls with
    178184 * four or fewer arguments. To pass these four arguments, we
     
    185191.global sysenter_handler
    186192sysenter_handler:
    187 
    188         /*
    189          * Note that the space needed for the istate structure has been
    190          * preallocated on the stack by before_thread_runs_arch().
    191          */
     193        subl $(ISTATE_REAL_SIZE), %esp
    192194
    193195        /*
     
    258260        movl ISTATE_OFFSET_ESP(%esp), %ecx
    259261
     262        addl $(ISTATE_REAL_SIZE), %esp
     263       
    260264        sysexit   /* return to userspace */
    261265
     
    349353#define ERROR_WORD_INTERRUPT_LIST  0x00027d00
    350354
     355/** Declare interrupt handlers
     356 *
     357 * Declare interrupt handlers for n interrupt
     358 * vectors starting at vector i.
     359 *
     360 */
    351361.macro handler i
    352362.global int_\i
  • kernel/arch/ia32/src/interrupt.c

    r4003861 r6b1a85c  
    6565void istate_decode(istate_t *istate)
    6666{
    67         printf("cs =%p\teip=%p\tefl=%p\terr=%p\n",
    68             istate->cs, istate->eip, istate->eflags, istate->error_word);
    69 
    70         printf("ds =%p\tes =%p\tfs =%p\tgs =%p\n",
    71             istate->ds, istate->es, istate->fs, istate->gs);
     67        printf("error_word=%p\n", istate->error_word);
     68        printf("eflags=%p\n", istate->eflags);
     69
     70        printf("cs =%p\tds =%p\tes =%p\n", istate->cs, istate->ds, istate->es);
     71        printf("fs =%p\tgs =%p", istate->fs, istate->gs);
    7272        if (istate_from_uspace(istate))
    73                 printf("ss =%p\n", istate->ss);
    74 
    75         printf("eax=%p\tebx=%p\tecx=%p\tedx=%p\n",
    76             istate->eax, istate->ebx, istate->ecx, istate->edx);
    77         printf("esi=%p\tedi=%p\tebp=%p\tesp=%p\n",
    78             istate->esi, istate->edi, istate->ebp,
    79             istate_from_uspace(istate) ? istate->esp : (uintptr_t)&istate->esp);
     73                printf("\tss =%p\n", istate->ss);
     74        else
     75                printf("\n");
     76
     77        printf("eax=%p\tebx=%p\tecx=%p\n", istate->eax, istate->ebx,
     78            istate->ecx);
     79        printf("edx=%p\tedi=%p\tesi=%p\n", istate->edx, istate->edi,
     80            istate->esi);
     81        printf("ebp=%p\tesp=%p\teip=%p\n", istate->ebp,
     82            istate_from_uspace(istate) ? istate->esp : (uintptr_t) &istate->esp,
     83            istate->eip);
    8084}
    8185
  • kernel/arch/ia32/src/proc/scheduler.c

    r4003861 r6b1a85c  
    3838#include <proc/thread.h>
    3939#include <arch.h>
    40 #include <arch/interrupt.h>
     40#include <arch/context.h>  /* SP_DELTA */
    4141#include <arch/pm.h>
    4242#include <arch/asm.h>
     
    5858void before_thread_runs_arch(void)
    5959{
    60         uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
     60        uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
     61            SP_DELTA];
    6162       
    6263        if (CPU->arch.fi.bits.sep) {
    6364                /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
    64                 write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t));
     65                write_msr(IA32_MSR_SYSENTER_ESP, kstk);
    6566        }
    6667       
Note: See TracChangeset for help on using the changeset viewer.