slightly better comments
This commit is contained in:
parent
f2ee8690ad
commit
63ef3b8c9f
|
@ -1,18 +1,19 @@
|
||||||
#
|
#
|
||||||
# code to switch between user and kernel space.
|
# low-level code to handle traps from user space into
|
||||||
|
# the kernel, and returns from kernel to user.
|
||||||
#
|
#
|
||||||
# this code is mapped at the same virtual address
|
# the kernel maps the page holding this code
|
||||||
# (TRAMPOLINE) in user and kernel space so that
|
# at the same virtual address (TRAMPOLINE)
|
||||||
# it continues to work when it switches page tables.
|
# in user and kernel space so that it continues
|
||||||
#
|
# to work when it switches page tables.
|
||||||
# kernel.ld causes this to be aligned
|
# kernel.ld causes this code to start at
|
||||||
# to a page boundary.
|
# a page boundary.
|
||||||
#
|
#
|
||||||
|
|
||||||
#include "riscv.h"
|
#include "riscv.h"
|
||||||
#include "memlayout.h"
|
#include "memlayout.h"
|
||||||
|
|
||||||
.section trampsec
|
.section trampsec
|
||||||
.globl trampoline
|
.globl trampoline
|
||||||
trampoline:
|
trampoline:
|
||||||
.align 4
|
.align 4
|
||||||
|
@ -31,7 +32,7 @@ uservec:
|
||||||
|
|
||||||
# each process has a separate p->trapframe memory area,
|
# each process has a separate p->trapframe memory area,
|
||||||
# but it's mapped to the same virtual address
|
# but it's mapped to the same virtual address
|
||||||
# (TRAPFRAME) in every process.
|
# (TRAPFRAME) in every process's user page table.
|
||||||
li a0, TRAPFRAME
|
li a0, TRAPFRAME
|
||||||
|
|
||||||
# save the user registers in TRAPFRAME
|
# save the user registers in TRAPFRAME
|
||||||
|
@ -70,29 +71,27 @@ uservec:
|
||||||
csrr t0, sscratch
|
csrr t0, sscratch
|
||||||
sd t0, 112(a0)
|
sd t0, 112(a0)
|
||||||
|
|
||||||
# restore kernel stack pointer from p->trapframe->kernel_sp
|
# initialize kernel stack pointer, from p->trapframe->kernel_sp
|
||||||
ld sp, 8(a0)
|
ld sp, 8(a0)
|
||||||
|
|
||||||
# make tp hold the current hartid, from p->trapframe->kernel_hartid
|
# make tp hold the current hartid, from p->trapframe->kernel_hartid
|
||||||
ld tp, 32(a0)
|
ld tp, 32(a0)
|
||||||
|
|
||||||
# load the address of usertrap(), p->trapframe->kernel_trap
|
# load the address of usertrap(), from p->trapframe->kernel_trap
|
||||||
ld t0, 16(a0)
|
ld t0, 16(a0)
|
||||||
|
|
||||||
# restore kernel page table from p->trapframe->kernel_satp
|
# load the kernel page table, from p->trapframe->kernel_satp
|
||||||
ld t1, 0(a0)
|
ld t1, 0(a0)
|
||||||
csrw satp, t1
|
csrw satp, t1
|
||||||
sfence.vma zero, zero
|
sfence.vma zero, zero
|
||||||
|
|
||||||
# a0 is no longer valid, since the kernel page
|
|
||||||
# table does not specially map p->tf.
|
|
||||||
|
|
||||||
# jump to usertrap(), which does not return
|
# jump to usertrap(), which does not return
|
||||||
jr t0
|
jr t0
|
||||||
|
|
||||||
.globl userret
|
.globl userret
|
||||||
userret:
|
userret:
|
||||||
# userret(pagetable)
|
# userret(pagetable)
|
||||||
|
# called by usertrapret() in trap.c to
|
||||||
# switch from kernel to user.
|
# switch from kernel to user.
|
||||||
# a0: user page table, for satp.
|
# a0: user page table, for satp.
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ usertrap(void)
|
||||||
// but we want to return to the next instruction.
|
// but we want to return to the next instruction.
|
||||||
p->trapframe->epc += 4;
|
p->trapframe->epc += 4;
|
||||||
|
|
||||||
// an interrupt will change sstatus &c registers,
|
// an interrupt will change sepc, scause, and sstatus,
|
||||||
// so don't enable until done with those registers.
|
// so enable only now that we're done with those registers.
|
||||||
intr_on();
|
intr_on();
|
||||||
|
|
||||||
syscall();
|
syscall();
|
||||||
|
@ -101,7 +101,7 @@ usertrapret(void)
|
||||||
w_stvec(trampoline_uservec);
|
w_stvec(trampoline_uservec);
|
||||||
|
|
||||||
// set up trapframe values that uservec will need when
|
// set up trapframe values that uservec will need when
|
||||||
// the process next re-enters the kernel.
|
// the process next traps into the kernel.
|
||||||
p->trapframe->kernel_satp = r_satp(); // kernel page table
|
p->trapframe->kernel_satp = r_satp(); // kernel page table
|
||||||
p->trapframe->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
|
p->trapframe->kernel_sp = p->kstack + PGSIZE; // process's kernel stack
|
||||||
p->trapframe->kernel_trap = (uint64)usertrap;
|
p->trapframe->kernel_trap = (uint64)usertrap;
|
||||||
|
|
Loading…
Reference in a new issue