Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm * Add a new machdep.powersave sysctl, which con...



details:   https://anonhg.NetBSD.org/src/rev/b4f64bf4a2eb
branches:  trunk
changeset: 535376:b4f64bf4a2eb
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Aug 16 15:25:53 2002 +0000

description:
* Add a new machdep.powersave sysctl, which controls the use of
  the CPU's "sleep" function in the idle loop.
* Default all CPUs to not use powersave, except for the PDA processors
  (SA11x0 and PXA2x0).

This significantly reduces inteterrupt latency in high-performance
applications (and was good to squeeze another ~10% out of an XScale
IOP on a Gig-E benchmark).

diffstat:

 sys/arch/arm/arm/cpufunc.c         |  21 ++++++++++++++++-
 sys/arch/arm/arm32/arm32_machdep.c |  21 ++++++++++++++++-
 sys/arch/arm/arm32/cpuswitch.S     |  46 ++++++++++++++++++++++---------------
 sys/arch/arm/include/cpu.h         |  11 +++++++-
 4 files changed, 76 insertions(+), 23 deletions(-)

diffs (219 lines):

diff -r a7cb58925bee -r b4f64bf4a2eb sys/arch/arm/arm/cpufunc.c
--- a/sys/arch/arm/arm/cpufunc.c        Fri Aug 16 15:08:08 2002 +0000
+++ b/sys/arch/arm/arm/cpufunc.c        Fri Aug 16 15:25:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc.c,v 1.51 2002/08/16 00:06:26 thorpej Exp $     */
+/*     $NetBSD: cpufunc.c,v 1.52 2002/08/16 15:25:53 thorpej Exp $     */
 
 /*
  * arm7tdmi support code Copyright (c) 2001 John Fremlin
@@ -95,6 +95,9 @@
 int    arm_dcache_align;
 int    arm_dcache_align_mask;
 
+/* 1 == use cpu_sleep(), 0 == don't */
+int cpu_do_powersave;
+
 #ifdef CPU_ARM3
 struct cpu_functions arm3_cpufuncs = {
        /* CPU functions */
@@ -827,6 +830,10 @@
        cputype = cpufunc_id();
        cputype &= CPU_ID_CPU_MASK;
 
+       /*
+        * NOTE: cpu_do_powersave defaults to off.  If we encounter a
+        * CPU type where we want to use it by default, then we set it.
+        */
 
 #ifdef CPU_ARM3
        if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
@@ -903,6 +910,10 @@
                cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it  */
                get_cachetype_table();
                pmap_pte_init_generic();
+
+               /* Use powersave on this CPU. */
+               cpu_do_powersave = 1;
+
                return 0;
        }
 #endif /* CPU_SA1100 */
@@ -912,6 +923,10 @@
                cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it  */
                get_cachetype_table();
                pmap_pte_init_generic();
+
+               /* Use powersave on this CPU. */
+               cpu_do_powersave = 1;
+
                return 0;
        }
 #endif /* CPU_SA1110 */
@@ -1020,6 +1035,10 @@
                cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
                get_cachetype_cp15();
                pmap_pte_init_xscale();
+
+               /* Use powersave on this CPU. */
+               cpu_do_powersave = 1;
+
                return 0;
        }
 #endif /* CPU_XSCALE_PXA2X0 */
diff -r a7cb58925bee -r b4f64bf4a2eb sys/arch/arm/arm32/arm32_machdep.c
--- a/sys/arch/arm/arm32/arm32_machdep.c        Fri Aug 16 15:08:08 2002 +0000
+++ b/sys/arch/arm/arm32/arm32_machdep.c        Fri Aug 16 15:25:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: arm32_machdep.c,v 1.24 2002/05/05 16:26:30 jdolecek Exp $      */
+/*     $NetBSD: arm32_machdep.c,v 1.25 2002/08/16 15:25:54 thorpej Exp $       */
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -379,6 +379,25 @@
                            booted_kernel);
                return (EOPNOTSUPP);
        }
+       case CPU_POWERSAVE: {
+               int error, newval;
+
+               newval = cpu_do_powersave;
+
+               if (cpufuncs.cf_sleep == (void *) cpufunc_nullop)
+                       error = sysctl_rdint(oldp, oldlenp, newp, newval);
+               else
+                       error = sysctl_int(oldp, oldlenp, newp, newlen,
+                           &newval);
+               if (error || newval == cpu_do_powersave)
+                       return (error);
+
+               if (newval < 0 || newval > 1)
+                       return (EINVAL);
+
+               cpu_do_powersave = newval;
+               return (0);
+       }
 
        default:
                return (EOPNOTSUPP);
diff -r a7cb58925bee -r b4f64bf4a2eb sys/arch/arm/arm32/cpuswitch.S
--- a/sys/arch/arm/arm32/cpuswitch.S    Fri Aug 16 15:08:08 2002 +0000
+++ b/sys/arch/arm/arm32/cpuswitch.S    Fri Aug 16 15:25:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpuswitch.S,v 1.14 2002/08/15 01:37:01 briggs Exp $    */
+/*     $NetBSD: cpuswitch.S,v 1.15 2002/08/16 15:25:54 thorpej Exp $   */
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -228,38 +228,47 @@
 Lblock_userspace_access:
        .word   _C_LABEL(block_userspace_access)
 
+.Lcpu_do_powersave:
+       .word   _C_LABEL(cpu_do_powersave)
+
 /*
  * Idle loop, exercised while waiting for a process to wake up.
  */
 /* LINTSTUB: Ignore */
 ASENTRY_NP(idle)
-
 #if defined(LOCKDEBUG)
        bl      _C_LABEL(sched_unlock_idle)
 #endif
        /* Enable interrupts */
        IRQenable
 
-       ldr     r3, Lcpufuncs
-       mov     r0, #0
-       add     lr, pc, #.Lidle_slept - . - 8
-       ldr     pc, [r3, #CF_SLEEP]
-
-       /* should also call the uvm pageidlezero stuff */
+       /* If we don't want to sleep, use a simpler loop. */
+       ldr     r3, .Lcpu_do_powersave
+       ldr     r7, Lwhichqs                    /* r7 = &whichqs */
+       ldr     r3, [r3]
+       teq     r3, #0
+       beq     .Lidle_nosleep
 
-.Lidle_slept:
-
-       /* Disable interrupts while we check for an active queue */
-       IRQdisable
-#if defined(LOCKDEBUG)
-       bl      _C_LABEL(sched_lock_idle)
-#endif
-       ldr     r7, Lwhichqs
+       /* Powersave idle. */
+       ldr     r4, Lcpufuncs
+.Lidle_sleep:
        ldr     r3, [r7]
        teq     r3, #0x00000000
+       bne     .Lswitch_search
 
-       beq     _ASM_LABEL(idle)
-       b       .Lidle_ret
+       /* if saving power, don't want to pageidlezero */
+       mov     r0, #0
+       add     lr, pc, #.Lidle_sleep - . - 8
+       ldr     pc, [r4, #(CF_SLEEP)]
+       /* loops back around */
+
+       /* Non-powersave idle. */
+.Lidle_nosleep:
+       /* should maybe do uvm pageidlezero stuff here */
+       ldr     r3, [r7]
+       teq     r3, #0x00000000
+       bne     .Lswitch_search
+       b       .Lidle_nosleep
 
 /*
  * Find a new process to run, save the current context and
@@ -332,7 +341,6 @@
        /* If not we must idle until we do. */
        teq     r3, #0x00000000
        beq     _ASM_LABEL(idle)
-.Lidle_ret:
 
        /* put old proc back in r1 */
        mov     r1, r5
diff -r a7cb58925bee -r b4f64bf4a2eb sys/arch/arm/include/cpu.h
--- a/sys/arch/arm/include/cpu.h        Fri Aug 16 15:08:08 2002 +0000
+++ b/sys/arch/arm/include/cpu.h        Fri Aug 16 15:25:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.28 2002/08/14 21:55:52 briggs Exp $  */
+/*     $NetBSD: cpu.h,v 1.29 2002/08/16 15:25:54 thorpej Exp $ */
 
 /*
  * Copyright (c) 1994-1996 Mark Brinicombe.
@@ -57,7 +57,8 @@
 #define        CPU_BOOTED_DEVICE       2       /* string: device we booted from */
 #define        CPU_BOOTED_KERNEL       3       /* string: kernel we booted */
 #define        CPU_CONSDEV             4       /* struct: dev_t of our console */
-#define        CPU_MAXID               5       /* number of valid machdep ids */
+#define        CPU_POWERSAVE           5       /* int: use CPU powersave mode */
+#define        CPU_MAXID               6       /* number of valid machdep ids */
 
 #define        CTL_MACHDEP_NAMES { \
        { 0, 0 }, \
@@ -65,6 +66,7 @@
        { "booted_device", CTLTYPE_STRING }, \
        { "booted_kernel", CTLTYPE_STRING }, \
        { "console_device", CTLTYPE_STRUCT }, \
+       { "powersave", CTLTYPE_INT }, \
 }    
 
 #ifdef _KERNEL
@@ -88,6 +90,11 @@
 
 #include <arm/armreg.h>
 
+#ifndef _LOCORE
+/* 1 == use cpu_sleep(), 0 == don't */
+extern int cpu_do_powersave;
+#endif
+
 #ifdef __PROG32
 #ifdef _LOCORE
 #define IRQdisable \



Home | Main Index | Thread Index | Old Index