[BACK]Return to longrun.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/longrun.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: longrun.c,v 1.13 2007/05/25 20:32:29 krw Exp $ */
                      2: /*
                      3:  * Copyright (c) 2003 Ted Unangst
                      4:  * Copyright (c) 2001 Tamotsu Hattori
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                     23:  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     24:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
                     25:  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     26:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     28:  * SUCH DAMAGE.
                     29:  */
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/kernel.h>
                     34: #include <sys/sysctl.h>
                     35: #include <sys/timeout.h>
                     36:
                     37: #include <machine/cpufunc.h>
                     38:
                     39: union msrinfo {
                     40:        u_int64_t msr;
                     41:        uint32_t regs[2];
                     42: };
                     43:
                     44: /*
                     45:  * Crusoe model specific registers which interest us.
                     46:  */
                     47: #define MSR_TMx86_LONGRUN       0x80868010
                     48: #define MSR_TMx86_LONGRUN_FLAGS 0x80868011
                     49:
                     50: #define LONGRUN_MODE_MASK(x) ((x) & 0x000000007f)
                     51: #define LONGRUN_MODE_RESERVED(x) ((x) & 0xffffff80)
                     52: #define LONGRUN_MODE_WRITE(x, y) (LONGRUN_MODE_RESERVED(x) | LONGRUN_MODE_MASK(y))
                     53:
                     54: void   longrun_update(void *);
                     55:
                     56: struct timeout longrun_timo;
                     57:
                     58: void
                     59: longrun_init(void)
                     60: {
                     61:        cpu_setperf = longrun_setperf;
                     62:
                     63:        timeout_set(&longrun_timo, longrun_update, NULL);
                     64:        timeout_add(&longrun_timo, hz);
                     65: }
                     66:
                     67: /*
                     68:  * These are the instantaneous values used by the CPU.
                     69:  * regs[0] = Frequency is self-evident.
                     70:  * regs[1] = Voltage is returned in millivolts.
                     71:  * regs[2] = Percent is amount of performance window being used, not
                     72:  * percentage of top megahertz.  (0 values are typical.)
                     73:  */
                     74: void
                     75: longrun_update(void *arg)
                     76: {
                     77:        uint32_t eflags, regs[4];
                     78:
                     79:        eflags = read_eflags();
                     80:        disable_intr();
                     81:        cpuid(0x80860007, regs);
                     82:        enable_intr();
                     83:        write_eflags(eflags);
                     84:
                     85:        cpuspeed = regs[0];
                     86:
                     87:        timeout_add(&longrun_timo, hz);
                     88: }
                     89:
                     90: /*
                     91:  * Transmeta documentation says performance window boundaries
                     92:  * must be between 0 and 100 or a GP0 exception is generated.
                     93:  * mode is really only a bit, 0 or 1
                     94:  * These values will be rounded by the CPU to within the
                     95:  * limits it handles.  Typically, there are about 5 performance
                     96:  * levels selectable.
                     97:  */
                     98: void
                     99: longrun_setperf(int high)
                    100: {
                    101:        uint32_t eflags, mode;
                    102:        union msrinfo msrinfo;
                    103:
                    104:        if (high >= 50)
                    105:                mode = 1;       /* power */
                    106:        else
                    107:                mode = 0;       /* battery */
                    108:
                    109:        eflags = read_eflags();
                    110:        disable_intr();
                    111:
                    112:        msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN);
                    113:        msrinfo.regs[0] = LONGRUN_MODE_WRITE(msrinfo.regs[0], 0); /* low */
                    114:        msrinfo.regs[1] = LONGRUN_MODE_WRITE(msrinfo.regs[1], high);
                    115:        wrmsr(MSR_TMx86_LONGRUN, msrinfo.msr);
                    116:
                    117:        msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN_FLAGS);
                    118:        msrinfo.regs[0] = (msrinfo.regs[0] & ~0x01) | mode;
                    119:        wrmsr(MSR_TMx86_LONGRUN_FLAGS, msrinfo.msr);
                    120:
                    121:        enable_intr();
                    122:        write_eflags(eflags);
                    123:
                    124:        longrun_update(NULL);
                    125: }
                    126:

CVSweb