kern
changeset 51:b1e8c8251884
lalalala
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 01 Aug 2011 06:45:29 +0300 |
parents | 1d8877d12de0 |
children | fa65b4f45366 |
files | run src/config.h src/intr.c src/intr.h src/proc.c src/proc.h src/sched.c src/sched.h src/syscall.c src/syscall.h src/sysnum.h src/test_proc.S src/timer.c src/timer.h src/vm.c |
diffstat | 15 files changed, 418 insertions(+), 41 deletions(-) [+] |
line diff
1.1 --- a/run Sat Jul 30 07:35:53 2011 +0300 1.2 +++ b/run Mon Aug 01 06:45:29 2011 +0300 1.3 @@ -1,3 +1,3 @@ 1.4 #!/bin/sh 1.5 1.6 -qemu -kernel kernel.elf -soundhw pcspk 1.7 +qemu -kernel kernel.elf -soundhw pcspk $*
2.1 --- a/src/config.h Sat Jul 30 07:35:53 2011 +0300 2.2 +++ b/src/config.h Mon Aug 01 06:45:29 2011 +0300 2.3 @@ -4,4 +4,7 @@ 2.4 /* frequency of generated timer ticks in hertz */ 2.5 #define TICK_FREQ_HZ 250 2.6 2.7 +#define TIMESLICE 100 2.8 +#define TIMESLICE_TICKS (TIMESLICE * TICK_FREQ_HZ / 1000) 2.9 + 2.10 #endif /* _CONFIG_H_ */
3.1 --- a/src/intr.c Sat Jul 30 07:35:53 2011 +0300 3.2 +++ b/src/intr.c Mon Aug 01 06:45:29 2011 +0300 3.3 @@ -38,7 +38,6 @@ 3.4 static void init_pic(int offset); 3.5 static void gate_desc(desc_t *desc, uint16_t sel, uint32_t addr, int dpl, int type); 3.6 static void set_intr_entry(int num, void (*handler)(void)); 3.7 -static void end_of_irq(int irq); 3.8 3.9 /* defined in intr-asm.S */ 3.10 void set_idt(uint32_t addr, uint16_t limit); 3.11 @@ -88,7 +87,7 @@ 3.12 void dispatch_intr(struct intr_frame frm) 3.13 { 3.14 if(intr_func[frm.inum]) { 3.15 - intr_func[frm.inum](frm.inum, frm.err); 3.16 + intr_func[frm.inum](frm.inum, &frm); 3.17 } else { 3.18 if(frm.inum < 32) { 3.19 panic("unhandled exception %d, error code: %d\n", frm.inum, frm.err); 3.20 @@ -141,7 +140,7 @@ 3.21 gate_desc(idt + num, selector(SEGM_KCODE, 0), (uint32_t)handler, 0, type); 3.22 } 3.23 3.24 -static void end_of_irq(int irq) 3.25 +void end_of_irq(int irq) 3.26 { 3.27 if(irq > 7) { 3.28 outb(OCW2_EOI, PIC2_CMD);
4.1 --- a/src/intr.h Sat Jul 30 07:35:53 2011 +0300 4.2 +++ b/src/intr.h Mon Aug 01 06:45:29 2011 +0300 4.3 @@ -28,7 +28,7 @@ 4.4 4.5 4.6 4.7 -typedef void (*intr_func_t)(int, uint32_t); 4.8 +typedef void (*intr_func_t)(int, struct intr_frame *frm); 4.9 4.10 4.11 void init_intr(void); 4.12 @@ -41,4 +41,6 @@ 4.13 4.14 void intr_ret(struct intr_frame ifrm); 4.15 4.16 +void end_of_irq(int irq); 4.17 + 4.18 #endif /* INTR_H_ */
5.1 --- a/src/proc.c Sat Jul 30 07:35:53 2011 +0300 5.2 +++ b/src/proc.c Mon Aug 01 06:45:29 2011 +0300 5.3 @@ -5,6 +5,8 @@ 5.4 #include "segm.h" 5.5 #include "intr.h" 5.6 #include "panic.h" 5.7 +#include "syscall.h" 5.8 +#include "sched.h" 5.9 5.10 5.11 /* defined in test_proc.S */ 5.12 @@ -18,50 +20,50 @@ 5.13 { 5.14 int proc_size_pg, img_start_pg, stack_pg; 5.15 void *img_start; 5.16 - cur_pid = -1; 5.17 + cur_pid = 0; 5.18 + 5.19 + init_syscall(); 5.20 5.21 /* prepare the first process */ 5.22 + proc[1].id = 1; 5.23 + proc[1].parent = 0; 5.24 5.25 /* allocate a chunk of memory for the process image 5.26 * and copy the code of test_proc there. 5.27 * (should be mapped at a fixed address) 5.28 */ 5.29 - /*proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1; 5.30 + proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1; 5.31 if((img_start_pg = pgalloc(proc_size_pg, MEM_USER)) == -1) { 5.32 panic("failed to allocate space for the init process image\n"); 5.33 } 5.34 img_start = (void*)PAGE_TO_ADDR(img_start_pg); 5.35 - memcpy(img_start, test_proc, proc_size_pg * PGSIZE);*/ 5.36 - img_start = test_proc; 5.37 + memcpy(img_start, test_proc, proc_size_pg * PGSIZE); 5.38 5.39 /* instruction pointer at the beginning of the process image */ 5.40 - proc[0].ctx.instr_ptr = (uint32_t)img_start; 5.41 + proc[1].ctx.instr_ptr = (uint32_t)img_start; 5.42 5.43 /* allocate the first page of the process stack */ 5.44 stack_pg = ADDR_TO_PAGE(KMEM_START) - 1; 5.45 if(pgalloc_vrange(stack_pg, 1) == -1) { 5.46 panic("failed to allocate user stack page\n"); 5.47 } 5.48 - proc[0].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE; 5.49 + proc[1].ctx.stack_ptr = PAGE_TO_ADDR(stack_pg) + PGSIZE; 5.50 5.51 /* create the virtual address space for this process */ 5.52 - proc[0].ctx.pgtbl_paddr = clone_vm(); 5.53 + proc[1].ctx.pgtbl_paddr = clone_vm(); 5.54 5.55 /* we don't need the image and the stack in this address space */ 5.56 - /*unmap_page_range(img_start_pg, proc_size_pg); 5.57 - pgfree(img_start_pg, proc_size_pg);*/ 5.58 + unmap_page_range(img_start_pg, proc_size_pg); 5.59 + pgfree(img_start_pg, proc_size_pg); 5.60 5.61 unmap_page(stack_pg); 5.62 pgfree(stack_pg, 1); 5.63 5.64 + /* add it to the scheduler queues */ 5.65 + //add_proc(1, STATE_RUNNING); 5.66 5.67 - /* switch to it by calling a function that takes the context 5.68 - * of the current process, plugs the values into the interrupt 5.69 - * stack, and calls iret. 5.70 - * (should also set ss0/sp0 in TSS before returning) 5.71 - */ 5.72 - context_switch(0); 5.73 - /* XXX this will never return */ 5.74 + /* switch to the initial process, this never returns */ 5.75 + context_switch(1); 5.76 } 5.77 5.78 5.79 @@ -76,7 +78,7 @@ 5.80 ifrm.inum = ifrm.err = 0; 5.81 5.82 ifrm.regs = ctx->regs; 5.83 - ifrm.eflags = ctx->flags; 5.84 + ifrm.eflags = ctx->flags | (1 << 9); 5.85 5.86 ifrm.eip = ctx->instr_ptr; 5.87 ifrm.cs = selector(SEGM_KCODE, 0); /* XXX change this when we setup the TSS */ 5.88 @@ -89,3 +91,18 @@ 5.89 5.90 intr_ret(ifrm); 5.91 } 5.92 + 5.93 +int get_current_pid(void) 5.94 +{ 5.95 + return cur_pid; 5.96 +} 5.97 + 5.98 +struct process *get_current_proc(void) 5.99 +{ 5.100 + return cur_pid ? &proc[cur_pid] : 0; 5.101 +} 5.102 + 5.103 +struct process *get_process(int pid) 5.104 +{ 5.105 + return &proc[pid]; 5.106 +}
6.1 --- a/src/proc.h Sat Jul 30 07:35:53 2011 +0300 6.2 +++ b/src/proc.h Mon Aug 01 06:45:29 2011 +0300 6.3 @@ -15,14 +15,29 @@ 6.4 /* TODO add FPU state */ 6.5 }; 6.6 6.7 +enum proc_state { 6.8 + STATE_RUNNING, 6.9 + STATE_BLOCKED, 6.10 + STATE_ZOMBIE 6.11 +}; 6.12 + 6.13 6.14 struct process { 6.15 - int parent; 6.16 + int id, parent; 6.17 + enum proc_state state; 6.18 + 6.19 + int ticks_left; 6.20 struct context ctx; 6.21 + 6.22 + struct process *next, *prev; /* for the scheduler queues */ 6.23 }; 6.24 6.25 void init_proc(void); 6.26 6.27 void context_switch(int pid); 6.28 6.29 +int get_current_pid(void); 6.30 +struct process *get_current_proc(void); 6.31 +struct process *get_process(int pid); 6.32 + 6.33 #endif /* PROC_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/sched.c Mon Aug 01 06:45:29 2011 +0300 7.3 @@ -0,0 +1,154 @@ 7.4 +#include <stdio.h> 7.5 +#include "sched.h" 7.6 +#include "proc.h" 7.7 +#include "intr.h" 7.8 +#include "asmops.h" 7.9 +#include "config.h" 7.10 + 7.11 +#define EMPTY(q) ((q).head == 0) 7.12 + 7.13 +struct proc_list { 7.14 + struct process *head, *tail; 7.15 +}; 7.16 + 7.17 +static void ins_back(struct proc_list *q, struct process *proc); 7.18 +static void ins_front(struct proc_list *q, struct process *proc); 7.19 +static void remove(struct proc_list *q, struct process *proc); 7.20 + 7.21 +static struct proc_list runq; 7.22 +static struct proc_list waitq; 7.23 +static struct proc_list zombieq; 7.24 + 7.25 +void schedule(void) 7.26 +{ 7.27 + if(EMPTY(runq)) { 7.28 + /* idle "process". 7.29 + * make sure interrupts are enabled before halting 7.30 + */ 7.31 + enable_intr(); 7.32 + halt_cpu(); 7.33 + /* this won't return, it'll just wake up in an interrupt later */ 7.34 + } 7.35 + 7.36 + disable_intr(); 7.37 + 7.38 + /* if the current process exhausted its timeslice, 7.39 + * move it to the back of the queue. 7.40 + */ 7.41 + if(runq.head->ticks_left <= 0) { 7.42 + if(runq.head->next) { 7.43 + struct process *proc = runq.head; 7.44 + remove(&runq, proc); 7.45 + ins_back(&runq, proc); 7.46 + } 7.47 + 7.48 + /* start a new timeslice */ 7.49 + runq.head->ticks_left = TIMESLICE_TICKS; 7.50 + } 7.51 + 7.52 + /* no need to re-enable interrupts, they will be enabled with the iret */ 7.53 + context_switch(runq.head->id); 7.54 +} 7.55 + 7.56 +int add_proc(int pid, enum proc_state state) 7.57 +{ 7.58 + int istate; 7.59 + struct proc_list *q; 7.60 + struct process *proc = get_process(pid); 7.61 + 7.62 + istate = get_intr_state(); 7.63 + disable_intr(); 7.64 + 7.65 + q = state == STATE_RUNNING ? &runq : &waitq; 7.66 + 7.67 + ins_back(q, proc); 7.68 + proc->state = state; 7.69 + 7.70 + set_intr_state(istate); 7.71 + return 0; 7.72 +} 7.73 + 7.74 +int block_proc(int pid) 7.75 +{ 7.76 + int istate; 7.77 + struct process *proc = get_process(pid); 7.78 + 7.79 + if(proc->state != STATE_RUNNING) { 7.80 + printf("block_proc: process %d not running\n", pid); 7.81 + return -1; 7.82 + } 7.83 + 7.84 + istate = get_intr_state(); 7.85 + disable_intr(); 7.86 + 7.87 + remove(&runq, proc); 7.88 + ins_back(&waitq, proc); 7.89 + proc->state = STATE_BLOCKED; 7.90 + 7.91 + set_intr_state(istate); 7.92 + return 0; 7.93 +} 7.94 + 7.95 +int unblock_proc(int pid) 7.96 +{ 7.97 + int istate; 7.98 + struct process *proc = get_process(pid); 7.99 + 7.100 + if(proc->state != STATE_BLOCKED) { 7.101 + printf("unblock_proc: process %d not blocked\n", pid); 7.102 + return -1; 7.103 + } 7.104 + 7.105 + istate = get_intr_state(); 7.106 + disable_intr(); 7.107 + 7.108 + remove(&waitq, proc); 7.109 + ins_back(&runq, proc); 7.110 + proc->state = STATE_RUNNING; 7.111 + 7.112 + set_intr_state(istate); 7.113 + return 0; 7.114 +} 7.115 + 7.116 + 7.117 +static void ins_back(struct proc_list *q, struct process *proc) 7.118 +{ 7.119 + if(EMPTY(*q)) { 7.120 + q->head = proc; 7.121 + } else { 7.122 + q->tail->next = proc; 7.123 + } 7.124 + 7.125 + proc->next = 0; 7.126 + proc->prev = q->tail; 7.127 + q->tail = proc; 7.128 +} 7.129 + 7.130 +static void ins_front(struct proc_list *q, struct process *proc) 7.131 +{ 7.132 + if(EMPTY(*q)) { 7.133 + q->tail = proc; 7.134 + } else { 7.135 + q->head->prev = proc; 7.136 + } 7.137 + 7.138 + proc->next = q->head; 7.139 + proc->prev = 0; 7.140 + q->head = proc; 7.141 +} 7.142 + 7.143 +static void remove(struct proc_list *q, struct process *proc) 7.144 +{ 7.145 + if(proc->prev) { 7.146 + proc->prev->next = proc->next; 7.147 + } 7.148 + if(proc->next) { 7.149 + proc->next->prev = proc->prev; 7.150 + } 7.151 + if(q->head == proc) { 7.152 + q->head = proc->next; 7.153 + } 7.154 + if(q->tail == proc) { 7.155 + q->tail = proc->prev; 7.156 + } 7.157 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/sched.h Mon Aug 01 06:45:29 2011 +0300 8.3 @@ -0,0 +1,12 @@ 8.4 +#ifndef SCHED_H_ 8.5 +#define SCHED_H_ 8.6 + 8.7 +#include "proc.h" 8.8 + 8.9 +void schedule(void); 8.10 + 8.11 +int add_proc(int pid, enum proc_state state); 8.12 +int block_proc(int pid); 8.13 +int unblock_proc(int pid); 8.14 + 8.15 +#endif /* SCHED_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/syscall.c Mon Aug 01 06:45:29 2011 +0300 9.3 @@ -0,0 +1,56 @@ 9.4 +#include <stdio.h> 9.5 +#include "syscall.h" 9.6 +#include "intr.h" 9.7 +#include "proc.h" 9.8 +#include "sched.h" 9.9 +#include "timer.h" 9.10 + 9.11 +static int (*sys_func[NUM_SYSCALLS])(); 9.12 + 9.13 +static void syscall(int inum, struct intr_frame *frm); 9.14 + 9.15 +static int sys_exit(int status); 9.16 +static int sys_hello(void); 9.17 +static int sys_sleep(int sec); 9.18 + 9.19 +void init_syscall(void) 9.20 +{ 9.21 + sys_func[SYS_EXIT] = sys_exit; 9.22 + sys_func[SYS_HELLO] = sys_hello; 9.23 + sys_func[SYS_SLEEP] = sys_sleep; 9.24 + 9.25 + interrupt(SYSCALL_INT, syscall); 9.26 +} 9.27 + 9.28 +static void syscall(int inum, struct intr_frame *frm) 9.29 +{ 9.30 + int idx = frm->regs.eax; 9.31 + 9.32 + if(idx < 0 || idx >= NUM_SYSCALLS) { 9.33 + printf("invalid syscall: %d\n", idx); 9.34 + return; 9.35 + } 9.36 + 9.37 + frm->regs.eax = sys_func[idx](frm->regs.ebx, frm->regs.ecx, frm->regs.edx, frm->regs.esi, frm->regs.edi); 9.38 + schedule(); 9.39 +} 9.40 + 9.41 +static int sys_exit(int status) 9.42 +{ 9.43 + return -1; /* not implemented yet */ 9.44 +} 9.45 + 9.46 +static int sys_hello(void) 9.47 +{ 9.48 + /*printf("process %d says hello!\n", get_current_pid());*/ 9.49 + return 0; 9.50 +} 9.51 + 9.52 +static int sys_sleep(int sec) 9.53 +{ 9.54 + int pid = get_current_pid(); 9.55 + /*printf("process %d will sleep for %d sec\n", pid, sec);*/ 9.56 + start_timer(sec * 1000, (timer_func_t)unblock_proc, (void*)pid); 9.57 + block_proc(pid); 9.58 + return 0; 9.59 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/syscall.h Mon Aug 01 06:45:29 2011 +0300 10.3 @@ -0,0 +1,17 @@ 10.4 +#ifndef SYSCALL_H_ 10.5 +#define SYSCALL_H_ 10.6 + 10.7 +#define SYSCALL_INT 0x80 10.8 + 10.9 +/* when we get rid of test_proc.S we'll turn this into an enum */ 10.10 +#define SYS_EXIT 0 10.11 +#define SYS_HELLO 1 10.12 +#define SYS_SLEEP 2 10.13 + 10.14 +#define NUM_SYSCALLS 3 10.15 + 10.16 +#ifndef ASM 10.17 +void init_syscall(void); 10.18 +#endif 10.19 + 10.20 +#endif /* SYSCALL_H_ */
11.1 --- a/src/sysnum.h Sat Jul 30 07:35:53 2011 +0300 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,10 +0,0 @@ 11.4 -#ifndef SYSNUM_H_ 11.5 -#define SYSNUM_H_ 11.6 - 11.7 -#define SYSCALL_INT 0x80 11.8 - 11.9 -#define SYS_EXIT 0 11.10 -#define SYS_HELLO 1 11.11 -#define SYS_SLEEP 2 11.12 - 11.13 -#endif /* SYSNUM_H_ */
12.1 --- a/src/test_proc.S Sat Jul 30 07:35:53 2011 +0300 12.2 +++ b/src/test_proc.S Mon Aug 01 06:45:29 2011 +0300 12.3 @@ -1,4 +1,5 @@ 12.4 -#include <sysnum.h> 12.5 +#define ASM 12.6 +#include <syscall.h> 12.7 12.8 .text 12.9 .globl test_proc
13.1 --- a/src/timer.c Sat Jul 30 07:35:53 2011 +0300 13.2 +++ b/src/timer.c Mon Aug 01 06:45:29 2011 +0300 13.3 @@ -3,6 +3,8 @@ 13.4 #include "intr.h" 13.5 #include "asmops.h" 13.6 #include "timer.h" 13.7 +#include "proc.h" 13.8 +#include "sched.h" 13.9 #include "config.h" 13.10 13.11 /* frequency of the oscillator driving the 8254 timer */ 13.12 @@ -39,9 +41,24 @@ 13.13 #define CMD_MODE_BCD 1 13.14 13.15 13.16 +#define MSEC_TO_TICKS(ms) ((ms) * TICK_FREQ_HZ / 1000) 13.17 + 13.18 +struct timer_event { 13.19 + int dt; /* remaining ticks delta from the previous event */ 13.20 + 13.21 + void (*callback)(void*); 13.22 + void *cbarg; 13.23 + 13.24 + struct timer_event *next; 13.25 +}; 13.26 + 13.27 + 13.28 static void intr_handler(); 13.29 13.30 13.31 +static struct timer_event *evlist; 13.32 + 13.33 + 13.34 void init_timer(void) 13.35 { 13.36 /* calculate the reload count: round(osc / freq) */ 13.37 @@ -62,11 +79,101 @@ 13.38 interrupt(IRQ_TO_INTR(0), intr_handler); 13.39 } 13.40 13.41 +int start_timer(unsigned long msec, timer_func_t cbfunc, void *cbarg) 13.42 +{ 13.43 + int ticks, tsum, istate; 13.44 + struct timer_event *ev, *node; 13.45 + 13.46 + printf("start_timer(%lu)\n", msec); 13.47 + 13.48 + if((ticks = MSEC_TO_TICKS(msec)) <= 0) { 13.49 + cbfunc(cbarg); 13.50 + return 0; 13.51 + } 13.52 + 13.53 + if(!(ev = malloc(sizeof *ev))) { 13.54 + printf("start_timer: failed to allocate timer_event structure\n"); 13.55 + return -1; 13.56 + } 13.57 + ev->callback = cbfunc; 13.58 + ev->cbarg = cbarg; 13.59 + 13.60 + istate = get_intr_state(); 13.61 + disable_intr(); 13.62 + 13.63 + /* insert at the beginning */ 13.64 + if(!evlist || ticks <= evlist->dt) { 13.65 + ev->next = evlist; 13.66 + evlist = ev; 13.67 + 13.68 + ev->dt = ticks; 13.69 + if(ev->next) { 13.70 + ev->next->dt -= ticks; 13.71 + } 13.72 + set_intr_state(istate); 13.73 + return 0; 13.74 + } 13.75 + 13.76 + tsum = evlist->dt; 13.77 + node = evlist; 13.78 + 13.79 + while(node->next && ticks > tsum + node->next->dt) { 13.80 + tsum += node->next->dt; 13.81 + node = node->next; 13.82 + } 13.83 + 13.84 + ev->next = node->next; 13.85 + node->next = ev; 13.86 + 13.87 + /* fix the relative times */ 13.88 + ev->dt = ticks - tsum; 13.89 + if(ev->next) { 13.90 + ev->next->dt -= ev->dt; 13.91 + } 13.92 + 13.93 + set_intr_state(istate); 13.94 + return 0; 13.95 +} 13.96 + 13.97 /* This will be called by the interrupt dispatcher approximately 13.98 * every 1/250th of a second, so it must be extremely fast. 13.99 * For now, just increasing a tick counter will suffice. 13.100 */ 13.101 -static void intr_handler() 13.102 +static void intr_handler(int inum) 13.103 { 13.104 + int istate; 13.105 + struct process *cur_proc; 13.106 + 13.107 nticks++; 13.108 + 13.109 + printf("TICKS: %d\n", nticks); 13.110 + 13.111 + istate = get_intr_state(); 13.112 + disable_intr(); 13.113 + 13.114 + /* find out if there are any timers that have to go off */ 13.115 + if(evlist) { 13.116 + evlist->dt--; 13.117 + 13.118 + while(evlist->dt <= 0) { 13.119 + struct timer_event *ev = evlist; 13.120 + evlist = evlist->next; 13.121 + 13.122 + printf("timer going off!!!\n"); 13.123 + ev->callback(ev->cbarg); 13.124 + free(ev); 13.125 + } 13.126 + } 13.127 + 13.128 + if((cur_proc = get_current_proc())) { 13.129 + if(--cur_proc->ticks_left <= 0) { 13.130 + /* since schedule will not return, we have to notify 13.131 + * the PIC that we're done with the IRQ handling 13.132 + */ 13.133 + end_of_irq(INTR_TO_IRQ(inum)); 13.134 + schedule(); 13.135 + } 13.136 + } 13.137 + 13.138 + set_intr_state(istate); 13.139 }
14.1 --- a/src/timer.h Sat Jul 30 07:35:53 2011 +0300 14.2 +++ b/src/timer.h Mon Aug 01 06:45:29 2011 +0300 14.3 @@ -1,8 +1,12 @@ 14.4 #ifndef _TIMER_H_ 14.5 #define _TIMER_H_ 14.6 14.7 +typedef void (*timer_func_t)(void*); 14.8 + 14.9 unsigned long nticks; 14.10 14.11 void init_timer(void); 14.12 14.13 +int start_timer(unsigned long msec, timer_func_t cbfunc, void *cbarg); 14.14 + 14.15 #endif /* _TIMER_H_ */
15.1 --- a/src/vm.c Sat Jul 30 07:35:53 2011 +0300 15.2 +++ b/src/vm.c Mon Aug 01 06:45:29 2011 +0300 15.3 @@ -37,7 +37,7 @@ 15.4 uint32_t get_fault_addr(void); 15.5 15.6 static void coalesce(struct page_range *low, struct page_range *mid, struct page_range *high); 15.7 -static void pgfault(int inum, uint32_t err); 15.8 +static void pgfault(int inum, struct intr_frame *frm); 15.9 static struct page_range *alloc_node(void); 15.10 static void free_node(struct page_range *node); 15.11 15.12 @@ -457,18 +457,18 @@ 15.13 } 15.14 } 15.15 15.16 -static void pgfault(int inum, uint32_t err) 15.17 +static void pgfault(int inum, struct intr_frame *frm) 15.18 { 15.19 printf("~~~~ PAGE FAULT ~~~~\n"); 15.20 15.21 printf("fault address: %x\n", get_fault_addr()); 15.22 15.23 - if(err & PG_PRESENT) { 15.24 - if(err & 8) { 15.25 + if(frm->err & PG_PRESENT) { 15.26 + if(frm->err & 8) { 15.27 printf("reserved bit set in some paging structure\n"); 15.28 } else { 15.29 - printf("%s protection violation ", (err & PG_WRITABLE) ? "write" : "read"); 15.30 - printf("in %s mode\n", err & PG_USER ? "user" : "kernel"); 15.31 + printf("%s protection violation ", (frm->err & PG_WRITABLE) ? "write" : "read"); 15.32 + printf("in %s mode\n", frm->err & PG_USER ? "user" : "kernel"); 15.33 } 15.34 } else { 15.35 printf("page not present\n");