diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-07-01 13:46:11 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2019-07-01 13:46:11 -0400 | 
| commit | 0498bfd15937d64599b8c63948907a8b60e5d6ae (patch) | |
| tree | f65d35cd340235216dbd9628184ef3d9547685b5 | |
| parent | c34bd3d1671f1f6e1b50614c22fbd0c83f504959 (diff) | |
| download | xv6-labs-0498bfd15937d64599b8c63948907a8b60e5d6ae.tar.gz xv6-labs-0498bfd15937d64599b8c63948907a8b60e5d6ae.tar.bz2 xv6-labs-0498bfd15937d64599b8c63948907a8b60e5d6ae.zip | |
timer interrupt in the kernel -> yield
| -rw-r--r-- | kernel/kernelvec.S | 2 | ||||
| -rw-r--r-- | 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, | 
