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))
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to