Active messages for x86
[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 /* Interrupt handler to start a process's context on this core. */
12 void __startcore(trapframe_t *tf)
13 {
14         uint32_t coreid = core_id();
15         struct proc *p_to_run = per_cpu_info[coreid].p_to_run;
16         trapframe_t local_tf, *tf_to_pop = per_cpu_info[coreid].tf_to_pop;
17
18         /* Once we copied in the message and are in the handler, we can allow future
19          * proc_management IPIs to this core. */
20         // TODO: replace this ghetto with an active message (AM)
21         per_cpu_info[coreid].proc_ipi_pending = 0;
22
23         /* EOI - we received the interrupt.  probably no issues with receiving
24          * further interrupts in this function.  need to do this before
25          * proc_startcore.  incidentally, interrupts are off in this handler
26          * anyways, since it's set up as an interrupt gate for now. */
27         lapic_send_eoi();
28
29         printk("Startcore on core %d\n", coreid);
30         assert(p_to_run);
31         // TODO: handle silly state (HSS)
32         if (!tf_to_pop) {
33                 tf_to_pop = &local_tf;
34                 memset(tf_to_pop, 0, sizeof(*tf_to_pop));
35                 env_init_trapframe(tf_to_pop);
36                 // Note the init_tf sets tf_to_pop->tf_esp = USTACKTOP;
37                 tf_to_pop->tf_regs.reg_eax = 1;
38                 tf_to_pop->tf_eip = p_to_run->env_entry;
39         }
40         proc_startcore(p_to_run, tf_to_pop);
41 }
42
43 /* Interrupt handler to stop running whatever context is on this core and to
44  * idle.  Note this leaves no trace of what was running.
45  * It's okay if death comes to a core that's already idling and has no current.
46  * It could happen if a process decref'd before proc_startcore could incref. */
47 void __death(trapframe_t *tf)
48 {
49         /* If we are currently running an address space on our core, we need a known
50          * good pgdir before releasing the old one.  This is currently the major
51          * practical implication of the kernel caring about a processes existence
52          * (the inc and decref).  This decref corresponds to the incref in
53          * proc_startcore (though it's not the only one). */
54         if (current) {
55                 lcr3(boot_cr3);
56                 proc_decref(current);
57                 current = NULL;
58         }
59         // As above, signal that it's okay to send us a proc mgmt IPI
60         // TODO: replace this ghetto with an active message (AM)
61         per_cpu_info[core_id()].proc_ipi_pending = 0;
62         lapic_send_eoi();
63         smp_idle();     
64 }