Hi, i think w/this it'll be more readable w/o the unnecessary branch and associated legacy fat. comments?
6 files changed, 35 insertions(+), 146 deletions(-) from teh optimizing 'less is more'-diff dept.. -Artturi diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c index c91108e7066..472c6113196 100644 --- a/sys/arch/arm/arm/cpufunc.c +++ b/sys/arch/arm/arm/cpufunc.c @@ -131,7 +131,6 @@ struct cpu_functions armv7_cpufuncs = { armv7_cpu_sleep, /* sleep (wait for interrupt) */ /* Soft functions */ - armv7_context_switch, /* context_switch */ armv7_setup /* cpu setup */ }; diff --git a/sys/arch/arm/arm/cpufunc_asm_armv7.S b/sys/arch/arm/arm/cpufunc_asm_armv7.S index 05679df15fa..fadcfef1cc3 100644 --- a/sys/arch/arm/arm/cpufunc_asm_armv7.S +++ b/sys/arch/arm/arm/cpufunc_asm_armv7.S @@ -36,9 +36,6 @@ ENTRY(armv7_periphbase) mrc CP15_CBAR(r0) mov pc, lr -/* Suitable default for a uniprocessor kernel. */ -#define TTBR_DEFAULT (TTBR_IRGN_WBNWA | TTBR_RGN_WBNWA) - /* * Functions to set the MMU Translation Table Base register */ @@ -208,32 +205,6 @@ ENTRY(armv7_dcache_inv_range) mov pc, lr -/* - * Context switch. - * - * These is the CPU-specific parts of the context switcher cpu_switch() - * These functions actually perform the TTB reload. - * - * NOTE: Special calling convention - * r1, r4-r13 must be preserved - */ -ENTRY(armv7_context_switch) - /* - * We can assume that the caches will only contain kernel addresses - * at this point. So no need to flush them again. - */ - mcr CP15_ICIALLU /* Flush I cache */ - mcr CP15_BPIALL /* Flush BP cache */ - dsb sy - isb sy - - orr r0, r0, #TTBR_DEFAULT - mcr CP15_TTBR0(r0) /* set the new TTB */ - mcr CP15_TLBIALL(r0) /* and flush the unified tlb */ - dsb sy - isb sy - mov pc, lr - /* XXX The following macros should probably be moved to asm.h */ #define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x: #define C_OBJECT(x) _DATA_OBJECT(_C_LABEL(x)) diff --git a/sys/arch/arm/arm/cpuswitch7.S b/sys/arch/arm/arm/cpuswitch7.S index 431a890dc94..87ea84a1a83 100644 --- a/sys/arch/arm/arm/cpuswitch7.S +++ b/sys/arch/arm/arm/cpuswitch7.S @@ -85,8 +85,6 @@ #include <machine/asm.h> #include <arm/sysreg.h> -/* LINTSTUB: include <sys/param.h> */ - #define IRQdisableALL \ cpsid if @@ -147,10 +145,9 @@ ENTRY(cpu_idle_leave) */ ENTRY(cpu_switchto) - stmfd sp!, {r4-r7, lr} + push {r4-r7, lr} sub sp, sp, #4 - - /* Get curcpu from TPIDRPRW. */ + /* r3 = curcpu() */ mrc CP15_TPIDRPRW(r3) #ifdef MULTIPROCESSOR str r3, [r1, #(P_CPU)] @@ -162,12 +159,11 @@ ENTRY(cpu_switchto) 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)] - + 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)] + /* r2 = new PCB */ str r2, [r3, #(CI_CURPCB)] /* @@ -177,126 +173,51 @@ 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)] - - mrs r3, cpsr - cpsid i, #(PSR_UND32_MODE) - -#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 r10, [r6, #(PCB_PAGEDIR)] /* r10 = old L1 */ + ldr r9, [r1, #(P_ADDR)] /* r9 = new PCB */ ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */ - /* rem: r6 = new proc */ - /* rem: r9 = new PCB */ - /* rem: r10 = old L1 */ - /* rem: r11 = new L1 */ + teq r10, r11 /* Same L1? */ + beq .context_switched__skip_flush /* yes! */ + orr r11, r11, #(TTBR_DEFAULT) /* - * 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 - - cmp r10, r11 /* Switching to the same L1? */ - ldr r10, .Lcpufuncs - beq .Lcs_context_switched /* Yup. */ - - /* - * Do a full context switch, including full TLB flush. - */ - mov r0, r11 - mov lr, pc - ldr pc, [r10, #CF_CONTEXT_SWITCH] - -.Lcs_context_switched: - - /* XXXSCW: Safe to re-enable FIQs here */ - - /* rem: r6 = new proc */ - /* rem: r9 = new PCB */ - + mcr CP15_ICIALLU + mcr CP15_BPIALL + dsb sy + isb sy + mcr CP15_TTBR0(r11) + mcr CP15_TLBIALL(r0) + dsb sy + isb sy + +.context_switched__skip_flush: /* stick tcb into user visable register */ - ldr r3, [r9, #(PCB_TCB)] - mcr CP15_TPIDRURO(r3) + ldr r5, [r9, #(PCB_TCB)] /* get ptr to tcb, and put it */ + mcr CP15_TPIDRURO(r5) /* into user visible register */ - mrs r3, cpsr - cps #(PSR_UND32_MODE) + 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 XXX why? */ - 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} - - 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. */ add sp, sp, #4 - ldmfd sp!, {r4-r7, pc} + pop {r4-r7, pc} -/* LINTSTUB: Func: void savectx(struct pcb *pcb) */ ENTRY(savectx) /* * r0 = pcb diff --git a/sys/arch/arm/arm/genassym.cf b/sys/arch/arm/arm/genassym.cf index 3937b930c39..b0f40ecf11f 100644 --- a/sys/arch/arm/arm/genassym.cf +++ b/sys/arch/arm/arm/genassym.cf @@ -148,7 +148,6 @@ member cf_icache_sync_all member cf_idcache_wbinv_all member cf_dcache_wb_range member cf_tlb_flushID_SE -member cf_context_switch member cf_sleep member cf_control diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h index 7e89418e57e..b474dbe75b3 100644 --- a/sys/arch/arm/include/armreg.h +++ b/sys/arch/arm/include/armreg.h @@ -350,4 +350,7 @@ #define TTBR_IRGN_WT ((1 << 0) | (0 << 6)) #define TTBR_IRGN_WBNWA ((1 << 0) | (1 << 6)) +/* Suitable default for a uniprocessor kernel. */ +#define TTBR_DEFAULT (TTBR_IRGN_WBNWA | TTBR_RGN_WBNWA) + #endif diff --git a/sys/arch/arm/include/cpufunc.h b/sys/arch/arm/include/cpufunc.h index 65da821b49a..80fa0c8f79d 100644 --- a/sys/arch/arm/include/cpufunc.h +++ b/sys/arch/arm/include/cpufunc.h @@ -150,7 +150,6 @@ struct cpu_functions { void (*cf_sleep) (int mode); /* Soft functions */ - void (*cf_context_switch) (u_int); void (*cf_setup) (void); }; @@ -199,7 +198,6 @@ extern u_int cputype; #define cpu_sleep(m) cpufuncs.cf_sleep(m) -#define cpu_context_switch(a) cpufuncs.cf_context_switch(a) #define cpu_setup(a) cpufuncs.cf_setup(a) int set_cpufuncs (void); @@ -223,8 +221,6 @@ void armv7_setttb (u_int); void armv7_tlb_flushID_SE (u_int); void armv7_tlb_flushI_SE (u_int); -void armv7_context_switch (u_int); - void armv7_setup (void); void armv7_tlb_flushID (void); void armv7_tlb_flushI (void);