summaryrefslogtreecommitdiff
path: root/kernel/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trap.c')
-rw-r--r--kernel/trap.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/kernel/trap.c b/kernel/trap.c
index ca732f2..a63249e 100644
--- a/kernel/trap.c
+++ b/kernel/trap.c
@@ -48,7 +48,7 @@ usertrap(void)
struct proc *p = myproc();
// save user program counter.
- p->tf->epc = r_sepc();
+ p->trapframe->epc = r_sepc();
if(r_scause() == 8){
// system call
@@ -58,7 +58,7 @@ usertrap(void)
// sepc points to the ecall instruction,
// but we want to return to the next instruction.
- p->tf->epc += 4;
+ p->trapframe->epc += 4;
// an interrupt will change sstatus &c registers,
// so don't enable until done with those registers.
@@ -91,8 +91,9 @@ usertrapret(void)
{
struct proc *p = myproc();
- // turn off interrupts, since we're switching
- // now from kerneltrap() to usertrap().
+ // we're about to switch the destination of traps from
+ // kerneltrap() to usertrap(), so turn off interrupts until
+ // we're back in user space, where usertrap() is correct.
intr_off();
// send syscalls, interrupts, and exceptions to trampoline.S
@@ -100,10 +101,10 @@ usertrapret(void)
// set up trapframe values that uservec will need when
// the process next re-enters the kernel.
- p->tf->kernel_satp = r_satp(); // kernel page table
- p->tf->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
- p->tf->kernel_trap = (uint64)usertrap;
- p->tf->kernel_hartid = r_tp(); // hartid for cpuid()
+ p->trapframe->kernel_satp = r_satp(); // kernel page table
+ p->trapframe->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
+ p->trapframe->kernel_trap = (uint64)usertrap;
+ p->trapframe->kernel_hartid = r_tp(); // hartid for cpuid()
// set up the registers that trampoline.S's sret will use
// to get to user space.
@@ -115,7 +116,7 @@ usertrapret(void)
w_sstatus(x);
// set S Exception Program Counter to the saved user pc.
- w_sepc(p->tf->epc);
+ w_sepc(p->trapframe->epc);
// tell trampoline.S the user page table to switch to.
uint64 satp = MAKE_SATP(p->pagetable);
@@ -129,7 +130,6 @@ usertrapret(void)
// 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()
{
@@ -189,9 +189,16 @@ devintr()
uartintr();
} else if(irq == VIRTIO0_IRQ){
virtio_disk_intr();
+ } else if(irq){
+ printf("unexpected interrupt irq=%d\n", irq);
}
- plic_complete(irq);
+ // the PLIC allows each device to raise at most one
+ // interrupt at a time; tell the PLIC the device is
+ // now allowed to interrupt again.
+ if(irq)
+ plic_complete(irq);
+
return 1;
} else if(scause == 0x8000000000000001L){
// software interrupt from a machine-mode timer interrupt,