Vcore0 can restart in _M mode
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 5 Apr 2010 22:25:18 +0000 (15:25 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:40 +0000 (17:35 -0700)
When notified or for other reasons that may cause a restart, vcore0 will
come up on a fresh transition stack (not USTACKTOP) with a fresh TLS
region.  In essence, the context from _S mode is just a user thread that
will need to be managed by a scheduler that needs to be invoked from
hart_entry().

Rebuild your cross compiler.

tests/mhello.c
tools/compilers/gcc-glibc/glibc-2.11.1-ros/sysdeps/ros/start.c
user/parlib/hart.c

index 7f2a476..0aa08bc 100644 (file)
@@ -20,6 +20,8 @@ int main(int argc, char** argv)
        hart_barrier_init(&b,hart_max_harts()-1);
 
 /* begin: stuff userspace needs to do before switching to multi-mode */
+       if (hart_init())
+               printf("Harts failed, we're fucked!\n");
 
        /* tell the kernel where and how we want to receive notifications */
        struct notif_method *nm;
index eb42dc8..a968e5f 100644 (file)
@@ -41,8 +41,9 @@ _start(void)
        if(init == 0)
                id = 0;
        
-       // threads besides thread 0 must acquire a TCB.
-       if(id != 0)
+       // vcore0 when it comes up again, and all threads besides thread 0 must
+       // acquire a TCB.
+       if(init || (id != 0))
        {
                TLS_INIT_TP(__hart_thread_control_blocks[id],0);
                hart_entry();
@@ -51,11 +52,6 @@ _start(void)
                goto diediedie;
        }
 
-       if(init)
-       {
-               failmsg("why did thread 0 re-enter _start?");
-               goto diediedie;
-       }
        init = 1;
 
        extern int main(int,char**,char**);
index f99c83e..b14f813 100644 (file)
@@ -80,14 +80,24 @@ int hart_init()
        hart_thread_control_blocks = (void**)calloc(hart_max_harts(),sizeof(void*));
 
        if(!hart_thread_control_blocks)
-       {
-               free(hart_thread_control_blocks);
-               errno = ENOMEM;
-               return -1;
-       }
+               goto hart_tcb_fail;
+
+       if (hart_allocate_stack(0))
+               goto hart_stack_fail;
+       
+       if (hart_allocate_tls(0))
+               goto hart_tls_fail;
 
        initialized = 1;
        return 0;
+
+hart_tls_fail:
+       hart_free_stack(0);
+hart_stack_fail:
+       free(hart_thread_control_blocks);
+hart_tcb_fail:
+       errno = ENOMEM;
+       return -1;
 }
 
 int hart_request(size_t k)