Vcore mapping and idle core management
[akaros.git] / kern / src / env.c
index 4413a65..4ad9677 100644 (file)
@@ -1,5 +1,9 @@
 /* See COPYRIGHT for copyright information. */
 
+#ifdef __SHARC__
+#pragma nosharc
+#endif
+
 #include <arch/arch.h>
 #include <arch/mmu.h>
 #include <elf.h>
@@ -87,15 +91,22 @@ env_init(void)
        int i;
 
        schedule_init();
+       // core 0 is not idle, all others are (for now)
+       spin_lock(&idle_lock);
+       num_idlecores = num_cpus - 1;
+       for (i = 0; i < num_idlecores; i++)
+               idlecoremap[i] = i + 1;
+       spin_unlock(&idle_lock);
        atomic_init(&num_envs, 0);
        TAILQ_INIT(&proc_freelist);
        assert(envs != NULL);
-       for (i = NENV-1; i >= 0; i--) { TRUSTEDBLOCK // asw ivy workaround
+       for (i = NENV-1; i >= 0; i--) {
                // these should already be set from when i memset'd the array to 0
                envs[i].state = ENV_FREE;
                envs[i].env_id = 0;
                TAILQ_INSERT_HEAD(&proc_freelist, &envs[i], proc_link);
        }
+
 }
 
 //
@@ -159,7 +170,8 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata)
        for(int i=0; i<PROCINFO_NUM_PAGES; i++) {
                if(page_alloc(&pginfo[i]) < 0)
                        goto env_setup_vm_error;
-               if(page_insert(e->env_pgdir, pginfo[i], (void*SNT)(UINFO + i*PGSIZE), PTE_USER_RO) < 0)
+               if(page_insert(e->env_pgdir, pginfo[i], (void*SNT)(UINFO + i*PGSIZE),
+                              PTE_USER_RO) < 0)
                        goto env_setup_vm_error;
        }
 
@@ -170,7 +182,8 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata)
        for(int i=0; i<PROCDATA_NUM_PAGES; i++) {
                if(page_alloc(&pgdata[i]) < 0)
                        goto env_setup_vm_error;
-               if(page_insert(e->env_pgdir, pgdata[i], (void*SNT)(UDATA + i*PGSIZE), PTE_USER_RW) < 0)
+               if(page_insert(e->env_pgdir, pgdata[i], (void*SNT)(UDATA + i*PGSIZE),
+                              PTE_USER_RW) < 0)
                        goto env_setup_vm_error;
        }
 
@@ -265,11 +278,17 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        e->env_runs = 0;
        e->env_refcnt = 1;
        e->env_flags = 0;
-
+       e->env_entry = 0; // cheating.  this really gets set in load_icode
+#ifdef __SHARC__
+       /* init SharC state */
+       sharC_env_init(&e->sharC_env);
+#endif
+       e->num_vcores = 0;
+       memset(&e->vcoremap, 0, sizeof(e->vcoremap));
 
        memset(&e->env_ancillary_state, 0, sizeof(e->env_ancillary_state));
        memset(&e->env_tf, 0, sizeof(e->env_tf));
-       env_init_trapframe(e);
+       proc_init_trapframe(&e->env_tf);
 
        /*
         * Initialize the contents of the e->env_procinfo structure
@@ -401,7 +420,8 @@ load_icode(env_t *SAFE e, uint8_t *COUNT(size) binary, size_t size)
                memset((void*)phdr.p_va + phdr.p_filesz, 0, phdr.p_memsz - phdr.p_filesz);
        }}
 
-       env_set_program_counter(e, elfhdr.e_entry);
+       proc_set_program_counter(&e->env_tf, elfhdr.e_entry);
+       e->env_entry = elfhdr.e_entry;
 
        // Now map one page for the program's initial stack
        // at virtual address USTACKTOP - PGSIZE.
@@ -455,6 +475,18 @@ env_free(env_t *e)
        TAILQ_INSERT_HEAD(&proc_freelist, e, proc_link);
 }
 
+
+#define PER_CPU_THING(type,name)\
+type SLOCKED(name##_lock) * RWPROTECT name;\
+type SLOCKED(name##_lock) *\
+(get_per_cpu_##name)()\
+{\
+       { R_PERMITTED(global(name))\
+               return &name[core_id()];\
+       }\
+}
+
+
 /* This is the top-half of an interrupt handler, where the bottom half is
  * proc_run (which never returns).  Just add it to the delayed work queue,
  * which (incidentally) can only hold one item at this point.
@@ -466,7 +498,7 @@ void run_env_handler(trapframe_t *tf, env_t *data)
        assert(data);
        struct work TP(env_t *) job;
        struct workqueue *workqueue = &per_cpu_info[core_id()].workqueue;
-       { //TRUSTEDBLOCK TODO: how do we make this func_t cast work?
+       {
        job.func = proc_run;
        job.data = data;
        }