struct process {
struct pagedir *p_pgdir;
- struct task *p_tasks;
+ struct task *p_tasks;
+ u32_t p_privl;
};
void foo(void)
extern int _pg_dir_vpxlate(pg_dir_t*, u32_t, u32_t*);
-int process_create(process_t **dst)
+int process_create(process_t **dst, u32_t ppl)
{
int ret_val;
process_t *proc;
goto cleanup;
}
+ proc->p_privl = ppl;
+
task_prepare(proc->p_tasks, (u32_t)pdbr, (u32_t)foo,
- (u32_t)kstack, (u32_t)ustack + PAGE_SIZE, 3);
+ (u32_t)kstack, (u32_t)ustack + PAGE_SIZE, ppl);
proc->p_tasks->t_sp = (u32_t)(CONFIG_KERNEL_STACK_BASE +
((u32_t)proc->p_tasks->t_sp - (u32_t)kstack));
#define OFFSET_ESP0 0
#define OFFSET_CR3 4
#define OFFSET_KSTACK 8
+#define OFFSET_PRIVL 12
.extern _cpu
movl 8(%esp), %eax
movl %eax, OFFSET_CR3(%edi)
+ /* store privilege level in task structure */
+ movl 24(%esp), %eax
+ movl %eax, OFFSET_PRIVL(%edi)
+
/* calculate stack start (since it grows down) */
movl 16(%esp), %eax
addl $CONFIG_KERNEL_STACK_SIZE, %eax
movl %ecx, CPU_ESP0(%eax)
movl $KERNEL_DATA, CPU_SS0(%eax)
+ /* set CS according to the task's privilege level */
+ movl OFFSET_PRIVL(%edi), %ecx
+ shll $4, %ecx
+ addl $8, %ecx
+ orl OFFSET_PRIVL(%edi), %ecx
+ movl %ecx, CPU_CS(%eax)
+
/*
- * We need to figure out the task's privilege level and
- * set the segment registers accordingly
+ * Set the data segment selectors (this assumes a privilege
+ * level's DS descriptor follows the CS descriptor)
*/
- /*
- movl $USER_CODE, CPU_CS(%eax)
- movl $USER_DATA, CPU_DS(%eax)
- movl $USER_DATA, CPU_ES(%eax)
- movl $USER_DATA, CPU_FS(%eax)
- movl $USER_DATA, CPU_GS(%eax)
- movl $USER_DATA, CPU_SS(%eax)
- */
+ addl $8, %ecx
+ movl %ecx, CPU_DS(%eax)
+ movl %ecx, CPU_ES(%eax)
+ movl %ecx, CPU_FS(%eax)
+ movl %ecx, CPU_GS(%eax)
+ movl %ecx, CPU_SS(%eax)
+
movl OFFSET_CR3(%edi), %ecx
/* check if we can avoid writing to cr3, which would clear the TLB */
u32_t t_sp;
u32_t t_pgdir;
void *t_kstack;
+ u32_t t_privl;
} __attribute__((packed));
int cpu_get_id(void);
u32_t cpu_set_pstate(int pstate);
-int process_create(process_t**);
+int process_create(process_t**, u32_t);
int task_prepare(struct task*, u32_t cr3, u32_t eip, u32_t esp0, u32_t esp, u32_t priv);
int task_switch(struct task*);