Avoids nehalem keyboard issues, better monitors
[akaros.git] / kern / arch / i686 / 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 void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
12                          uintptr_t entryp, uintptr_t stack_top)
13 {
14         memset(tf,0,sizeof(*tf));
15
16         /* Set up appropriate initial values for the segment registers.
17          * GD_UD is the user data segment selector in the GDT, and
18          * GD_UT is the user text segment selector (see inc/memlayout.h).
19          * The low 2 bits of each segment register contains the
20          * Requestor Privilege Level (RPL); 3 means user mode. */
21         tf->tf_ds = GD_UD | 3;
22         tf->tf_es = GD_UD | 3;
23         tf->tf_ss = GD_UD | 3;
24         tf->tf_esp = stack_top-64;
25         tf->tf_cs = GD_UT | 3;
26         /* set the env's EFLAGSs to have interrupts enabled */
27         tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
28
29         tf->tf_eip = entryp;
30
31         /* Coupled closely with user's entry.S.  id is the vcoreid, which entry.S
32          * uses to determine what to do.  vcoreid == 0 is the main core/context. */
33         tf->tf_regs.reg_eax = vcoreid;
34 }
35
36 void proc_secure_trapframe(struct trapframe *tf)
37 {
38         /* we normally don't need to set the non-CS regs, but they could be
39          * gibberish and cause a GPF.  gs can still be gibberish, but we don't
40          * necessarily know what it ought to be (we could check, but that's a pain).
41          * the code protecting the kernel from TLS related things ought to be able
42          * to handle GPFs on popping gs. TODO: (TLSV) */
43         tf->tf_ds = GD_UD | 3;
44         tf->tf_es = GD_UD | 3;
45         tf->tf_fs = 0;
46         //tf->tf_gs = whatevs.  ignoring this.
47         tf->tf_ss = GD_UD | 3;
48         tf->tf_cs ? GD_UT | 3 : 0; // can be 0 for sysenter TFs.
49         tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
50 }
51
52 /* Called when we are currently running an address space on our core and want to
53  * abandon it.  We need a known good pgdir before releasing the old one.  We
54  * decref, since current no longer tracks the proc (and current no longer
55  * protects the cr3).  We also need to clear out the TLS registers (before
56  * unmapping the address space!) */
57 void __abandon_core(void)
58 {
59         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
60         asm volatile ("movw %%ax,%%gs; lldt %%ax" :: "a"(0));
61         lcr3(boot_cr3);
62         proc_decref(pcpui->cur_proc);
63         pcpui->cur_proc = 0;
64 }