adopt github PR98 (No need to store TRAPFRAME in sscratch register)
This commit is contained in:
		
							parent
							
								
									ca6fc54934
								
							
						
					
					
						commit
						9fc9f755e1
					
				
					 3 changed files with 31 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
#ifndef __ASSEMBLER__
 | 
			
		||||
 | 
			
		||||
// which hart (core) is this?
 | 
			
		||||
static inline uint64
 | 
			
		||||
r_mhartid()
 | 
			
		||||
| 
						 | 
				
			
			@ -331,6 +333,10 @@ sfence_vma()
 | 
			
		|||
  asm volatile("sfence.vma zero, zero");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef uint64 pte_t;
 | 
			
		||||
typedef uint64 *pagetable_t; // 512 PTEs
 | 
			
		||||
 | 
			
		||||
#endif // __ASSEMBLER__
 | 
			
		||||
 | 
			
		||||
#define PGSIZE 4096 // bytes per page
 | 
			
		||||
#define PGSHIFT 12  // bits of offset within a page
 | 
			
		||||
| 
						 | 
				
			
			@ -361,6 +367,3 @@ sfence_vma()
 | 
			
		|||
// Sv39, to avoid having to sign-extend virtual addresses
 | 
			
		||||
// that have the high bit set.
 | 
			
		||||
#define MAXVA (1L << (9 + 9 + 9 + 12 - 1))
 | 
			
		||||
 | 
			
		||||
typedef uint64 pte_t;
 | 
			
		||||
typedef uint64 *pagetable_t; // 512 PTEs
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,10 @@
 | 
			
		|||
	# kernel.ld causes this to be aligned
 | 
			
		||||
        # to a page boundary.
 | 
			
		||||
        #
 | 
			
		||||
 | 
			
		||||
#include "riscv.h"
 | 
			
		||||
#include "memlayout.h"
 | 
			
		||||
 | 
			
		||||
	.section trampsec
 | 
			
		||||
.globl trampoline
 | 
			
		||||
trampoline:
 | 
			
		||||
| 
						 | 
				
			
			@ -20,13 +24,15 @@ uservec:
 | 
			
		|||
        # in supervisor mode, but with a
 | 
			
		||||
        # user page table.
 | 
			
		||||
        #
 | 
			
		||||
        # sscratch points to where the process's p->trapframe is
 | 
			
		||||
        # mapped into user space, at TRAPFRAME.
 | 
			
		||||
        #
 | 
			
		||||
 | 
			
		||||
	# swap a0 and sscratch
 | 
			
		||||
        # so that a0 is TRAPFRAME
 | 
			
		||||
        csrrw a0, sscratch, a0
 | 
			
		||||
        # save user a0 in sscratch so
 | 
			
		||||
        # a0 can be used to get at TRAPFRAME.
 | 
			
		||||
        csrw sscratch, a0
 | 
			
		||||
 | 
			
		||||
        # each process has a separate p->trapframe memory area,
 | 
			
		||||
        # but it's mapped to the same virtual address
 | 
			
		||||
        # (TRAPFRAME) in every process.
 | 
			
		||||
        li a0, TRAPFRAME
 | 
			
		||||
        
 | 
			
		||||
        # save the user registers in TRAPFRAME
 | 
			
		||||
        sd ra, 40(a0)
 | 
			
		||||
| 
						 | 
				
			
			@ -86,20 +92,15 @@ uservec:
 | 
			
		|||
 | 
			
		||||
.globl userret
 | 
			
		||||
userret:
 | 
			
		||||
        # userret(TRAPFRAME, pagetable)
 | 
			
		||||
        # userret(pagetable)
 | 
			
		||||
        # switch from kernel to user.
 | 
			
		||||
        # usertrapret() calls here.
 | 
			
		||||
        # a0: TRAPFRAME, in user page table.
 | 
			
		||||
        # a1: user page table, for satp.
 | 
			
		||||
        # a0: user page table, for satp.
 | 
			
		||||
 | 
			
		||||
        # switch to the user page table.
 | 
			
		||||
        csrw satp, a1
 | 
			
		||||
        csrw satp, a0
 | 
			
		||||
        sfence.vma zero, zero
 | 
			
		||||
 | 
			
		||||
        # put the saved user a0 in sscratch, so we
 | 
			
		||||
        # can swap it with our a0 (TRAPFRAME) in the last step.
 | 
			
		||||
        ld t0, 112(a0)
 | 
			
		||||
        csrw sscratch, t0
 | 
			
		||||
        li a0, TRAPFRAME
 | 
			
		||||
 | 
			
		||||
        # restore all but a0 from TRAPFRAME
 | 
			
		||||
        ld ra, 40(a0)
 | 
			
		||||
| 
						 | 
				
			
			@ -133,8 +134,8 @@ userret:
 | 
			
		|||
        ld t5, 272(a0)
 | 
			
		||||
        ld t6, 280(a0)
 | 
			
		||||
 | 
			
		||||
	# restore user a0, and save TRAPFRAME in sscratch
 | 
			
		||||
        csrrw a0, sscratch, a0
 | 
			
		||||
	# restore user a0
 | 
			
		||||
        ld a0, 112(a0)
 | 
			
		||||
        
 | 
			
		||||
        # return to user mode and user pc.
 | 
			
		||||
        # usertrapret() set up sstatus and sepc.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,8 +96,9 @@ usertrapret(void)
 | 
			
		|||
  // we're back in user space, where usertrap() is correct.
 | 
			
		||||
  intr_off();
 | 
			
		||||
 | 
			
		||||
  // send syscalls, interrupts, and exceptions to trampoline.S
 | 
			
		||||
  w_stvec(TRAMPOLINE + (uservec - trampoline));
 | 
			
		||||
  // send syscalls, interrupts, and exceptions to uservec in trampoline.S
 | 
			
		||||
  uint64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline);
 | 
			
		||||
  w_stvec(trampoline_uservec);
 | 
			
		||||
 | 
			
		||||
  // set up trapframe values that uservec will need when
 | 
			
		||||
  // the process next re-enters the kernel.
 | 
			
		||||
| 
						 | 
				
			
			@ -121,11 +122,11 @@ usertrapret(void)
 | 
			
		|||
  // tell trampoline.S the user page table to switch to.
 | 
			
		||||
  uint64 satp = MAKE_SATP(p->pagetable);
 | 
			
		||||
 | 
			
		||||
  // jump to trampoline.S at the top of memory, which 
 | 
			
		||||
  // jump to userret in trampoline.S at the top of memory, which 
 | 
			
		||||
  // switches to the user page table, restores user registers,
 | 
			
		||||
  // and switches to user mode with sret.
 | 
			
		||||
  uint64 fn = TRAMPOLINE + (userret - trampoline);
 | 
			
		||||
  ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp);
 | 
			
		||||
  uint64 trampoline_userret = TRAMPOLINE + (userret - trampoline);
 | 
			
		||||
  ((void (*)(uint64))trampoline_userret)(satp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// interrupts and exceptions from kernel code go here via kernelvec,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue