Added support for kernel-aware stack pointers to glibc
authorAndrew Waterman <waterman@s143.Millennium.Berkeley.EDU>
Sat, 13 Mar 2010 05:45:22 +0000 (21:45 -0800)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:36 +0000 (17:35 -0700)
kern/include/ros/procdata.h
kern/include/ros/sysevent.h
lib/parlib/hart.c
lib/parlib/parlib.h
tools/compilers/gcc-glibc/glibc-2.11.1-ros/sysdeps/ros/start.c

index 5c3a4de..7d072a9 100644 (file)
@@ -21,8 +21,13 @@ typedef struct procdata {
        segdesc_t *ldt;
 #endif
 
-       char stack_pointers[MAX_NUM_CPUS];
+       intptr_t stack_pointers[MAX_NUM_CPUS];
 } procdata_t;
 #define PROCDATA_NUM_PAGES  ((sizeof(procdata_t)-1)/PGSIZE + 1)
 
+// this is how user programs access the procdata page
+#ifndef ROS_KERNEL
+# define __procdata (*(procdata_t*)UDATA)
+#endif
+
 #endif // !ROS_PROCDATA_H
index a1c7dc5..6583360 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef ROS_SYSEVENT_H
 #define ROS_SYSEVENT_H
 
-#include <ros/error.h>
 #include <ros/ring_buffer.h>
 
 typedef enum {
@@ -27,7 +26,7 @@ typedef struct sysevent {
 } sysevent_t;
 
 typedef struct sysevent_rsp {
-       error_t rsp;
+       int rsp;
 } sysevent_rsp_t;
 
 // Generic Sysevent Ring Buffer
index a08e9c9..805f8c0 100644 (file)
@@ -8,7 +8,6 @@
 static size_t _current_harts = 1;
 static hart_lock_t _hart_lock = HART_LOCK_INIT;
 
-extern char** hart_stack_pointers;
 extern void** hart_thread_control_blocks;
 
 static void hart_free_tls(int id)
@@ -36,7 +35,6 @@ static int hart_allocate_tls(int id)
 }
 
 #define HART_STACK_SIZE (32*1024)
-#define HART_STACK_POINTER_OFFSET (HART_STACK_SIZE-96)
 
 static void hart_free_stack(int id)
 {
@@ -45,15 +43,14 @@ static void hart_free_stack(int id)
 
 static int hart_allocate_stack(int id)
 {
-       if(hart_stack_pointers[id])
+       if(__procdata.stack_pointers[id])
                return 0; // reuse old stack
 
-       if((hart_stack_pointers[id] = malloc(HART_STACK_SIZE)) == NULL)
+       if(!(__procdata.stack_pointers[id] = (intptr_t)malloc(HART_STACK_SIZE)))
        {
                errno = ENOMEM;
                return -1;
        }
-       hart_stack_pointers[id] += HART_STACK_POINTER_OFFSET;
        return 0;
 }
 
@@ -63,13 +60,11 @@ static int hart_init()
        if(initialized)
                return 0;
 
-       hart_stack_pointers = (char**)calloc(hart_max_harts(),sizeof(char*));
        hart_thread_control_blocks = (void**)calloc(hart_max_harts(),sizeof(void*));
 
-       if(!hart_thread_control_blocks || !hart_stack_pointers)
+       if(!hart_thread_control_blocks)
        {
                free(hart_thread_control_blocks);
-               free(hart_stack_pointers);
                errno = ENOMEM;
                return -1;
        }
index 6c417cd..c05a5c3 100644 (file)
@@ -13,6 +13,7 @@
 #include <ros/memlayout.h>
 #include <ros/syscall.h>
 #include <ros/procinfo.h>
+#include <ros/procdata.h>
 #include <stdint.h>
 
 enum {
index f32f4fb..9d52548 100644 (file)
@@ -6,8 +6,6 @@
 #include <ros/procinfo.h>
 #include <unistd.h>
 
-void** __hart_stack_pointers = NULL;
-weak_alias(__hart_stack_pointers,hart_stack_pointers)
 void** __hart_thread_control_blocks = NULL;
 weak_alias(__hart_thread_control_blocks,hart_thread_control_blocks)
 
@@ -30,15 +28,12 @@ weak_alias(__hart_yield,hart_yield)
 void
 _start(void)
 {
-       // threads besides thread 0 must acquire a stack and TCB.
-       // WARNING: no function calls or register spills may occur
-       // before the stack pointer is set!
-       // WARNING2: __hart_self_on_entry must be read before
+       // threads besides thread 0 must acquire a TCB.
+       // WARNING: __hart_self_on_entry must be read before
        // anything is register-allocated!
        int id = __hart_self_on_entry;
        if(id != 0)
        {
-               __hart_set_stack_pointer(__hart_stack_pointers[id]);
                TLS_INIT_TP(__hart_thread_control_blocks[id],0);
                hart_entry();
                hart_yield();