Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Feb 2016 12:49:28 +0000 (UTC)
From:      Ruslan Bukin <br@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r295253 - in head/sys/riscv: include riscv
Message-ID:  <201602041249.u14CnS8m071697@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: br
Date: Thu Feb  4 12:49:28 2016
New Revision: 295253
URL: https://svnweb.freebsd.org/changeset/base/295253

Log:
  Reuse gp register for pcpu pointer.
  
  gp (global pointer) is used by compiler in userland only,
  so re-use it for pcpup in kernel, save it on stack on switching
  out to userland and load back on return to kernel.
  
  Discussed with:	jhb, andrew, kib
  Sponsored by:	DARPA, AFRL
  Sponsored by:	HEIF5
  Differential Revision:	https://reviews.freebsd.org/D5178

Modified:
  head/sys/riscv/include/pcpu.h
  head/sys/riscv/riscv/exception.S
  head/sys/riscv/riscv/genassym.c
  head/sys/riscv/riscv/machdep.c
  head/sys/riscv/riscv/swtch.S
  head/sys/riscv/riscv/vm_machdep.c

Modified: head/sys/riscv/include/pcpu.h
==============================================================================
--- head/sys/riscv/include/pcpu.h	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/include/pcpu.h	Thu Feb  4 12:49:28 2016	(r295253)
@@ -47,8 +47,11 @@ extern struct pcpu *pcpup;
 static inline struct pcpu *
 get_pcpu(void)
 {
+	struct pcpu *pcpu;
 
-	return (pcpup);
+	__asm __volatile("mv %0, gp" : "=&r"(pcpu));
+
+	return (pcpu);
 }
 
 static inline struct thread *
@@ -56,7 +59,7 @@ get_curthread(void)
 {
 	struct thread *td;
 
-	td = (struct thread *)*(uint64_t *)pcpup;
+	__asm __volatile("ld %0, 0(gp)" : "=&r"(td));
 
 	return (td);
 }

Modified: head/sys/riscv/riscv/exception.S
==============================================================================
--- head/sys/riscv/riscv/exception.S	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/riscv/exception.S	Thu Feb  4 12:49:28 2016	(r295253)
@@ -41,12 +41,16 @@ __FBSDID("$FreeBSD$");
 #include <machine/riscvreg.h>
 
 .macro save_registers el
-	addi	sp, sp, -280
+	addi	sp, sp, -(TF_SIZE)
 
 	sd	ra, (TF_RA)(sp)
-	sd	gp, (TF_GP)(sp)
 	sd	tp, (TF_TP)(sp)
 
+.if \el == 0	/* We came from userspace. Load our pcpu */
+	sd	gp, (TF_GP)(sp)
+	ld	gp, (TF_SIZE)(sp)
+.endif
+
 	sd	t0, (TF_T + 0 * 8)(sp)
 	sd	t1, (TF_T + 1 * 8)(sp)
 	sd	t2, (TF_T + 2 * 8)(sp)
@@ -127,13 +131,16 @@ __FBSDID("$FreeBSD$");
 	csrw	sepc, t0
 
 .if \el == 0
-	/* Load user sp */
+	/* We go to userspace. Load user sp */
 	ld	t0, (TF_SP)(sp)
 	csrw	sscratch, t0
+
+	/* And store our pcpu */
+	sd	gp, (TF_SIZE)(sp)
+	ld	gp, (TF_GP)(sp)
 .endif
 
 	ld	ra, (TF_RA)(sp)
-	ld	gp, (TF_GP)(sp)
 	ld	tp, (TF_TP)(sp)
 
 	ld	t0, (TF_T + 0 * 8)(sp)
@@ -166,7 +173,7 @@ __FBSDID("$FreeBSD$");
 	ld	a6, (TF_A + 6 * 8)(sp)
 	ld	a7, (TF_A + 7 * 8)(sp)
 
-	addi	sp, sp, 280
+	addi	sp, sp, (TF_SIZE)
 .endm
 
 .macro	do_ast

Modified: head/sys/riscv/riscv/genassym.c
==============================================================================
--- head/sys/riscv/riscv/genassym.c	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/riscv/genassym.c	Thu Feb  4 12:49:28 2016	(r295253)
@@ -85,6 +85,7 @@ ASSYM(TD_FRAME, offsetof(struct thread, 
 ASSYM(TD_MD, offsetof(struct thread, td_md));
 ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
 
+ASSYM(TF_SIZE, sizeof(struct trapframe));
 ASSYM(TF_RA, offsetof(struct trapframe, tf_ra));
 ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
 ASSYM(TF_GP, offsetof(struct trapframe, tf_gp));

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/riscv/machdep.c	Thu Feb  4 12:49:28 2016	(r295253)
@@ -256,7 +256,9 @@ ptrace_clear_single_step(struct thread *
 void
 exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
 {
-	struct trapframe *tf = td->td_frame;
+	struct trapframe *tf;
+
+	tf = td->td_frame;
 
 	memset(tf, 0, sizeof(struct trapframe));
 
@@ -563,6 +565,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, 
 static void
 init_proc0(vm_offset_t kstack)
 {
+
 	pcpup = &__pcpu[0];
 
 	proc_linkup0(&proc0, &thread0);
@@ -760,11 +763,7 @@ initriscv(struct riscv_bootparams *rvbp)
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 
 	/* Set the pcpu pointer */
-#if 0
-	/* SMP TODO: try re-use gp for pcpu pointer */
-	__asm __volatile(
-	    "mv gp, %0" :: "r"(pcpup));
-#endif
+	__asm __volatile("mv gp, %0" :: "r"(pcpup));
 
 	PCPU_SET(curthread, &thread0);
 

Modified: head/sys/riscv/riscv/swtch.S
==============================================================================
--- head/sys/riscv/riscv/swtch.S	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/riscv/swtch.S	Thu Feb  4 12:49:28 2016	(r295253)
@@ -74,8 +74,6 @@ ENTRY(cpu_throw)
 	/* Load registers */
 	ld	ra, (PCB_RA)(x13)
 	ld	sp, (PCB_SP)(x13)
-	ld	gp, (PCB_GP)(x13)
-	ld	tp, (PCB_TP)(x13)
 
 	/* s[0-11] */
 	ld	s0, (PCB_S + 0 * 8)(x13)
@@ -120,8 +118,6 @@ ENTRY(cpu_switch)
 	/* Store the callee-saved registers */
 	sd	ra, (PCB_RA)(x13)
 	sd	sp, (PCB_SP)(x13)
-	sd	gp, (PCB_GP)(x13)
-	sd	tp, (PCB_TP)(x13)
 
 	/* We use these in fork_trampoline */
 	sd	t0, (PCB_T + 0 * 8)(x13)
@@ -176,8 +172,6 @@ ENTRY(cpu_switch)
 	/* Restore the registers */
 	ld	ra, (PCB_RA)(x13)
 	ld	sp, (PCB_SP)(x13)
-	ld	gp, (PCB_GP)(x13)
-	ld	tp, (PCB_TP)(x13)
 
 	/* We use these in fork_trampoline */
 	ld	t0, (PCB_T + 0 * 8)(x13)
@@ -254,12 +248,23 @@ ENTRY(fork_trampoline)
 	ld	a6, (TF_A + 6 * 8)(sp)
 	ld	a7, (TF_A + 7 * 8)(sp)
 
+	/* Load user ra and sp */
+	ld	tp, (TF_TP)(sp)
+	ld	ra, (TF_RA)(sp)
+
+	/*
+	 * Store our pcpup on stack, we will load it back
+	 * on kernel mode trap.
+	 */
+	sd	gp, (TF_SIZE)(sp)
+	ld	gp, (TF_GP)(sp)
+
 	/* Save kernel stack so we can use it doing a user trap */
+	addi	sp, sp, TF_SIZE
 	csrw	sscratch, sp
 
-	/* Load user ra and sp */
-	ld	ra, (TF_RA)(sp)
-	ld	sp, (TF_SP)(sp)
+	/* Load user stack */
+	ld	sp, (TF_SP - TF_SIZE)(sp)
 
 	eret
 END(fork_trampoline)

Modified: head/sys/riscv/riscv/vm_machdep.c
==============================================================================
--- head/sys/riscv/riscv/vm_machdep.c	Thu Feb  4 12:11:18 2016	(r295252)
+++ head/sys/riscv/riscv/vm_machdep.c	Thu Feb  4 12:49:28 2016	(r295253)
@@ -218,7 +218,7 @@ cpu_thread_alloc(struct thread *td)
 	td->td_pcb = (struct pcb *)(td->td_kstack +
 	    td->td_kstack_pages * PAGE_SIZE) - 1;
 	td->td_frame = (struct trapframe *)STACKALIGN(
-	    td->td_pcb - 1);
+	    (caddr_t)td->td_pcb - 8 - sizeof(struct trapframe));
 }
 
 void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602041249.u14CnS8m071697>