Changeset 4003861 in mainline


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

Location:
kernel/arch
Files:
10 edited

Legend:

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

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

    r6b1a85c r4003861  
    6565void istate_decode(istate_t *istate)
    6666{
    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);
     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);
    7682}
    7783
  • kernel/arch/amd64/src/pm.c

    r6b1a85c r4003861  
    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);
    180177        }
     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);
    181244}
    182245
  • kernel/arch/amd64/src/proc/scheduler.c

    r6b1a85c r4003861  
    3838#include <proc/thread.h>
    3939#include <arch.h>
    40 #include <arch/context.h>
    4140#include <arch/asm.h>
    4241#include <print.h>
     
    5756{
    5857        CPU->arch.tss->rsp0 =
    59             (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
     58            (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
    6059       
    6160        /*
  • kernel/arch/amd64/src/proc/thread.c

    r6b1a85c r4003861  
    3434
    3535#include <proc/thread.h>
     36#include <arch/interrupt.h>
    3637
    3738/** Perform amd64 specific thread initialization.
     
    4950         */
    5051        thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =
    51             (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(uint64_t)];
     52            (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)];
    5253}
    5354
  • kernel/arch/ia32/include/asm.h

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

    r6b1a85c r4003861  
    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 /*
    183177 * The SYSENTER syscall mechanism can be used for syscalls with
    184178 * four or fewer arguments. To pass these four arguments, we
     
    191185.global sysenter_handler
    192186sysenter_handler:
    193         subl $(ISTATE_REAL_SIZE), %esp
     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         */
    194192
    195193        /*
     
    260258        movl ISTATE_OFFSET_ESP(%esp), %ecx
    261259
    262         addl $(ISTATE_REAL_SIZE), %esp
    263        
    264260        sysexit   /* return to userspace */
    265261
     
    353349#define ERROR_WORD_INTERRUPT_LIST  0x00027d00
    354350
    355 /** Declare interrupt handlers
    356  *
    357  * Declare interrupt handlers for n interrupt
    358  * vectors starting at vector i.
    359  *
    360  */
    361351.macro handler i
    362352.global int_\i
  • kernel/arch/ia32/src/interrupt.c

    r6b1a85c r4003861  
    6565void istate_decode(istate_t *istate)
    6666{
    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);
     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);
    7272        if (istate_from_uspace(istate))
    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);
     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);
    8480}
    8581
  • kernel/arch/ia32/src/proc/scheduler.c

    r6b1a85c r4003861  
    3838#include <proc/thread.h>
    3939#include <arch.h>
    40 #include <arch/context.h>  /* SP_DELTA */
     40#include <arch/interrupt.h>
    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 -
    61             SP_DELTA];
     60        uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
    6261       
    6362        if (CPU->arch.fi.bits.sep) {
    6463                /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
    65                 write_msr(IA32_MSR_SYSENTER_ESP, kstk);
     64                write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t));
    6665        }
    6766       
Note: See TracChangeset for help on using the changeset viewer.