User programs now tell kernel the stack pointers for new harts
[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 // architecture-specific process initialization code
12 void proc_init_arch(struct proc *SAFE p)
13 {
14 }
15
16 // architecture-specific process termination code
17 void proc_free_arch(struct proc *SAFE p)
18 {
19 }
20
21 void proc_init_trapframe(trapframe_t *tf, uint32_t vcoreid,
22                          uint32_t entryp, uint32_t stack_top)
23 {
24         /* Set up appropriate initial values for the segment registers.
25          * GD_UD is the user data segment selector in the GDT, and
26          * GD_UT is the user text segment selector (see inc/memlayout.h).
27          * The low 2 bits of each segment register contains the
28          * Requestor Privilege Level (RPL); 3 means user mode. */
29         tf->tf_ds = GD_UD | 3;
30         tf->tf_es = GD_UD | 3;
31         tf->tf_ss = GD_UD | 3;
32         tf->tf_esp = stack_top;
33         tf->tf_cs = GD_UT | 3;
34         /* set the env's EFLAGSs to have interrupts enabled */
35         tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
36
37         tf->tf_eip = entryp;
38
39         /* Coupled closely with user's entry.S.  id is the vcoreid, which entry.S
40          * uses to determine what to do.  vcoreid == 0 is the main core/context. */
41         tf->tf_regs.reg_eax = vcoreid;
42 }
43
44 /* For cases that we won't return from a syscall via the normal path, and need
45  * to set the syscall return value in the registers manually.  Like in a syscall
46  * moving to RUNNING_M */
47 void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value)
48 {
49         tf->tf_regs.reg_eax = value;
50 }