svn commit: r327690 - in head/sys/arm64: arm64 include

Andrew Turner andrew at FreeBSD.org
Mon Jan 8 10:23:32 UTC 2018


Author: andrew
Date: Mon Jan  8 10:23:31 2018
New Revision: 327690
URL: https://svnweb.freebsd.org/changeset/base/327690

Log:
  Move some of the common thread switching code into C. This will help with
  future optimisations, e.g. using Address Space IDs (asid).
  
  MFC after:	1 week
  Sponsored by:	DARPA, AFRL

Modified:
  head/sys/arm64/arm64/pmap.c
  head/sys/arm64/arm64/swtch.S
  head/sys/arm64/include/pmap.h

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c	Mon Jan  8 09:20:08 2018	(r327689)
+++ head/sys/arm64/arm64/pmap.c	Mon Jan  8 10:23:31 2018	(r327690)
@@ -4660,6 +4660,38 @@ pmap_activate(struct thread *td)
 	critical_exit();
 }
 
+struct pcb *
+pmap_switch(struct thread *old, struct thread *new)
+{
+	struct pcb *pcb;
+
+	/* Store the new curthread */
+	PCPU_SET(curthread, new);
+
+	/* And the new pcb */
+	pcb = new->td_pcb;
+	PCPU_SET(curpcb, pcb);
+
+	/*
+	 * TODO: We may need to flush the cache here if switching
+	 * to a user process.
+	 */
+
+	__asm __volatile(
+	    /* Switch to the new pmap */
+	    "msr	ttbr0_el1, %0	\n"
+	    "isb			\n"
+
+	    /* Invalidate the TLB */
+	    "dsb	ishst		\n"
+	    "tlbi	vmalle1is	\n"
+	    "dsb	ish		\n"
+	    "isb			\n"
+	    : : "r"(new->td_proc->p_md.md_l0addr));
+
+	return (pcb);
+}
+
 void
 pmap_sync_icache(pmap_t pmap, vm_offset_t va, vm_size_t sz)
 {

Modified: head/sys/arm64/arm64/swtch.S
==============================================================================
--- head/sys/arm64/arm64/swtch.S	Mon Jan  8 09:20:08 2018	(r327689)
+++ head/sys/arm64/arm64/swtch.S	Mon Jan  8 10:23:31 2018	(r327690)
@@ -70,33 +70,16 @@ ENTRY(cpu_throw)
 
 #ifdef VFP
 	/* Backup the new thread pointer around a call to C code */
-	mov	x19, x1
+	mov	x19, x0
+	mov	x20, x1
 	bl	vfp_discard
-	mov	x1, x19
+	mov	x1, x20
+	mov	x0, x19
 #endif
 
-	/* Store the new curthread */
-	str	x1, [x18, #PC_CURTHREAD]
-	/* And the new pcb */
-	ldr	x4, [x1, #TD_PCB]
-	str	x4, [x18, #PC_CURPCB]
+	bl	pmap_switch
+	mov	x4, x0
 
-	/*
-	 * TODO: We may need to flush the cache here.
-	 */
-
-	/* Switch to the new pmap */
-	ldr	x28, [x1, #TD_PROC]
-	ldr	x5, [x28, #(P_MD + MD_L0ADDR)]
-	msr	ttbr0_el1, x5
-	isb
-
-	/* Invalidate the TLB */
-	dsb	ishst
-	tlbi	vmalle1
-	dsb	ish
-	isb
-
 	/* If we are single stepping, enable it */
 	ldr	w5, [x4, #PCB_FLAGS]
 	set_step_flag w5, x6
@@ -161,45 +144,25 @@ ENTRY(cpu_switch)
 	ldr	w5, [x4, #PCB_FLAGS]
 	clear_step_flag w5, x6
 
-#ifdef VFP
 	mov	x19, x0
 	mov	x20, x1
 	mov	x21, x2
+
+#ifdef VFP
 	/* Load the pcb address */
 	mov	x1, x4
 	bl	vfp_save_state
-	mov	x2, x21
 	mov	x1, x20
 	mov	x0, x19
 #endif
 
-	/* Store the new curthread */
-	str	x1, [x18, #PC_CURTHREAD]
+	bl	pmap_switch
+	/* Move the new pcb out of the way */
+	mov	x4, x0
 
-	/*
-	 * Restore the saved context and set it as curpcb.
-	 */
-	ldr	x4, [x1, #TD_PCB]
-	str	x4, [x18, #PC_CURPCB]
-
-	/*
-	 * TODO: We may need to flush the cache here if switching
-	 * to a user process.
-	 */
-
-	/* Load the new proc address */
-	ldr	x28, [x1, #TD_PROC]
-
-	/* Switch to the new pmap */
-	ldr	x5, [x28, #(P_MD + MD_L0ADDR)]
-	msr	ttbr0_el1, x5
-	isb
-
-	/* Invalidate the TLB */
-	dsb	ishst
-	tlbi	vmalle1
-	dsb	ish
-	isb
+	mov	x2, x21
+	mov	x1, x20
+	mov	x0, x19
 
 	/*
 	 * Release the old thread. This doesn't need to be a store-release

Modified: head/sys/arm64/include/pmap.h
==============================================================================
--- head/sys/arm64/include/pmap.h	Mon Jan  8 09:20:08 2018	(r327689)
+++ head/sys/arm64/include/pmap.h	Mon Jan  8 10:23:31 2018	(r327690)
@@ -106,6 +106,8 @@ struct pv_chunk {
 
 typedef struct pmap *pmap_t;
 
+struct thread;
+
 #ifdef _KERNEL
 extern struct pmap	kernel_pmap_store;
 #define	kernel_pmap	(&kernel_pmap_store)
@@ -155,6 +157,8 @@ bool	pmap_get_tables(pmap_t, vm_offset_t, pd_entry_t *
     pd_entry_t **, pt_entry_t **);
 
 int	pmap_fault(pmap_t, uint64_t, uint64_t);
+
+struct pcb *pmap_switch(struct thread *, struct thread *);
 
 #define	pmap_page_is_mapped(m)	(!TAILQ_EMPTY(&(m)->md.pv_list))
 


More information about the svn-src-head mailing list