73ad437d136dcefc172bb1952d940133e0c5299b
[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         /* EOI - we received the interrupt.  probably no issues with receiving
19          * further interrupts in this function.  need to do this before
20          * proc_startcore.  incidentally, interrupts are off in this handler
21          * anyways, since it's set up as an interrupt gate for now. */
22         lapic_send_eoi();
23
24         printk("Startcore on core %d\n", coreid);
25         assert(p_to_run);
26         // TODO: handle silly state (HSS)
27         if (!tf_to_pop) {
28                 tf_to_pop = &local_tf;
29                 memset(tf_to_pop, 0, sizeof(*tf_to_pop));
30                 env_init_trapframe(tf_to_pop);
31                 // Note the init_tf sets tf_to_pop->tf_esp = USTACKTOP;
32                 tf_to_pop->tf_regs.reg_eax = 1;
33                 tf_to_pop->tf_eip = p_to_run->env_entry;
34         }
35         proc_startcore(p_to_run, tf_to_pop);
36 }
37
38 /* Interrupt handler to stop running whatever context is on this core and to
39  * idle.  Note this leaves no trace of what was running. */
40 void __death(trapframe_t *tf)
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         } else {
52                 warn("Sent a DEATH IPI to a core with no current process!");
53         }
54         smp_idle();             
55 }