Massive cleanup of SPARC kernel entry code
authorAndrew Waterman <waterman@s143.Millennium.Berkeley.EDU>
Sun, 25 Apr 2010 06:01:50 +0000 (23:01 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:44 +0000 (17:35 -0700)
1) Routine kernel messages no longer crash if currently in the kernel.

2) More sane handling of stack-fucking.

3) Performance enhancements when taking interrupts in the kernel.

4) Userspace vcore stuff fixed.  This is a combination of allocating
   space near the top of the stack, and also an artifact of #2.

kern/arch/sparc/arch.h
kern/arch/sparc/atomic.h
kern/arch/sparc/cpuinfo.c
kern/arch/sparc/entry.S
kern/arch/sparc/sparc.h
kern/arch/sparc/spillfill.S
kern/arch/sparc/trap.c
kern/arch/sparc/trap_entry.S
kern/arch/sparc/trap_table.h
tests/vvadd.c [new file with mode: 0644]
user/include/sparc/arch.h

index 6a124b3..c68634b 100644 (file)
@@ -156,7 +156,7 @@ clflush(uintptr_t* addr)
 static __inline int
 irq_is_enabled(void)
 {
 static __inline int
 irq_is_enabled(void)
 {
-       return (read_psr() & 0xF00) == 0;
+       return (read_psr() & PSR_PIL) == 0;
 }
 
 static __inline uint32_t
 }
 
 static __inline uint32_t
index bd0e8fc..f2d060d 100644 (file)
@@ -129,7 +129,7 @@ static inline void spin_lock(spinlock_t*SAFE lock)
 static inline void spin_unlock(spinlock_t*SAFE lock)
 {
        wmb();
 static inline void spin_unlock(spinlock_t*SAFE lock)
 {
        wmb();
-       __asm__ __volatile__ ("stub %%g0,[%0+3]" : : "r"(&lock->rlock) : "memory");
+       lock->rlock = 0;
 }
 
 static inline void spinlock_init(spinlock_t* lock)
 }
 
 static inline void spinlock_init(spinlock_t* lock)
index a1a9198..59684db 100644 (file)
@@ -40,10 +40,9 @@ print_cpuinfo(void)
 
        cprintf("CPU Info:\n");
        cprintf("ISA:             SPARC V8\n");
 
        cprintf("CPU Info:\n");
        cprintf("ISA:             SPARC V8\n");
-       cprintf("Number of cores: %d\n",num_cores());
+       cprintf("Number of cores: %d\n",num_cpus);
        cprintf("Implementation:  0x%x\n",(psr >> 28) & 0xF);
        cprintf("Version:         0x%x\n",(psr >> 24) & 0xF);
        cprintf("Implementation:  0x%x\n",(psr >> 28) & 0xF);
        cprintf("Version:         0x%x\n",(psr >> 24) & 0xF);
-       cprintf("Number of Cores: %d\n",num_cpus);
        cprintf("Current PSR:     0x%08x\n",psr);
        cprintf("Current WIM:     0x%08x\n",wim);
        cprintf("Current TBR:     0x%08x\n",tbr);
        cprintf("Current PSR:     0x%08x\n",psr);
        cprintf("Current WIM:     0x%08x\n",wim);
        cprintf("Current TBR:     0x%08x\n",tbr);
index 14d1c9c..371214f 100644 (file)
@@ -58,6 +58,13 @@ _start:
        st      %g3,[%g1]
        flush   %g1
 
        st      %g3,[%g1]
        flush   %g1
 
+       // and patch the trap entry point.
+       set     RELOC(trap_patchme),%g1
+       ld      [%g1],%g3
+       or      %g2,%g3,%g3
+       st      %g3,[%g1]
+       flush   %g1
+
        // store NWINDOWS away for safekeeping
        set     RELOC(NWINDOWS),%g1
        inc     %g2
        // store NWINDOWS away for safekeeping
        set     RELOC(NWINDOWS),%g1
        inc     %g2
index 95b5602..189e197 100644 (file)
@@ -29,14 +29,12 @@ static __inline uint32_t read_psr(void) __attribute__((always_inline));
 static __inline uint32_t read_wim(void) __attribute__((always_inline));
 static __inline uint32_t read_tbr(void) __attribute__((always_inline));
 static __inline uint32_t read_mmu_reg(uint32_t which) __attribute__((always_inline));
 static __inline uint32_t read_wim(void) __attribute__((always_inline));
 static __inline uint32_t read_tbr(void) __attribute__((always_inline));
 static __inline uint32_t read_mmu_reg(uint32_t which) __attribute__((always_inline));
-static __inline uint32_t read_y(void) __attribute__((always_inline));
 static __inline uint32_t read_fsr(void) __attribute__((always_inline));
 static __inline uint64_t read_perfctr(uint32_t core, uint32_t which) __attribute__((always_inline));
 static __inline void write_psr(uint32_t val) __attribute__((always_inline));
 static __inline void write_wim(uint32_t val) __attribute__((always_inline));
 static __inline void write_tbr(uint32_t val) __attribute__((always_inline));
 static __inline void write_mmu_reg(uint32_t which, uint32_t val) __attribute__((always_inline));
 static __inline uint32_t read_fsr(void) __attribute__((always_inline));
 static __inline uint64_t read_perfctr(uint32_t core, uint32_t which) __attribute__((always_inline));
 static __inline void write_psr(uint32_t val) __attribute__((always_inline));
 static __inline void write_wim(uint32_t val) __attribute__((always_inline));
 static __inline void write_tbr(uint32_t val) __attribute__((always_inline));
 static __inline void write_mmu_reg(uint32_t which, uint32_t val) __attribute__((always_inline));
-static __inline void write_y(uint32_t val) __attribute__((always_inline));
 static __inline void write_fsr(uint32_t val) __attribute__((always_inline));
 static __inline uint32_t memsize_mb(void) __attribute__((always_inline));
 static __inline uint32_t mmu_probe(uint32_t va) __attribute__((always_inline));
 static __inline void write_fsr(uint32_t val) __attribute__((always_inline));
 static __inline uint32_t memsize_mb(void) __attribute__((always_inline));
 static __inline uint32_t mmu_probe(uint32_t va) __attribute__((always_inline));
@@ -51,7 +49,7 @@ static __inline uint32_t
 read_psr(void)
 {
        uint32_t reg;
 read_psr(void)
 {
        uint32_t reg;
-       asm volatile ("mov %%psr,%0" : "=r"(reg));
+       asm volatile ("mov %%psr,%0" : "=r"(reg) : : "memory");
        return reg;
 }
 
        return reg;
 }
 
@@ -59,7 +57,7 @@ static __inline uint32_t
 read_wim(void)
 {
        uint32_t reg;
 read_wim(void)
 {
        uint32_t reg;
-       asm volatile ("mov %%wim,%0" : "=r"(reg));
+       asm volatile ("mov %%wim,%0" : "=r"(reg) : : "memory");
        return reg;
 }
 
        return reg;
 }
 
@@ -67,7 +65,7 @@ static __inline uint32_t
 read_tbr(void)
 {
        uint32_t reg;
 read_tbr(void)
 {
        uint32_t reg;
-       asm volatile ("mov %%tbr,%0" : "=r"(reg));
+       asm volatile ("mov %%tbr,%0" : "=r"(reg) : : "memory");
        return reg;
 }
 
        return reg;
 }
 
@@ -78,18 +76,10 @@ read_mmu_reg(uint32_t which)
 }
 
 static __inline uint32_t
 }
 
 static __inline uint32_t
-read_y(void)
-{
-       uint32_t reg;
-       asm volatile ("mov %%y,%0" : "=r"(reg));
-       return reg;
-}
-
-static __inline uint32_t
 read_fsr(void)
 {
        uint32_t reg;
 read_fsr(void)
 {
        uint32_t reg;
-       asm volatile ("st %%fsr,%0" : "=m"(reg));
+       asm volatile ("st %%fsr,%0" : "=m"(reg) : : "memory");
        return reg;
 }
 
        return reg;
 }
 
@@ -118,12 +108,6 @@ write_mmu_reg(uint32_t which, uint32_t val)
 }
 
 static __inline void
 }
 
 static __inline void
-write_y(uint32_t val)
-{
-       asm volatile ("mov %0,%%y; nop;nop;nop" : : "r"(val) : "memory");
-}
-
-static __inline void
 write_fsr(uint32_t val)
 {
        asm volatile ("ld %0,%%fsr; nop;nop;nop" : : "m"(val) : "memory");
 write_fsr(uint32_t val)
 {
        asm volatile ("ld %0,%%fsr; nop;nop;nop" : : "m"(val) : "memory");
index e5cf4e7..3196975 100644 (file)
@@ -2,92 +2,22 @@
 #include <arch/sparc.h>
 #include <arch/trap.h>
 #include <ros/memlayout.h>
 #include <arch/sparc.h>
 #include <arch/trap.h>
 #include <ros/memlayout.h>
+#include <arch/trap_table.h>
 
 
-// before spilling a window, we must be certain
-// that %sp is 8-byte aligned and the range [%sp,%sp+64)
-// is validly mapped in
-#define VALIDATE_STACK(reg1,reg2,misaligned,pagefault) \
-       mov     %psr,reg1               ;\
-       btst    7,%sp                   ;\
-       bne     misaligned              ;\
-        mov    reg1,%psr               ;\
-       andn    %sp,0xFFF,reg1          ;\
-       or      reg1,0x400,reg1         ;\
-       lda     [reg1] 3,reg2           ;\
-       add     %sp,56,reg1             ;\
-       andn    reg1,0xFFF,reg1         ;\
-       or      reg1,0x400,reg1         ;\
-       lda     [reg1] 3,reg1           ;\
-       and     reg2,reg1,reg2          ;\
-       mov     %psr,reg1               ;\
-       btst    PTE_PTE,reg2            ;\
-       be      pagefault               ;\
-        mov    reg1,%psr
-
-#define RETHROW_TRAP(func)             \
-       mov     %psr,%l7                ;\
-       and     %l7,PSR_CWP,%l4         ;\
-       set     NWINDOWS,%l3            ;\
-       ld      [%l3],%l3               ;\
-       dec     %l3                     ;\
-       cmp     %l3,%l4                 ;\
-       inc     %l4                     ;\
-       be,a    7f                      ;\
-        mov    0,%l4                   ;\
-7:     mov     1,%l3                   ;\
-       sll     %l3,%l4,%l4             ;\
-       mov     %g0,%wim                ;\
-       set     bootstacktop-64-SIZEOF_TRAPFRAME_T,%sp  ;\
-       mov     CORE_ID_REG,%l5         ;\
-       sll     %l5,KSTKSHIFT,%l5       ;\
-       sub     %sp,%l5,%sp             ;\
-       btst    PSR_PS,%l7              ;\
-       bne,a   8f                      ;\
-        sub    %fp,64+SIZEOF_TRAPFRAME_T,%sp ;\
-8:     mov     %l7,%psr                ;\
-       mov     %l1,%o1                 ;\
-       mov     %l2,%o2                 ;\
-       call    env_save_tf             ;\
-        add    %sp,64,%o0              ;\
-       mov     %l4,%wim                ;\
-       mov     %psr,%o0                ;\
-       wr      %o0,PSR_ET,%psr         ;\
-       call    func                    ;\
-        add    %sp,64,%o0
-
-       .global handle_window_overflow
-handle_window_overflow:
-       sethi   %hi(spill),%l7
-       jmpl    %l7+%lo(spill),%l7
-        nop
-       jmp     %l1
-       rett    %l2
-
-/*     .global handle_window_underflow
-handle_window_underflow:
-       sethi   %hi(fill),%l7
-       jmpl    %l7+%lo(fill),%l7
-        nop
-       jmp     %l1
-       rett    %l2*/
-
-! after handling a window trap, spill will return to window_rett+8,
-! so these two nops are necessary!
-       .global window_rett
-window_rett:
-       nop
-       nop
-       jmp     %l1
-       rett    %l2
+#define MAKE_STACK \
+       set     bootstacktop - SIZEOF_TRAPFRAME_T - 64,%fp; \
+       mov     CORE_ID_REG,%l0; \
+       sll     %l0,KSTKSHIFT,%l0; \
+       sub     %fp,%l0,%fp
 
 ! preconditions:
 ! WIM & (1<<CWP) != 0
 ! link address in %l7
 ! postconditions:
 ! CWP same, but is now valid
 
 ! preconditions:
 ! WIM & (1<<CWP) != 0
 ! link address in %l7
 ! postconditions:
 ! CWP same, but is now valid
-! %l0, %l1, %l2, %l5, %l6 have not changed 
-.global spill
-spill:
+! %l0, %l1, %l2, %l5, %l6, %l7 have not changed 
+.global handle_window_overflow
+handle_window_overflow:
        mov     %g1,%l4
        mov     %wim,%l3
        mov     %g0,%wim
        mov     %g1,%l4
        mov     %wim,%l3
        mov     %g0,%wim
@@ -100,11 +30,15 @@ spill_patchme:
 
        srl     %l3,1,%l3
        or      %g1,%l3,%g1
 
        srl     %l3,1,%l3
        or      %g1,%l3,%g1
-       mov     %g2,%l3
+       mov     %psr,%l3
 
        save
        mov     %g1,%wim
 
        save
        mov     %g1,%wim
-       VALIDATE_STACK(%g1,%g2,1f,2f)
+       btst    7,%sp
+       bne     2f
+        lda    [%g0] 4,%g1             ! do the fill in no-fault mode
+       or      %g1,2,%g1               ! NF = 1
+       sta     %g1,[%g0] 4
        std     %l0,[%sp+ 0]
        std     %l2,[%sp+ 8]
        std     %l4,[%sp+16]
        std     %l0,[%sp+ 0]
        std     %l2,[%sp+ 8]
        std     %l4,[%sp+16]
@@ -115,15 +49,30 @@ spill_patchme:
        std     %i6,[%sp+56]
        restore
 
        std     %i6,[%sp+56]
        restore
 
-       mov     %l3,%g2
-       jmp     %l7+8
-       mov     %l4,%g1
+       xor     %g1,2,%g1
+       sta     %g1,[%g0] 4             ! NF = 0
+       mov     0x300,%g1
+       lda     [%g1] 4,%g1
+       btst    0x1C,%g1                ! FT != 0 ?
+       bne     1f
+        mov    %l4,%g1
+
+       // success!
+       mov     %l3,%psr
+       jmp     %l1
+        rett   %l2
 
 
-// spill failed!
-1:     restore
-       RETHROW_TRAP(stack_misaligned)
-2:     restore
-       RETHROW_TRAP(stack_pagefault)
+1:     // page fault
+       mov     %l3,%psr
+       MAKE_STACK
+       TRAP_TABLE_ENTRY(spill_pagefault)
+
+2:     // spill misaligned
+       restore
+       mov     %l3,%psr
+       mov     %l4,%g1
+       MAKE_STACK
+       TRAP_TABLE_ENTRY(spill_misaligned)
 
 .global handle_window_underflow
 handle_window_underflow:
 
 .global handle_window_underflow
 handle_window_underflow:
@@ -174,9 +123,8 @@ fill_patchme:
 1:     // page fault
        mov     %l3,%wim
        mov     %l5,%psr
 1:     // page fault
        mov     %l3,%wim
        mov     %l5,%psr
-       set     trap_table_pagefault,%l6
-       jmp     %l6
-        nop
+       MAKE_STACK
+       TRAP_TABLE_ENTRY(fill_pagefault)
 
 2:     // fill misaligned
        save
 
 2:     // fill misaligned
        save
@@ -184,6 +132,5 @@ fill_patchme:
        mov     %l4,%g1
        mov     %l3,%wim
        mov     %l5,%psr
        mov     %l4,%g1
        mov     %l3,%wim
        mov     %l5,%psr
-       set     trap_table_misaligned,%l6
-       jmp     %l6
-        nop
+       MAKE_STACK
+       TRAP_TABLE_ENTRY(fill_misaligned)
index cc57f43..8a15305 100644 (file)
@@ -252,6 +252,9 @@ unhandled_trap(trapframe_t* state)
        uint32_t trap_type = (state->tbr >> 4) & 0xFF;
        get_trapname(trap_type,buf);
 
        uint32_t trap_type = (state->tbr >> 4) & 0xFF;
        get_trapname(trap_type,buf);
 
+       static spinlock_t screwup_lock = SPINLOCK_INITIALIZER;
+       spin_lock(&screwup_lock);
+
        if(in_kernel(state))
        {
                print_trapframe(state);
        if(in_kernel(state))
        {
                print_trapframe(state);
@@ -262,6 +265,7 @@ unhandled_trap(trapframe_t* state)
                warn("Unhandled trap in user!\nTrap type: %s",buf);
                print_trapframe(state);
                backtrace();
                warn("Unhandled trap in user!\nTrap type: %s",buf);
                print_trapframe(state);
                backtrace();
+               spin_unlock(&screwup_lock);
 
                assert(current);
                proc_incref(current, 1);
 
                assert(current);
                proc_incref(current, 1);
@@ -271,49 +275,43 @@ unhandled_trap(trapframe_t* state)
        }
 }
 
        }
 }
 
-static void
+static trapframe_t*
 stack_fucked(trapframe_t* state)
 {
 stack_fucked(trapframe_t* state)
 {
-       // see if the problem arose when flushing out
-       // windows during handle_trap
-       extern uint32_t tflush;
-       if(state->pc == (uint32_t)&tflush)
-       {
-               // the trap happened while flushing out windows.
-               // hope this happened in the user, or else we're hosed...
-               state = (trapframe_t*)(bootstacktop-SIZEOF_TRAPFRAME_T-core_id()*KSTKSIZE);
-       }
-
        warn("You just got stack fucked!");
        warn("You just got stack fucked!");
-       unhandled_trap(state);
+       extern char tflush1, tflush2;
+       if(state->pc == (uint32_t)&tflush1 || state->pc == (uint32_t)&tflush2)
+               return (trapframe_t*)(bootstacktop - core_id()*KSTKSIZE
+                                                  - sizeof(trapframe_t));
+       return state;
 }
 
 void
 fill_misaligned(trapframe_t* state)
 {
 }
 
 void
 fill_misaligned(trapframe_t* state)
 {
+       state = stack_fucked(state);
        state->tbr = (state->tbr & ~0xFFF) | 0x070;
        state->tbr = (state->tbr & ~0xFFF) | 0x070;
-       stack_fucked(state);
+       address_unaligned(state);
 }
 
 void
 fill_pagefault(trapframe_t* state)
 {
 }
 
 void
 fill_pagefault(trapframe_t* state)
 {
+       state = stack_fucked(state);
        state->tbr = (state->tbr & ~0xFFF) | 0x090;
        state->tbr = (state->tbr & ~0xFFF) | 0x090;
-       stack_fucked(state);
+       data_access_exception(state);
 }
 
 void
 }
 
 void
-stack_misaligned(trapframe_t* state)
+spill_misaligned(trapframe_t* state)
 {
 {
-       state->tbr = (state->tbr & ~0xFFF) | 0x070;
-       stack_fucked(state);
+       fill_misaligned(state);
 }
 
 void
 }
 
 void
-stack_pagefault(trapframe_t* state)
+spill_pagefault(trapframe_t* state)
 {
 {
-       state->tbr = (state->tbr & ~0xFFF) | 0x090;
-       stack_fucked(state);
+       fill_pagefault(state);
 }
 
 void
 }
 
 void
@@ -403,6 +401,7 @@ handle_syscall(trapframe_t* state)
        uint32_t a5 = state->gpr[12];
 
        advance_pc(state);
        uint32_t a5 = state->gpr[12];
 
        advance_pc(state);
+       enable_irq();
 
        /* Note we are not preemptively saving the TF in the env_tf.  We do maintain
         * a reference to it in current_tf (a per-cpu pointer).
 
        /* Note we are not preemptively saving the TF in the env_tf.  We do maintain
         * a reference to it in current_tf (a per-cpu pointer).
index 5c23ae4..836a9c7 100644 (file)
@@ -7,75 +7,88 @@
        .section        ".text"!,#alloc,#execinstr,#progbits
        .align          4
 
        .section        ".text"!,#alloc,#execinstr,#progbits
        .align          4
 
-       .global tflush
+       .global tflush1
+       .global tflush2
+       .global trap_patchme
 
        .global handle_trap
 handle_trap:
 
 
        .global handle_trap
 handle_trap:
 
-       // At this point, %l1 = pc, %l2 = npc, and %l0/3/4/5
-       // might contain an active message.  so we only get %l6/%l7
-
-       // calculate stack pointer (-64 is space for window spill).
-       // sp = bootstacktop - core_id*KSTKSIZE - 64 - sizeof(trapframe_t).
-       // should you change this, make sure to change stack_fucked()
-       set     bootstacktop-64-SIZEOF_TRAPFRAME_T,%l6
-       mov     CORE_ID_REG,%l7
-       sll     %l7,KSTKSHIFT,%l7
-       sub     %l6,%l7,%l6
-
-       // see if trap came from kernel; if so, use that stack
-       // also preserve the psr, since we'll screw with the condition codes
-       mov     %psr,%l0
-       btst    PSR_PS,%l0
-       bne,a   1f
-        sub    %fp,64+SIZEOF_TRAPFRAME_T,%l6
-
-       // here is where we might do something with an active message
-
-       // At this point we may use %l3/4/5/7 as temporary regs
-1:
-       // is CWP valid?
-       and     %l0,PSR_CWP,%l4 ! %l4 = cwp
-       mov     1,%l7
-       sll     %l7,%l4,%l4     ! %l4 = 1 << cwp
-       mov     %wim,%l3
-       btst    %l3,%l4         ! (%wim & %l4) == 0?
-       be      2f
-        sethi  %hi(spill),%l7
-       jmpl    %lo(spill)+%l7,%l7      !no, spill a window
-        nop
-
-       // At this point we may use %o0-7, %l3/4/5/7 as temporary regs
-       // save the whole user context to a trapframe_t
+       // First, make sure we have a valid register window.
+       // The restore won't trap, but the save might.
+       // The spill handler won't overwrite l0/l5/l6, so stash l1 (pc) and l2 (npc)
+       // in there, since the hardware will overwrite them if save traps
+       mov     %psr,%l7
+       wr      %l7,PSR_PIL,%psr
+       wr      %l7,PSR_PIL|PSR_ET,%psr
+
+       // Are we user or kernel?
+       btst    PSR_PS,%l7
+       mov     %l2,%l6
+       be      1f
+        mov    %l1,%l5
+
+       // Trap came from kernel.  Spill a window if necessary.
+       restore
+       save
 
 
-2:
-       mov     %l6,%sp
-       mov     %l1,%o1
-       mov     %l2,%o2
-       mov     %l0,%psr                        ! restore condition codes before saving trapframe
+       // Save TF then call handler
+       sub     %fp,64+SIZEOF_TRAPFRAME_T,%sp
        call    env_save_tf
         add    %sp,64,%o0
        call    env_save_tf
         add    %sp,64,%o0
+       call    %l0
+        add    %sp,64,%o0
+
+#define FINISH_POP_TF(tf) \
+       ld      [tf+132],%l1 ;\
+       ld      [tf+136],%l2 ;\
+       ld      [tf+148],%l5 ;\
+       mov     %l5,%y ;\
+       jmp     %l1 ;\
+       rett    %l2
+
+       // Get outta here! Fill a window if necessary.
+       restore
+       save
+       mov     %l7,%psr
+       add     %sp,64,%o0
+       FINISH_POP_TF(%o0)
+
+       // Trap came from user.  Spill a window if necessary.
+1:     restore
+tflush1:
+       save
 
 
-       // enable traps (but not interrupts)
-       or      %l0,PSR_PIL,%g3
-       wr      %g3,0,%psr
-       wr      %g3,PSR_ET,%psr
+       mov     CORE_ID_REG,%l1
+       sll     %l1,KSTKSHIFT,%l1
+       set     bootstacktop-64-SIZEOF_TRAPFRAME_T,%sp
+       sub     %sp,%l1,%sp
+
+       call    env_save_tf
+        add    %sp,64,%o0
 
        // spill all trapper's windows out to the stack.
        // the 'save' may trap (triggering the spill),
        // and if the stack is corrupted, the process may die
 
        // spill all trapper's windows out to the stack.
        // the 'save' may trap (triggering the spill),
        // and if the stack is corrupted, the process may die
+       mov     %l7,%g3
        mov     %sp,%g4
        mov     %sp,%g4
-       set     NWINDOWS,%g1
-       ld      [%g1],%g1
-       sub     %g1,1,%g2
+       mov %l0,%g5
+trap_patchme:
+       mov     0,%g2                                           // 0 will become NWINDOWS-1
 5:     deccc   %g2
        bne,a   5b
 5:     deccc   %g2
        bne,a   5b
-tflush:         save   %sp,0,%sp
-       mov     %g4,%sp 
-       wr      %g3,PSR_ET,%psr
+tflush2:
+        save
+
+       mov     %g0,%wim
+       andn    %g3,PSR_CWP,%g3
+       wr      %g3,PSR_PIL|PSR_ET,%psr
+       nop; nop; nop
+       mov     1<<1,%wim
+       mov     %g4,%sp
 
 
-       // call the handler and pass in the tf and handler address
-       call    %l5
+       // Call the handler
+       call    %g5
         add    %sp,64,%o0
 
        // fallthrough to env_pop_tf, which is right below this function
         add    %sp,64,%o0
 
        // fallthrough to env_pop_tf, which is right below this function
@@ -119,24 +132,22 @@ env_pop_tf:
        ldd     [%o0+16],%g4
        ldd     [%o0+24],%g6
 
        ldd     [%o0+16],%g4
        ldd     [%o0+24],%g6
 
-       ld      [%o0+132],%l1
-       ld      [%o0+136],%l2
-       ld      [%o0+148],%l5
-       mov     %l5,%y
        ld      [%o0+152],%l5
        mov     %l5,%asr13
        ld      [%o0+152],%l5
        mov     %l5,%asr13
+       FINISH_POP_TF(%o0)
 
 
-       jmp     %l1
-       rett    %l2
-
-// void env_save_tf(trapframe_t* tf, uint32_t trap_pc, uint32_t trap_npc)
+       // env_save_tf has a non-standard calling convention.
+       // o0: destination trapframe_t*
+       // l5: PC
+       // l6: nPC
+       // l7: PSR
        .global env_save_tf
 env_save_tf:
 
        mov     %psr,%o4
        .global env_save_tf
 env_save_tf:
 
        mov     %psr,%o4
-       st      %o4,[%o0+128]
-       st      %o1,[%o0+132]
-       st      %o2,[%o0+136]
+       st      %l7,[%o0+128]
+       st      %l5,[%o0+132]
+       st      %l6,[%o0+136]
        mov     %wim,%o4
        st      %o4,[%o0+140]
        mov     %tbr,%o4
        mov     %wim,%o4
        st      %o4,[%o0+140]
        mov     %tbr,%o4
@@ -156,7 +167,7 @@ env_save_tf:
        std     %o4,[%o0+168]
 
        # try to read out the faulting insn (in no-fault mode)
        std     %o4,[%o0+168]
 
        # try to read out the faulting insn (in no-fault mode)
-       andn    %o1,3,%o1
+       andn    %l5,3,%o1
        lda     [%g0] 4,%o2
        or      %o2,2,%o3
        sta     %o3,[%g0] 4
        lda     [%g0] 4,%o2
        or      %o2,2,%o3
        sta     %o3,[%g0] 4
index 0c5b176..2551d49 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ROS_ARCH_TRAP_TABLE_H
 #define ROS_ARCH_TRAP_TABLE_H
 
 #ifndef ROS_ARCH_TRAP_TABLE_H
 #define ROS_ARCH_TRAP_TABLE_H
 
-#define TRAP_TABLE_ENTRY(label) sethi %hi(handle_trap),%l6; sethi %hi(label),%l5; jmp %lo(handle_trap)+%l6; or %lo(label),%l5,%l5
+#define TRAP_TABLE_ENTRY(label) sethi %hi(handle_trap),%l6; sethi %hi(label),%l0; jmp %lo(handle_trap)+%l6; or %lo(label),%l0,%l0
 #define JMP(target) sethi %hi(target),%l4; jmp %lo(target)+%l4; nop; nop
 
 #define ENTER_ERROR_MODE unimp; unimp; unimp; unimp
 #define JMP(target) sethi %hi(target),%l4; jmp %lo(target)+%l4; nop; nop
 
 #define ENTER_ERROR_MODE unimp; unimp; unimp; unimp
diff --git a/tests/vvadd.c b/tests/vvadd.c
new file mode 100644 (file)
index 0000000..579c9be
--- /dev/null
@@ -0,0 +1,26 @@
+#include <assert.h>
+#include <stdio.h>
+
+int main()
+{
+       #define N 12345
+       double x[N];
+       double y[N];
+       double z[N];
+
+       for(int i = 0; i < N; i++)
+       {
+               x[i] = (double)i;
+               y[i] = (double)(2*i);
+       }
+
+       for(int i = 0; i < N; i++)
+               z[i] = x[i]+y[i];
+
+       for(int i = 0; i < N; i++)
+               assert((int)z[i] == 3*i);
+
+       printf("vvadd works!\n");
+
+       return 0;
+}
index cdf5203..0142ded 100644 (file)
@@ -16,6 +16,7 @@ double do_rsqrt(double);
 static __inline void
 set_stack_pointer(void* sp)
 {
 static __inline void
 set_stack_pointer(void* sp)
 {
+       sp = (char*)sp - 96;
        __asm__ __volatile__ ("mov %0,%%sp" : : "r"(sp));
 }
 
        __asm__ __volatile__ ("mov %0,%%sp" : : "r"(sp));
 }