init commit of lab2_3

lab2_3_pagefault
Zhiyuan Shao 3 years ago
parent 032708bd84
commit 5b9d0b55ea

@ -70,7 +70,7 @@ USER_OBJS := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPPS)))
USER_TARGET := $(OBJ_DIR)/app_naive_malloc
USER_TARGET := $(OBJ_DIR)/app_sum_sequence
#------------------------targets------------------------
$(OBJ_DIR):
@-mkdir -p $(OBJ_DIR)

@ -6,6 +6,9 @@
#include "process.h"
#include "strap.h"
#include "syscall.h"
#include "pmm.h"
#include "vmm.h"
#include "util/functions.h"
#include "spike_interface/spike_utils.h"
@ -41,6 +44,28 @@ void handle_mtimer_trap() {
}
//
// the page fault handler. added @lab2_3. parameters:
// sepc: the pc when fault happens;
// stval: the virtual address that causes pagefault when being accessed.
//
void handle_user_page_fault(uint64 mcause, uint64 sepc, uint64 stval) {
sprint("handle_page_fault: %lx\n", stval);
switch (mcause) {
case CAUSE_STORE_PAGE_FAULT:
// TODO (lab2_3): implement the operations that solve the page fault to
// dynamically increase application stack.
// hint: first allocate a new physical page, and then, maps the new page to the
// virtual address that causes the page fault.
panic( "You need to implement the operations that actually handle the page fault in lab2_3.\n" );
break;
default:
sprint("unknown page fault.\n");
break;
}
}
//
// kernel/smode_trap.S will pass control to smode_trap_handler, when a trap happens
// in S-mode.
@ -58,15 +83,25 @@ void smode_trap_handler(void) {
// read_csr() and CAUSE_USER_ECALL are macros defined in kernel/riscv.h
uint64 cause = read_csr(scause);
// we need to handle the timer trap @lab1_3.
if (cause == CAUSE_USER_ECALL) {
handle_syscall(current->trapframe);
} else if (cause == CAUSE_MTIMER_S_TRAP) { //soft trap generated by timer interrupt in M mode
handle_mtimer_trap();
} else {
sprint("smode_trap_handler(): unexpected scause %p\n", read_csr(scause));
sprint(" sepc=%p stval=%p\n", read_csr(sepc), read_csr(stval));
panic( "unexpected exception happened.\n" );
// use switch-case instead of if-else, as there are many cases since lab2_3.
switch (cause) {
case CAUSE_USER_ECALL:
handle_syscall(current->trapframe);
break;
case CAUSE_MTIMER_S_TRAP:
handle_mtimer_trap();
break;
case CAUSE_STORE_PAGE_FAULT:
case CAUSE_LOAD_PAGE_FAULT:
// the address of missing page is stored in stval
// call handle_user_page_fault to process page faults
handle_user_page_fault(cause, read_csr(sepc), read_csr(stval));
break;
default:
sprint("smode_trap_handler(): unexpected scause %p\n", read_csr(scause));
sprint(" sepc=%p stval=%p\n", read_csr(sepc), read_csr(stval));
panic( "unexpected exception happened.\n" );
break;
}
// continue (come back to) the execution of current process.

@ -1,22 +0,0 @@
/*
* Below is the given application for lab2_2.
*/
#include "user_lib.h"
#include "util/types.h"
struct my_structure {
char c;
int n;
};
int main(void) {
struct my_structure* s = (struct my_structure*)naive_malloc();
s->c = 'a';
s->n = 1;
printu("s: %lx, {%c %d}\n", s, s->c, s->n);
naive_free(s);
exit(0);
}

@ -0,0 +1,28 @@
/*
* The application of lab2_3.
*/
#include "user_lib.h"
#include "util/types.h"
//
// compute the summation of an arithmetic sequence. for a given "n", compute
// result = n + (n-1) + (n-2) + ... + 0
// sum_sequence() calls itself recursively till 0. The recursive call, however,
// may consume more memory (from stack) than a physical 4KB page, leading to a page fault.
// PKE kernel needs to improved to handle such page fault by expanding the stack.
//
uint64 sum_sequence(uint64 n) {
if (n == 0)
return 0;
else
return sum_sequence( n-1 ) + n;
}
int main(void) {
// we need a large enough "n" to trigger pagefaults in the user stack
uint64 n = 1000;
printu("Summation of an arithmetic sequence from 0 to %ld is: %ld \n", n, sum_sequence(1000) );
exit(0);
}
Loading…
Cancel
Save