SMP Booting, APIC, and IRQs
[akaros.git] / kern / env.c
index af583ee..ea4b100 100644 (file)
@@ -1,4 +1,7 @@
 /* See COPYRIGHT for copyright information. */
+#ifdef __DEPUTY__
+#pragma nodeputy
+#endif
 
 #include <inc/x86.h>
 #include <inc/mmu.h>
@@ -189,6 +192,8 @@ env_alloc(struct Env **newenv_store, envid_t parent_id)
        e->env_tf.tf_esp = USTACKTOP;
        e->env_tf.tf_cs = GD_UT | 3;
        // You will set e->env_tf.tf_eip later.
+       // set the env's EFLAGSs to have interrupts enabled
+       e->env_tf.tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
 
        // commit the allocation
        LIST_REMOVE(e, env_link);
@@ -218,7 +223,7 @@ segment_alloc(struct Env *e, void *va, size_t len)
        end = ROUNDUP(va + len, PGSIZE);
        if (start >= end)
                panic("Wrap-around in memory allocation addresses!");
-       if ((uint32_t)end > UTOP)
+       if ((uintptr_t)end > UTOP)
                panic("Attempting to map above UTOP!");
        // page_insert/pgdir_walk alloc a page and read/write to it via its address
        // starting from pgdir (e's), so we need to be using e's pgdir
@@ -383,6 +388,9 @@ env_free(struct Env *e)
                page_decref(pa2page(pa));
        }
 
+       // need a known good pgdir before releasing the old one
+       lcr3(boot_cr3);
+
        // free the page directory
        pa = e->env_cr3;
        e->env_pgdir = 0;
@@ -404,6 +412,14 @@ env_destroy(struct Env *e)
 {
        env_free(e);
 
+       int i;
+       // ugly, but for now just linearly search through all possible
+       // environments for a runnable one.
+       for (i = 0; i < NENV; i++) {
+               e = &envs[ENVX(i)];
+               if (e && e->env_status == ENV_RUNNABLE)
+                       env_run(e);
+       }
        cprintf("Destroyed the only environment - nothing more to do!\n");
        while (1)
                monitor(NULL);
@@ -450,10 +466,11 @@ env_run(struct Env *e)
        //      e->env_tf to sensible values.
        
                // would set the curenv->env_status if we had more states
-       curenv = e;
-       e->env_runs++;
-       lcr3(e->env_cr3);
-       panic("remove me to step through env_pop_tf or once int 0x30 is supported.");
+       if (e != curenv) {
+               curenv = e;
+               e->env_runs++;
+               lcr3(e->env_cr3);
+       }
     env_pop_tf(&e->env_tf);
 }