timer interrupt in the kernel -> yield
This commit is contained in:
parent
c34bd3d167
commit
0498bfd159
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue