Add 'cpu_frequency' command to cli_monitor (fix #776)

This commit extends the Fiasco.OC specific extensions of the cli_monitor
to enable the user to interactively change or show current CPU frequency
This commit is contained in:
Stefan Kalkowski 2013-06-24 13:08:33 +02:00 committed by Norman Feske
parent cb01f75a9d
commit 5a3c2c33b7
3 changed files with 88 additions and 19 deletions

View File

@ -60,18 +60,18 @@ namespace Regulator {
***************************************/
enum Cpu_clock_freq {
CPU_FREQ_200,
CPU_FREQ_400,
CPU_FREQ_600,
CPU_FREQ_800,
CPU_FREQ_1000,
CPU_FREQ_1200,
CPU_FREQ_1400,
CPU_FREQ_1600,
CPU_FREQ_1700, /* warning: 1700 not recommended by the reference manual
we just insert this for performance measurement against
Linux, which uses this overclocking */
CPU_FREQ_MAX
CPU_FREQ_200 = 200000000,
CPU_FREQ_400 = 400000000,
CPU_FREQ_600 = 600000000,
CPU_FREQ_800 = 800000000,
CPU_FREQ_1000 = 1000000000,
CPU_FREQ_1200 = 1200000000,
CPU_FREQ_1400 = 1400000000,
CPU_FREQ_1600 = 1600000000,
CPU_FREQ_1700 = 1700000000,
/* warning: 1700 not recommended by the reference manual
we just insert this for performance measurement against
Linux, which uses this overclocking */
};
}

View File

@ -11,9 +11,14 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <regulator_session/connection.h>
#include <util/string.h>
/* local includes */
#include <extension.h>
#include <terminal_util.h>
#include <command_line.h>
/* Fiasco includes */
namespace Fiasco {
@ -64,8 +69,40 @@ struct Reboot_command : Command
};
struct Cpufreq_command : Command
{
Regulator::Connection &regulator;
Cpufreq_command(Regulator::Connection &r)
: Command("cpu_frequency", "set/show CPU frequency"),
regulator(r) { }
void execute(Command_line &cmd, Terminal::Session &terminal)
{
char freq[128];
freq[0] = 0;
if (cmd.argument(0, freq, sizeof(freq)) == false) {
tprintf(terminal, "Current CPU frequency: %ld Hz\n",
regulator.level());
return;
}
unsigned long f = 0;
Genode::ascii_to(freq, &f, 10);
tprintf(terminal, "set frequency to %ld Hz\n", f);
regulator.set_level(f);
}
};
void init_extension(Command_registry &commands)
{
try { /* only inserts commands if route to regulator session exists */
static Regulator::Connection reg(Regulator::CLK_CPU);
static Cpufreq_command cpufreq_command(reg);
commands.insert(&cpufreq_command);
} catch (...) { PDBG("No regulator session available!"); };
static Kdebug_command kdebug_command;
commands.insert(&kdebug_command);

View File

@ -236,8 +236,44 @@ class Cmu : public Regulator::Driver,
Cpu_clock_freq _cpu_freq;
void _cpu_clk_freq(Cpu_clock_freq freq)
void _cpu_clk_freq(unsigned long level)
{
unsigned freq;
switch (level) {
case CPU_FREQ_200:
freq = 0;
break;
case CPU_FREQ_400:
freq = 1;
break;
case CPU_FREQ_600:
freq = 2;
break;
case CPU_FREQ_800:
freq = 3;
break;
case CPU_FREQ_1000:
freq = 4;
break;
case CPU_FREQ_1200:
freq = 5;
break;
case CPU_FREQ_1400:
freq = 6;
break;
case CPU_FREQ_1600:
freq = 7;
break;
case CPU_FREQ_1700:
freq = 8;
break;
default:
PWRN("Unsupported CPU frequency level %ld", level);
PWRN("Supported values are 200, 400, 600, 800 MHz");
PWRN("and 1, 1.2, 1.4, 1.6, 1.7 GHz");
return;
};
/**
* change clock divider values
*/
@ -276,7 +312,7 @@ class Cmu : public Regulator::Driver,
while (read<Clk_mux_stat_cpu::Cpu_sel>()
!= Clk_mux_stat_cpu::Cpu_sel::MOUT_APLL) ;
_cpu_freq = freq;
_cpu_freq = static_cast<Cpu_clock_freq>(level);
}
@ -408,11 +444,7 @@ class Cmu : public Regulator::Driver,
{
switch (id) {
case CLK_CPU:
if (level >= CPU_FREQ_MAX) {
PWRN("level=%ld not supported", level);
return;
}
_cpu_clk_freq(static_cast<Cpu_clock_freq>(level));
_cpu_clk_freq(level);
break;
default:
PWRN("Unsupported for %s", names[id].name);