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 +}