timer interrupt in the kernel -> yield

This commit is contained in:
Robert Morris 2019-07-01 13:46:11 -04:00
parent c34bd3d167
commit 0498bfd159
2 changed files with 15 additions and 4 deletions

View file

@ -47,7 +47,7 @@ kernelvec:
ld ra, 0(sp) ld ra, 0(sp)
ld sp, 8(sp) ld sp, 8(sp)
ld gp, 16(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 t0, 32(sp)
ld t1, 40(sp) ld t1, 40(sp)
ld t2, 48(sp) ld t2, 48(sp)

View file

@ -121,12 +121,14 @@ usertrapret(void)
((void (*)(uint64,uint64))TRAMPOLINE)(TRAMPOLINE - PGSIZE, satp); ((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. // on whatever the current kernel stack is.
// must be 4-byte aligned to fit in stvec. // must be 4-byte aligned to fit in stvec.
void void
kerneltrap() kerneltrap()
{ {
int which_dev = 0;
uint64 sepc = r_sepc();
uint64 sstatus = r_sstatus(); uint64 sstatus = r_sstatus();
uint64 scause = r_scause(); uint64 scause = r_scause();
@ -135,11 +137,20 @@ kerneltrap()
if(intr_get() != 0) if(intr_get() != 0)
panic("kerneltrap: interrupts enabled"); panic("kerneltrap: interrupts enabled");
if(devintr() == 0){ if((which_dev = devintr()) == 0){
printf("scause 0x%p\n", scause); printf("scause %p\n", scause);
printf("sepc=%p stval=%p\n", r_sepc(), r_stval()); printf("sepc=%p stval=%p\n", r_sepc(), r_stval());
panic("kerneltrap"); 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, // check if it's an external interrupt or software interrupt,