Process management via active messages
[akaros.git] / kern / arch / i386 / process.c
1 #include <arch/arch.h>
2 #include <arch/trap.h>
3 #include <process.h>
4 #include <pmap.h>
5 #include <smp.h>
6
7 #include <string.h>
8 #include <assert.h>
9 #include <stdio.h>
10
11 /* Active message handler to start a process's context on this core.  Tightly
12  * coupled with proc_run() */
13 void __startcore(trapframe_t *tf, uint32_t srcid, uint32_t a0, uint32_t a1,
14                  uint32_t a2)
15 {
16         uint32_t coreid = core_id();
17         struct proc *p_to_run = (struct proc *SAFE) TC(a0);
18         trapframe_t local_tf;
19         trapframe_t *tf_to_pop = (trapframe_t *SAFE) TC(a1);
20
21         printk("Startcore on core %d\n", coreid);
22         assert(p_to_run);
23         // TODO: handle silly state (HSS)
24         if (!tf_to_pop) {
25                 tf_to_pop = &local_tf;
26                 memset(tf_to_pop, 0, sizeof(*tf_to_pop));
27                 env_init_trapframe(tf_to_pop);
28                 // Note the init_tf sets tf_to_pop->tf_esp = USTACKTOP;
29                 tf_to_pop->tf_regs.reg_eax = 1;
30                 tf_to_pop->tf_eip = p_to_run->env_entry;
31         }
32         proc_startcore(p_to_run, tf_to_pop);
33 }
34
35 /* Active message handler to stop running whatever context is on this core and
36  * to idle.  Note this leaves no trace of what was running.
37  * It's okay if death comes to a core that's already idling and has no current.
38  * It could happen if a process decref'd before proc_startcore could incref. */
39 void __death(trapframe_t *tf, uint32_t srcid, uint32_t a0, uint32_t a1,
40              uint32_t a2)
41 {
42         /* If we are currently running an address space on our core, we need a known
43          * good pgdir before releasing the old one.  This is currently the major
44          * practical implication of the kernel caring about a processes existence
45          * (the inc and decref).  This decref corresponds to the incref in
46          * proc_startcore (though it's not the only one). */
47         if (current) {
48                 lcr3(boot_cr3);
49                 proc_decref(current);
50                 current = NULL;
51         }
52         smp_idle();
53 }