fixed sparc atomics; added sparc newlib
authorAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Tue, 4 Aug 2009 02:52:31 +0000 (19:52 -0700)
committerAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Tue, 4 Aug 2009 03:30:26 +0000 (20:30 -0700)
added sparc udelay (prototype now in kern/include/timing.h)

18 files changed:
kern/arch/i386/apic.h
kern/arch/sparc/atomic.h
kern/arch/sparc/console.c
kern/arch/sparc/pmap.c
kern/arch/sparc/timer.c
kern/arch/sparc/trap.c
kern/include/timing.h [new file with mode: 0644]
kern/src/testing.c
user/apps/parlib/Makefrag
user/parlib/newlib/lib/i386/libc.a [new file with mode: 0644]
user/parlib/newlib/lib/i386/libg.a [new file with mode: 0644]
user/parlib/newlib/lib/i386/libm.a [new file with mode: 0644]
user/parlib/newlib/lib/libc.a [deleted file]
user/parlib/newlib/lib/libg.a [deleted file]
user/parlib/newlib/lib/libm.a [deleted file]
user/parlib/newlib/lib/sparc/libc.a [new file with mode: 0644]
user/parlib/newlib/lib/sparc/libg.a [new file with mode: 0644]
user/parlib/newlib/lib/sparc/libm.a [new file with mode: 0644]

index 2a5863f..2d84236 100644 (file)
@@ -100,7 +100,6 @@ uint32_t lapic_get_default_id(void);
 // PIT related
 void pit_set_timer(uint32_t freq, uint32_t mode);
 void timer_init(void);
-void udelay(uint64_t usec);
 void udelay_pit(uint64_t usec);
 // TODO: right now timer defaults to TSC
 uint64_t gettimer(void);
index 33ed9cd..fb8275c 100644 (file)
@@ -9,69 +9,76 @@
 
 typedef volatile uint32_t spinlock_t;
 
-//linux style atomic ops
-typedef struct {volatile int32_t real_num;} atomic_t;
-#define atomic_read(atom) ((atom)->real_num >> 8)
-#define atomic_init(i) {(i) << 8}
-//and the atomic incs, etc take an atomic_t ptr, deref inside
-
-static inline void atomic_set(atomic_t*SAFE number, int32_t val);
-static inline void atomic_add(atomic_t*SAFE number, int32_t inc);
-static inline void atomic_inc(atomic_t*SAFE number);
-static inline void atomic_dec(atomic_t*SAFE number);
+// atomic_t is void*, so we can't accidentally dereference it
+typedef void* atomic_t;
+
+static inline void atomic_init(atomic_t* number, int32_t val);
+static inline int32_t atomic_read(atomic_t* number);
+static inline void atomic_set(atomic_t* number, int32_t val);
+static inline void atomic_add(atomic_t* number, int32_t inc);
+static inline void atomic_inc(atomic_t* number);
+static inline void atomic_dec(atomic_t* number);
 static inline uint32_t spin_trylock(spinlock_t*SAFE lock);
 static inline void spin_lock(spinlock_t*SAFE lock);
 static inline void spin_unlock(spinlock_t*SAFE lock);
 
 /* Inlined functions declared above */
 
-static inline void atomic_add(atomic_t*SAFE number, int32_t inc)
+static inline void atomic_init(atomic_t* number, int32_t val)
+{
+       val <<= 8;
+       asm volatile ("st %0,[%1]" : : "r"(val), "r"(number) : "memory");
+}
+
+static inline int32_t atomic_read(atomic_t* number)
+{
+       int32_t val;
+       asm volatile ("ld [%1],%0" : "=r"(val) : "r"(number));
+       return val >> 8;
+}
+
+static inline void atomic_add(atomic_t* number, int32_t inc)
 {
        // this is pretty clever.  the lower 8 bits (i.e byte 3)
        // of the atomic_t serve as a spinlock.  let's acquire it.
-       spin_lock((spinlock_t*SAFE)number);
+       { TRUSTEDBLOCK spin_lock((spinlock_t*)number); }
 
        // compute new counter value.
-       // must shift the old counter right by 8
-       inc += number->real_num >> 8;
+       inc += atomic_read(number);
 
-       // set the new counter value.
-       // since the lower 8 bits will be cleared by the shift,
-       // we also release the lock (for free!)
-       number->real_num = inc << 8;
+       // set the new counter value.  the lock is cleared (for free)
+       atomic_init(number,inc);
 }
 
-static inline void atomic_set(atomic_t*SAFE number, uint32_t val)
+static inline void atomic_set(atomic_t* number, uint32_t val)
 {
-       // this works basically the same as atomic_add
+       // this works basically the same as atomic_add... but without the add
        spin_lock((spinlock_t*)number);
-       number->real_num = val << 8;
+       atomic_init(number,val);
 }
 
-static inline void atomic_inc(atomic_t*SAFE number)
+static inline void atomic_inc(atomic_t* number)
 {
        atomic_add(number,1);
 }
 
-static inline void atomic_dec(atomic_t*SAFE number)
+static inline void atomic_dec(atomic_t* number)
 {
        atomic_add(number,-1);
 }
 
 static inline uint32_t spin_trylock(spinlock_t*SAFE lock)
 {
-       // we don't need to initialize reg, but it quiets the compiler
        uint32_t reg;
-       asm volatile("ldstub [%1+3],%0"
-                    : "=r"(reg)
-                    : "r"(lock)
-                    : "memory");
+       asm volatile("ldstub [%1+3],%0" : "=r"(reg) : "r"(lock) : "memory");
        return reg;
 }
 
-static inline uint8_t spin_locked(spinlock_t*SAFE lock)
+static inline uint32_t spin_locked(spinlock_t*SAFE lock)
 {
-       return *((volatile uint8_t*COUNT(sizeof(spinlock_t)))lock+3);
+       uint32_t reg;
+       asm volatile("ldub [%1+3],%0" : "=r"(reg) : "r"(lock));
+       return reg;
 }
 
 static inline void spin_lock(spinlock_t*SAFE lock)
@@ -83,7 +90,7 @@ static inline void spin_lock(spinlock_t*SAFE lock)
 static inline void spin_unlock(spinlock_t*SAFE lock)
 {
        wmb();
-       *((volatile uint8_t*COUNT(sizeof(spinlock_t)))lock+3) = 0;
+       asm volatile("stub %%g0,[%0+3]" : : "r"(lock) : "memory");
 }
 
 #endif /* !ROS_INCLUDE_ATOMIC_H */
index 37c1ff7..4b0c2af 100644 (file)
@@ -10,7 +10,7 @@ cons_init(void)
 void
 cputbuf(const char*COUNT(len) buf, int len)
 {
-       frontend_syscall(RAMP_SYSCALL_write,1,buf,len);
+       frontend_syscall(RAMP_SYSCALL_write,1,(uint32_t)buf,len);
 }
 
 // Low-level console I/O
index a5d5dbb..a4c1171 100644 (file)
@@ -8,6 +8,7 @@
 #include <pmap.h>
 #include <string.h>
 
+physaddr_t boot_cr3;
 pde_t* boot_pgdir;
 char* boot_freemem;
 page_t* pages;
@@ -21,6 +22,7 @@ vm_init(void)
 
        extern pde_t l1_page_table[NL1ENTRIES];
        boot_pgdir = l1_page_table;
+       boot_cr3 = PADDR(boot_pgdir);
 
        size_t page_array_size = ROUNDUP(npage*sizeof(page_t),PGSIZE);
        pages = (page_t*)boot_alloc(page_array_size,PGSIZE);
index 12c44bd..15a02a9 100644 (file)
@@ -3,6 +3,7 @@
 #include <arch/trap.h>
 #include <arch/arch.h>
 #include <stdio.h>
+#include <assert.h>
 
 system_timing_t system_timing = {0};
 volatile uint32_t timer_ticks = 0;
@@ -39,3 +40,22 @@ timer_init(void)
 
        cprintf("TSC Frequency: %llu\n", system_timing.tsc_freq);
 }
+
+void
+udelay(uint64_t usec)
+{
+       if (system_timing.tsc_freq != 0)
+       {
+               uint64_t start, end, now;
+        
+               start = read_tsc();
+               end = start + (system_timing.tsc_freq * usec) / 1000000;
+
+               do
+               {
+                       cpu_relax();
+                       now = read_tsc();
+               } while (now < end || (now > start && end < start));
+       }
+       else panic("udelay() was called before timer_init(), moron!");
+}
index ee058eb..80dcc44 100644 (file)
@@ -2,7 +2,7 @@
 #include <assert.h>
 #include <arch/trap.h>
 #include <string.h>
-#include <env.h>
+#include <process.h>
 #include <syscall.h>
 #include <monitor.h>
 #include <manager.h>
@@ -25,9 +25,8 @@ sysenter_init(void)
 void
 trap_handled(void)
 {
-       env_t* curenv = curenvs[core_id()];
-       if(curenv)
-               env_run(curenv);
+       if(current)
+               proc_startcore(current,&current->env_tf);
        else if(core_id() == 0)
                manager();
        else
@@ -108,14 +107,11 @@ void
 trap(trapframe_t* state, active_message_t* msg,
      void (*handler)(trapframe_t*,active_message_t*))
 {
-       env_t* curenv = curenvs[core_id()];
-       //assert(curenv);
-
        // TODO: this will change with multicore processes
-       if(curenv)
+       if(current)
        {
-               curenv->env_tf = *state;
-               handler(&curenv->env_tf,msg);
+               current->env_tf = *state;
+               handler(&current->env_tf,msg);
        }
        else
                handler(state,msg);
@@ -134,7 +130,6 @@ void
 unhandled_trap(trapframe_t* state)
 {
        char buf[TRAPNAME_MAX];
-       env_t* curenv = curenvs[core_id()];
        uint32_t trap_type = (state->tbr >> 4) & 0xFF;
        get_trapname(trap_type,buf);
 
@@ -145,8 +140,8 @@ unhandled_trap(trapframe_t* state)
        else
        {
                warn("Unhandled trap in user!\nTrap type: %s",buf);
-               assert(curenv);
-               env_destroy(curenv);
+               assert(current);
+               env_destroy(current);
                panic("I shouldn't have gotten here!");
        }
 }
@@ -212,8 +207,6 @@ fp_disabled(trapframe_t* state)
 void
 handle_syscall(trapframe_t* state)
 {
-       env_t* curenv = curenvs[core_id()];
-
        uint32_t num = state->gpr[1];
        uint32_t a1 = state->gpr[8];
        uint32_t a2 = state->gpr[9];
@@ -225,9 +218,9 @@ handle_syscall(trapframe_t* state)
        state->pc = state->npc;
        state->npc += 4;
 
-       env_push_ancillary_state(curenv);
+       env_push_ancillary_state(current);
 
-       state->gpr[8] = syscall(curenv,num,a1,a2,a3,a4,a5);
+       state->gpr[8] = syscall(current,num,a1,a2,a3,a4,a5);
 
        trap_handled();
 }
@@ -266,7 +259,7 @@ handle_breakpoint(trapframe_t* state)
        state->pc = state->npc;
        state->npc += 4;
 
-       env_push_ancillary_state(state);
+       env_push_ancillary_state(current);
 
        // run the monitor
        monitor(state);
diff --git a/kern/include/timing.h b/kern/include/timing.h
new file mode 100644 (file)
index 0000000..eaa6c63
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef ROS_INC_TIMING_H
+#define ROS_INC_TIMING_H
+
+#include <arch/types.h>
+
+void udelay(uint64_t usec);
+
+#endif
index 021a06e..af9a83c 100644 (file)
@@ -16,6 +16,7 @@
 #include <trap.h>
 #include <process.h>
 #include <syscall.h>
+#include <timing.h>
 
 #define test_vector 0xeb
 
index 761f312..43e95fc 100644 (file)
@@ -9,7 +9,7 @@ USER_APPS_PARLIB_LDFLAGS   := $(USER_LDFLAGS) -static \
                               -T $(USER_APPS_PARLIB_DIR)/apps.ld
 
 USER_APPS_PARLIB_LDDIRS    := -L$(OBJDIR)/$(USER_PARLIB_DIR) \
-                              -L$(USER_PARLIB_NEWLIB_DIR)/lib
+                              -L$(USER_PARLIB_NEWLIB_DIR)/lib/$(TARGET_ARCH)
 
 USER_APPS_PARLIB_LDLIBS    := --start-group -lc -lm -lg -lparlib -livyparlib --end-group
 
diff --git a/user/parlib/newlib/lib/i386/libc.a b/user/parlib/newlib/lib/i386/libc.a
new file mode 100644 (file)
index 0000000..fdfc8ad
Binary files /dev/null and b/user/parlib/newlib/lib/i386/libc.a differ
diff --git a/user/parlib/newlib/lib/i386/libg.a b/user/parlib/newlib/lib/i386/libg.a
new file mode 100644 (file)
index 0000000..fdfc8ad
Binary files /dev/null and b/user/parlib/newlib/lib/i386/libg.a differ
diff --git a/user/parlib/newlib/lib/i386/libm.a b/user/parlib/newlib/lib/i386/libm.a
new file mode 100644 (file)
index 0000000..863d5c5
Binary files /dev/null and b/user/parlib/newlib/lib/i386/libm.a differ
diff --git a/user/parlib/newlib/lib/libc.a b/user/parlib/newlib/lib/libc.a
deleted file mode 100644 (file)
index fdfc8ad..0000000
Binary files a/user/parlib/newlib/lib/libc.a and /dev/null differ
diff --git a/user/parlib/newlib/lib/libg.a b/user/parlib/newlib/lib/libg.a
deleted file mode 100644 (file)
index fdfc8ad..0000000
Binary files a/user/parlib/newlib/lib/libg.a and /dev/null differ
diff --git a/user/parlib/newlib/lib/libm.a b/user/parlib/newlib/lib/libm.a
deleted file mode 100644 (file)
index 863d5c5..0000000
Binary files a/user/parlib/newlib/lib/libm.a and /dev/null differ
diff --git a/user/parlib/newlib/lib/sparc/libc.a b/user/parlib/newlib/lib/sparc/libc.a
new file mode 100644 (file)
index 0000000..6c54239
Binary files /dev/null and b/user/parlib/newlib/lib/sparc/libc.a differ
diff --git a/user/parlib/newlib/lib/sparc/libg.a b/user/parlib/newlib/lib/sparc/libg.a
new file mode 100644 (file)
index 0000000..6c54239
Binary files /dev/null and b/user/parlib/newlib/lib/sparc/libg.a differ
diff --git a/user/parlib/newlib/lib/sparc/libm.a b/user/parlib/newlib/lib/sparc/libm.a
new file mode 100644 (file)
index 0000000..1b9642d
Binary files /dev/null and b/user/parlib/newlib/lib/sparc/libm.a differ