
CpuPowerDaemon, (c) 2008-2009 Markus Strobl <markus.strobl@gmx.at>
Web: http://sourceforge.net/projects/cpupowerd.

A daemon which controls the frequency and voltage of CPUs.

This userland program adjusts the frequency and voltage according to the
CPU's load. Its capabilities include overvolting as well as undervolting.
Currently are supported only AMD K8 processors like Athlon, Athlon64 (X2),
Sempron, Opteron, Turion ...

This daemon has been tested successfully on:

    AMD Mobile Sempron 3100+,      1.8 GHz,   Model E, Stepping 6
    AMD Sempron 64 LE-1300,        2.3 GHz,   Model G, Stepping 2
    AMD Turion 64 X2 TL-56,        2x1.8 Ghz, Model F, Stepping 2
    AMD Athlon 64 X2 3800+ EE SFF, 2x2.0 GHz, Model F, Stepping 2
    AMD Athlon 64 X2 5200+,        2x2.7 GHz, Model G, Stepping 2
    AMD Athlon 64 X2 BE-2400,      2x2.3 GHz, Model G, Stepping 1
    AMD Athlon 64 X2 4050e,        2x2.1 GHz, Model G, Stepping 2
    AMD Athlon 64 X2 4400+,        2x2.3 GHz, Model G, Stepping 2

Using lower voltages could make your hardware quietly and maybe longer
living, too. Laptops could work longer in battery mode.


WARNING:
--------

This program could cause damage to your Hardware!


AUTHOR:
-------

Written by Markus Strobl <markus.strobl@gmx.at>

Ideas from the following projects are used in this program:
cpupw written by Daniel Rubio Bonilla
    <danielrubiob@gmail.com> <http://www.tuxamito.com.es/cpupw/>
powernowd written by John Clemens
    <clemej@alum.rpi.edu> <http://www.deater.net/john/powernowd.html>


REQUIREMENTS:
-------------

BIOS:
On AMD-System enable Cool'n Quiet, on Intel-System enable EIST.
Don't use a fix value for CPU voltage, if the BIOS have such possibillity.

Linux:
The msr and cpufreq kernel modules must be available.
On AMD-Systems powernow-k8 kernel module must available too.

FreeBSD:
The devcpu kernel modul from ports/sysutils must be installed
before(!) you begin to compile cpupowerd.

You must be root to run the program.


COMPILING:
----------

tar -xzf cpupowerd-x.x.x.tar.gz
cd cpupowerd-x.x.x/src
make

(then, as root)
make install

Default binary install path is /usr/sbin. If you want use
another path as /usr please use PREFIX=/to/install/path 
(e.g. "make install PREFIX=/usr/local" installs the binary
to /usr/local/sbin).
Ensure that the install path is in your $PATH environment variable.


USAGE:
------

Stop and disable all other userland tools for changing CPU frequency.
Load the required kernel moduls. 
Find the lowest possible voltage for every available CPU frequency
and change the values in the auto generated configfile.
To supress frequencies in the config file, you can delete or comment
out with # the relevant lines.
Which kernel moduls are required and how you can get the voltages is
available in the chapter "FIND LOWEST POSSIBLE CPU VOLTAGES".
For running cpupowerd at startup on a Linux system, you can use the start
script cpupowerd.sh which you will find under cpupowerd-x.x.x/tools.
This start script loads all kernel moduls, which are required.
Edit CPUPOWERD_STARTPARAMETERS on the beginning of the script, copying
it to the right place for your Linux distribution and rename it if you want.
Don't forget to stop cpupowerd on system shutdown.
On FreeBSD, cpupowerd is (shortly) in the ports tree with a start script
available.
Please ensure, that only one cpupowerd is running. If you will change the
parameters, stop cpupowerd first and then start cpupowerd with the modified
parameters (in the start script) again.
In daemon mode, cpupowerd writes log messages to syslogd. Every Linux distro
and FreeBSD has a different syslogd configuration and philosophy.
The logging levels INFO, WARNING and ERROR are used.
To know which message in which file is stored, please have a look at
your /etc/syslog(d).conf for the facility daemon.
To have all cpupowerd messages in one file ensure that a line
"daemon.*   /var/log/daemon" exists in /etc/syslog(d).conf file
and the file /var/log/daemon is available.
(if not, create it with "touch /var/log/daemon").
To remove old log files safely as well as to prevent from a 'disc full'
problem, add the daemon log file to the logrotate.conf file.

Run as root:
cpupowerd <options>

Options:
  -h, --help                print this help
  -v, --version             print version and exit
  -d, --daemonize           run program as a daemon
  -m, --messagelevel ARG    level of the cpupowerd messages,
                            ARG can be 0,1 or 2 (default = 1):
                              0=ERROR, 1=WARNING, 2=INFO
  -c, --config ARG          use parameters in ARG configuration file
  -a, --autoconfig ARG      write automatic configuration parameters to file
                            ARG
  -t, --time ARG            ARG is the time in milliseconds the program waits
                            to check the load of the mastercpus (default
                            = 1000)
  -s, --status              show status of the mastercpus
  -l, --laptop              activate laptop mode check
  -r, --reducevoltage ARG   reduce voltage for all cpus and frequencies at
                            ARG, expressed as a float value. The highest value
                            for reduce is 0.2000 V
  -e, --enhancevoltage ARG  enhance voltage for all cpus and frequencies at
                            ARG, expressed as a float value. The highest value
                            for enhance is 0.1000 V
  -S, --strategy ARG        strategy of operation, ARG can be 0,1,2,3,4,5 or 6
                            (default=4):
                              0=MINIMUM, 1=SINE, 2=AGGRESSIVE, 3=PASSIVE,
                              4=BSD, 5=LEAPS, 6=MAXIMUM
  -U, --up ARG              set ARG to be the default percentage of use causing
                            increase the cpu frequency [0 .. 100, default 80]
  -D, --down ARG            set ARG to be the default percentage of use causing
                            decrease the cpu frequency [0 .. 100, default 20]
  -V, --voltage ARG1|ARG2   set ARG2 in volts as the new voltage, expressed as
                            a float value for mastercpuid ARG1
  -F, --freq ARG1|ARG2      set ARG2 in MHz as the new frequency, expressed as
                            a int value for mastercpuid ARG1


EXAMPLES:
---------

* show help
  cpupowerd -h

* show CPU status
  cpupowerd -s

  output for AMD Athlon 64 X2 3800+ EE SFF:
  # cpupowerd -s
  cpupowerd 0.2.0 written by Markus Strobl.
  WARNING: This program could cause damage to your Hardware!
  Vendor                      : AMD
  Family                      : K8
  Model                       : 4
    Mastercpuid               : 0
      Affected cpuids         : 0 1
      Current voltage (VID)   : 1.0000 V (22)
      Current frequency (FID) : 1000 MHz (2)
      Supported frequencies   : 1000 1800 2000 MHz

  This is a case of one mastercpu with 2 affected cpus.
  The CPU Vendor is AMD and CPU Family is the K8.
  The Model No. 4 assumes the CPU Model F.
  It shows one mastercpu with id 0 and affected cpuids 0 and 1.
  The voltage on the mastercpu and on all affected cpus is 1.0 V (VID 22)
  The frequency (FID 2.0) is 1000 MHz.
  1000, 1800 and 2000 MHz are possible frequencies for the mastercore.

* set frequency (1800MHz) for mastercpu 0
  cpupowerd -F "0|1800"

* set voltage (0.975V) for used frequency and mastercpu 0
  cpupowerd -V "0|0.975"

* generate the config file
  cpupowerd -a cpupowerd.conf

  example of the config file:
  1000 1.0000
  1800 1.0500
  2000 1.1000

  The values in the first column are the cpu frequencies in MHz and in the
  second column are the corresponding voltages in volt.

* use the config file in daemon mode with messagelevel 2
  cpupowerd -d -c cpupowerd.conf -m 2

* use the config file in daemon mode, laptop mode, polling interval 100ms,
  other values for up and down percentage and strategy AGGRESSIVE
  cpupowerd -d -l -U 60 -D 10 -S 2 -t 100 -c cpupowerd.conf

* reduce voltage with general undervolting all system cpus
  cpupowerd -r 0.1

* enhance voltage with general overvolting all system cpus
  cpupowerd -e 0.1


FIND LOWEST POSSIBLE CPU VOLTAGES:
----------------------------------

* Read this README file completely. 
* Stop all other userland tools for changing CPU frequency (e.g.
  powernowd or cpufreqd on Linux or powerd on FreeBSD).
* Login as the root user.
* Linux: Load msr kernel modul with "modprobe msr".
  FreeBSD: Load cpu kernel modul with "kldload cpu".
* Linux: Check the cpufreq_userspace kernel modul ("lsmod | grep cpufreq") and
  load it if necessary ("modprobe cpufreq_userspace").
  FreeBSD: Check if the frequency levels are available
  ("sysctl dev.cpu. | grep freq_levels").
* Linux: If you have a AMD-System, check the powernow_k8 kernel modul
  ("lsmod | grep powernow_k8") and load it if necessary
  ("modprobe powernow_k8").
  FreeBSD: -
* Use 'cpupowerd -s' to check if cpupowerd detects your cpu correctly.
* If CPU detecting fails stop all tests. Create a bug report
  using 'cpupowerd -s' and add your CPU datas (Linux: 'cat /proc/cpuinfo',
  FreeBSD: install x86info from ports/sysutils and add the output) and send
  it to markus.strobl@gmx.at please.
* Remember the original voltage which 'cpupowerd -s' had told you.
* Do your first undervolting using 'cpupowerd -V "0|1.025"' (1.025 as example
  voltage and is depended from your CPU). Use a voltage not very different 
  from the original voltage for the first time. The possible voltages for 
  your AMD K8 CPU you will find in the chapter AMD K8 VOLTAGES.
  Remember, for CPU Models to E, the lowest possible voltage is 0.8000 V!
* Use 'cpupowerd -s' to check if the CPU is undervolted. Check the effect
  with an energy checker, if you have such a device. For Linux, alternatively
  you can use lm-sensors tool (download http://www.lm-sensors.org).
* If undervolting works correctly, restore voltage to the original value.
* Create autoconfig file with 'cpupowerd -a cpupowerd.conf'. The CPU goes 
  through all Cool'n Quiet frequencies looking for the original voltage and
  writes it into the config file. In the config file each line contains
  the frequency in MHz and the voltage in V. Now you have the original
  voltage saved.
* Change the CPU frequency with 'cpupowerd -F "0|1800" ' (1800 as example 
  frequency and is depended from your CPU).
* Find the lowest possible voltage for the applied frequency with 
  'cpupowerd -V "0|x.xxx"'. Set the voltage down until computer freeze.
  Now use the higher voltage value before computer freeze. Test the stability
  of your settings for the applied frequency with mprime
  (download ftp://mersenne.org/gimps/) for several hours. If you have a
  FreeBSD system, install cpuburn package from ports/sysutils and use burnMMX.
  If computer freezes again, increase the voltage.
* Repeat step above to find the lowest possible CPU voltages for all
  available frequencies.
* Change voltage in the config file with your lowest stable voltage for every
  frequency and start cpupowerd with the highest message level for full
  message output.
* Use the createload.sh script as none root (under cpupowerd-x.x.x/tools)
  to test the frequency switching of the daemon and all your settings for 
  several hours. If necessary, change the path and/or the used benchmark
  program for your operating system on the beginning of the script.
* Check your settings in normal usage several hours (very important!).
  The used benchmark program creates only full CPU load, but in the most 
  cases, this isn't the real usage of a computer. I have heard about freezes 
  in a mprime stable configuration. So you must increase the voltage to the 
  next higher value and test the normal usage again.
* You can use additional benchmark programs like stress
  (download http://weather.ou.edu/~apw/projects/stress/, 
  ports/sysutils/stress on FreeBSD ) or cpuburn
  (download http://users.bigpond.net.au/CPUBURN/,
  ports/sysutils/cpuburn on FreeBSD) to test the stability of your settings.
  Under FreeBSD, the mprime benchmark program is only available for i386
  under ports/math/mprime.
* If all is stable - congratulations!
  Now save energy and enjoy :-).


AMD K8 VOLTAGES:
----------------

The following CPU voltages are available:

1.5500 V 1.1500 V 0.7625 V 0.5625 V
1.5250 V 1.1250 V 0.7500 V 0.5500 V
1.5000 V 1.1000 V 0.7375 V 0.5375 V
1.4750 V 1.0750 V 0.7250 V 0.5250 V
1.4500 V 1.0500 V 0.7125 V 0.5125 V
1.4250 V 1.0250 V 0.7000 V 0.5000 V
1.4000 V 1.0000 V 0.6875 V 0.4875 V
1.3750 V 0.9750 V 0.6750 V 0.4750 V
1.3500 V 0.9500 V 0.6625 V 0.4625 V
1.3250 V 0.9250 V 0.6500 V 0.4500 V
1.3000 V 0.9000 V 0.6375 V 0.4375 V
1.2750 V 0.8750 V 0.6250 V 0.4250 V
1.2500 V 0.8500 V 0.6125 V 0.4125 V
1.2250 V 0.8250 V 0.6000 V 0.4000 V
1.2000 V 0.8000 V 0.5875 V 0.3875 V
1.1750 V 0.7750 V 0.5750 V 0.3750 V

The lowest voltage depends from the CPU Model (production process).
On some older Turion and Sempron CPUs (Model E, Stepping 6) the voltage
can't be set under 1.0750 V because they have a hardware voltage lock
inside. On some mainboards there are problems with undervolting under 0.8V.
AMD has extended the CPU voltage range from 0.8 - 1.55 V to 0.375 - 1.55 V
but some mainboard manufacturers don't implement this extension correctly
what could cause the CPU overvolting above 1.55V!
For CPU Models older than E included the lowest possible voltage is 0.8V!

For more informations about AMD K8 CPU Models and Steppings see wikipedia:
http://en.wikipedia.org/wiki/List_of_AMD_Athlon_64_microprocessors
http://en.wikipedia.org/wiki/List_of_AMD_Turion_microprocessors
http://en.wikipedia.org/wiki/List_of_AMD_Sempron_microprocessors
http://en.wikipedia.org/wiki/List_of_AMD_Opteron_microprocessors


STRATEGIES:
-----------

There are 7 strategies supported by cpupowerd daemon:

Strategy 0, MINIMUM:    Changes the frequency to the minimum and holds.
Strategy 1, SINE:       Changes the frequency like a sine wave function, 
                        raising the frequency by "step" Hz every time the 
                        CPU usage goes over a defined value (e.g. 80%) and 
                        decreases it by "step" Hz as it drops below a defined
                        value (e.g. 20%).
Strategy 2, AGGRESSIVE: Changes the frequency like a sawtooth function.
                        Immediately jumps to the highest frequency whenever
                        CPU usage goes over a defined value (e.g. 80%) and 
                        decreases it by "step" Hz as it drops below a defined
                        value (e.g. 20%).
Strategy 3, PASSIVE:    The inverse of AGGRESSIVE. Immediately jump to lowest
                        frequency when CPU usage drops below a defined value
                        (e.g. 20%) and raises by "step" Hz if it goes above a
                        defined value (e.g. 80%)
Strategy 4, BSD:        Changes the frequency like the SINE mode, but raising
                        the frequency by 2 "steps" Hz every time the CPU usage
                        goes over a defined value (e.g. 80%). This is the
                        default behavior - it's a good compromise.
Strategy 5, LEAPS:      Immediately jump to the highest frequency if CPU usage
                        goes above a defined value (e.g. 80%). Immediately
                        jumps to the lowest frequency if CPU usage drops below
                        a defined value (e.g. 20%).
Strategy 6, MAXIMUM:    Changes the frequency to the maximum and holds.


CONCEPT:
--------

Possible cpu layouts (depending on your CPU(s)):

mastercpus       |     affected_cpus
-----------------------------------------

HW: One Socket, SingelCore CPU
[cpuid 0]--------------[cpuid 0]

HW: One Socket, DualCore CPU
[cpuid 0]---------------[cpuid 0]
                 |
                 -------[cpuid 1]

HW: One Socket, TripleCore CPU
[cpuid 0]---------------[cpuid 0]
                 |
                 -------[cpuid 1]

[cpuid 2]---------------[cpuid 2]

HW: One Socket, QuadCore CPU
[cpuid 0]---------------[cpuid 0]
                 |
                 -------[cpuid 1]
                 |
                 -------[cpuid 2]
                 |
                 -------[cpuid 3]

HW: One Socket, QuadCore CPU
[cpuid 0]---------------[cpuid 0]
                 |
                 -------[cpuid 1]
                 
[cpuid 2]---------------[cpuid 2]
                 |
                 -------[cpuid 3]

HW: Dual Socket, 2xQuadCore CPU
[cpuid 0]---------------[cpuid 0]
                 |
                 -------[cpuid 1]
                
[cpuid 2]---------------[cpuid 2]
                 |
                 -------[cpuid 3]

[cpuid 4]---------------[cpuid 4]
                 |
                 -------[cpuid 5]
                
[cpuid 6]---------------[cpuid 6]
                 |
                 -------[cpuid 7]

The daemon changes only the values of the mastercpus. Changes on mastercpu
will be applied on all affected_cpus of the respective mastercpu.
The program checks periodicaly the CPU load. The polling interval is normaly
1 second, but can be tuned to a higher or lower value.
If the CPU frequency is to be changed the CPU voltage will be restored from
the undervolting value to the normal value. Then the frequency change is
executed over the cpufreq kernel modul. At last the CPU voltage is adjusted
to the undervolting value for the new frequency. If you don't want to use all
available frequencies, delete or comment out with # the relevant lines in
config file.
Future releases will change the frequency over the msr modul so voltage
restore will be no more necessary. It also allows you to use more frequencies.


KNOWN PROBLEMS:
---------------

* Extended AMD voltage specifications: AMD changes the possible voltage range
  for the AMD K8 CPUs from 1.55 - 0.8 V to 1.55 - 0.375 V since Model F.
  But some mainboard manufacturers don't implement the extended voltage
  specifications correctly and the CPU can be unintendly overvolted!
  In the most cases 0.775V works correctly, but on lower voltages the CPU
  will be overvolted to 1.55V! I know about some circumstances, but no CPU
  was died. If you do undervolting lower than 0.8V, please check the effect
  with an energy checker and ensure, that the energy consumption don't jump
  to a higher value. If you don't have such a device, please control the
  voltage with lm-sensor (download http://www.lm-sensors.org/) under Linux.

  Known mainboards, which switch of the CPU at 0.775V:
    ASUS M2N-VM DVI
  Known mainboards, which overvolt the CPU to 1.55V at 0.775V:
    ASRock AliveNF7G-HDready, Biostar TF8200 A2+
  Known mainboards, which working normal lower than 0.775V:
    Abit AN-M2(HD), ASRock ALiveNF7G-HD720p, Abit A-N68SV, 
    ASRock AliveNF7G-FullHD 3.0, Gigabyte GA-MA78GM-S2H

* Problems with the hald-addon-cpufreq: In some configurations this hald addon
  makes trouble under Ubuntu 8.04 with Gnome. On my test installation
  cpupowerd worked without any problems with the enclosed start script, linked
  with S99cpupowerd or S23cpupowerd to ../init.d/cpupowerd in /etc/rc2.d.
  I have seen one entry in the log file shortly after the start, that governor
  (and in few cases frequency, too) would be adjusted back to the cpupowerd
  values. After this all worked fine and no other messages appeared.
  If you have such problems, comment out the follow lines in the begining
  section of the start script:
    sleep 30
    killall hald-addon-cpufreq


THANKS:
-------

People that tested the program in alpha status and helped me to develop
this tool:

* Andrea Chin
* Bernhard Fröhlich         decke@bluelife.at
* Bernhard Kornberger       bkorn@ist.tugraz.at
* Grigory Goronzy           greg@geekmind.org
* Martin Peprnik            mpeprnik@inmail.sk
* Sebastian Sieburg         sebi-s@web.de
* Stephan Römer
* Thomas Hinterberger       kult-ex@aon.at

Special thanks to Bernhard Fröhlich for his help on the FreeBSD modul.


