kern
diff src/proc.c @ 47:f65b348780e3
continuing with the process implementation. not done yet, panics.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 28 Jul 2011 05:43:04 +0300 |
parents | b8f02479e3f4 |
children | 50730d42d2d3 |
line diff
1.1 --- a/src/proc.c Thu Jul 28 05:33:59 2011 +0300 1.2 +++ b/src/proc.c Thu Jul 28 05:43:04 2011 +0300 1.3 @@ -1,13 +1,22 @@ 1.4 +#include <string.h> 1.5 #include "proc.h" 1.6 #include "tss.h" 1.7 #include "vm.h" 1.8 +#include "segm.h" 1.9 +#include "intr.h" 1.10 +#include "panic.h" 1.11 + 1.12 + 1.13 +/* defined in test_proc.S */ 1.14 +void test_proc(void); 1.15 +void test_proc_end(void); 1.16 1.17 static struct process proc[MAX_PROC]; 1.18 static int cur_pid; 1.19 1.20 void init_proc(void) 1.21 { 1.22 - int proc_size_pg, img_start_pg; 1.23 + int proc_size_pg, img_start_pg, stack_pg; 1.24 void *img_start; 1.25 cur_pid = -1; 1.26 1.27 @@ -24,30 +33,56 @@ 1.28 img_start = (void*)PAGE_TO_ADDR(img_start_pg); 1.29 memcpy(img_start, test_proc, proc_size_pg * PGSIZE); 1.30 1.31 + /* instruction pointer at the beginning of the process image */ 1.32 + proc[0].ctx.instr_ptr = (uint32_t)img_start; 1.33 + 1.34 + /* allocate the first page of the process stack */ 1.35 + stack_pg = ADDR_TO_PAGE(KMEM_START) - 1; 1.36 + if(pgalloc_vrange(stack_pg, 1) == -1) { 1.37 + panic("failed to allocate user stack page\n"); 1.38 + } 1.39 + proc[0].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE; 1.40 + 1.41 /* create the virtual address space for this process */ 1.42 - proc[0].ctx.pgtbl_paddr = clone_vmem(); 1.43 + proc[0].ctx.pgtbl_paddr = clone_vm(); 1.44 1.45 - /* we don't need the image in this address space */ 1.46 - unmap_pa 1.47 + /* we don't need the image and the stack in this address space */ 1.48 + unmap_page_range(img_start_pg, proc_size_pg); 1.49 pgfree(img_start_pg, proc_size_pg); 1.50 1.51 + unmap_page(stack_pg); 1.52 + pgfree(stack_pg, 1); 1.53 1.54 - /* fill in the proc[0].ctx with the appropriate process stack 1.55 - * and instruction pointers 1.56 - */ 1.57 1.58 /* switch to it by calling a function that takes the context 1.59 * of the current process, plugs the values into the interrupt 1.60 * stack, and calls iret. 1.61 * (should also set ss0/sp0 in TSS before returning) 1.62 */ 1.63 + context_switch(0); 1.64 + /* XXX this will never return */ 1.65 } 1.66 1.67 -/* 1.68 -void save_context(struct intr_frame *ifrm) 1.69 + 1.70 +void context_switch(int pid) 1.71 { 1.72 - proc[cur_pid].ctx->regs = ifrm->regs; 1.73 - proc[cur_pid].ctx->instr_ptr = ifrm->eip; 1.74 - proc[cur_pid].ctx->stack_ptr = ifrm->esp; 1.75 - proc[cur_pid].ctx->flags = ifrm->eflags; 1.76 -}*/ 1.77 + struct intr_frame ifrm; 1.78 + struct context *ctx = &proc[pid].ctx; 1.79 + 1.80 + cur_pid = pid; 1.81 + 1.82 + ifrm.inum = ifrm.err = 0; 1.83 + 1.84 + ifrm.regs = ctx->regs; 1.85 + ifrm.eflags = ctx->flags; 1.86 + 1.87 + ifrm.eip = ctx->instr_ptr; 1.88 + ifrm.cs = SEGM_KCODE; /* XXX change this when we setup the TSS */ 1.89 + ifrm.esp = ctx->stack_ptr; 1.90 + ifrm.ss = SEGM_KDATA; /* XXX */ 1.91 + 1.92 + /* switch to the vm of the process */ 1.93 + set_pgdir_addr(ctx->pgtbl_paddr); 1.94 + 1.95 + intr_ret(ifrm); 1.96 +}