init commit of lab1_3

lab1_3_irq
Zhiyuan Shao 2 years ago
parent 2859704c47
commit 9c8cbfaa3b

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

@ -4,6 +4,9 @@
// we use only one HART (cpu) in fundamental experiments
#define NCPU 1
//interval of timer interrupt. added @lab1_3
#define TIMER_INTERVAL 1000000
#define DRAM_BASE 0x80000000
/* we use fixed physical (also logical) addresses for the stacks and trap frames as in

@ -76,6 +76,17 @@ static void delegate_traps() {
assert(read_csr(medeleg) == exceptions);
}
//
// enabling timer interrupt (irq) in Machine mode. added @lab1_3
//
void timerinit(uintptr_t hartid) {
// fire timer irq after TIMER_INTERVAL from now.
*(uint64*)CLINT_MTIMECMP(hartid) = *(uint64*)CLINT_MTIME + TIMER_INTERVAL;
// enable machine-mode timer irq in MIE (Machine Interrupt Enable) csr.
write_csr(mie, read_csr(mie) | MIE_MTIE);
}
//
// m_start: machine mode C entry point.
//
@ -103,10 +114,19 @@ void m_start(uintptr_t hartid, uintptr_t dtb) {
// setup trap handling vector for machine mode. added @lab1_2
write_csr(mtvec, (uint64)mtrapvec);
// enable machine-mode interrupts. added @lab1_3
write_csr(mstatus, read_csr(mstatus) | MSTATUS_MIE);
// delegate all interrupts and exceptions to supervisor mode.
// delegate_traps() is defined above.
delegate_traps();
// also enables interrupt handling in supervisor mode. added @lab1_3
write_csr(sie, read_csr(sie) | SIE_SEIE | SIE_STIE | SIE_SSIE);
// init timing. added @lab1_3
timerinit(hartid);
// switch to supervisor mode (S mode) and jump to s_start(), i.e., set pc to mepc
asm volatile("mret");
}

@ -14,12 +14,25 @@ static void handle_misaligned_load() { panic("Misaligned Load!"); }
static void handle_misaligned_store() { panic("Misaligned AMO!"); }
// added @lab1_3
static void handle_timer() {
int cpuid = 0;
// setup the timer fired at next time (TIMER_INTERVAL from now)
*(uint64*)CLINT_MTIMECMP(cpuid) = *(uint64*)CLINT_MTIMECMP(cpuid) + TIMER_INTERVAL;
// setup a soft interrupt in sip (S-mode Interrupt Pending) to be handled in S-mode
write_csr(sip, SIP_SSIP);
}
//
// handle_mtrap calls a handling function according to the type of a machine mode interrupt (trap).
//
void handle_mtrap() {
uint64 mcause = read_csr(mcause);
switch (mcause) {
case CAUSE_MTIMER:
handle_timer();
break;
case CAUSE_FETCH_ACCESS:
handle_instruction_access_fault();
break;

@ -52,6 +52,18 @@
#define CAUSE_LOAD_PAGE_FAULT 0xd // Load page fault
#define CAUSE_STORE_PAGE_FAULT 0xf // Store/AMO page fault
// irqs (interrupts). added @lab1_3
#define CAUSE_MTIMER 0x8000000000000007
#define CAUSE_MTIMER_S_TRAP 0x8000000000000001
//Supervisor interrupt-pending register
#define SIP_SSIP (1L << 1)
// core local interruptor (CLINT), which contains the timer.
#define CLINT 0x2000000L
#define CLINT_MTIMECMP(hartid) (CLINT + 0x4000 + 8 * (hartid))
#define CLINT_MTIME (CLINT + 0xBFF8) // cycles since boot.
// fields of sstatus, the Supervisor mode Status register
#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable

@ -26,6 +26,21 @@ static void handle_syscall(trapframe *tf) {
}
//
// global variable that store the recorded "ticks". added @lab1_3
static uint64 g_ticks = 0;
//
// added @lab1_3
//
void handle_mtimer_trap() {
sprint("Ticks %d\n", g_ticks);
// TODO (lab1_3): increase g_ticks to record this "tick", and then clear the "SIP"
// field in sip register.
// hint: use write_csr to disable the SIP_SSIP bit in sip.
panic( "lab1_3: increase g_ticks by one, and clear SIP field in sip register.\n" );
}
//
// kernel/smode_trap.S will pass control to smode_trap_handler, when a trap happens
// in S-mode.
@ -41,8 +56,13 @@ void smode_trap_handler(void) {
// if the cause of trap is syscall from user application.
// read_csr() and CAUSE_USER_ECALL are macros defined in kernel/riscv.h
if (read_csr(scause) == CAUSE_USER_ECALL) {
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));

@ -1,15 +0,0 @@
/*
* Below is the given application for lab1_2.
* This app attempts to issue M-mode instruction in U-mode, and consequently raises an exception.
*/
#include "user_lib.h"
#include "util/types.h"
int main(void) {
printu("Going to hack the system by running privilege instructions.\n");
// we are now in U(user)-mode, but the "csrw" instruction requires M-mode privilege.
// Attempting to execute such instruction will raise illegal instruction exception.
asm volatile("csrw sscratch, 0");
exit(0);
}

@ -0,0 +1,20 @@
/*
* Below is the given application for lab1_3.
* This app performs a long loop, during which, timers are
* generated and pop messages to our screen.
*/
#include "user_lib.h"
#include "util/types.h"
int main(void) {
printu("Hello world!\n");
int i;
for (i = 0; i < 100000000; ++i) {
if (i % 5000000 == 0) printu("wait %d\n", i);
}
exit(0);
return 0;
}
Loading…
Cancel
Save