Date: Mon, 8 Jan 2018 10:23:31 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r327690 - in head/sys/arm64: arm64 include Message-ID: <201801081023.w08ANVNi097681@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201801081023.w08ANVNi097681>