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)