Changed some handlers to use void*
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 1 May 2009 22:07:07 +0000 (15:07 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 1 May 2009 22:07:07 +0000 (15:07 -0700)
Also uses the run_env handler to start two processes on different cores,
and shows how to receive their async syscalls.

kern/init.c
kern/smp.c
kern/testing.c
user/hello.c

index 74f3757..47b0520 100644 (file)
@@ -31,7 +31,8 @@ static void print_cpuinfo(void);
 
 static void run_env_handler(trapframe_t *tf, void* data)
 {
-       env_run(&envs[0]);
+       assert(data);
+       env_run((env_t*)data);
 }
 
 void kernel_init(multiboot_info_t *mboot_info)
@@ -79,13 +80,15 @@ void kernel_init(multiboot_info_t *mboot_info)
        //ENV_CREATE(user_divzero);
        //ENV_CREATE(user_buggyhello);
        ENV_CREATE(user_hello);
+       ENV_CREATE(user_hello);
        //ENV_CREATE(user_evilhello);
 
        // We only have one user environment for now, so just run it.
        //env_run(&envs[0]);
        // run_env_handler just runs the first env, like the prev command
        // need a way to have call_func to pass a pointer to a struct for arguments
-       smp_call_function_single(2, run_env_handler, 0, 0);
+       smp_call_function_single(2, run_env_handler, &envs[0], 0);
+       smp_call_function_single(4, run_env_handler, &envs[1], 0);
 
        // wait 5 sec, then print what's in shared mem
        udelay(5000000);
@@ -97,10 +100,17 @@ void kernel_init(multiboot_info_t *mboot_info)
                *(uint32_t*)(envs[0].env_procdata + 8),
                *(uint32_t*)(envs[0].env_procdata + 12));
                */
-       printk("Attempting to run the syscall at the beginning of procdata:\n");
-       printk("\n");
+
+       printk("Attempting to run the syscall at the beginning of procdata for env 0:\n\n");
+       // need to switch to the right context, so we can handle the user pointer
+       // that points to a data payload of the syscall
+       lcr3(envs[0].env_cr3);
        syscall_async((syscall_t*)(envs[0].env_procdata));
        printk("\n");
+       printk("Attempting to run the syscall at the beginning of procdata for env 1:\n\n");
+       lcr3(envs[1].env_cr3);
+       syscall_async((syscall_t*)(envs[1].env_procdata));
+       printk("\n");
        panic("Don't Panic");
 }
 
index 3e93a70..dd121c0 100644 (file)
@@ -17,7 +17,6 @@
 
 volatile uint8_t num_cpus = 0xee;
 uintptr_t smp_stack_top;
-barrier_t generic_barrier;
 
 /*************************** IPI Wrapper Stuff ********************************/
 // checklists to protect the global interrupt_handlers for 0xf0, f1, f2, f3, f4
@@ -55,8 +54,7 @@ static void init_smp_call_function(void)
 
 static void smp_mtrr_handler(trapframe_t *tf, void* data)
 {
-       // TODO - pass in the barrier via data, and not the global
-       setup_default_mtrrs(&generic_barrier);
+       setup_default_mtrrs((barrier_t*)data);
 }
 
 void smp_boot(void)
@@ -124,8 +122,9 @@ void smp_boot(void)
        init_smp_call_function();
 
        // Set up all cores to use the proper MTRRs
+       barrier_t generic_barrier;
        init_barrier(&generic_barrier, num_cpus); // barrier used by smp_mtrr_handler
-       smp_call_function_all(smp_mtrr_handler, 0, 0);
+       smp_call_function_all(smp_mtrr_handler, &generic_barrier, 0);
 
        // Should probably flush everyone's TLB at this point, to get rid of
        // temp mappings that were removed.  TODO
index 684bb46..8122cdc 100644 (file)
@@ -259,21 +259,12 @@ void test_checklists(void)
 
 }
 
-volatile uint32_t a = 0, b = 0, c = 0;
+uint32_t a = 0, b = 0, c = 0;
 
-void test_A_incrementer_handler(struct Trapframe *tf, void* data)
+void test_incrementer_handler(struct Trapframe *tf, void* data)
 {
-       atomic_inc(&a);
-}
-
-void test_B_incrementer_handler(struct Trapframe *tf, void* data)
-{
-       atomic_inc(&b);
-}
-
-void test_C_incrementer_handler(struct Trapframe *tf, void* data)
-{
-       atomic_inc(&c);
+       assert(data);
+       atomic_inc((uint32_t*)data);
 }
 
 void test_null_handler(struct Trapframe *tf, void* data)
@@ -331,22 +322,22 @@ void test_smp_call_functions(void)
        smp_call_wait(waiter0);
        printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
        printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", a, b, c);
-       smp_call_function_all(test_A_incrementer_handler, 0, 0);
-       smp_call_function_all(test_B_incrementer_handler, 0, 0);
-       smp_call_function_all(test_C_incrementer_handler, 0, 0);
+       smp_call_function_all(test_incrementer_handler, &a, 0);
+       smp_call_function_all(test_incrementer_handler, &b, 0);
+       smp_call_function_all(test_incrementer_handler, &c, 0);
        // if i can clobber a previous IPI, the interleaving might do it
-       smp_call_function_single(1, test_A_incrementer_handler, 0, 0);
-       smp_call_function_single(2, test_B_incrementer_handler, 0, 0);
-       smp_call_function_single(3, test_C_incrementer_handler, 0, 0);
-       smp_call_function_single(4, test_A_incrementer_handler, 0, 0);
-       smp_call_function_single(5, test_B_incrementer_handler, 0, 0);
-       smp_call_function_single(6, test_C_incrementer_handler, 0, 0);
-       smp_call_function_all(test_A_incrementer_handler, 0, 0);
-       smp_call_function_single(3, test_C_incrementer_handler, 0, 0);
-       smp_call_function_all(test_B_incrementer_handler, 0, 0);
-       smp_call_function_single(1, test_A_incrementer_handler, 0, 0);
-       smp_call_function_all(test_C_incrementer_handler, 0, 0);
-       smp_call_function_single(2, test_B_incrementer_handler, 0, 0);
+       smp_call_function_single(1, test_incrementer_handler, &a, 0);
+       smp_call_function_single(2, test_incrementer_handler, &b, 0);
+       smp_call_function_single(3, test_incrementer_handler, &c, 0);
+       smp_call_function_single(4, test_incrementer_handler, &a, 0);
+       smp_call_function_single(5, test_incrementer_handler, &b, 0);
+       smp_call_function_single(6, test_incrementer_handler, &c, 0);
+       smp_call_function_all(test_incrementer_handler, &a, 0);
+       smp_call_function_single(3, test_incrementer_handler, &c, 0);
+       smp_call_function_all(test_incrementer_handler, &b, 0);
+       smp_call_function_single(1, test_incrementer_handler, &a, 0);
+       smp_call_function_all(test_incrementer_handler, &c, 0);
+       smp_call_function_single(2, test_incrementer_handler, &b, 0);
        // wait, so we're sure the others finish before printing.
        // without this, we could (and did) get 19,18,19, since the B_inc
        // handler didn't finish yet
index d201968..f12f68f 100644 (file)
@@ -8,13 +8,12 @@ void umain(void)
        cprintf("i am environment %08x\n", env->env_id);
 
        // async via shared mem
-       char* hello = "First cross-chip async syscall success!  Shiver me timbers!\n";
        cprintf("about to write to shared mem.  hope it gets printed.  blimey! \n");
        // note that when using the cprintf family, we can't currently call again,
        // since the library functions use the same buffer.  the last used string
        // will be the one printed when the syscall is serviced, regardless of
        // whether the actual syscall can handle multiples in flight.
-       cprintf_async(hello);
+       cprintf_async("Cross-Core call, coming from env %08x\n", env->env_id);
 
        // might as well spin, just to make sure nothing gets deallocated
        // while we're waiting to test the async call