Changeset 074c9bd in mainline for kernel/arch/amd64/src


Ignore:
Timestamp:
2010-07-15T10:39:23Z (16 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
Children:
5c16ce7
Parents:
41ce4d9 (diff), 4003861 (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 mainline changes.

Location:
kernel/arch/amd64/src
Files:
7 edited

Legend:

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

    r41ce4d9 r074c9bd  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    29 #define IREGISTER_SPACE  80
    30 
    31 #define IOFFSET_RAX  0x00
    32 #define IOFFSET_RCX  0x08
    33 #define IOFFSET_RDX  0x10
    34 #define IOFFSET_RSI  0x18
    35 #define IOFFSET_RDI  0x20
    36 #define IOFFSET_R8   0x28
    37 #define IOFFSET_R9   0x30
    38 #define IOFFSET_R10  0x38
    39 #define IOFFSET_R11  0x40
    40 #define IOFFSET_RBP  0x48
    41 
    42 /**
    43  * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
    44  * has no error word  and 1 means interrupt with error word
    45  *
    46  */
    47 #define ERROR_WORD_INTERRUPT_LIST  0x00027D00
    4828
    4929#include <arch/pm.h>
     
    174154        ret
    175155
    176 /** Push all volatile general purpose registers on stack
    177  *
     156#define ISTATE_OFFSET_RAX               0
     157#define ISTATE_OFFSET_RBX               8
     158#define ISTATE_OFFSET_RCX               16
     159#define ISTATE_OFFSET_RDX               24
     160#define ISTATE_OFFSET_RSI               32
     161#define ISTATE_OFFSET_RDI               40
     162#define ISTATE_OFFSET_RBP               48
     163#define ISTATE_OFFSET_R8                56
     164#define ISTATE_OFFSET_R9                64
     165#define ISTATE_OFFSET_R10               72
     166#define ISTATE_OFFSET_R11               80
     167#define ISTATE_OFFSET_R12               88     
     168#define ISTATE_OFFSET_R13               96
     169#define ISTATE_OFFSET_R14               104
     170#define ISTATE_OFFSET_R15               112
     171#define ISTATE_OFFSET_ALIGNMENT         120
     172#define ISTATE_OFFSET_RBP_FRAME         128
     173#define ISTATE_OFFSET_RIP_FRAME         136
     174#define ISTATE_OFFSET_ERROR_WORD        144
     175#define ISTATE_OFFSET_RIP               152
     176#define ISTATE_OFFSET_CS                160
     177#define ISTATE_OFFSET_RFLAGS            168
     178#define ISTATE_OFFSET_RSP               176
     179#define ISTATE_OFFSET_SS                184
     180
     181/*
     182 * Size of the istate structure without the hardware-saved part and without the
     183 * error word.
    178184 */
    179 .macro save_all_gpr
    180         movq %rax, IOFFSET_RAX(%rsp)
    181         movq %rcx, IOFFSET_RCX(%rsp)
    182         movq %rdx, IOFFSET_RDX(%rsp)
    183         movq %rsi, IOFFSET_RSI(%rsp)
    184         movq %rdi, IOFFSET_RDI(%rsp)
    185         movq %r8, IOFFSET_R8(%rsp)
    186         movq %r9, IOFFSET_R9(%rsp)
    187         movq %r10, IOFFSET_R10(%rsp)
    188         movq %r11, IOFFSET_R11(%rsp)
    189         movq %rbp, IOFFSET_RBP(%rsp)
    190 .endm
    191 
    192 .macro restore_all_gpr
    193         movq IOFFSET_RAX(%rsp), %rax
    194         movq IOFFSET_RCX(%rsp), %rcx
    195         movq IOFFSET_RDX(%rsp), %rdx
    196         movq IOFFSET_RSI(%rsp), %rsi
    197         movq IOFFSET_RDI(%rsp), %rdi
    198         movq IOFFSET_R8(%rsp), %r8
    199         movq IOFFSET_R9(%rsp), %r9
    200         movq IOFFSET_R10(%rsp), %r10
    201         movq IOFFSET_R11(%rsp), %r11
    202         movq IOFFSET_RBP(%rsp), %rbp
    203 .endm
    204 
    205 #define INTERRUPT_ALIGN  128
    206 
    207 /** Declare interrupt handlers
    208  *
    209  * Declare interrupt handlers for n interrupt
    210  * vectors starting at vector i.
    211  *
    212  * The handlers call exc_dispatch().
     185#define ISTATE_SOFT_SIZE        144
     186
     187/**
     188 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
     189 * has no error word  and 1 means interrupt with error word
    213190 *
    214191 */
    215 .macro handler i n
    216        
     192#define ERROR_WORD_INTERRUPT_LIST  0x00027D00
     193
     194.macro handler i
     195.global int_\i
     196int_\i:
     197
    217198        /*
    218199         * Choose between version with error code and version without error
    219          * code. Both versions have to be of the same size. amd64 assembly is,
    220          * however, a little bit tricky. For instance, subq $0x80, %rsp and
    221          * subq $0x78, %rsp can result in two instructions with different
    222          * op-code lengths.
    223          * Therefore we align the interrupt handlers.
     200         * code.
    224201         */
    225202       
     
    229206                         * Version with error word.
    230207                         */
    231                         subq $IREGISTER_SPACE, %rsp
     208                        subq $ISTATE_SOFT_SIZE, %rsp
    232209                .else
    233210                        /*
    234                          * Version without error word,
     211                         * Version without error word.
    235212                         */
    236                         subq $(IREGISTER_SPACE + 8), %rsp
     213                        subq $(ISTATE_SOFT_SIZE + 8), %rsp
    237214                .endif
    238215        .else
    239216                /*
    240                  * Version without error word,
     217                 * Version without error word.
    241218                 */
    242                 subq $(IREGISTER_SPACE + 8), %rsp
     219                subq $(ISTATE_SOFT_SIZE + 8), %rsp
    243220        .endif
    244221       
    245         save_all_gpr
     222        /*
     223         * Save the general purpose registers.
     224         */
     225        movq %rax, ISTATE_OFFSET_RAX(%rsp)
     226        movq %rbx, ISTATE_OFFSET_RBX(%rsp)
     227        movq %rcx, ISTATE_OFFSET_RCX(%rsp)
     228        movq %rdx, ISTATE_OFFSET_RDX(%rsp)
     229        movq %rsi, ISTATE_OFFSET_RSI(%rsp)
     230        movq %rdi, ISTATE_OFFSET_RDI(%rsp)
     231        movq %rbp, ISTATE_OFFSET_RBP(%rsp)
     232        movq %r8, ISTATE_OFFSET_R8(%rsp)
     233        movq %r9, ISTATE_OFFSET_R9(%rsp)
     234        movq %r10, ISTATE_OFFSET_R10(%rsp)
     235        movq %r11, ISTATE_OFFSET_R11(%rsp)
     236        movq %r12, ISTATE_OFFSET_R12(%rsp)
     237        movq %r13, ISTATE_OFFSET_R13(%rsp)
     238        movq %r14, ISTATE_OFFSET_R14(%rsp)
     239        movq %r15, ISTATE_OFFSET_R15(%rsp)
     240
     241        /*
     242         * Imitate a regular stack frame linkage.
     243         * Stop stack traces here if we came from userspace.
     244         */
     245        xorq %rdx, %rdx
     246        cmpq $(gdtselector(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
     247        cmovnzq %rdx, %rbp
     248
     249        movq %rbp, ISTATE_OFFSET_RBP_FRAME(%rsp)
     250        movq ISTATE_OFFSET_RIP(%rsp), %rax
     251        movq %rax, ISTATE_OFFSET_RIP_FRAME(%rsp)
     252        leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp
     253
     254        movq $(\i), %rdi   /* pass intnum in the first argument */
     255        movq %rsp, %rsi    /* pass istate address in the second argument */
     256       
    246257        cld
    247        
    248         /*
    249          * Stop stack traces here if we came from userspace.
    250          */
    251         movq %cs, %rax
    252         xorq %rdx, %rdx
    253         cmpq %rax, IREGISTER_SPACE+16(%rsp)
    254         cmovneq %rdx, %rbp
    255 
    256         movq $(\i), %rdi   /* %rdi - first argument */
    257         movq %rsp, %rsi    /* %rsi - pointer to istate */
    258        
     258
    259259        /* Call exc_dispatch(i, istate) */
    260260        call exc_dispatch
    261        
    262         restore_all_gpr
     261
     262        /*
     263         * Restore all scratch registers and the preserved registers we have
     264         * clobbered in this handler (i.e. RBP).
     265         */
     266        movq ISTATE_OFFSET_RAX(%rsp), %rax
     267        movq ISTATE_OFFSET_RCX(%rsp), %rcx
     268        movq ISTATE_OFFSET_RDX(%rsp), %rdx
     269        movq ISTATE_OFFSET_RSI(%rsp), %rsi
     270        movq ISTATE_OFFSET_RDI(%rsp), %rdi
     271        movq ISTATE_OFFSET_RBP(%rsp), %rbp
     272        movq ISTATE_OFFSET_R8(%rsp), %r8
     273        movq ISTATE_OFFSET_R9(%rsp), %r9
     274        movq ISTATE_OFFSET_R10(%rsp), %r10
     275        movq ISTATE_OFFSET_R11(%rsp), %r11
    263276       
    264277        /* $8 = Skip error word */
    265         addq $(IREGISTER_SPACE + 8), %rsp
     278        addq $(ISTATE_SOFT_SIZE + 8), %rsp
    266279        iretq
    267        
    268         .align INTERRUPT_ALIGN
    269         .if (\n - \i) - 1
    270                 handler "(\i + 1)", \n
    271         .endif
    272280.endm
    273281
    274 .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
    275287interrupt_handlers:
    276         h_start:
    277                 handler 0 IDT_ITEMS
    278         h_end:
     288.irp cnt, LIST_0_63
     289        handler \cnt
     290.endr
    279291
    280292/** Low-level syscall handler
     
    309321        movq %gs:8, %rsp  /* set this thread's kernel RSP */
    310322       
    311         /* 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 */
    312366        swapgs
    313367        sti
    314368       
    315         pushq %rcx
    316         pushq %r11
    317         pushq %rbp
    318        
    319         xorq %rbp, %rbp  /* stop the stack traces here */
    320        
    321369        /* Copy the 4th argument where it is expected  */
    322370        movq %r10, %rcx
    323         pushq %rax
    324        
     371
     372        /*
     373         * Call syscall_handler() with the 7th argument passed on stack.
     374         */
    325375        call syscall_handler
    326376       
    327         addq $8, %rsp
    328        
    329         popq %rbp
    330         popq %r11
    331         popq %rcx
    332        
    333377        cli
    334         swapgs
    335        
    336         /* Restore the user RSP */
    337         movq %gs:0, %rsp
    338         swapgs
    339        
     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
    340388        sysretq
    341389
     
    484532        ret
    485533
    486 .data
    487 .global interrupt_handler_size
    488 
    489 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
  • kernel/arch/amd64/src/interrupt.c

    r41ce4d9 r074c9bd  
    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/mm/page.c

    r41ce4d9 r074c9bd  
    9090        if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
    9191                fault_if_from_uspace(istate, "Page fault: %#x.", page);
    92                 panic_memtrap(istate, access, page, "Page fault.");
     92                panic_memtrap(istate, access, page, NULL);
    9393        }
    9494}
  • kernel/arch/amd64/src/pm.c

    r41ce4d9 r074c9bd  
    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

    r41ce4d9 r074c9bd  
    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

    r41ce4d9 r074c9bd  
    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/amd64/src/syscall.c

    r41ce4d9 r074c9bd  
    6666         * - clear DF so that the string instructions operate in
    6767         *   the right direction
     68         * - clear NT to prevent a #GP should the flag proliferate to an IRET
    6869         */
    69         write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF);
     70        write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF | RFLAGS_NT);
    7071}
    7172
Note: See TracChangeset for help on using the changeset viewer.