diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-07-26 09:38:22 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2019-07-26 09:38:22 -0400 | 
| commit | fa2e2e3c81b2686229acc204ece380953a8031ea (patch) | |
| tree | 67c055fc880e8d286124814fff649c170434ea3e | |
| parent | 8d30e21b59d2f6d48e593cd6c2399d0743971155 (diff) | |
| download | xv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.tar.gz xv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.tar.bz2 xv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.zip | |
uservec before userret in trampoline, to match book and kernelvec
| -rw-r--r-- | kernel/kernelvec.S | 5 | ||||
| -rw-r--r-- | kernel/trampoline.S | 122 | ||||
| -rw-r--r-- | kernel/trap.c | 5 | 
3 files changed, 69 insertions, 63 deletions
| diff --git a/kernel/kernelvec.S b/kernel/kernelvec.S index 9aabe96..222b172 100644 --- a/kernel/kernelvec.S +++ b/kernel/kernelvec.S @@ -8,8 +8,10 @@  .globl kernelvec  .align 4  kernelvec: +        // make room to save registers.          addi sp, sp, -256 +        // save the registers.          sd ra, 0(sp)          sd sp, 8(sp)          sd gp, 16(sp) @@ -42,8 +44,10 @@ kernelvec:          sd t5, 232(sp)          sd t6, 240(sp) +	// call the C trap handler in trap.c          call kerneltrap +        // restore registers.          ld ra, 0(sp)          ld sp, 8(sp)          ld gp, 16(sp) @@ -78,6 +82,7 @@ kernelvec:          addi sp, sp, 256 +        // return to whatever we were doing in the kernel.          sret          # diff --git a/kernel/trampoline.S b/kernel/trampoline.S index bc31974..6e436d2 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -2,77 +2,21 @@          # code to switch between user and kernel space.          #          # this code is mapped at the same virtual address -        # in user and kernel space so that it continues -        # to work when it switches page tables. +        # (TRAMPOLINE) in user and kernel space so that +        # it continues to work when it switches page tables.  	# -	# kernel.ld causes userret to be aligned +	# kernel.ld causes this to be aligned          # to a page boundary.          #  	.section trampsec  .globl trampoline  trampoline: -.globl userret -userret: -        # userret(trapframe, pagetable) -        # switch from kernel to user. -        # usertrapret() calls here. -	# a0: p->tf in user page table -        # a1: new value for satp, for user page table - -	# switch to the user page table. -	sfence.vma zero, zero -        csrw satp, a1 - -        # put the saved user a0 in sscratch, so we -        # can swap it with our a0 (p->tf) in the last step. -        ld t0, 112(a0) -        csrw sscratch, t0 - -        # restore all but a0 from p->tf -        ld ra, 40(a0) -        ld sp, 48(a0) -        ld gp, 56(a0) -        ld tp, 64(a0) -        ld t0, 72(a0) -        ld t1, 80(a0) -        ld t2, 88(a0) -        ld s0, 96(a0) -        ld s1, 104(a0) -        ld a1, 120(a0) -        ld a2, 128(a0) -        ld a3, 136(a0) -        ld a4, 144(a0) -        ld a5, 152(a0) -        ld a6, 160(a0) -        ld a7, 168(a0) -        ld s2, 176(a0) -        ld s3, 184(a0) -        ld s4, 192(a0) -        ld s5, 200(a0) -        ld s6, 208(a0) -        ld s7, 216(a0) -        ld s8, 224(a0) -        ld s9, 232(a0) -        ld s10, 240(a0) -        ld s11, 248(a0) -        ld t3, 256(a0) -        ld t4, 264(a0) -        ld t5, 272(a0) -        ld t6, 280(a0) - -	# restore user a0, and save p->tf in sscratch -        csrrw a0, sscratch, a0 -         -        # return to user mode and user pc. -        # usertrapret() set up sstatus and sepc. -        sret -  .align 4  .globl uservec  uservec:      	# -        # trap.c set stvec to point here, so -        # user interrupts and exceptions start here, +        # trap.c sets stvec to point here, so +        # traps from user space start here,          # in supervisor mode, but with a          # user page table.          # @@ -139,3 +83,59 @@ uservec:          # jump to usertrap(), which does not return          jr t0 + +.globl userret +userret: +        # userret(trapframe, pagetable) +        # switch from kernel to user. +        # usertrapret() calls here. +	# a0: p->tf in user page table +        # a1: new value for satp, for user page table + +	# switch to the user page table. +	sfence.vma zero, zero +        csrw satp, a1 + +        # put the saved user a0 in sscratch, so we +        # can swap it with our a0 (p->tf) in the last step. +        ld t0, 112(a0) +        csrw sscratch, t0 + +        # restore all but a0 from p->tf +        ld ra, 40(a0) +        ld sp, 48(a0) +        ld gp, 56(a0) +        ld tp, 64(a0) +        ld t0, 72(a0) +        ld t1, 80(a0) +        ld t2, 88(a0) +        ld s0, 96(a0) +        ld s1, 104(a0) +        ld a1, 120(a0) +        ld a2, 128(a0) +        ld a3, 136(a0) +        ld a4, 144(a0) +        ld a5, 152(a0) +        ld a6, 160(a0) +        ld a7, 168(a0) +        ld s2, 176(a0) +        ld s3, 184(a0) +        ld s4, 192(a0) +        ld s5, 200(a0) +        ld s6, 208(a0) +        ld s7, 216(a0) +        ld s8, 224(a0) +        ld s9, 232(a0) +        ld s10, 240(a0) +        ld s11, 248(a0) +        ld t3, 256(a0) +        ld t4, 264(a0) +        ld t5, 272(a0) +        ld t6, 280(a0) + +	# restore user a0, and save p->tf in sscratch +        csrrw a0, sscratch, a0 +         +        # return to user mode and user pc. +        # usertrapret() set up sstatus and sepc. +        sret diff --git a/kernel/trap.c b/kernel/trap.c index ad2d0f8..ce7a65a 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -9,7 +9,7 @@  struct spinlock tickslock;  uint ticks; -extern char trampoline[], uservec[]; +extern char trampoline[], uservec[], userret[];  // in kernelvec.S, calls kerneltrap().  void kernelvec(); @@ -123,7 +123,8 @@ usertrapret(void)    // jump to trampoline.S at the top of memory, which     // switches to the user page table, restores user registers,    // and switches to user mode with sret. -  ((void (*)(uint64,uint64))TRAMPOLINE)(TRAPFRAME, satp); +  uint64 fn = TRAMPOLINE + (userret - trampoline); +  ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp);  }  // interrupts and exceptions from kernel code go here via kernelvec, | 
