Trap from Kernel Space Sequence
sequenceDiagram autonumber actor K as Kernel code participant CPU as RISC-V hardware / CSRs participant KV as kernelvec<br/>(kernelvec.S) participant KT as kerneltrap()<br/>(trap.c) participant DI as devintr()<br/>(trap.c) participant B as device / timer backend participant P as panic / yield Note over K,CPU: Mode = S<br/>satp = kernel page table<br/>stvec = kernelvec K->>CPU: device interrupt / timer interrupt / kernel exception CPU->>CPU: save trap state<br/>sepc = interrupted kernel PC<br/>scause = cause<br/>stval = fault address if any CPU->>CPU: stay in supervisor mode CPU->>KV: set PC = stvec<br/>enter kernelvec Note over KV: Mode = S<br/>satp already = kernel page table<br/>sp already = current kernel stack KV->>KV: make stack frame on current kernel stack KV->>KV: save caller-saved registers<br/>ra gp tp t0-t2 a0-a7 t3-t6 KV->>KT: call kerneltrap() Note over KT: kerneltrap runs on interrupted kernel stack KT->>CPU: read sepc KT->>CPU: read sstatus KT->>CPU: read scause KT->>KT: check SPP == supervisor alt trap did not come from supervisor mode KT->>P: panic("kerneltrap: not from supervisor mode") else came from supervisor mode KT->>KT: continue end KT->>KT: check interrupts are disabled alt interrupts are enabled KT->>P: panic("kerneltrap: interrupts enabled") else interrupts disabled KT->>DI: devintr() end alt supervisor external interrupt DI->>B: plic_claim() alt UART interrupt B->>B: uartintr() else virtio disk interrupt B->>B: virtio_disk_intr() else unknown external irq B->>B: print unexpected irq end B->>B: plic_complete(irq) DI-->>KT: return 1 KT->>KT: ordinary device interrupt<br/>no yield required else timer interrupt DI->>B: clockintr() B->>B: ticks++ on CPU 0<br/>wakeup(&ticks)<br/>set next stimecmp DI-->>KT: return 2 alt myproc() != 0 KT->>P: yield() P-->>KT: later resumes inside kerneltrap() else no current process KT->>KT: do not yield end else not a recognized interrupt DI-->>KT: return 0 KT->>KT: print scause, sepc, stval KT->>P: panic("kerneltrap") end KT->>CPU: restore sepc KT->>CPU: restore sstatus KT-->>KV: return to kernelvec KV->>KV: restore caller-saved registers<br/>tp is not restored KV->>KV: pop stack frame KV->>CPU: sret CPU->>K: resume interrupted kernel code Note over K,CPU: Mode = S<br/>satp = kernel page table