Made pthreads work on SPARC
authorAndrew Waterman <waterman@ros-dev.(none)>
Mon, 19 Apr 2010 22:13:29 +0000 (15:13 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:43 +0000 (17:35 -0700)
Some nastiness with TLS and vcoreids.  Both live in
registers set up by the trapframe, so they require
special care when popping the tf.

kern/arch/sparc/ros/trapframe.h
kern/arch/sparc/trap.c
kern/arch/sparc/trap_table.S
kern/src/Makefrag
user/include/rassert.h
user/include/sparc/vcore.h

index 9caa5c9..246d5bb 100644 (file)
@@ -2,6 +2,7 @@
 #define ROS_INCLUDE_ARCH_TRAPFRAME_H
 
 #include <ros/common.h>
+#include <stdint.h>
 
 typedef struct trapframe
 {
index d6cfaa0..cc57f43 100644 (file)
@@ -385,6 +385,14 @@ handle_pop_tf(trapframe_t* state)
 }
 
 void
+handle_set_tf(trapframe_t* state)
+{
+       advance_pc(state);
+       if(memcpy_to_user(current,(void*)state->gpr[8],state,sizeof(*state)))
+               proc_destroy(current);
+}
+
+void
 handle_syscall(trapframe_t* state)
 {
        uint32_t num = state->gpr[1];
index 6797554..a3cc060 100644 (file)
@@ -145,7 +145,7 @@ trap_table_pagefault:
        UNHANDLED_TRAP                          ! 0x82
        TRAP_TABLE_ENTRY(handle_flushw)         ! 0x83
        TRAP_TABLE_ENTRY(handle_pop_tf)         ! 0x84
-       UNHANDLED_TRAP                          ! 0x85
+       TRAP_TABLE_ENTRY(handle_set_tf)         ! 0x85
        UNHANDLED_TRAP                          ! 0x86
        UNHANDLED_TRAP                          ! 0x87
        TRAP_TABLE_ENTRY(handle_syscall)        ! 0x88
index d661512..5ff229c 100644 (file)
@@ -99,7 +99,7 @@ $(OBJDIR)/$(KERN_DIR)/%.o: $(KERN_DIR)/%.S
 UDEBUG := $(findstring -g,$(USER_CFLAGS))
 $(OBJDIR)/$(KERN_DIR)/kernel: $(KERN_LDDEPENDS)
        @echo + ld [KERN] $@
-       @if [ "$(UDEBUG)" != "-g" ]; then \
+       @if [ "$(UDEBUG)" != "-g" ] && [ "$(KERN_APPFILES)" != "" ]; then \
                $(STRIP) -s $(KERN_APPFILES) ; \
        fi
        $(V)$(LD) -o $@ $(KERN_LDFLAGS) $(KERN_OBJFILES) $(KERN_LDLIBS) \
index 6e6e1e9..a774883 100644 (file)
@@ -3,6 +3,9 @@
 #ifndef ROS_INC_ASSERT_H
 #define ROS_INC_ASSERT_H
 
+#include <assert.h>
+#undef assert
+
 void _warn(const char*, int, const char*, ...);
 void _panic(const char*, int, const char*, ...) __attribute__((noreturn));
 
index 8e62675..b10ba83 100644 (file)
@@ -6,6 +6,21 @@
 #include <arch/arch.h>
 #include <ros/syscall.h>
 #include <ros/procdata.h>
+#include <assert.h>
+
+/* Feel free to ignore vcoreid.  It helps x86 to avoid a call to
+ * sys_getvcoreid() if we pass it in. */
+static inline void *get_tls_desc(uint32_t vcoreid)
+{
+       void *tmp;
+       asm volatile ("mov %%g7,%0" : "=r"(tmp));
+       return tmp;
+}
+
+static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
+{
+       asm volatile ("mov %0,%%g7" : : "r"(tls_desc) : "memory");
+}
 
 /* Pops an ROS kernel-provided TF, reanabling notifications at the same time.
  * A Userspace scheduler can call this when transitioning off the transition
@@ -23,7 +38,7 @@
 static inline void pop_ros_tf(struct user_trapframe *tf, uint32_t vcoreid)
 {
        // since we're changing the stack, move stuff into regs for now
-       register uint32_t _vcoreid = _vcoreid;
+       register uint32_t _vcoreid = vcoreid;
        register struct user_trapframe* _tf = tf;
 
        set_stack_pointer((void*)tf->gpr[14]);
@@ -32,6 +47,15 @@ static inline void pop_ros_tf(struct user_trapframe *tf, uint32_t vcoreid)
        vcoreid = _vcoreid;
        struct preempt_data* vcpd = &__procdata.vcore_preempt_data[vcoreid];
 
+       // if this is a trap frame we just init'ed, we need to set up TLS
+       if(tf->gpr[7] == 0)
+               tf->gpr[7] = (uint32_t)get_tls_desc(vcoreid);
+       else
+               assert(tf->gpr[7] == (uint32_t)get_tls_desc(vcoreid));
+
+       // don't clobber the vcore id!
+       tf->asr13 = vcoreid;
+
        vcpd->notif_enabled = true;
        if(vcpd->notif_pending)
                ros_syscall(SYS_self_notify,vcoreid,0,0,0,0);
@@ -45,7 +69,9 @@ static inline void pop_ros_tf(struct user_trapframe *tf, uint32_t vcoreid)
  * restore with pop_ros_tf(). */
 static inline void save_ros_tf(struct user_trapframe *tf)
 {
-       // TODO!!
+       // just do it in the kernel.  since we need to flush windows anyway,
+       // this isn't an egregious overhead.
+       asm volatile ("mov %0, %%o0; ta 5" : : "r"(tf) : "o0");
 }
 
 /* This assumes a user_tf looks like a regular kernel trapframe */
@@ -58,20 +84,6 @@ init_user_tf(struct user_trapframe *u_tf, uint32_t entry_pt, uint32_t stack_top)
        u_tf->npc = entry_pt + 4;
 }
 
-/* Feel free to ignore vcoreid.  It helps x86 to avoid a call to
- * sys_getvcoreid() if we pass it in. */
-static inline void *get_tls_desc(uint32_t vcoreid)
-{
-       void *tmp;
-       asm volatile ("mov %%g7,%0" : "=r"(tmp));
-       return tmp;
-}
-
-static inline void set_tls_desc(void *tls_desc, uint32_t vcoreid)
-{
-       asm volatile ("mov %0,%%g7" : : "r"(tls_desc) : "memory");
-}
-
 #define __vcore_id_on_entry (__vcore_id())
 
 static inline int