0. Warning ========== USE THIS PROGRAM AT YOU OWN RISK. IT MAY DAMAGE YOUR HARDWARE. 1. What the program can do ========================== * It is intended for Intel Core and Core 2 CPU's, but it also may work with other processors (namely processors with Intel SpeedStep) * It runs under Linux * It can change the processor frequency and voltage; * enable SpeedStep (e.g. if it was disabled by the BIOS due to overclocking); * read out frequency and voltage information 2. Requirements =============== * A Linux kernel with MSR support (Processor type and features --> /dev/cpu/*/msr - Model-specific register support) and write access to /dev/cpu/*/msr * Libraries: none (linked statically) * For Compiling: Freepascal compiler (http://www.freepascal.org) 3. Usage ======== c2ctl <cpu>[-<cpun>] Print some information about CPU(s) <cpu>(-<cpun>) c2ctl <cpu>[-<cpun>] <fid> <vid> Set fid and vid for CPU(s) <cpu>(-<cpun>) and enable EIST if necessary. c2ctl <cpu>[-<cpun>] -e Enable EIST for CPU(s) <cpu>(-<cpun>) c2ctl <cpu> -a Print DSDT template for CPU <cpu> using the current settings c2ctl -h Help 4. Meaning of the fid and vid ============================= The frequency ID (fid) is the multiplier for the reference clock (e.g. the FSB clock). The voltage ID (vid) is processor specific. Unfortunately Intel publishes no information about the meaning of this value but the conversion formula for Core CPU's seems to be UCpu = 700 mV + vid*12.5 mV and for Core 2 CPU's it seems to be UCpu = 800 mV + vid*12.5 mV . 5. Examples =========== c2ctl 0-3 8 32 Set fid=8 and vid=32 for CPUs 0-3 c2ctl 0 -a Print a DSDT template for CPU 0 6. Modifying core frequency and voltage ======================================= 1. Make sure, that the core voltage can be adjusted by the CPU. (E.g. set BIOS setting to "Normal" or "Auto".) 2. Read out the current and minimum / maximum settings using # c2ctl 0-3 (assuming you have 4 cores) in order to get a reference. The fid usually is the frequency multiplier. Higher vid's mean higher voltages. Unfortunately Intel publishes no formulas or tables for converting vid's to voltages. 3. Modify core frequency and voltage as desired. For example, # c2ctl 0-3 8 32 sets fid=8 and vid=32 to the first 4 cores. 7. Enabling Enhanced Intel SpeedStep ==================================== If SpeedStep is disabled (for example due to overclocking) it can be enabled simply using e.g. # c2ctl <cpu>[-<cpun>] -e But in order to use automatic performance scaling (using cpufreq) you need to inform the kernel about working fid-vid pairs. The most elegant way to do this is to modify the DSDT: 1. Find stable fid-vid pairs by repeating steps 1-3 of Section 4. 2. Modify the DSDT as described in [1,2]. You need to add one _PCT object, one _PSS object and one _PPC object to every Processor object as described in [3, Section 8.4.4], see also [4]. The _PSS object defines the so called P-States. Each P-State contains one fid-vid pair. The P-States are ordered, the fastest P-State is the first one. As a helper for the DSDT modification the command # c2ctl <cpu> -a can be used to create a DSDT template. 3. Include the new DSDT into the kernel as described in [1]. The acpi-cpufreq driver should be loaded now. To get it working you need to enable SpeedStep using # c2ctl <cpu>[-<cpun>] -e An example section of a DSDT, which defines 3 P-States for a Q9450 Core 2 Quad Processor running with a FSB frequency of 388 MHz is listed below. 8. References ============= [1] Overriding a DSDT, http://www.lesswatts.org/projects/acpi/overridingDSDT.php [2] HOWTO: Fix Common ACPI Problems (DSDT, ECDT, etc.), http://gentoo-wiki.com/HOWTO_Fix_Common_ACPI_Problems [3] ACPI Specification, http://www.acpi.info/DOWNLOADS/ACPIspec30a.pdf [4] Intel and IA-32 Architectures Software Developer's Manual Volume 3B, Appendix B http://www.intel.com/products/processor/manuals 9. DSDT Example =============== Scope (\_PR) { Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) { Name (_PPC, 0x00) Name (_PCT, Package (0x02) { ResourceTemplate () { Register (FFixedHW, // PERF_CTL 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000199, // Address ,) }, ResourceTemplate () { Register (FFixedHW, // PERF_STATUS 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000198, // Address ,) } }) Name (_PSS, Package (0x03) { Package (0x06) // P-State 0 { 3104, // f in MHz 75000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x00000820, // value written to PERF_CTL; fid=8, vid=32 0x00000820 // value of PERF_STATE after successful transition; fid=8, vid=32 }, Package (0x06) // P-State 1 { 2716, // f in MHz 65000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000071C, // value written to PERF_CTL; fid=7, vid=28 0x0000071C // value of PERF_STATE after successful transition; fid=7, vid=28 }, Package (0x06) // P-State 2 { 2328, // f in MHz 60000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000061A, // value written to PERF_CTL; fid=6, vid=26 0x0000061A // value of PERF_STATE after successful transition; fid=6, vid=26 }, }) } Processor (\_PR.CPU1, 0x01, 0x00000410, 0x06) { Name (_PPC, 0x00) Name (_PCT, Package (0x02) { ResourceTemplate () { Register (FFixedHW, // PERF_CTL 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000199, // Address ,) }, ResourceTemplate () { Register (FFixedHW, // PERF_STATUS 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000198, // Address ,) } }) Name (_PSS, Package (0x03) { Package (0x06) // P-State 0 { 3104, // f in MHz 75000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x00000820, // value written to PERF_CTL; fid=8, vid=32 0x00000820 // value of PERF_STATE after successful transition; fid=8, vid=32 }, Package (0x06) // P-State 1 { 2716, // f in MHz 65000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000071C, // value written to PERF_CTL; fid=7, vid=28 0x0000071C // value of PERF_STATE after successful transition; fid=7, vid=28 }, Package (0x06) // P-State 2 { 2328, // f in MHz 60000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000061A, // value written to PERF_CTL; fid=6, vid=26 0x0000061A // value of PERF_STATE after successful transition; fid=6, vid=26 }, }) } Processor (\_PR.CPU2, 0x02, 0x00000410, 0x06) { Name (_PPC, 0x00) Name (_PCT, Package (0x02) { ResourceTemplate () { Register (FFixedHW, // PERF_CTL 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000199, // Address ,) }, ResourceTemplate () { Register (FFixedHW, // PERF_STATUS 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000198, // Address ,) } }) Name (_PSS, Package (0x03) { Package (0x06) // P-State 0 { 3104, // f in MHz 75000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x00000820, // value written to PERF_CTL; fid=8, vid=32 0x00000820 // value of PERF_STATE after successful transition; fid=8, vid=32 }, Package (0x06) // P-State 1 { 2716, // f in MHz 65000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000071C, // value written to PERF_CTL; fid=7, vid=28 0x0000071C // value of PERF_STATE after successful transition; fid=7, vid=28 }, Package (0x06) // P-State 2 { 2328, // f in MHz 60000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000061A, // value written to PERF_CTL; fid=6, vid=26 0x0000061A // value of PERF_STATE after successful transition; fid=6, vid=26 }, }) } Processor (\_PR.CPU3, 0x03, 0x00000410, 0x06) { Name (_PPC, 0x00) Name (_PCT, Package (0x02) { ResourceTemplate () { Register (FFixedHW, // PERF_CTL 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000199, // Address ,) }, ResourceTemplate () { Register (FFixedHW, // PERF_STATUS 0x10, // Bit Width 0x00, // Bit Offset 0x0000000000000198, // Address ,) } }) Name (_PSS, Package (0x03) { Package (0x06) // P-State 0 { 3104, // f in MHz 75000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x00000820, // value written to PERF_CTL; fid=8, vid=32 0x00000820 // value of PERF_STATE after successful transition; fid=8, vid=32 }, Package (0x06) // P-State 1 { 2716, // f in MHz 65000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000071C, // value written to PERF_CTL; fid=7, vid=28 0x0000071C // value of PERF_STATE after successful transition; fid=7, vid=28 }, Package (0x06) // P-State 2 { 2328, // f in MHz 60000, // P in mW 10, // Transition latency in us 10, // Bus Master latency in us 0x0000061A, // value written to PERF_CTL; fid=6, vid=26 0x0000061A // value of PERF_STATE after successful transition; fid=6, vid=26 }, }) } }