kern

annotate src/proc.c @ 52:fa65b4f45366

picking this up again, let's fix it
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 07 Aug 2011 06:42:00 +0300
parents b1e8c8251884
children 23abbeea4d5f
rev   line source
nuclear@52 1 #include <stdio.h>
nuclear@47 2 #include <string.h>
nuclear@52 3 #include <assert.h>
nuclear@42 4 #include "proc.h"
nuclear@42 5 #include "tss.h"
nuclear@45 6 #include "vm.h"
nuclear@47 7 #include "segm.h"
nuclear@47 8 #include "intr.h"
nuclear@47 9 #include "panic.h"
nuclear@51 10 #include "syscall.h"
nuclear@51 11 #include "sched.h"
nuclear@47 12
nuclear@52 13 #define FLAGS_INTR_BIT 9
nuclear@47 14
nuclear@47 15 /* defined in test_proc.S */
nuclear@47 16 void test_proc(void);
nuclear@47 17 void test_proc_end(void);
nuclear@42 18
nuclear@42 19 static struct process proc[MAX_PROC];
nuclear@42 20 static int cur_pid;
nuclear@42 21
nuclear@42 22 void init_proc(void)
nuclear@42 23 {
nuclear@47 24 int proc_size_pg, img_start_pg, stack_pg;
nuclear@45 25 void *img_start;
nuclear@51 26 cur_pid = 0;
nuclear@51 27
nuclear@51 28 init_syscall();
nuclear@42 29
nuclear@42 30 /* prepare the first process */
nuclear@51 31 proc[1].id = 1;
nuclear@51 32 proc[1].parent = 0;
nuclear@42 33
nuclear@42 34 /* allocate a chunk of memory for the process image
nuclear@42 35 * and copy the code of test_proc there.
nuclear@42 36 * (should be mapped at a fixed address)
nuclear@42 37 */
nuclear@51 38 proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1;
nuclear@45 39 if((img_start_pg = pgalloc(proc_size_pg, MEM_USER)) == -1) {
nuclear@45 40 panic("failed to allocate space for the init process image\n");
nuclear@45 41 }
nuclear@45 42 img_start = (void*)PAGE_TO_ADDR(img_start_pg);
nuclear@51 43 memcpy(img_start, test_proc, proc_size_pg * PGSIZE);
nuclear@45 44
nuclear@52 45 printf("copied init process at: %x\n", (unsigned int)img_start);
nuclear@52 46
nuclear@47 47 /* instruction pointer at the beginning of the process image */
nuclear@51 48 proc[1].ctx.instr_ptr = (uint32_t)img_start;
nuclear@47 49
nuclear@47 50 /* allocate the first page of the process stack */
nuclear@47 51 stack_pg = ADDR_TO_PAGE(KMEM_START) - 1;
nuclear@47 52 if(pgalloc_vrange(stack_pg, 1) == -1) {
nuclear@47 53 panic("failed to allocate user stack page\n");
nuclear@47 54 }
nuclear@51 55 proc[1].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE;
nuclear@47 56
nuclear@52 57 proc[1].stack_end = KMEM_START;
nuclear@52 58 proc[1].stack_start = KMEM_START - PGSIZE;
nuclear@52 59
nuclear@45 60 /* create the virtual address space for this process */
nuclear@51 61 proc[1].ctx.pgtbl_paddr = clone_vm();
nuclear@45 62
nuclear@47 63 /* we don't need the image and the stack in this address space */
nuclear@51 64 unmap_page_range(img_start_pg, proc_size_pg);
nuclear@51 65 pgfree(img_start_pg, proc_size_pg);
nuclear@45 66
nuclear@47 67 unmap_page(stack_pg);
nuclear@47 68 pgfree(stack_pg, 1);
nuclear@42 69
nuclear@51 70 /* add it to the scheduler queues */
nuclear@52 71 add_proc(1, STATE_RUNNING);
nuclear@42 72
nuclear@51 73 /* switch to the initial process, this never returns */
nuclear@51 74 context_switch(1);
nuclear@42 75 }
nuclear@42 76
nuclear@47 77
nuclear@47 78 void context_switch(int pid)
nuclear@42 79 {
nuclear@52 80 struct context *ctx;
nuclear@47 81 struct intr_frame ifrm;
nuclear@52 82 struct intr_frame *cur_frame = get_intr_frame();
nuclear@47 83
nuclear@52 84 assert(0);
nuclear@49 85
nuclear@52 86 if(cur_pid == pid) {
nuclear@52 87 assert(cur_frame);
nuclear@52 88 intr_ret(*cur_frame);
nuclear@52 89 }
nuclear@52 90
nuclear@52 91 ctx = &proc[pid].ctx;
nuclear@47 92 cur_pid = pid;
nuclear@47 93
nuclear@47 94 ifrm.inum = ifrm.err = 0;
nuclear@47 95
nuclear@47 96 ifrm.regs = ctx->regs;
nuclear@52 97 ifrm.eflags = ctx->flags | (1 << FLAGS_INTR_BIT);
nuclear@47 98
nuclear@47 99 ifrm.eip = ctx->instr_ptr;
nuclear@49 100 ifrm.cs = selector(SEGM_KCODE, 0); /* XXX change this when we setup the TSS */
nuclear@52 101 /*ifrm.regs.esp = ctx->stack_ptr;*/ /* ... until then... */
nuclear@52 102 ifrm.esp = ctx->stack_ptr; /* this will only be used when we switch to userspace */
nuclear@52 103 ifrm.ss = selector(SEGM_KDATA, 0);
nuclear@47 104
nuclear@47 105 /* switch to the vm of the process */
nuclear@47 106 set_pgdir_addr(ctx->pgtbl_paddr);
nuclear@47 107 intr_ret(ifrm);
nuclear@47 108 }
nuclear@51 109
nuclear@51 110 int get_current_pid(void)
nuclear@51 111 {
nuclear@51 112 return cur_pid;
nuclear@51 113 }
nuclear@51 114
nuclear@51 115 struct process *get_current_proc(void)
nuclear@51 116 {
nuclear@51 117 return cur_pid ? &proc[cur_pid] : 0;
nuclear@51 118 }
nuclear@51 119
nuclear@51 120 struct process *get_process(int pid)
nuclear@51 121 {
nuclear@51 122 return &proc[pid];
nuclear@51 123 }