Module Name: src Committed By: matt Date: Mon Dec 17 17:45:01 UTC 2012
Modified Files: src/sys/arch/arm/arm32: cpuswitch.S Log Message: Make sure to load the FPEXC context on context switch (if there a VFP) so that the VFP state will be what the LWP expects. (This isn't needed on PPC or MIPS since their FPU/VEC state is reflected in the PSL/CPO_STATUS which is handled automatically.) To generate a diff of this commit: cvs rdiff -u -r1.75 -r1.76 src/sys/arch/arm/arm32/cpuswitch.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm32/cpuswitch.S diff -u src/sys/arch/arm/arm32/cpuswitch.S:1.75 src/sys/arch/arm/arm32/cpuswitch.S:1.76 --- src/sys/arch/arm/arm32/cpuswitch.S:1.75 Mon Dec 10 01:37:30 2012 +++ src/sys/arch/arm/arm32/cpuswitch.S Mon Dec 17 17:45:01 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuswitch.S,v 1.75 2012/12/10 01:37:30 matt Exp $ */ +/* $NetBSD: cpuswitch.S,v 1.76 2012/12/17 17:45:01 matt Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. @@ -89,7 +89,7 @@ #include <machine/asm.h> #include <machine/cpu.h> - RCSID("$NetBSD: cpuswitch.S,v 1.75 2012/12/10 01:37:30 matt Exp $") + RCSID("$NetBSD: cpuswitch.S,v 1.76 2012/12/17 17:45:01 matt Exp $") /* LINTSTUB: include <sys/param.h> */ @@ -141,26 +141,26 @@ ENTRY(cpu_switchto) mov r4, r0 #ifdef TPIDRPRW_IS_CURCPU - GET_CURCPU(r7) + GET_CURCPU(r3) #elif defined(TPIDRPRW_IS_CURLWP) mcr p15, 0, r0, c13, c0, 4 /* get old lwp (r4 maybe 0) */ - ldr r7, [r0, #(L_CPU)] /* get cpu from old lwp */ + ldr r3, [r0, #(L_CPU)] /* get cpu from old lwp */ #elif !defined(MULTIPROCESSOR) - ldr r7, [r6, #L_CPU] /* get cpu from new lwp */ + ldr r3, [r6, #L_CPU] /* get cpu from new lwp */ #else #error curcpu() method not defined #endif + /* rem: r3 = curcpu() */ /* rem: r4 = old lwp */ /* rem: r6 = new lwp */ - /* rem: r7 = curcpu() */ #ifndef __HAVE_UNNESTED_INTRS IRQdisable #endif #ifdef MULTIPROCESSOR - str r7, [r6, #(L_CPU)] + str r3, [r6, #(L_CPU)] #else /* l->l_cpu initialized in fork1() for single-processor */ #endif @@ -169,7 +169,7 @@ ENTRY(cpu_switchto) mcr p15, 0, r6, c13, c0, 4 /* set current lwp */ #endif /* We have a new curlwp now so make a note it */ - str r6, [r7, #(CI_CURLWP)] + str r6, [r3, #(CI_CURLWP)] /* Get the new pcb */ ldr r7, [r6, #(L_PCB)] @@ -179,6 +179,7 @@ ENTRY(cpu_switchto) IRQenable #endif + /* rem: r3 = curlwp */ /* rem: r4 = old lwp */ /* rem: r6 = new lwp */ /* rem: r7 = new pcb */ @@ -193,6 +194,7 @@ ENTRY(cpu_switchto) teq r4, #0 beq .Ldo_switch + /* rem: r3 = curlwp */ /* rem: r4 = old lwp */ /* rem: r6 = new lwp */ /* rem: r7 = new pcb */ @@ -204,7 +206,7 @@ ENTRY(cpu_switchto) ldr r5, [r4, #(L_PCB)] /* Save all the registers in the old lwp's pcb */ -#if defined(__XSCALE__) || defined(_ARM_ARCH_6) +#if defined(_ARM_ARCH_DWORD_OK) strd r8, [r5, #(PCB_R8)] strd r10, [r5, #(PCB_R10)] strd r12, [r5, #(PCB_R12)] @@ -225,6 +227,7 @@ ENTRY(cpu_switchto) * them for the new process. */ + /* rem: r3 = curlwp */ /* rem: r4 = old lwp */ /* rem: r5 = old pcb */ /* rem: r6 = new lwp */ @@ -234,6 +237,7 @@ ENTRY(cpu_switchto) /* Restore saved context */ .Ldo_switch: + /* rem: r3 = curlwp */ /* rem: r4 = old lwp */ /* rem: r6 = new lwp */ /* rem: r7 = new pcb */ @@ -249,6 +253,16 @@ ENTRY(cpu_switchto) mcr p15, 0, r0, c13, c0, 3 #endif +#ifdef FPU_VFP + /* + * If we have a VFP, we need to load FPEXC. + */ + ldr r0, [r3, #(CI_VFP_ID)] + cmp r0, #0 + ldrne r0, [r7, #(PCB_VFP_FPEXC)] + mcrne p10, 7, r0, c8, c0, 0 +#endif + ldr r5, [r6, #(L_PROC)] /* fetch the proc for below */ /* Restore all the saved registers */ @@ -258,18 +272,18 @@ ENTRY(cpu_switchto) ldr r10, [r7, #(PCB_R10)] ldr r11, [r7, #(PCB_R11)] ldr r12, [r7, #(PCB_R12)] - ldr r13, [r7, #(PCB_KSP)] -#elif defined(_ARM_ARCH_6) + ldr r13, [r7, #(PCB_KSP)] /* sp */ +#elif defined(_ARM_ARCH_DWORD_OK) ldrd r8, [r7, #(PCB_R8)] ldrd r10, [r7, #(PCB_R10)] - ldrd r12, [r7, #(PCB_R12)] + ldrd r12, [r7, #(PCB_R12)] /* sp */ #else add r0, r7, #PCB_R8 ldmia r0, {r8-r13} #endif /* Record the old lwp for pmap_activate()'s benefit */ - ldr r1, .Lpmap_previous_active_lwp + ldr r1, .Lpmap_previous_active_lwp /* XXXSMP */ str r4, [r1] /* rem: r4 = old lwp */