Hi,

would anyone care to look at diffs aiming to make diffs like below possible
for armv7 too? doesn't take 'much' fixing beyond removing cruft, and can
be done mostly w/o touching the files/headers shared with armish/zaurus, if
wanted.

-Artturi


 sys/arch/arm/arm/cpuswitch7.S | 224 +++++++-----------------------------------
 1 file changed, 38 insertions(+), 186 deletions(-)

diff --git a/sys/arch/arm/arm/cpuswitch7.S b/sys/arch/arm/arm/cpuswitch7.S
index 43bf7da..a5cc631 100644
--- a/sys/arch/arm/arm/cpuswitch7.S
+++ b/sys/arch/arm/arm/cpuswitch7.S
@@ -83,6 +83,7 @@
 #include <machine/frame.h>
 #include <machine/intr.h>
 #include <machine/asm.h>
+#include <machine/sysreg.h>
 
 /* LINTSTUB: include <sys/param.h> */
        
@@ -157,27 +158,25 @@ ENTRY(cpu_idle_leave)
  */
 
 ENTRY(cpu_switchto)
-       stmfd   sp!, {r4-r7, lr}
+       push    {r4-r7, lr}
+       sub     sp, sp, #4
 
-       /* Get curcpu from TPIDRPRW. */
-       mrc     p15, 0, r3, c13, c0, 4
+       /* Process is now on a processor. */
+       mov     r2, #SONPROC                    /* p->p_stat = SONPROC */
+       strb    r2, [r1, #P_STAT]
+
+       mrc     CP15_TPIDRPRW(r3)               /* r3 = curcpu */
 #ifdef MULTIPROCESSOR
-       str     r3, [r1, #(P_CPU)]
+       str     r3, [r1, #P_CPU]
 #else
        /* p->p_cpu initialized in fork1() for single-processor */
 #endif
-
-       /* Process is now on a processor. */
-       mov     r2, #SONPROC                    /* p->p_stat = SONPROC */
-       strb    r2, [r1, #(P_STAT)]
-
-       /* We have a new curproc now so make a note it */
-       str     r1, [r3, #(CI_CURPROC)]
+       str     r1, [r3, #CI_CURPROC]           /* set new curproc */
+       ldr     r6, [r3, #CI_CURPCB]            /* r6 = old PCB */
 
        /* Hook in a new pcb */
-       ldr     r6, [r3, #(CI_CURPCB)]          /* Remember the old PCB */
-       ldr     r2, [r1, #(P_ADDR)]
-       str     r2, [r3, #(CI_CURPCB)]
+       ldr     r2, [r1, #P_ADDR]               /* r2 = new PCB */
+       str     r2, [r3, #CI_CURPCB]
 
        /*
         * If the old proc on entry to cpu_switch was zero then the
@@ -186,192 +185,45 @@ ENTRY(cpu_switchto)
         * to clear the cache and TLB).
         */
        teq     r0, #0x00000000
-       beq     .Lswitch_exited
-
-       /* Stage two: Save old context */
-
-       /* Save all the registers in the old proc's pcb */
-       add     r7, r6, #(PCB_R8)
-       stmia   r7, {r8-r13}
-
-.Lswitch_exited:
-       /*
-        * NOTE: We can now use r8-r13 until it is time to restore
-        * them for the new process.
-        */
-
-       /* Remember the old PCB. */
-       mov     r8, r6
-
-       /* Save new proc in r6 now. */
-       mov     r6, r1
-
-       /* Get the user structure for the new process in r9 */
-       ldr     r9, [r6, #(P_ADDR)]
-
-       /*
-        * This can be optimised... We know we want to go from SVC32
-        * mode to UND32 mode
-        */
-        mrs    r3, cpsr
-       bic     r2, r3, #(PSR_MODE)
-       orr     r2, r2, #(PSR_UND32_MODE | PSR_I)
-        msr    cpsr_c, r2
-
-#ifdef notworthit
-       teq     r0, #0x00000000
-       strne   sp, [r8, #(PCB_UND_SP)]
-#else
-       str     sp, [r8, #(PCB_UND_SP)]
-#endif
-
-        msr    cpsr_c, r3              /* Restore the old mode */
-
-       /* rem: r0 = old proc */
-       /* rem: r1 = r6 = new process */
-       /* rem: r8 = old PCB */
-       /* rem: r9 = new PCB */
-
-       /* What else needs to be saved  Only FPA stuff when that is supported */
-
-       /* Third phase: restore saved context */
+       beq     .switch_exited__skip_save
 
+       add     r7, r6, #PCB_R8                 /* save registers in */
+       stmia   r7, {r8-r13}                    /* the old proc's pcb */
+.switch_exited__skip_save:
        /*
-        * Get the new L1 table pointer into r11.  If we're switching to
-        * an LWP with the same address space as the outgoing one, we can
-        * skip the cache purge and the TTB load.
-        *
-        * To avoid data dep stalls that would happen anyway, we try
-        * and get some useful work done in the mean time.
+        * If we're switching to the same address space as the outgoing
+        * one, we can skip the cache purge and the TTB load.
         */
-       ldr     r10, [r8, #(PCB_PAGEDIR)]       /* r10 = old L1 */
-       ldr     r11, [r9, #(PCB_PAGEDIR)]       /* r11 = new L1 */
-
-       ldr     r0, [r8, #(PCB_DACR)]           /* r0 = old DACR */
-       ldr     r1, [r9, #(PCB_DACR)]           /* r1 = new DACR */
+       ldr     r10, [r6, #PCB_PAGEDIR]         /* r10 = old L1 */
+       ldr     r9, [r1, #P_ADDR]               /* r9 = new PCB */
+       ldr     r11, [r9, #PCB_PAGEDIR]         /* r11 = new L1 */
 
        teq     r10, r11                        /* Same L1? */
-       cmpeq   r0, r1                          /* Same DACR? */
-       beq     .Lcs_context_switched           /* yes! */
-
-       mov     r2, #DOMAIN_CLIENT
-       cmp     r1, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */
-       beq     .Lcs_cache_purge_skipped        /* Yup. Don't flush cache */
-
-       stmfd   sp!, {r0-r3}
-       ldr     r1, .Lcpufuncs
-       mov     lr, pc
-       ldr     pc, [r1, #CF_ICACHE_SYNC_ALL]
-       ldmfd   sp!, {r0-r3}
-
-.Lcs_cache_purge_skipped:
-       /* rem: r1 = new DACR */
-       /* rem: r6 = new proc */
-       /* rem: r9 = new PCB */
-       /* rem: r10 = old L1 */
-       /* rem: r11 = new L1 */
-
-       ldr     r7, [r9, #(PCB_PL1VEC)]
+       beq     .context_switched__skip_flush   /* yes! */
 
        /*
-        * At this point we need to kill IRQ's again.
-        *
-        * XXXSCW: Don't need to block FIQs if vectors have been relocated
+        * Do a full context switch = full TLB flush.
         */
-       IRQdisableALL
-
-       /*
-        * Ensure the vector table is accessible by fixing up the L1
-        */
-       cmp     r7, #0                  /* No need to fixup vector table? */
-       ldrne   r2, [r7]                /* But if yes, fetch current value */
-       ldrne   r0, [r9, #(PCB_L1VEC)]  /* Fetch new vector_page value */
-       mcr     p15, 0, r1, c3, c0, 0   /* Update DACR for new context */
-       cmpne   r2, r0                  /* Stuffing the same value? */
-#ifndef PMAP_INCLUDE_PTE_SYNC
-       strne   r0, [r7]                /* Nope, update it */
-#else
-       beq     .Lcs_same_vector
-       str     r0, [r7]                /* Otherwise, update it */
-
-       /*
-        * Need to sync the cache to make sure that last store is
-        * visible to the MMU.
-        */
-       ldr     r2, .Lcpufuncs
-       mov     r0, r7
-       mov     r1, #4
-       mov     lr, pc
-       ldr     pc, [r2, #CF_DCACHE_WB_RANGE]
-
-.Lcs_same_vector:
-#endif /* PMAP_INCLUDE_PTE_SYNC */
-
-       cmp     r10, r11                /* Switching to the same L1? */
-       ldr     r10, .Lcpufuncs
-       beq     .Lcs_same_l1            /* Yup. */
-
-       /*
-        * Do a full context switch, including full TLB flush.
-        */
-       mov     r0, r11
-       mov     lr, pc
-       ldr     pc, [r10, #CF_CONTEXT_SWITCH]
-
-       b       .Lcs_context_switched
-
-       /*
-        * We're switching to a different process in the same L1.
-        * In this situation, we only need to flush the TLB for the
-        * vector_page mapping, and even then only if r7 is non-NULL.
-        */
-.Lcs_same_l1:
-       cmp     r7, #0
-       movne   r0, #0                  /* We *know* vector_page's VA is 0x0 */
-       movne   lr, pc
-       ldrne   pc, [r10, #CF_TLB_FLUSHID_SE]
-
-.Lcs_context_switched:
-
-       /* XXXSCW: Safe to re-enable FIQs here */
-
-       /* rem: r6 = new proc */
-       /* rem: r9 = new PCB */
-
-       /*
-        * This can be optimised... We know we want to go from SVC32
-        * mode to UND32 mode
-        */
-        mrs    r3, cpsr
-       bic     r2, r3, #(PSR_MODE)
-       orr     r2, r2, #(PSR_UND32_MODE)
-        msr    cpsr_c, r2
-
-       ldr     sp, [r9, #(PCB_UND_SP)]
-
-        msr    cpsr_c, r3              /* Restore the old mode */
-
-       /* Restore all the save registers */
-       add     r7, r9, #PCB_R8
-       ldmia   r7, {r8-r13}
-
+       mcr     CP15_ICIALLU
+       mcr     CP15_BPIALL
+       dsb     sy
+       isb     sy
+       mcr     CP15_TTBR0(r11)
+       mcr     CP15_TLBIALL
+       dsb     sy
+       isb     sy
+
+.context_switched__skip_flush:
+       add     r7, r9, #PCB_R8         /* restore registers saved */
+       ldmia   r7, {r8-r13}            /* in the new proc's pcb */
        sub     r7, r7, #PCB_R8         /* restore PCB pointer */
 
-       /* rem: r6 = new proc */
-       /* rem: r7 = new pcb */
-
-       /* We can enable interrupts again */
-       IRQenableALL
-
-       /* rem: r6 = new proc */
-       /* rem: r7 = new PCB */
-
-.Lswitch_return:
        /*
         * Pull the registers that got pushed when either savectx() or
         * cpu_switch() was called and return.
         */
-       ldmfd   sp!, {r4-r7, pc}
+       add     sp, sp, #4
+       pop     {r4-r7, pc}
 
 /* LINTSTUB: Func: void savectx(struct pcb *pcb) */
 ENTRY(savectx)

Reply via email to