Can use per-process shared data page
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Apr 2009 19:17:03 +0000 (12:17 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 25 Apr 2009 02:49:14 +0000 (19:49 -0700)
Basics to communicate from user -> kernel through shared memory, across
cores.  Just prints a string right now.

inc/lib.h
kern/env.c
kern/init.c
kern/smp.c
kern/smp.h
kern/smp_entry.S
user/hello.c

index ccbee30..e9921b4 100644 (file)
--- a/inc/lib.h
+++ b/inc/lib.h
@@ -24,8 +24,8 @@ extern char *binaryname;
 extern volatile env_t *env;
 // will need to change these types when we have real structs
 // seems like they need to be either arrays [] or functions () for it to work
-extern volatile uint8_t procinfo[];
-extern volatile uint8_t procdata[];
+extern volatile uint8_t (COUNT(PGSIZE * UINFO_PAGES) procinfo)[];
+extern volatile uint8_t (COUNT(PGSIZE * UDATA_PAGES) procdata)[];
 extern volatile page_t pages[];
 void   exit(void);
 
index f4f3191..1b02794 100644 (file)
@@ -14,6 +14,8 @@
 #include <kern/pmap.h>
 #include <kern/trap.h>
 #include <kern/monitor.h>
+#include <kern/apic.h>
+#include <kern/smp.h>
 
 env_t *envs = NULL;            // All environments
 env_t *curenv = NULL;          // The current env
@@ -445,10 +447,19 @@ env_destroy(env_t *e)
 {
        env_free(e);
 
-       int i;
+       // for old envs that die on user cores.  since env run never returns, cores
+       // never get back to their old hlt/relaxed/spin state, so we need to force
+       // them back to an idle function.
+       uint32_t id = lapic_get_id();
+       if (id) {
+               smp_idle();
+               panic("should never see me");
+       }
+       // else we're core 0 and can do the usual
+
        // ugly, but for now just linearly search through all possible
        // environments for a runnable one.
-       for (i = 0; i < NENV; i++) {
+       for (int i = 0; i < NENV; i++) {
                e = &envs[ENVX(i)];
                if (e && e->env_status == ENV_RUNNABLE)
                        env_run(e);
index 71f386a..9957b7e 100644 (file)
 #include <kern/apic.h>
 #include <kern/testing.h>
 #include <kern/atomic.h>
-#include <kern/smp.h> 
+#include <kern/smp.h>
 
 static void print_cpuinfo(void);
 
+static void run_env_handler(trapframe_t *tf)
+{
+       env_run(&envs[0]);
+}
+
 void kernel_init(multiboot_info_t *mboot_info)
 {
        extern char (BND(__this, end) edata)[], (SNT end)[];
@@ -55,9 +60,8 @@ void kernel_init(multiboot_info_t *mboot_info)
        // this returns when all other cores are done and ready to receive IPIs
        smp_boot();
 
+       /*
        test_smp_call_functions();
-       panic("Don't Panic");
-
        test_checklists();
        test_barrier();
        test_print_info();
@@ -66,6 +70,7 @@ void kernel_init(multiboot_info_t *mboot_info)
        test_barrier();
        test_print_info();
        test_ipi_sending();
+       */
 
        //ENV_CREATE(user_faultread);
        //ENV_CREATE(user_faultreadkernel);
@@ -79,7 +84,16 @@ void kernel_init(multiboot_info_t *mboot_info)
        //ENV_CREATE(user_evilhello);
 
        // We only have one user environment for now, so just run it.
-       env_run(&envs[0]);
+       //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);
+
+       // wait 5 sec, then print what's in shared mem
+       udelay(5000000);
+       printk("Reading from shared mem from hello on core 2:\n");
+       printk(envs[0].env_procdata); // horrible for security!
+       panic("Don't Panic");
 }
 
 /*
index 3104329..c038c6a 100644 (file)
@@ -212,6 +212,14 @@ uint32_t smp_main(void)
        return my_stack_top; // will be loaded in smp_entry.S
 }
 
+// this idles a core, sometimes we need to call it directly.  never returns.
+// the pause is somewhat of a hack, since kvm isn't halting.  not sure what the
+// deal is wit that.
+void smp_idle(void)
+{
+       asm volatile("1: hlt; pause; jmp 1b;");
+}
+
 // could have the backend checklists static/global too.
 // or at least have the pointers global (save a little RAM)
 
index d743ac8..d2ed1d6 100644 (file)
@@ -28,6 +28,7 @@ typedef struct HandlerWrapper {
 
 /* SMP bootup functions */
 void smp_boot(void);
+void smp_idle(void);
 
 /* SMP utility functions */
 void smp_call_function_self(isr_t handler, bool wait);
index f9a1e30..434a1d9 100644 (file)
@@ -89,6 +89,7 @@ here:
        sti                                             # turn on interrupts, and wait for an IPI
 spinwait:
        hlt                                             # hlts, else will just spin.
+       pause                                   # hack, since kvm is ignoring the hlt.
        jmp             spinwait
 
        # Below here is just data, stored with the code text
index af82c1c..f1fea0f 100644 (file)
@@ -6,4 +6,9 @@ void umain(void)
        cprintf("goodbye, world!\n");
        // this is just their way of generating a pagefault..., until now!
        cprintf("i am environment %08x\n", env->env_id);
+
+       // hello via shared mem
+       const char* hello = "Is there anybody in there?\n";
+       memcpy(procdata, hello, strlen(hello));
+       cprintf("wrote to shared mem.  just nod if you can hear me.\n");
 }