From 0498bfd15937d64599b8c63948907a8b60e5d6ae Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Mon, 1 Jul 2019 13:46:11 -0400 Subject: [PATCH] timer interrupt in the kernel -> yield --- kernel/kernelvec.S | 2 +- kernel/trap.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/kernel/kernelvec.S b/kernel/kernelvec.S index 4f52688..e9b0ced 100644 --- a/kernel/kernelvec.S +++ b/kernel/kernelvec.S @@ -47,7 +47,7 @@ kernelvec: ld ra, 0(sp) ld sp, 8(sp) ld gp, 16(sp) - ld tp, 24(sp) + // not this, in case we moved CPUs: ld tp, 24(sp) ld t0, 32(sp) ld t1, 40(sp) ld t2, 48(sp) diff --git a/kernel/trap.c b/kernel/trap.c index 586f123..06fc4b3 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -121,12 +121,14 @@ usertrapret(void) ((void (*)(uint64,uint64))TRAMPOLINE)(TRAMPOLINE - PGSIZE, satp); } -// interrupts and exceptions from kernel code go here, +// interrupts and exceptions from kernel code go here via kernelvec, // on whatever the current kernel stack is. // must be 4-byte aligned to fit in stvec. void kerneltrap() { + int which_dev = 0; + uint64 sepc = r_sepc(); uint64 sstatus = r_sstatus(); uint64 scause = r_scause(); @@ -135,11 +137,20 @@ kerneltrap() if(intr_get() != 0) panic("kerneltrap: interrupts enabled"); - if(devintr() == 0){ - printf("scause 0x%p\n", scause); + if((which_dev = devintr()) == 0){ + printf("scause %p\n", scause); printf("sepc=%p stval=%p\n", r_sepc(), r_stval()); panic("kerneltrap"); } + + // give up the CPU if this is a timer interrupt. + if(which_dev == 2 && myproc() != 0 && myproc()->state == RUNNING) + yield(); + + // the yield() may have caused some traps to occur, + // so restore trap registers for use by kernelvec.S's sepc instruction. + w_sepc(sepc); + w_sstatus(sstatus); } // check if it's an external interrupt or software interrupt,