kern

annotate src/proc.c @ 50:1d8877d12de0

tidyed up the intr_ret bit, made it a bit more reasonably structured, and cleaned up some debugging things
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 30 Jul 2011 07:35:53 +0300
parents 50730d42d2d3
children b1e8c8251884
rev   line source
nuclear@47 1 #include <string.h>
nuclear@42 2 #include "proc.h"
nuclear@42 3 #include "tss.h"
nuclear@45 4 #include "vm.h"
nuclear@47 5 #include "segm.h"
nuclear@47 6 #include "intr.h"
nuclear@47 7 #include "panic.h"
nuclear@47 8
nuclear@47 9
nuclear@47 10 /* defined in test_proc.S */
nuclear@47 11 void test_proc(void);
nuclear@47 12 void test_proc_end(void);
nuclear@42 13
nuclear@42 14 static struct process proc[MAX_PROC];
nuclear@42 15 static int cur_pid;
nuclear@42 16
nuclear@42 17 void init_proc(void)
nuclear@42 18 {
nuclear@47 19 int proc_size_pg, img_start_pg, stack_pg;
nuclear@45 20 void *img_start;
nuclear@42 21 cur_pid = -1;
nuclear@42 22
nuclear@42 23 /* prepare the first process */
nuclear@42 24
nuclear@42 25 /* allocate a chunk of memory for the process image
nuclear@42 26 * and copy the code of test_proc there.
nuclear@42 27 * (should be mapped at a fixed address)
nuclear@42 28 */
nuclear@49 29 /*proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1;
nuclear@45 30 if((img_start_pg = pgalloc(proc_size_pg, MEM_USER)) == -1) {
nuclear@45 31 panic("failed to allocate space for the init process image\n");
nuclear@45 32 }
nuclear@45 33 img_start = (void*)PAGE_TO_ADDR(img_start_pg);
nuclear@49 34 memcpy(img_start, test_proc, proc_size_pg * PGSIZE);*/
nuclear@49 35 img_start = test_proc;
nuclear@45 36
nuclear@47 37 /* instruction pointer at the beginning of the process image */
nuclear@47 38 proc[0].ctx.instr_ptr = (uint32_t)img_start;
nuclear@47 39
nuclear@47 40 /* allocate the first page of the process stack */
nuclear@47 41 stack_pg = ADDR_TO_PAGE(KMEM_START) - 1;
nuclear@47 42 if(pgalloc_vrange(stack_pg, 1) == -1) {
nuclear@47 43 panic("failed to allocate user stack page\n");
nuclear@47 44 }
nuclear@47 45 proc[0].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE;
nuclear@47 46
nuclear@45 47 /* create the virtual address space for this process */
nuclear@47 48 proc[0].ctx.pgtbl_paddr = clone_vm();
nuclear@45 49
nuclear@47 50 /* we don't need the image and the stack in this address space */
nuclear@49 51 /*unmap_page_range(img_start_pg, proc_size_pg);
nuclear@49 52 pgfree(img_start_pg, proc_size_pg);*/
nuclear@45 53
nuclear@47 54 unmap_page(stack_pg);
nuclear@47 55 pgfree(stack_pg, 1);
nuclear@42 56
nuclear@42 57
nuclear@42 58 /* switch to it by calling a function that takes the context
nuclear@42 59 * of the current process, plugs the values into the interrupt
nuclear@42 60 * stack, and calls iret.
nuclear@42 61 * (should also set ss0/sp0 in TSS before returning)
nuclear@42 62 */
nuclear@47 63 context_switch(0);
nuclear@47 64 /* XXX this will never return */
nuclear@42 65 }
nuclear@42 66
nuclear@47 67
nuclear@47 68 void context_switch(int pid)
nuclear@42 69 {
nuclear@47 70 struct intr_frame ifrm;
nuclear@47 71 struct context *ctx = &proc[pid].ctx;
nuclear@47 72
nuclear@49 73
nuclear@47 74 cur_pid = pid;
nuclear@47 75
nuclear@47 76 ifrm.inum = ifrm.err = 0;
nuclear@47 77
nuclear@47 78 ifrm.regs = ctx->regs;
nuclear@47 79 ifrm.eflags = ctx->flags;
nuclear@47 80
nuclear@47 81 ifrm.eip = ctx->instr_ptr;
nuclear@49 82 ifrm.cs = selector(SEGM_KCODE, 0); /* XXX change this when we setup the TSS */
nuclear@49 83 ifrm.esp = 0;/*ctx->stack_ptr; /* this will only be used when we switch to userspace */
nuclear@49 84 ifrm.regs.esp = ctx->stack_ptr; /* ... until then... */
nuclear@49 85 ifrm.ss = 0;/*selector(SEGM_KDATA, 0); /* XXX */
nuclear@47 86
nuclear@47 87 /* switch to the vm of the process */
nuclear@47 88 set_pgdir_addr(ctx->pgtbl_paddr);
nuclear@47 89
nuclear@47 90 intr_ret(ifrm);
nuclear@47 91 }