* Committed Clemens Zeidler's Intel speedstep driver. Thanks a lot, Clemens!
This is a very welcome addition. * There are a few issues, and maybe questionable decisions (like the dependence on ACPI), but I see no reason why it shouldn't be added in its current form already. * Unfortunately, I could not test it yet, though, as the CPU of my laptop is not supported; will see if I can find a supported hardware, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28903 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7a6bda7716
commit
40890e97b3
39
headers/private/device/power_managment.h
Normal file
39
headers/private/device/power_managment.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef POWER_MANAGMENT_H
|
||||
#define POWER_MANAGMENT_H
|
||||
|
||||
#include <Drivers.h>
|
||||
|
||||
// io controls
|
||||
enum {
|
||||
// ioctl response with kMagicFreqID
|
||||
IDENTIFY_DEVICE = B_DEVICE_OP_CODES_END + 20001,
|
||||
|
||||
// CPU Frequence:
|
||||
// get a list of freq_info, the list is terminated with a element with
|
||||
// frequency = 0
|
||||
GET_CPU_FREQ_STATES = B_DEVICE_OP_CODES_END + 20005,
|
||||
// get and set a freq_info
|
||||
GET_CURENT_CPU_FREQ_STATE,
|
||||
SET_CPU_FREQ_STATE,
|
||||
// start watching for frequency changes, ioctl blocks until the frequency
|
||||
// has changed
|
||||
WATCH_CPU_FREQ,
|
||||
// stop all watching ioctl, ioctl return B_ERROR
|
||||
STOP_WATCHING_CPU_FREQ
|
||||
};
|
||||
|
||||
// CPU Frequence:
|
||||
// magic id returned by IDENTIFY_DEVICE
|
||||
const uint32 kMagicFreqID = 48921;
|
||||
|
||||
#define MAX_CPU_FREQUENCY_STATES 10
|
||||
|
||||
typedef struct {
|
||||
uint16 frequency; // [Mhz]
|
||||
uint16 volts;
|
||||
uint16 id;
|
||||
int power;
|
||||
} freq_info;
|
||||
|
||||
|
||||
#endif
|
@ -3,3 +3,4 @@ SubDir HAIKU_TOP src add-ons kernel drivers power ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_button ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_lid ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers power acpi_thermal ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers power enhanced_speedstep ;
|
||||
|
18
src/add-ons/kernel/drivers/power/enhanced_speedstep/Jamfile
Normal file
18
src/add-ons/kernel/drivers/power/enhanced_speedstep/Jamfile
Normal file
@ -0,0 +1,18 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers power enhanced_speedstep ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
# Needed for <ACPI.h>. Unfortunately we also get the other headers there,
|
||||
# that we don't really want.
|
||||
UsePublicHeaders drivers ;
|
||||
}
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
|
||||
KernelAddon enhanced_speedstep :
|
||||
enhanced_speedstep.cpp
|
||||
frequency.cpp
|
||||
;
|
||||
|
||||
Depends acpi_enhanced_speedstep : acpi ;
|
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <Drivers.h>
|
||||
#include <Errors.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <kernel/arch/x86/arch_cpu.h>
|
||||
|
||||
#include <ACPI.h>
|
||||
#include "enhanced_speedstep.h"
|
||||
#include <condition_variable.h>
|
||||
|
||||
#include "frequency.h"
|
||||
|
||||
|
||||
#define EST_MODULE_NAME "drivers/power/enhanced_speedstep/driver_v1"
|
||||
|
||||
#define EST_DEVICE_MODULE_NAME "drivers/power/enhanced_speedstep/device_v1"
|
||||
|
||||
/* Base Namespace devices are published to */
|
||||
#define EST_BASENAME "power/enhanced_speedstep/%d"
|
||||
|
||||
// name of pnp generator of path ids
|
||||
#define EST_PATHID_GENERATOR "est/path_id"
|
||||
|
||||
static device_manager_info *sDeviceManager;
|
||||
static ConditionVariable cv_frequency;
|
||||
vint32 current_id;
|
||||
|
||||
status_t est_control(void* _cookie, uint32 op, void* arg, size_t len);
|
||||
|
||||
|
||||
static status_t
|
||||
est_open(void *initCookie, const char *path, int flags, void** cookie)
|
||||
{
|
||||
TRACE("est: open\n");
|
||||
est_cookie *device = (est_cookie*)initCookie;
|
||||
*cookie = device;
|
||||
device->stop_watching = 0;
|
||||
|
||||
// enable enhanced speedstep
|
||||
TRACE("est: check if enhanced speedstep is enabled\n");
|
||||
uint64 msrMisc = x86_read_msr(MSR_MISC);
|
||||
if ((msrMisc & MSR_EST_ENABLED) == 0) {
|
||||
TRACE("est: enable enhanced speedstep\n");
|
||||
x86_write_msr(MSR_MISC, msrMisc | MSR_EST_ENABLED);
|
||||
|
||||
uint64 msrMisc = x86_read_msr(MSR_MISC);
|
||||
if ((msrMisc & MSR_EST_ENABLED) == 0) {
|
||||
TRACE("est: enable enhanced speedstep failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// get freq_info
|
||||
if (est_get_info(&(device->available_states)) != B_OK)
|
||||
return B_ERROR;
|
||||
freq_info *freqsInfo = device->available_states;
|
||||
|
||||
// count number of states
|
||||
TRACE("est: frequency info:\n");
|
||||
freq_info *f;
|
||||
device->number_states = 0;
|
||||
for (f = freqsInfo; f->frequency != 0; f++) {
|
||||
TRACE("est: Frequency %u, Volts %u, Power %i, Latency %u, id %u\n",
|
||||
f->frequency, f->volts, f->power, f->id, EST_TRANS_LAT);
|
||||
device->number_states++;
|
||||
}
|
||||
|
||||
// print current frequency
|
||||
freq_info *f2 = est_get_current(freqsInfo);
|
||||
if (f2) {
|
||||
TRACE("est: Current Frequency %u, Volts %u, Power %i, Latency %u\n",
|
||||
f2->frequency, f2->volts, f2->power, EST_TRANS_LAT);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_read(void* _cookie, off_t position, void *buf, size_t* num_bytes)
|
||||
{
|
||||
TRACE("est: est_read\n");
|
||||
|
||||
if (*num_bytes < 1)
|
||||
return B_IO_ERROR;
|
||||
|
||||
est_cookie *device = (est_cookie *)_cookie;
|
||||
|
||||
if (position == 0) {
|
||||
size_t max_len = *num_bytes;
|
||||
char *str = (char *)buf;
|
||||
|
||||
snprintf(str, max_len, "CPU Frequency states:\n");
|
||||
max_len-= strlen(str);
|
||||
str += strlen(str);
|
||||
|
||||
freq_info *freqsInfo = device->available_states;
|
||||
freq_info *f;
|
||||
for (f = freqsInfo; f->frequency != 0; f++) {
|
||||
snprintf(str, max_len, " Frequency %hu, Volts %hu, Power %i, Latency %i, id %hu\n",
|
||||
f->frequency, f->volts, f->power, f->id,
|
||||
EST_TRANS_LAT);
|
||||
max_len-= strlen(str);
|
||||
str += strlen(str);
|
||||
}
|
||||
|
||||
freq_info *f2 = est_get_current(freqsInfo);
|
||||
if (f2) {
|
||||
snprintf(str, max_len, "\nCurrent State: Frequency %hu, Volts %hu, Power %i, Latency %i\n",
|
||||
f2->frequency, f2->volts, f2->power, EST_TRANS_LAT);
|
||||
}
|
||||
|
||||
*num_bytes = strlen((char *)buf);
|
||||
} else {
|
||||
*num_bytes = 0;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
est_control(void* _cookie, uint32 op, void* arg, size_t len)
|
||||
{
|
||||
TRACE("est: est_control op %u\n", int(op));
|
||||
est_cookie* device = (est_cookie*)_cookie;
|
||||
status_t err = B_ERROR;
|
||||
|
||||
uint32* magicId;
|
||||
uint16* id;
|
||||
freq_info* freqInfo = NULL;
|
||||
switch (op) {
|
||||
case IDENTIFY_DEVICE:
|
||||
if (len < sizeof(uint32))
|
||||
return B_IO_ERROR;
|
||||
magicId = (uint32*)arg;
|
||||
*magicId = kMagicFreqID;
|
||||
err = B_OK;
|
||||
break;
|
||||
|
||||
case GET_CPU_FREQ_STATES:
|
||||
if (len < sizeof(freq_info) * (device->number_states + 1))
|
||||
return B_IO_ERROR;
|
||||
freqInfo = (freq_info*)arg;
|
||||
user_memcpy(freqInfo, device->available_states,
|
||||
sizeof(freq_info) * (device->number_states + 1));
|
||||
err = B_OK;
|
||||
break;
|
||||
|
||||
case GET_CURENT_CPU_FREQ_STATE:
|
||||
if (len < sizeof(uint16))
|
||||
return B_IO_ERROR;
|
||||
freqInfo = est_get_current(device->available_states);
|
||||
if (!freqInfo)
|
||||
return B_ERROR;
|
||||
atomic_set(¤t_id, freqInfo->id);
|
||||
*((uint16*)arg) = freqInfo->id;
|
||||
err = B_OK;
|
||||
break;
|
||||
|
||||
case SET_CPU_FREQ_STATE:
|
||||
if (len < sizeof(uint16))
|
||||
return B_IO_ERROR;
|
||||
id = (uint16*)arg;
|
||||
err = est_set_id16(*id);
|
||||
if (err == B_OK) {
|
||||
atomic_set(¤t_id, *id);
|
||||
cv_frequency.NotifyAll();
|
||||
}
|
||||
break;
|
||||
|
||||
case WATCH_CPU_FREQ:
|
||||
if (len < sizeof(uint16))
|
||||
return B_IO_ERROR;
|
||||
cv_frequency.Wait();
|
||||
if (atomic_get(&(device->stop_watching))) {
|
||||
atomic_set(&(device->stop_watching), 0);
|
||||
err = B_ERROR;
|
||||
}
|
||||
else {
|
||||
*((uint16*)arg) = atomic_get(¤t_id);
|
||||
err = B_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case STOP_WATCHING_CPU_FREQ:
|
||||
atomic_set(&(device->stop_watching), 1);
|
||||
cv_frequency.NotifyAll();
|
||||
err = B_OK;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_close (void* cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_free (void* cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - driver module API
|
||||
|
||||
|
||||
static float
|
||||
est_support(device_node *parent)
|
||||
{
|
||||
const char *bus;
|
||||
uint32 device_type;
|
||||
|
||||
dprintf("EST1\n");
|
||||
// make sure parent is really the ACPI bus manager
|
||||
if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
|
||||
return -1;
|
||||
dprintf("EST2\n");
|
||||
|
||||
if (strcmp(bus, "acpi"))
|
||||
return 0.0;
|
||||
dprintf("EST3\n");
|
||||
|
||||
// check whether it's really a cpu Device
|
||||
if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM,
|
||||
&device_type, false) != B_OK
|
||||
|| device_type != ACPI_TYPE_PROCESSOR) {
|
||||
return 0.0;
|
||||
}
|
||||
dprintf("EST4\n");
|
||||
TRACE("est_support: supported\n");
|
||||
|
||||
// check if cpu support est
|
||||
uint32 cpuNum = 0;
|
||||
system_info sysInfo;
|
||||
if (get_system_info(&sysInfo) != B_OK)
|
||||
return 0.0;
|
||||
TRACE("cpu_type: %u vendor %u model %u\n", sysInfo.cpu_type,
|
||||
sysInfo.cpu_type & B_CPU_x86_VENDOR_MASK,
|
||||
sysInfo.cpu_type & 0x00FF);
|
||||
dprintf("EST5\n");
|
||||
if ((sysInfo.cpu_type & B_CPU_x86_VENDOR_MASK) != B_CPU_INTEL_x86)
|
||||
return 0.0;
|
||||
dprintf("EST6\n");
|
||||
|
||||
TRACE("ext\n");
|
||||
cpuid_info info;
|
||||
if (get_cpuid(&info, 1, cpuNum) != B_OK)
|
||||
return 0.0;
|
||||
dprintf("EST7\n");
|
||||
|
||||
TRACE("extended_features: %i\n", int(info.eax_1.extended_features));
|
||||
dprintf("EST8\n");
|
||||
|
||||
// check for enhanced speedstep
|
||||
if (info.eax_1.extended_features & IA32_FEATURE_EXT_EST)
|
||||
TRACE("supprot est\n");
|
||||
else
|
||||
return 0.0;
|
||||
dprintf("EST9\n");
|
||||
|
||||
TRACE("success\n");
|
||||
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_register_device(device_node *node)
|
||||
{
|
||||
device_attr attrs[] = {
|
||||
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
|
||||
{ string: "ACPI Enhanced Speedstep" }},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
return sDeviceManager->register_node(node, EST_MODULE_NAME, attrs,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_init_driver(device_node *node, void **_driverCookie)
|
||||
{
|
||||
*_driverCookie = node;
|
||||
|
||||
cv_frequency.Init(NULL, "frequency cv");
|
||||
current_id = -1;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
est_uninit_driver(void *driverCookie)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_register_child_devices(void *_cookie)
|
||||
{
|
||||
device_node *node = (device_node*)_cookie;
|
||||
int path_id;
|
||||
char name[128];
|
||||
|
||||
path_id = sDeviceManager->create_id(EST_PATHID_GENERATOR);
|
||||
if (path_id < 0) {
|
||||
TRACE("est_register_child_devices: couldn't create a path_id\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), EST_BASENAME, path_id);
|
||||
|
||||
return sDeviceManager->publish_device(node, name, EST_DEVICE_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
est_init_device(void *driverCookie, void **cookie)
|
||||
{
|
||||
est_cookie *device;
|
||||
device = (est_cookie *)calloc(1, sizeof(est_cookie));
|
||||
if (device == NULL)
|
||||
return B_NO_MEMORY;
|
||||
*cookie = device;
|
||||
|
||||
device_node *node = (device_node *)driverCookie;
|
||||
device->node = node;
|
||||
|
||||
device_node *parent;
|
||||
parent = sDeviceManager->get_parent_node(node);
|
||||
sDeviceManager->get_driver(parent, (driver_module_info **)&device->acpi,
|
||||
(void **)&device->acpi_cookie);
|
||||
sDeviceManager->put_node(parent);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
est_uninit_device(void *_cookie)
|
||||
{
|
||||
TRACE("est: est_uninit_device\n");
|
||||
est_cookie *device = (est_cookie*)_cookie;
|
||||
free(device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
module_dependency module_dependencies[] = {
|
||||
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
driver_module_info est_driver_module = {
|
||||
{
|
||||
EST_MODULE_NAME,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
|
||||
est_support,
|
||||
est_register_device,
|
||||
est_init_driver,
|
||||
est_uninit_driver,
|
||||
est_register_child_devices,
|
||||
NULL, // rescan
|
||||
NULL, // removed
|
||||
};
|
||||
|
||||
|
||||
struct device_module_info est_device_module = {
|
||||
{
|
||||
EST_DEVICE_MODULE_NAME,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
|
||||
est_init_device,
|
||||
est_uninit_device,
|
||||
NULL,
|
||||
|
||||
est_open,
|
||||
est_close,
|
||||
est_free,
|
||||
est_read,
|
||||
est_write,
|
||||
NULL,
|
||||
est_control,
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&est_driver_module,
|
||||
(module_info *)&est_device_module,
|
||||
NULL
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
#ifndef _EST_H
|
||||
#define _EST_H
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <ACPI.h>
|
||||
|
||||
#include "frequency.h"
|
||||
|
||||
// Model Specific Register
|
||||
#define MSR_MISC 0x1a0
|
||||
#define MSR_EST_ENABLED (1<<16)
|
||||
|
||||
|
||||
struct est_cookie {
|
||||
// this three variables are not needed yet but helpfull when extend this
|
||||
// driver to use acpi
|
||||
device_node *node;
|
||||
acpi_device_module_info *acpi;
|
||||
acpi_device acpi_cookie;
|
||||
|
||||
// array of states don't delete it
|
||||
freq_info* available_states;
|
||||
uint8 number_states;
|
||||
|
||||
vint32 stop_watching;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _EST_H */
|
@ -0,0 +1,197 @@
|
||||
#include "frequency.h"
|
||||
|
||||
#include <kernel/arch/x86/arch_cpu.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void
|
||||
est_get_id16(uint16 *id16_p)
|
||||
{
|
||||
*id16_p = x86_read_msr(MSR_GET_FREQ_STATE) & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
est_set_id16(uint16 id16, bool need_check)
|
||||
{
|
||||
uint64 msr;
|
||||
|
||||
// Read the current register, mask out the old, set the new id.
|
||||
msr = x86_read_msr(MSR_GET_FREQ_STATE);
|
||||
msr = (msr & ~0xffff) | id16;
|
||||
x86_write_msr(MSR_SET_FREQ_STATE, msr);
|
||||
|
||||
if (need_check) {
|
||||
// Wait a short while for the new setting. XXX Is this necessary?
|
||||
snooze(EST_TRANS_LAT);
|
||||
|
||||
uint16 new_id16;
|
||||
est_get_id16(&new_id16);
|
||||
if (new_id16 != id16)
|
||||
return B_ERROR;
|
||||
TRACE("EST: set frequency ok, id %i\n", id16);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
freq_info *
|
||||
est_get_current(freq_info *freq_list)
|
||||
{
|
||||
freq_info *f;
|
||||
int i;
|
||||
uint16 id16;
|
||||
|
||||
/*
|
||||
* Try a few times to get a valid value. Sometimes, if the CPU
|
||||
* is in the middle of an asynchronous transition (i.e., P4TCC),
|
||||
* we get a temporary invalid result.
|
||||
*/
|
||||
for (i = 0; i < 5; i++) {
|
||||
est_get_id16(&id16);
|
||||
for (f = freq_list; f->id != 0; f++) {
|
||||
if (f->id == id16)
|
||||
return (f);
|
||||
}
|
||||
snooze(100);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
est_get_info(freq_info **freqsInfo)
|
||||
{
|
||||
uint64 msr;
|
||||
status_t error = B_ERROR;
|
||||
|
||||
msr = x86_read_msr(MSR_GET_FREQ_STATE);
|
||||
error = est_table_info(msr, freqsInfo);
|
||||
if (error != B_OK) {
|
||||
TRACE("EST: Get frequency table from model specific register\n");
|
||||
error = est_msr_info(msr, freqsInfo);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
TRACE("est: CPU supports Enhanced Speedstep, but is not recognized.\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
est_table_info(uint64 msr, freq_info **freqs)
|
||||
{
|
||||
ss_cpu_info *p;
|
||||
uint32 id;
|
||||
|
||||
/* Find a table which matches (vendor, id32). */
|
||||
system_info sysInfo;
|
||||
if (get_system_info(&sysInfo) != B_OK)
|
||||
return B_ERROR;
|
||||
id = msr >> 32;
|
||||
for (p = ESTprocs; p->id32 != 0; p++) {
|
||||
if (p->vendor_id == uint32(sysInfo.cpu_type & B_CPU_x86_VENDOR_MASK)
|
||||
&& p->id32 == id)
|
||||
break;
|
||||
}
|
||||
if (p->id32 == 0)
|
||||
return B_ERROR;
|
||||
|
||||
/* Make sure the current setpoint is valid. */
|
||||
if (est_get_current(p->freqtab) == NULL) {
|
||||
TRACE("current setting not found in table\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
*freqs = p->freqtab;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bus_speed_ok(int bus)
|
||||
{
|
||||
switch (bus) {
|
||||
case 100:
|
||||
case 133:
|
||||
case 333:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flesh out a simple rate table containing the high and low frequencies
|
||||
* based on the current clock speed and the upper 32 bits of the MSR.
|
||||
*/
|
||||
status_t
|
||||
est_msr_info(uint64 msr, freq_info **freqs)
|
||||
{
|
||||
freq_info *fp;
|
||||
int32 bus, freq, volts;
|
||||
uint16 id;
|
||||
|
||||
// Figure out the bus clock.
|
||||
system_info sysInfo;
|
||||
if (get_system_info(&sysInfo) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
freq = sysInfo.cpu_clock_speed / 1000000;
|
||||
id = msr >> 32;
|
||||
bus = freq / (id >> 8);
|
||||
|
||||
TRACE("est: Guessed bus clock (high) of %d MHz\n", int(bus));
|
||||
if (!bus_speed_ok(bus)) {
|
||||
// We may be running on the low frequency.
|
||||
id = msr >> 48;
|
||||
bus = freq / (id >> 8);
|
||||
TRACE("est: Guessed bus clock (low) of %d MHz\n", int(bus));
|
||||
if (!bus_speed_ok(bus))
|
||||
return B_ERROR;
|
||||
|
||||
// Calculate high frequency.
|
||||
id = msr >> 32;
|
||||
freq = ((id >> 8) & 0xff) * bus;
|
||||
}
|
||||
|
||||
// Fill out a new freq table containing just the high and low freqs.
|
||||
fp = (freq_info*)malloc(sizeof(freq_info) * 3);
|
||||
memset(fp, 0, sizeof(freq_info) * 3);
|
||||
|
||||
// First, the high frequency.
|
||||
volts = id & 0xff;
|
||||
if (volts != 0) {
|
||||
volts <<= 4;
|
||||
volts += 700;
|
||||
}
|
||||
fp[0].frequency = freq;
|
||||
fp[0].volts = volts;
|
||||
fp[0].id = id;
|
||||
fp[0].power = CPUFREQ_VAL_UNKNOWN;
|
||||
TRACE("Guessed high setting of %d MHz @ %d Mv\n", int(freq), int(volts));
|
||||
|
||||
// Second, the low frequency.
|
||||
id = msr >> 48;
|
||||
freq = ((id >> 8) & 0xff) * bus;
|
||||
volts = id & 0xff;
|
||||
if (volts != 0) {
|
||||
volts <<= 4;
|
||||
volts += 700;
|
||||
}
|
||||
fp[1].frequency = freq;
|
||||
fp[1].volts = volts;
|
||||
fp[1].id = id;
|
||||
fp[1].power = CPUFREQ_VAL_UNKNOWN;
|
||||
TRACE("Guessed low setting of %d MHz @ %d Mv\n", int(freq), int(volts));
|
||||
|
||||
// Table is already terminated due to M_ZERO.
|
||||
*freqs = fp;
|
||||
return B_OK;
|
||||
}
|
852
src/add-ons/kernel/drivers/power/enhanced_speedstep/frequency.h
Normal file
852
src/add-ons/kernel/drivers/power/enhanced_speedstep/frequency.h
Normal file
@ -0,0 +1,852 @@
|
||||
#ifndef FREQ_TABLE_H
|
||||
#define FREQ_TABLE_H
|
||||
|
||||
#include <OS.h>
|
||||
#include <KernelExport.h>
|
||||
#include <Errors.h>
|
||||
|
||||
#include "device/power_managment.h"
|
||||
|
||||
#define TRACE_EST
|
||||
#ifdef TRACE_EST
|
||||
# define TRACE(x...) dprintf(x)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
#endif
|
||||
|
||||
// this code is taken from freeBSD
|
||||
|
||||
#define MSR_GET_FREQ_STATE 0x198
|
||||
#define MSR_SET_FREQ_STATE 0x199
|
||||
|
||||
/* Estimate in microseconds of latency for performing a transition. */
|
||||
#define EST_TRANS_LAT 1000
|
||||
|
||||
/* Identifying characteristics of a processor and supported frequencies. */
|
||||
typedef struct {
|
||||
const uint32 vendor_id;
|
||||
uint32 id32;
|
||||
freq_info *freqtab;
|
||||
} ss_cpu_info;
|
||||
|
||||
|
||||
status_t est_get_info(freq_info **freqsInfo);
|
||||
status_t est_table_info(uint64 msr, freq_info **freqs);
|
||||
status_t est_msr_info(uint64 msr, freq_info **freqs);
|
||||
|
||||
freq_info* est_get_current(freq_info *freq_list);
|
||||
void est_get_id16(uint16 *id16_p);
|
||||
status_t est_set_id16(uint16 id16, bool need_check = false);
|
||||
|
||||
/* Convert MHz and mV into IDs for passing to the MSR. */
|
||||
#define ID16(MHz, mV, bus_clk) \
|
||||
(((MHz / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
|
||||
#define ID32(MHz_hi, mV_hi, MHz_lo, mV_lo, bus_clk) \
|
||||
((ID16(MHz_lo, mV_lo, bus_clk) << 16) | (ID16(MHz_hi, mV_hi, bus_clk)))
|
||||
|
||||
/* Format for storing IDs in our table. */
|
||||
#define CPUFREQ_VAL_UNKNOWN (-1)
|
||||
#define CPU_VENDOR_INTEL B_CPU_INTEL_x86
|
||||
#define CPU_VENDOR_CENTAUR B_CPU_VIA_IDT_x86
|
||||
|
||||
#define FREQ_INFO_PWR(MHz, mV, bus_clk, mW) \
|
||||
{ MHz, mV, ID16(MHz, mV, bus_clk), mW }
|
||||
#define FREQ_INFO(MHz, mV, bus_clk) \
|
||||
FREQ_INFO_PWR(MHz, mV, bus_clk, CPUFREQ_VAL_UNKNOWN)
|
||||
#define INTEL(tab, zhi, vhi, zlo, vlo, bus_clk) \
|
||||
{ CPU_VENDOR_INTEL, ID32(zhi, vhi, zlo, vlo, bus_clk), tab }
|
||||
#define CENTAUR(tab, zhi, vhi, zlo, vlo, bus_clk) \
|
||||
{ CPU_VENDOR_CENTAUR, ID32(zhi, vhi, zlo, vlo, bus_clk), tab }
|
||||
|
||||
/* Default bus clock value for Centrino processors. */
|
||||
#define INTEL_BUS_CLK 100
|
||||
|
||||
/*
|
||||
* Frequency (MHz) and voltage (mV) settings. Data from the
|
||||
* Intel Pentium M Processor Datasheet (Order Number 252612), Table 5.
|
||||
*
|
||||
* Dothan processors have multiple VID#s with different settings for
|
||||
* each VID#. Since we can't uniquely identify this info
|
||||
* without undisclosed methods from Intel, we can't support newer
|
||||
* processors with this table method. If ACPI Px states are supported,
|
||||
* we get info from them.
|
||||
*/
|
||||
static freq_info PM17_130[] = {
|
||||
/* 130nm 1.70GHz Pentium M */
|
||||
FREQ_INFO(1700, 1484, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM16_130[] = {
|
||||
/* 130nm 1.60GHz Pentium M */
|
||||
FREQ_INFO(1600, 1484, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1420, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM15_130[] = {
|
||||
/* 130nm 1.50GHz Pentium M */
|
||||
FREQ_INFO(1500, 1484, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1452, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM14_130[] = {
|
||||
/* 130nm 1.40GHz Pentium M */
|
||||
FREQ_INFO(1400, 1484, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1436, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM13_130[] = {
|
||||
/* 130nm 1.30GHz Pentium M */
|
||||
FREQ_INFO(1300, 1388, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1356, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1292, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1260, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM13_LV_130[] = {
|
||||
/* 130nm 1.30GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1300, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1004, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM12_LV_130[] = {
|
||||
/* 130 nm 1.20GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1004, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM11_LV_130[] = {
|
||||
/* 130 nm 1.10GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1100, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM11_ULV_130[] = {
|
||||
/* 130 nm 1.10GHz Ultra Low Voltage Pentium M */
|
||||
FREQ_INFO(1100, 1004, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 972, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM10_ULV_130[] = {
|
||||
/* 130 nm 1.00GHz Ultra Low Voltage Pentium M */
|
||||
FREQ_INFO(1000, 1004, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 972, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
|
||||
/*
|
||||
* Data from "Intel Pentium M Processor on 90nm Process with
|
||||
* 2-MB L2 Cache Datasheet", Order Number 302189, Table 5.
|
||||
*/
|
||||
static freq_info PM_765A_90[] = {
|
||||
/* 90 nm 2.10GHz Pentium M, VID #A */
|
||||
FREQ_INFO(2100, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_765B_90[] = {
|
||||
/* 90 nm 2.10GHz Pentium M, VID #B */
|
||||
FREQ_INFO(2100, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1260, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_765C_90[] = {
|
||||
/* 90 nm 2.10GHz Pentium M, VID #C */
|
||||
FREQ_INFO(2100, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_765E_90[] = {
|
||||
/* 90 nm 2.10GHz Pentium M, VID #E */
|
||||
FREQ_INFO(2100, 1356, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_755A_90[] = {
|
||||
/* 90 nm 2.00GHz Pentium M, VID #A */
|
||||
FREQ_INFO(2000, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1292, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1196, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_755B_90[] = {
|
||||
/* 90 nm 2.00GHz Pentium M, VID #B */
|
||||
FREQ_INFO(2000, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_755C_90[] = {
|
||||
/* 90 nm 2.00GHz Pentium M, VID #C */
|
||||
FREQ_INFO(2000, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_755D_90[] = {
|
||||
/* 90 nm 2.00GHz Pentium M, VID #D */
|
||||
FREQ_INFO(2000, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1800, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1196, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_745A_90[] = {
|
||||
/* 90 nm 1.80GHz Pentium M, VID #A */
|
||||
FREQ_INFO(1800, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1292, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_745B_90[] = {
|
||||
/* 90 nm 1.80GHz Pentium M, VID #B */
|
||||
FREQ_INFO(1800, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_745C_90[] = {
|
||||
/* 90 nm 1.80GHz Pentium M, VID #C */
|
||||
FREQ_INFO(1800, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1260, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_745D_90[] = {
|
||||
/* 90 nm 1.80GHz Pentium M, VID #D */
|
||||
FREQ_INFO(1800, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1600, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_735A_90[] = {
|
||||
/* 90 nm 1.70GHz Pentium M, VID #A */
|
||||
FREQ_INFO(1700, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_735B_90[] = {
|
||||
/* 90 nm 1.70GHz Pentium M, VID #B */
|
||||
FREQ_INFO(1700, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_735C_90[] = {
|
||||
/* 90 nm 1.70GHz Pentium M, VID #C */
|
||||
FREQ_INFO(1700, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_735D_90[] = {
|
||||
/* 90 nm 1.70GHz Pentium M, VID #D */
|
||||
FREQ_INFO(1700, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_725A_90[] = {
|
||||
/* 90 nm 1.60GHz Pentium M, VID #A */
|
||||
FREQ_INFO(1600, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_725B_90[] = {
|
||||
/* 90 nm 1.60GHz Pentium M, VID #B */
|
||||
FREQ_INFO(1600, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1260, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1196, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_725C_90[] = {
|
||||
/* 90 nm 1.60GHz Pentium M, VID #C */
|
||||
FREQ_INFO(1600, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1244, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_725D_90[] = {
|
||||
/* 90 nm 1.60GHz Pentium M, VID #D */
|
||||
FREQ_INFO(1600, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1164, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_715A_90[] = {
|
||||
/* 90 nm 1.50GHz Pentium M, VID #A */
|
||||
FREQ_INFO(1500, 1340, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1228, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_715B_90[] = {
|
||||
/* 90 nm 1.50GHz Pentium M, VID #B */
|
||||
FREQ_INFO(1500, 1324, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1148, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_715C_90[] = {
|
||||
/* 90 nm 1.50GHz Pentium M, VID #C */
|
||||
FREQ_INFO(1500, 1308, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1212, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1132, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_715D_90[] = {
|
||||
/* 90 nm 1.50GHz Pentium M, VID #D */
|
||||
FREQ_INFO(1500, 1276, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1180, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_778_90[] = {
|
||||
/* 90 nm 1.60GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1600, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1300, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_758_90[] = {
|
||||
/* 90 nm 1.50GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1500, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1300, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1084, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_738_90[] = {
|
||||
/* 90 nm 1.40GHz Low Voltage Pentium M */
|
||||
FREQ_INFO(1400, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1300, 1116, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 1100, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 1068, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 1052, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 1036, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 1020, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 988, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_773G_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #G */
|
||||
FREQ_INFO(1300, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_773H_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #H */
|
||||
FREQ_INFO(1300, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_773I_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #I */
|
||||
FREQ_INFO(1300, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_773J_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #J */
|
||||
FREQ_INFO(1300, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_773K_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #K */
|
||||
FREQ_INFO(1300, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_773L_90[] = {
|
||||
/* 90 nm 1.30GHz Ultra Low Voltage Pentium M, VID #L */
|
||||
FREQ_INFO(1300, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1200, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753G_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #G */
|
||||
FREQ_INFO(1200, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753H_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #H */
|
||||
FREQ_INFO(1200, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753I_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #I */
|
||||
FREQ_INFO(1200, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753J_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #J */
|
||||
FREQ_INFO(1200, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753K_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #K */
|
||||
FREQ_INFO(1200, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_753L_90[] = {
|
||||
/* 90 nm 1.20GHz Ultra Low Voltage Pentium M, VID #L */
|
||||
FREQ_INFO(1200, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1100, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
|
||||
static freq_info PM_733JG_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #G */
|
||||
FREQ_INFO(1100, 956, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733JH_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #H */
|
||||
FREQ_INFO(1100, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733JI_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #I */
|
||||
FREQ_INFO(1100, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733JJ_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #J */
|
||||
FREQ_INFO(1100, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733JK_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #K */
|
||||
FREQ_INFO(1100, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733JL_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M, VID #L */
|
||||
FREQ_INFO(1100, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 860, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 844, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
};
|
||||
static freq_info PM_733_90[] = {
|
||||
/* 90 nm 1.10GHz Ultra Low Voltage Pentium M */
|
||||
FREQ_INFO(1100, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO(1000, 924, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 892, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
static freq_info PM_723_90[] = {
|
||||
/* 90 nm 1.00GHz Ultra Low Voltage Pentium M */
|
||||
FREQ_INFO(1000, 940, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 900, 908, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 800, 876, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 600, 812, INTEL_BUS_CLK),
|
||||
FREQ_INFO( 0, 0, 1),
|
||||
};
|
||||
|
||||
/*
|
||||
* VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
|
||||
* Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
|
||||
*/
|
||||
static freq_info C7M_795[] = {
|
||||
/* 2.00GHz Centaur C7-M 533 Mhz FSB */
|
||||
FREQ_INFO_PWR(2000, 1148, 133, 20000),
|
||||
FREQ_INFO_PWR(1867, 1132, 133, 18000),
|
||||
FREQ_INFO_PWR(1600, 1100, 133, 15000),
|
||||
FREQ_INFO_PWR(1467, 1052, 133, 13000),
|
||||
FREQ_INFO_PWR(1200, 1004, 133, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 133, 7000),
|
||||
FREQ_INFO_PWR( 667, 844, 133, 6000),
|
||||
FREQ_INFO_PWR( 533, 844, 133, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_785[] = {
|
||||
/* 1.80GHz Centaur C7-M 533 Mhz FSB */
|
||||
FREQ_INFO_PWR(1867, 1148, 133, 18000),
|
||||
FREQ_INFO_PWR(1600, 1100, 133, 15000),
|
||||
FREQ_INFO_PWR(1467, 1052, 133, 13000),
|
||||
FREQ_INFO_PWR(1200, 1004, 133, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 133, 7000),
|
||||
FREQ_INFO_PWR( 667, 844, 133, 6000),
|
||||
FREQ_INFO_PWR( 533, 844, 133, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_765[] = {
|
||||
/* 1.60GHz Centaur C7-M 533 Mhz FSB */
|
||||
FREQ_INFO_PWR(1600, 1084, 133, 15000),
|
||||
FREQ_INFO_PWR(1467, 1052, 133, 13000),
|
||||
FREQ_INFO_PWR(1200, 1004, 133, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 133, 7000),
|
||||
FREQ_INFO_PWR( 667, 844, 133, 6000),
|
||||
FREQ_INFO_PWR( 533, 844, 133, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
|
||||
static freq_info C7M_794[] = {
|
||||
/* 2.00GHz Centaur C7-M 400 Mhz FSB */
|
||||
FREQ_INFO_PWR(2000, 1148, 100, 20000),
|
||||
FREQ_INFO_PWR(1800, 1132, 100, 18000),
|
||||
FREQ_INFO_PWR(1600, 1100, 100, 15000),
|
||||
FREQ_INFO_PWR(1400, 1052, 100, 13000),
|
||||
FREQ_INFO_PWR(1000, 1004, 100, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 100, 7000),
|
||||
FREQ_INFO_PWR( 600, 844, 100, 6000),
|
||||
FREQ_INFO_PWR( 400, 844, 100, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_784[] = {
|
||||
/* 1.80GHz Centaur C7-M 400 Mhz FSB */
|
||||
FREQ_INFO_PWR(1800, 1148, 100, 18000),
|
||||
FREQ_INFO_PWR(1600, 1100, 100, 15000),
|
||||
FREQ_INFO_PWR(1400, 1052, 100, 13000),
|
||||
FREQ_INFO_PWR(1000, 1004, 100, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 100, 7000),
|
||||
FREQ_INFO_PWR( 600, 844, 100, 6000),
|
||||
FREQ_INFO_PWR( 400, 844, 100, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_764[] = {
|
||||
/* 1.60GHz Centaur C7-M 400 Mhz FSB */
|
||||
FREQ_INFO_PWR(1600, 1084, 100, 15000),
|
||||
FREQ_INFO_PWR(1400, 1052, 100, 13000),
|
||||
FREQ_INFO_PWR(1000, 1004, 100, 10000),
|
||||
FREQ_INFO_PWR( 800, 844, 100, 7000),
|
||||
FREQ_INFO_PWR( 600, 844, 100, 6000),
|
||||
FREQ_INFO_PWR( 400, 844, 100, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_754[] = {
|
||||
/* 1.50GHz Centaur C7-M 400 Mhz FSB */
|
||||
FREQ_INFO_PWR(1500, 1004, 100, 12000),
|
||||
FREQ_INFO_PWR(1400, 988, 100, 11000),
|
||||
FREQ_INFO_PWR(1000, 940, 100, 9000),
|
||||
FREQ_INFO_PWR( 800, 844, 100, 7000),
|
||||
FREQ_INFO_PWR( 600, 844, 100, 6000),
|
||||
FREQ_INFO_PWR( 400, 844, 100, 5000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_771[] = {
|
||||
/* 1.20GHz Centaur C7-M 400 Mhz FSB */
|
||||
FREQ_INFO_PWR(1200, 860, 100, 7000),
|
||||
FREQ_INFO_PWR(1000, 860, 100, 6000),
|
||||
FREQ_INFO_PWR( 800, 844, 100, 5500),
|
||||
FREQ_INFO_PWR( 600, 844, 100, 5000),
|
||||
FREQ_INFO_PWR( 400, 844, 100, 4000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
|
||||
static freq_info C7M_775_ULV[] = {
|
||||
/* 1.50GHz Centaur C7-M ULV */
|
||||
FREQ_INFO_PWR(1500, 956, 100, 7500),
|
||||
FREQ_INFO_PWR(1400, 940, 100, 6000),
|
||||
FREQ_INFO_PWR(1000, 860, 100, 5000),
|
||||
FREQ_INFO_PWR( 800, 828, 100, 2800),
|
||||
FREQ_INFO_PWR( 600, 796, 100, 2500),
|
||||
FREQ_INFO_PWR( 400, 796, 100, 2000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_772_ULV[] = {
|
||||
/* 1.20GHz Centaur C7-M ULV */
|
||||
FREQ_INFO_PWR(1200, 844, 100, 5000),
|
||||
FREQ_INFO_PWR(1000, 844, 100, 4000),
|
||||
FREQ_INFO_PWR( 800, 828, 100, 2800),
|
||||
FREQ_INFO_PWR( 600, 796, 100, 2500),
|
||||
FREQ_INFO_PWR( 400, 796, 100, 2000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_779_ULV[] = {
|
||||
/* 1.00GHz Centaur C7-M ULV */
|
||||
FREQ_INFO_PWR(1000, 796, 100, 3500),
|
||||
FREQ_INFO_PWR( 800, 796, 100, 2800),
|
||||
FREQ_INFO_PWR( 600, 796, 100, 2500),
|
||||
FREQ_INFO_PWR( 400, 796, 100, 2000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
static freq_info C7M_770_ULV[] = {
|
||||
/* 1.00GHz Centaur C7-M ULV */
|
||||
FREQ_INFO_PWR(1000, 844, 100, 5000),
|
||||
FREQ_INFO_PWR( 800, 796, 100, 2800),
|
||||
FREQ_INFO_PWR( 600, 796, 100, 2500),
|
||||
FREQ_INFO_PWR( 400, 796, 100, 2000),
|
||||
FREQ_INFO(0, 0, 1),
|
||||
};
|
||||
|
||||
static ss_cpu_info ESTprocs[] = {
|
||||
INTEL(PM17_130, 1700, 1484, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM16_130, 1600, 1484, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM15_130, 1500, 1484, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM14_130, 1400, 1484, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM13_130, 1300, 1388, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM13_LV_130, 1300, 1180, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM12_LV_130, 1200, 1180, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM11_LV_130, 1100, 1180, 600, 956, INTEL_BUS_CLK),
|
||||
INTEL(PM11_ULV_130, 1100, 1004, 600, 844, INTEL_BUS_CLK),
|
||||
INTEL(PM10_ULV_130, 1000, 1004, 600, 844, INTEL_BUS_CLK),
|
||||
INTEL(PM_765A_90, 2100, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_765B_90, 2100, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_765C_90, 2100, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_765E_90, 2100, 1356, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_755A_90, 2000, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_755B_90, 2000, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_755C_90, 2000, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_755D_90, 2000, 1276, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_745A_90, 1800, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_745B_90, 1800, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_745C_90, 1800, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_745D_90, 1800, 1276, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_735A_90, 1700, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_735B_90, 1700, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_735C_90, 1700, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_735D_90, 1700, 1276, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_725A_90, 1600, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_725B_90, 1600, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_725C_90, 1600, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_725D_90, 1600, 1276, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_715A_90, 1500, 1340, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_715B_90, 1500, 1324, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_715C_90, 1500, 1308, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_715D_90, 1500, 1276, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_778_90, 1600, 1116, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_758_90, 1500, 1116, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_738_90, 1400, 1116, 600, 988, INTEL_BUS_CLK),
|
||||
INTEL(PM_773G_90, 1300, 956, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_773H_90, 1300, 940, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_773I_90, 1300, 924, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_773J_90, 1300, 908, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_773K_90, 1300, 892, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_773L_90, 1300, 876, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753G_90, 1200, 956, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753H_90, 1200, 940, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753I_90, 1200, 924, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753J_90, 1200, 908, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753K_90, 1200, 892, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_753L_90, 1200, 876, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JG_90, 1100, 956, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JH_90, 1100, 940, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JI_90, 1100, 924, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JJ_90, 1100, 908, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JK_90, 1100, 892, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733JL_90, 1100, 876, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_733_90, 1100, 940, 600, 812, INTEL_BUS_CLK),
|
||||
INTEL(PM_723_90, 1000, 940, 600, 812, INTEL_BUS_CLK),
|
||||
|
||||
CENTAUR(C7M_795, 2000, 1148, 533, 844, 133),
|
||||
CENTAUR(C7M_794, 2000, 1148, 400, 844, 100),
|
||||
CENTAUR(C7M_785, 1867, 1148, 533, 844, 133),
|
||||
CENTAUR(C7M_784, 1800, 1148, 400, 844, 100),
|
||||
CENTAUR(C7M_765, 1600, 1084, 533, 844, 133),
|
||||
CENTAUR(C7M_764, 1600, 1084, 400, 844, 100),
|
||||
CENTAUR(C7M_754, 1500, 1004, 400, 844, 100),
|
||||
CENTAUR(C7M_775_ULV, 1500, 956, 400, 796, 100),
|
||||
CENTAUR(C7M_771, 1200, 860, 400, 844, 100),
|
||||
CENTAUR(C7M_772_ULV, 1200, 844, 400, 796, 100),
|
||||
CENTAUR(C7M_779_ULV, 1000, 796, 400, 796, 100),
|
||||
CENTAUR(C7M_770_ULV, 1000, 844, 400, 796, 100),
|
||||
{ 0, 0, NULL },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2,6 +2,7 @@ SubDir HAIKU_TOP src preferences ;
|
||||
|
||||
SubInclude HAIKU_TOP src preferences appearance ;
|
||||
SubInclude HAIKU_TOP src preferences backgrounds ;
|
||||
SubInclude HAIKU_TOP src preferences cpufrequency ;
|
||||
SubInclude HAIKU_TOP src preferences datatranslations ;
|
||||
SubInclude HAIKU_TOP src preferences devices ;
|
||||
#SubInclude HAIKU_TOP src preferences dun ;
|
||||
|
243
src/preferences/cpufrequency/CPUFrequencyView.cpp
Normal file
243
src/preferences/cpufrequency/CPUFrequencyView.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "CPUFrequencyView.h"
|
||||
|
||||
#include "StatusView.h"
|
||||
|
||||
#include <Box.h>
|
||||
#include <Deskbar.h>
|
||||
#include <GroupView.h>
|
||||
#include <MenuField.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
|
||||
const char* kCPUFreqPreferencesFile = "CPUFrequency";
|
||||
const char* kPrefSignature = "application/x-vnd.Haiku-CPUFrequencyPref";
|
||||
const char* kPreferencesFileName = "CPUFrequency";
|
||||
|
||||
const uint32 kInstallIntoDeskbar = '&iid';
|
||||
const uint32 kIntegrationTimeChanged = '&itc';
|
||||
|
||||
const bigtime_t kMilliSecond = 1000;
|
||||
|
||||
|
||||
CPUFrequencyView::CPUFrequencyView(BRect frame,
|
||||
PreferencesStorage<freq_preferences>* storage)
|
||||
: BView(frame, "CPUFrequencyView", B_FOLLOW_NONE, B_WILL_DRAW),
|
||||
fStorage(storage)
|
||||
{
|
||||
BGroupLayout* mainLayout = new BGroupLayout(B_VERTICAL);
|
||||
SetLayout(mainLayout);
|
||||
mainLayout->SetSpacing(10);
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
// stepping policy
|
||||
BRect rect = Bounds();
|
||||
rect.InsetBy(5, 5);
|
||||
BBox *policyBox = new BBox(rect, "policyBox");
|
||||
policyBox->SetLabel("Stepping Policy");
|
||||
BGroupLayout* policyLayout = new BGroupLayout(B_VERTICAL);
|
||||
policyLayout->SetInsets(10, policyBox->TopBorderOffset() * 2 + 10, 10, 10);
|
||||
policyLayout->SetSpacing(10);
|
||||
policyBox->SetLayout(policyLayout);
|
||||
mainLayout->AddView(policyBox);
|
||||
|
||||
fPolicyMenu = new BMenu("Stepping Policy");
|
||||
BMenuField *menuField = new BMenuField("Stepping Policy", fPolicyMenu);
|
||||
|
||||
policyLayout->AddView(menuField);
|
||||
|
||||
// dynamic stepping
|
||||
BBox *dynamicBox = new BBox(rect, "dynamicBox");
|
||||
dynamicBox->SetLabel("Dynamic Stepping");
|
||||
BGroupLayout* dynamicLayout = new BGroupLayout(B_VERTICAL);
|
||||
dynamicLayout->SetInsets(10, dynamicBox->TopBorderOffset() * 2 + 10,
|
||||
10, 10);
|
||||
dynamicLayout->SetSpacing(10);
|
||||
dynamicBox->SetLayout(dynamicLayout);
|
||||
mainLayout->AddView(dynamicBox);
|
||||
|
||||
fColorStepView = new ColorStepView(frame);
|
||||
fColorStepView->SetFrequencys(fDriverInterface.GetCpuFrequencyStates());
|
||||
|
||||
fIntegrationTime = new BTextControl(BRect(0,0,Bounds().Width(),10),
|
||||
"intergal",
|
||||
"Integration Time [ms]", "",
|
||||
new BMessage(kIntegrationTimeChanged));
|
||||
|
||||
dynamicLayout->AddView(fColorStepView);
|
||||
dynamicLayout->AddView(fIntegrationTime);
|
||||
|
||||
// status view
|
||||
BBox *statusBox = new BBox(rect, "statusBox");
|
||||
statusBox->SetLabel("CPU Frequency Status View");
|
||||
BGroupLayout* statusLayout = new BGroupLayout(B_HORIZONTAL);
|
||||
statusLayout->SetInsets(10, statusBox->TopBorderOffset() * 2 + 10, 10, 10);
|
||||
statusLayout->SetSpacing(10);
|
||||
statusBox->SetLayout(statusLayout);
|
||||
mainLayout->AddView(statusBox);
|
||||
|
||||
fStatusView = new StatusView(BRect(0, 0, 5, 5), false,
|
||||
fStorage);
|
||||
fStatusView->ShowPopUpMenu(false);
|
||||
|
||||
fInstallButton = new BButton("installButton",
|
||||
"Install Replicant into Deskbar",
|
||||
new BMessage(kInstallIntoDeskbar));
|
||||
|
||||
statusLayout->AddView(fStatusView);
|
||||
statusLayout->AddView(fInstallButton);
|
||||
statusLayout->AddItem(BSpaceLayoutItem::CreateGlue());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::MessageReceived(BMessage* message)
|
||||
{
|
||||
freq_preferences* pref = fStorage->GetPreferences();
|
||||
bool configChanged = false;
|
||||
|
||||
switch (message->what) {
|
||||
case kUpdatedPreferences:
|
||||
fStatusView->MessageReceived(message);
|
||||
if (pref->mode == DYNAMIC) {
|
||||
fColorStepView->SetEnabled(true);
|
||||
fIntegrationTime->SetEnabled(true);
|
||||
}
|
||||
else {
|
||||
fColorStepView->SetEnabled(false);
|
||||
fIntegrationTime->SetEnabled(false);
|
||||
}
|
||||
configChanged = true;
|
||||
break;
|
||||
|
||||
case kSteppingChanged:
|
||||
// from ColorStepView
|
||||
pref->stepping_threshold = fColorStepView->GetSliderPosition();
|
||||
fStorage->SavePreferences();
|
||||
configChanged = true;
|
||||
break;
|
||||
|
||||
case kIntegrationTimeChanged:
|
||||
_ReadIntegrationTime();
|
||||
fStorage->SavePreferences();
|
||||
configChanged = true;
|
||||
break;
|
||||
|
||||
case kInstallIntoDeskbar:
|
||||
_InstallReplicantInDeskbar();
|
||||
break;
|
||||
|
||||
case kRevertMsg:
|
||||
case kDefaultMsg:
|
||||
fStatusView->UpdateCPUFreqState();
|
||||
_UpdateViews();
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
}
|
||||
|
||||
if (configChanged)
|
||||
Window()->PostMessage(kConfigChangedMsg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::AttachedToWindow()
|
||||
{
|
||||
fFrequencyMenu = new FrequencyMenu(fPolicyMenu, this,
|
||||
fStorage, &fDriverInterface);
|
||||
AddFilter(fFrequencyMenu);
|
||||
|
||||
fColorStepView->SetTarget(this);
|
||||
fIntegrationTime->SetTarget(this);
|
||||
fInstallButton->SetTarget(this);
|
||||
|
||||
_UpdateViews();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::DetachedFromWindow()
|
||||
{
|
||||
// emty menu for the case the view is attached again
|
||||
while (true) {
|
||||
BMenuItem* item = fPolicyMenu->RemoveItem(int32(0));
|
||||
if (!item)
|
||||
break;
|
||||
delete item;
|
||||
}
|
||||
if (RemoveFilter(fFrequencyMenu))
|
||||
delete fFrequencyMenu;
|
||||
|
||||
_ReadIntegrationTime();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
our_image(image_info& image)
|
||||
{
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
|
||||
if ((char *)our_image >= (char *)image.text
|
||||
&& (char *)our_image <= (char *)image.text + image.text_size)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::_InstallReplicantInDeskbar()
|
||||
{
|
||||
image_info info;
|
||||
entry_ref ref;
|
||||
if (our_image(info) == B_OK
|
||||
&& get_ref_for_path(info.name, &ref) == B_OK) {
|
||||
BDeskbar deskbar;
|
||||
deskbar.AddItem(&ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::_UpdateViews()
|
||||
{
|
||||
fFrequencyMenu->UpdateMenu();
|
||||
freq_preferences* pref = fStorage->GetPreferences();
|
||||
fColorStepView->SetSliderPosition(pref->stepping_threshold);
|
||||
if (pref->mode == DYNAMIC) {
|
||||
fColorStepView->SetEnabled(true);
|
||||
fIntegrationTime->SetEnabled(true);
|
||||
}
|
||||
else {
|
||||
fColorStepView->SetEnabled(false);
|
||||
fIntegrationTime->SetEnabled(false);
|
||||
}
|
||||
|
||||
BString out;
|
||||
out << pref->integration_time / kMilliSecond;
|
||||
fIntegrationTime->SetText(out.String());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFrequencyView::_ReadIntegrationTime()
|
||||
{
|
||||
freq_preferences* pref = fStorage->GetPreferences();
|
||||
bigtime_t integration_time = atoi(fIntegrationTime->Text()) * kMilliSecond;
|
||||
if (integration_time == 0) {
|
||||
BString out;
|
||||
out << pref->integration_time / kMilliSecond;
|
||||
fIntegrationTime->SetText(out.String());
|
||||
}
|
||||
else {
|
||||
pref->integration_time = integration_time;
|
||||
}
|
||||
}
|
83
src/preferences/cpufrequency/CPUFrequencyView.h
Normal file
83
src/preferences/cpufrequency/CPUFrequencyView.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef CPUFREQUENCYVIEW_h
|
||||
#define CPUFREQUENCYVIEW_h
|
||||
|
||||
#include "DriverInterface.h"
|
||||
#include "ColorStepView.h"
|
||||
#include "PreferencesWindow.h"
|
||||
|
||||
#include <Handler.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuItem.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
|
||||
extern const char* kPrefSignature;
|
||||
extern const char* kPreferencesFileName;
|
||||
|
||||
enum stepping_mode {
|
||||
DYNAMIC,
|
||||
PERFORMANCE,
|
||||
LOW_ENERGIE,
|
||||
CUSTOM
|
||||
};
|
||||
|
||||
|
||||
struct freq_preferences
|
||||
{
|
||||
// stepping mode
|
||||
stepping_mode mode;
|
||||
int16 custom_stepping;
|
||||
|
||||
// dynamic stepping
|
||||
float stepping_threshold;
|
||||
bigtime_t integration_time;
|
||||
};
|
||||
|
||||
|
||||
const freq_preferences kDefaultPreferences =
|
||||
{
|
||||
DYNAMIC,
|
||||
-1,
|
||||
0.25,
|
||||
500000 //half second
|
||||
};
|
||||
|
||||
|
||||
class FrequencyMenu;
|
||||
class StatusView;
|
||||
|
||||
class CPUFrequencyView : public BView
|
||||
{
|
||||
public:
|
||||
CPUFrequencyView(BRect frame,
|
||||
PreferencesStorage<freq_preferences>* storage);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
||||
private:
|
||||
void _InstallReplicantInDeskbar();
|
||||
void _UpdateViews();
|
||||
void _ReadIntegrationTime();
|
||||
|
||||
BMenu* fPolicyMenu;
|
||||
FrequencyMenu* fFrequencyMenu;
|
||||
ColorStepView* fColorStepView;
|
||||
BTextControl* fIntegrationTime;
|
||||
StatusView* fStatusView;
|
||||
BButton* fInstallButton;
|
||||
|
||||
PreferencesStorage<freq_preferences>* fStorage;
|
||||
CPUFreqDriverInterface fDriverInterface;
|
||||
};
|
||||
|
||||
#endif
|
329
src/preferences/cpufrequency/ColorStepView.cpp
Normal file
329
src/preferences/cpufrequency/ColorStepView.cpp
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "ColorStepView.h"
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
const int32 kColorBarHeight = 15;
|
||||
|
||||
const uint32 kMSGSliderChanged = '&slc';
|
||||
|
||||
|
||||
ColorStepView::ColorStepView(BRect frame)
|
||||
: BControl(frame, "ColorStepView", "", new BMessage(kSteppingChanged),
|
||||
B_FOLLOW_ALL, B_WILL_DRAW),
|
||||
fOffScreenView(NULL),
|
||||
fOffScreenBitmap(NULL)
|
||||
{
|
||||
fPerformanceList = new PerformanceList(20, true);
|
||||
|
||||
fSliderPosition = 0;
|
||||
fNSteps = 0;
|
||||
fLowFreqColor.red = 0;
|
||||
fLowFreqColor.blue = 255;
|
||||
fLowFreqColor.green = 0;
|
||||
|
||||
fHighFreqColor.red = 255;
|
||||
fHighFreqColor.blue = 0;
|
||||
fHighFreqColor.green = 0;
|
||||
|
||||
fMinFrequencyLabel = "? MHz";
|
||||
fMaxFrequencyLabel = "? MHz";
|
||||
_InitView();
|
||||
}
|
||||
|
||||
|
||||
ColorStepView::~ColorStepView()
|
||||
{
|
||||
delete fPerformanceList;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::AttachedToWindow()
|
||||
{
|
||||
fSlider->SetTarget(this);
|
||||
|
||||
if (!fOffScreenView) {
|
||||
fOffScreenView = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
|
||||
}
|
||||
if (!fOffScreenBitmap) {
|
||||
fOffScreenBitmap = new BBitmap(Bounds(), B_CMAP8, true, false);
|
||||
Window()->Lock();
|
||||
if (fOffScreenBitmap && fOffScreenView)
|
||||
fOffScreenBitmap->AddChild(fOffScreenView);
|
||||
Window()->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::DetachedFromWindow()
|
||||
{
|
||||
BView::DetachedFromWindow();
|
||||
|
||||
if (fOffScreenBitmap) {
|
||||
delete fOffScreenBitmap;
|
||||
fOffScreenBitmap = NULL;
|
||||
fOffScreenView = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::FrameResized(float w,float h)
|
||||
{
|
||||
BView::FrameResized(w, h);
|
||||
|
||||
BRect bounds(Bounds());
|
||||
|
||||
if (bounds.right <= 0.0f || bounds.bottom <= 0.0f)
|
||||
return;
|
||||
|
||||
if (fOffScreenBitmap) {
|
||||
fOffScreenBitmap->RemoveChild(fOffScreenView);
|
||||
delete fOffScreenBitmap;
|
||||
|
||||
fOffScreenView->ResizeTo(bounds.Width(), bounds.Height());
|
||||
|
||||
fOffScreenBitmap = new BBitmap(Bounds(), B_RGBA32, true, false);
|
||||
fOffScreenBitmap->AddChild(fOffScreenView);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::GetPreferredSize(float *width, float *height)
|
||||
{
|
||||
*width = Frame().Width();
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
|
||||
*height = fSlider->Frame().Height();
|
||||
*height += kColorBarHeight;
|
||||
*height += fontHeight.descent + fontHeight.ascent + 5;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::Draw(BRect updateRect)
|
||||
{
|
||||
BView *view = NULL;
|
||||
if(fOffScreenView){
|
||||
view = fOffScreenView;
|
||||
}
|
||||
else{
|
||||
view = this;
|
||||
}
|
||||
|
||||
if (!fOffScreenBitmap || !fOffScreenBitmap->Lock())
|
||||
return;
|
||||
view->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
view->FillRect(updateRect);
|
||||
|
||||
BRect colorBarRect = fSlider->BarFrame();
|
||||
colorBarRect.top = 0;
|
||||
colorBarRect.bottom = kColorBarHeight;
|
||||
colorBarRect.OffsetTo(colorBarRect.left, fSlider->Frame().bottom);
|
||||
|
||||
float pos = 0.0;
|
||||
for (int i = fPerformanceList->CountItems() - 1; i >= 0 ; i--) {
|
||||
performance_step* perfState = fPerformanceList->ItemAt(i);
|
||||
|
||||
float nextPos = perfState->cpu_usage;
|
||||
float width = colorBarRect.Width();
|
||||
|
||||
BRect subRect(colorBarRect);
|
||||
subRect.left += pos * width;
|
||||
subRect.right = colorBarRect.left + nextPos * width;
|
||||
|
||||
view->SetHighColor(perfState->color);
|
||||
view->FillRect(subRect);
|
||||
|
||||
pos = nextPos;
|
||||
}
|
||||
// draw label
|
||||
if (IsEnabled()) {
|
||||
view->SetHighColor(0, 0, 0);
|
||||
} else {
|
||||
view->SetHighColor(tint_color(LowColor(), B_DISABLED_LABEL_TINT));
|
||||
}
|
||||
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
float totalFontHeight = fontHeight.descent + fontHeight.ascent;
|
||||
|
||||
view->DrawString(fMinFrequencyLabel.String(),
|
||||
BPoint(0.0,
|
||||
colorBarRect.bottom + totalFontHeight + 5));
|
||||
|
||||
view->DrawString(fMaxFrequencyLabel.String(),
|
||||
BPoint(Bounds().right
|
||||
- StringWidth(fMaxFrequencyLabel.String()),
|
||||
colorBarRect.bottom + totalFontHeight + 5));
|
||||
|
||||
// blit bitmap
|
||||
fOffScreenView->Sync();
|
||||
fOffScreenBitmap->Unlock();
|
||||
DrawBitmap(fOffScreenBitmap, B_ORIGIN);
|
||||
|
||||
BView::Draw(updateRect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::MessageReceived(BMessage *message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMSGSliderChanged:
|
||||
fSliderPosition = fSlider->Position();
|
||||
_CalculatePerformanceSteps();
|
||||
Invalidate();
|
||||
break;
|
||||
case kSteppingChanged:
|
||||
Invoke();
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::SetEnabled(bool enabled)
|
||||
{
|
||||
fSlider->SetEnabled(enabled);
|
||||
BControl::SetEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::SetFrequencys(StateList *list)
|
||||
{
|
||||
fStateList = list;
|
||||
fNSteps = fStateList->CountItems();
|
||||
if (fNSteps >= 2) {
|
||||
float minFreq = fStateList->ItemAt(fNSteps - 1)->frequency;
|
||||
float maxFreq = fStateList->ItemAt(0)->frequency;
|
||||
fMinFrequencyLabel = CreateFrequencyString(minFreq);
|
||||
fMaxFrequencyLabel = CreateFrequencyString(maxFreq);
|
||||
}
|
||||
|
||||
// fit size of fPerformanceList
|
||||
int32 perfNumber = fPerformanceList->CountItems();
|
||||
if (perfNumber < fNSteps) {
|
||||
for (int i = 0; i < fNSteps - perfNumber; i++)
|
||||
fPerformanceList->AddItem(new performance_step);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < perfNumber - fNSteps; i++)
|
||||
fPerformanceList->RemoveItemAt(0);
|
||||
}
|
||||
// and fill the list
|
||||
_CalculatePerformanceSteps();
|
||||
|
||||
}
|
||||
|
||||
|
||||
PerformanceList*
|
||||
ColorStepView::GetPerformanceSteps()
|
||||
{
|
||||
return fPerformanceList;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
ColorStepView::CreateFrequencyString(uint16 frequency)
|
||||
{
|
||||
BString string = "";
|
||||
if (frequency >= 1000) {
|
||||
char buffer [10];
|
||||
sprintf (buffer, "%.1f", float(frequency) / 1000);
|
||||
string << buffer;
|
||||
string += " GHz";
|
||||
}
|
||||
else {
|
||||
string << frequency;
|
||||
string += " MHz";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float
|
||||
ColorStepView::UsageOfStep(int32 step, int32 nSteps, float base)
|
||||
{
|
||||
float singleWidth = (1 - base) / (nSteps - 1);
|
||||
return base + singleWidth * step;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::_InitView()
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
BRect sliderFrame(Bounds());
|
||||
|
||||
fSlider = new BSlider(sliderFrame, "StepSlider", "Step up by CPU usage:",
|
||||
new BMessage(kSteppingChanged), 0, 100);
|
||||
fSlider->SetModificationMessage(new BMessage(kMSGSliderChanged));
|
||||
|
||||
fSliderPosition = 0.25 - fNSteps * 0.05;
|
||||
fSlider->SetPosition(fSliderPosition);
|
||||
fSlider->SetLimitLabels("0%", "100%");
|
||||
fSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
|
||||
fSlider->SetHashMarkCount(5);
|
||||
AddChild(fSlider);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::_CalculatePerformanceSteps()
|
||||
{
|
||||
for (int i = 0; i < fNSteps; i++) {
|
||||
// begin with the lowest frequency
|
||||
performance_step* perfState = fPerformanceList->ItemAt(fNSteps -1 - i);
|
||||
perfState->cpu_usage = _PositonStep(i);
|
||||
_ColorStep(i, perfState->color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
ColorStepView::_PositonStep(int32 step)
|
||||
{
|
||||
if (step >= fNSteps)
|
||||
return 1.0;
|
||||
|
||||
return UsageOfStep(step, fNSteps, fSliderPosition);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColorStepView::_ColorStep(int32 step, rgb_color &color)
|
||||
{
|
||||
color.red = fLowFreqColor.red
|
||||
+ (fHighFreqColor.red - fLowFreqColor.red)
|
||||
/ (fNSteps - 1) * step;
|
||||
color.green = fLowFreqColor.green
|
||||
+ (fHighFreqColor.green - fLowFreqColor.green)
|
||||
/ (fNSteps - 1) * step;
|
||||
color.blue = fLowFreqColor.blue
|
||||
+ (fHighFreqColor.blue - fLowFreqColor.blue)
|
||||
/ (fNSteps - 1) * step;
|
||||
}
|
||||
|
82
src/preferences/cpufrequency/ColorStepView.h
Normal file
82
src/preferences/cpufrequency/ColorStepView.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef COLORSTEPVIEW_H
|
||||
#define COLORSTEPVIEW_H
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Control.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Slider.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "DriverInterface.h"
|
||||
|
||||
const uint32 kSteppingChanged = '&spc';
|
||||
|
||||
struct performance_step {
|
||||
float cpu_usage; // upper limit
|
||||
rgb_color color;
|
||||
};
|
||||
|
||||
|
||||
typedef BObjectList<performance_step> PerformanceList;
|
||||
|
||||
|
||||
class ColorStepView : public BControl
|
||||
{
|
||||
public:
|
||||
ColorStepView(BRect frame);
|
||||
~ColorStepView();
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void FrameResized(float w,float h);
|
||||
|
||||
virtual void GetPreferredSize(float *width, float *height);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
virtual void SetEnabled(bool enabled);
|
||||
|
||||
void SetFrequencys(StateList *list);
|
||||
PerformanceList* GetPerformanceSteps();
|
||||
static BString CreateFrequencyString(uint16 frequency);
|
||||
|
||||
void SetSliderPosition(float pos) {
|
||||
fSlider->SetPosition(pos);
|
||||
fSliderPosition = pos;
|
||||
_CalculatePerformanceSteps();
|
||||
}
|
||||
float GetSliderPosition() { return fSliderPosition; }
|
||||
|
||||
static float UsageOfStep(int32 step, int32 nSteps, float base);
|
||||
|
||||
private:
|
||||
void _InitView();
|
||||
void _CalculatePerformanceSteps();
|
||||
float _PositonStep(int32 step);
|
||||
void _ColorStep(int32 step, rgb_color &color);
|
||||
|
||||
BSlider* fSlider;
|
||||
|
||||
float fSliderPosition;
|
||||
int32 fNSteps;
|
||||
rgb_color fLowFreqColor;
|
||||
rgb_color fHighFreqColor;
|
||||
|
||||
BView* fOffScreenView;
|
||||
BBitmap* fOffScreenBitmap;
|
||||
|
||||
BString fMinFrequencyLabel;
|
||||
BString fMaxFrequencyLabel;
|
||||
|
||||
PerformanceList* fPerformanceList;
|
||||
StateList* fStateList;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
217
src/preferences/cpufrequency/DriverInterface.cpp
Normal file
217
src/preferences/cpufrequency/DriverInterface.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "DriverInterface.h"
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
#define DRIVER_DIR "/dev/power"
|
||||
|
||||
CPUFreqDriverInterface::CPUFreqDriverInterface()
|
||||
: fInitOK(false),
|
||||
fDriverHandler(-1),
|
||||
fIsWatching(false),
|
||||
fWatchingMessenger(NULL)
|
||||
{
|
||||
fFrequencyStates = new StateList(20, true);
|
||||
|
||||
if (_FindSpeedStepDriver(DRIVER_DIR) == B_OK)
|
||||
fInitOK = true;
|
||||
|
||||
status_t ret;
|
||||
freq_info states[MAX_CPU_FREQUENCY_STATES];
|
||||
ret = ioctl(fDriverHandler, GET_CPU_FREQ_STATES, &states,
|
||||
sizeof(freq_info) * MAX_CPU_FREQUENCY_STATES);
|
||||
if (ret != B_OK)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < MAX_CPU_FREQUENCY_STATES && states[i].frequency != 0;
|
||||
i++) {
|
||||
fFrequencyStates->AddItem(new freq_info(states[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CPUFreqDriverInterface::~CPUFreqDriverInterface()
|
||||
{
|
||||
delete fFrequencyStates;
|
||||
|
||||
if (InitCheck() == B_OK)
|
||||
close(fDriverHandler);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CPUFreqDriverInterface::InitCheck()
|
||||
{
|
||||
if (fInitOK)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
StateList*
|
||||
CPUFreqDriverInterface::GetCpuFrequencyStates()
|
||||
{
|
||||
return fFrequencyStates;
|
||||
}
|
||||
|
||||
|
||||
freq_info*
|
||||
CPUFreqDriverInterface::GetCurrentFrequencyState()
|
||||
{
|
||||
uint16 stateId = 0;
|
||||
status_t ret;
|
||||
ret = ioctl(fDriverHandler, GET_CURENT_CPU_FREQ_STATE, &stateId,
|
||||
sizeof(uint16));
|
||||
if (ret != B_OK)
|
||||
return NULL;
|
||||
int32 i = 0;
|
||||
while (true) {
|
||||
freq_info* state = fFrequencyStates->ItemAt(i);
|
||||
if (!state)
|
||||
break;
|
||||
i++;
|
||||
|
||||
if (state->id == stateId)
|
||||
return state;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
CPUFreqDriverInterface::GetNumberOfFrequencyStates()
|
||||
{
|
||||
return fFrequencyStates->CountItems();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CPUFreqDriverInterface::SetFrequencyState(const freq_info* state)
|
||||
{
|
||||
status_t ret;
|
||||
ret = ioctl(fDriverHandler, SET_CPU_FREQ_STATE, &(state->id),
|
||||
sizeof(uint16));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CPUFreqDriverInterface::StartWatching(BHandler* target)
|
||||
{
|
||||
if (fIsWatching)
|
||||
return B_ERROR;
|
||||
|
||||
if (fWatchingMessenger)
|
||||
delete fWatchingMessenger;
|
||||
fWatchingMessenger = new BMessenger(target);
|
||||
|
||||
status_t status = B_ERROR;
|
||||
fThreadId = spawn_thread(&_ThreadWatchFreqFunction, "FreqThread",
|
||||
B_LOW_PRIORITY, this);
|
||||
if (fThreadId >= 0)
|
||||
status = resume_thread(fThreadId);
|
||||
else
|
||||
return fThreadId;
|
||||
|
||||
if (status == B_OK) {
|
||||
fIsWatching = true;
|
||||
return B_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CPUFreqDriverInterface::StopWatching()
|
||||
{
|
||||
|
||||
if (fIsWatching &&
|
||||
ioctl(fDriverHandler, STOP_WATCHING_CPU_FREQ) == B_OK)
|
||||
{
|
||||
delete fWatchingMessenger;
|
||||
fWatchingMessenger = NULL;
|
||||
fIsWatching = false;
|
||||
|
||||
status_t status;
|
||||
return wait_for_thread(fThreadId, &status);
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
CPUFreqDriverInterface::_ThreadWatchFreqFunction(void* data)
|
||||
{
|
||||
CPUFreqDriverInterface* that = (CPUFreqDriverInterface*)data;
|
||||
that->_WatchFrequency();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPUFreqDriverInterface::_WatchFrequency()
|
||||
{
|
||||
uint16 newId = 0;
|
||||
while (ioctl(fDriverHandler, WATCH_CPU_FREQ, &newId,
|
||||
sizeof(uint16)) == B_OK)
|
||||
{
|
||||
int i = 0;
|
||||
while (true) {
|
||||
freq_info* state = fFrequencyStates->ItemAt(i);
|
||||
if (!state)
|
||||
break;
|
||||
i++;
|
||||
|
||||
if (state->id == newId) {
|
||||
BMessage msg(kMSGFrequencyChanged);
|
||||
msg.AddPointer("freq_info", state);
|
||||
fWatchingMessenger->SendMessage(&msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CPUFreqDriverInterface::_FindSpeedStepDriver(const char* path)
|
||||
{
|
||||
BDirectory dir(path);
|
||||
BEntry entry;
|
||||
|
||||
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
|
||||
if (entry.IsDirectory()) {
|
||||
if (_FindSpeedStepDriver(path.Path()) == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
else {
|
||||
printf("path %s\n", path.Path());
|
||||
fDriverHandler = open(path.Path(), O_RDWR);
|
||||
if (fDriverHandler >= 0) {
|
||||
uint32 magicId = 0;
|
||||
status_t ret;
|
||||
ret = ioctl(fDriverHandler, IDENTIFY_DEVICE, &magicId,
|
||||
sizeof(uint32));
|
||||
if (ret == B_OK && magicId == kMagicFreqID)
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
53
src/preferences/cpufrequency/DriverInterface.h
Normal file
53
src/preferences/cpufrequency/DriverInterface.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef DRIVERINTERFACE_H
|
||||
#define DRIVERINTERFACE_H
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "device/power_managment.h"
|
||||
|
||||
const uint32 kMSGFrequencyChanged = '&frc';
|
||||
|
||||
typedef BObjectList<freq_info> StateList;
|
||||
|
||||
|
||||
class CPUFreqDriverInterface
|
||||
{
|
||||
public:
|
||||
CPUFreqDriverInterface();
|
||||
~CPUFreqDriverInterface();
|
||||
|
||||
status_t InitCheck();
|
||||
StateList* GetCpuFrequencyStates();
|
||||
freq_info* GetCurrentFrequencyState();
|
||||
int32 GetNumberOfFrequencyStates();
|
||||
status_t SetFrequencyState(const freq_info* state);
|
||||
|
||||
status_t StartWatching(BHandler* target);
|
||||
status_t StopWatching();
|
||||
private:
|
||||
static int32 _ThreadWatchFreqFunction(void* data);
|
||||
void _WatchFrequency();
|
||||
|
||||
thread_id fThreadId;
|
||||
status_t _FindSpeedStepDriver(const char* path);
|
||||
|
||||
bool fInitOK;
|
||||
int32 fDriverHandler;
|
||||
|
||||
StateList* fFrequencyStates;
|
||||
|
||||
bool fIsWatching;
|
||||
BMessenger* fWatchingMessenger;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
13
src/preferences/cpufrequency/Jamfile
Normal file
13
src/preferences/cpufrequency/Jamfile
Normal file
@ -0,0 +1,13 @@
|
||||
SubDir HAIKU_TOP src preferences cpufrequency ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
Preference CPUFrequency :
|
||||
ColorStepView.cpp
|
||||
CPUFrequencyView.cpp
|
||||
DriverInterface.cpp
|
||||
main.cpp
|
||||
StatusView.cpp
|
||||
: be
|
||||
: cpufrequency.rdef
|
||||
;
|
439
src/preferences/cpufrequency/PreferencesWindow.h
Normal file
439
src/preferences/cpufrequency/PreferencesWindow.h
Normal file
@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef PREFERENCESWINDOW_h
|
||||
#define PREFERENCESWINDOW_h
|
||||
|
||||
#define DEBUG 1
|
||||
#include <Debug.h>
|
||||
|
||||
#if DEBUG
|
||||
# define LOG(text...) PRINT((text))
|
||||
#else
|
||||
# define LOG(text...)
|
||||
#endif
|
||||
|
||||
#include <Button.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
#include <Window.h>
|
||||
|
||||
// headers PreferencesStorage
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <File.h>
|
||||
#include <String.h>
|
||||
|
||||
// headers PrefFileWatcher
|
||||
#include <MessageFilter.h>
|
||||
|
||||
// headers PreferencesWindow
|
||||
#include <GroupView.h>
|
||||
#include <Screen.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
|
||||
|
||||
// messages PrefFileWatcher
|
||||
const uint32 kUpdatedPreferences = '&UdP';
|
||||
|
||||
template<typename Preferences>
|
||||
class PreferencesStorage
|
||||
{
|
||||
public:
|
||||
PreferencesStorage(const char* file,
|
||||
const Preferences& defaultPreferences);
|
||||
~PreferencesStorage();
|
||||
|
||||
void Revert();
|
||||
void Defaults();
|
||||
|
||||
BPoint WindowPosition(){return fWindowPosition;}
|
||||
void SetWindowPosition(BPoint position){
|
||||
fWindowPosition = position;}
|
||||
|
||||
Preferences* GetPreferences(){return &fPreferences;}
|
||||
|
||||
status_t LoadPreferences();
|
||||
status_t SavePreferences();
|
||||
|
||||
BString& PreferencesFile() { return fPreferencesFile; }
|
||||
status_t GetPreferencesPath(BPath &path);
|
||||
|
||||
private:
|
||||
BString fPreferencesFile;
|
||||
|
||||
Preferences fPreferences;
|
||||
Preferences fStartPreferences;
|
||||
const Preferences& fDefaultPreferences;
|
||||
BPoint fWindowPosition;
|
||||
};
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
class PrefFileWatcher : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
PrefFileWatcher(PreferencesStorage<Preferences>* storage,
|
||||
BHandler* target);
|
||||
~PrefFileWatcher();
|
||||
virtual filter_result Filter(BMessage *message, BHandler **target);
|
||||
|
||||
private:
|
||||
PreferencesStorage<Preferences>* fPreferencesStorage;
|
||||
node_ref fPreferencesNode;
|
||||
node_ref fPreferencesDirectoryNode;
|
||||
|
||||
BHandler* fTarget;
|
||||
};
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
class PreferencesWindow : public BWindow, public PreferencesStorage<Preferences>
|
||||
{
|
||||
public:
|
||||
PreferencesWindow(const char* title,
|
||||
const char* file,
|
||||
const Preferences& defaultPreferences);
|
||||
~PreferencesWindow();
|
||||
virtual void MessageReceived(BMessage *msg);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
virtual bool SetPreferencesView(BView* prefView);
|
||||
|
||||
private:
|
||||
void _MoveToPosition();
|
||||
BView* fPreferencesView;
|
||||
BButton* fRevertButton;
|
||||
BButton* fDefaultButton;
|
||||
BGroupLayout* fRootLayout;
|
||||
};
|
||||
|
||||
|
||||
const uint32 kDefaultMsg = 'dems';
|
||||
const uint32 kRevertMsg = 'rems';
|
||||
const uint32 kConfigChangedMsg = '&cgh';
|
||||
|
||||
template<typename Preferences>
|
||||
PreferencesStorage<Preferences>::PreferencesStorage(const char* file,
|
||||
const Preferences& defaultPreferences)
|
||||
: fDefaultPreferences(defaultPreferences)
|
||||
{
|
||||
// default center position
|
||||
fWindowPosition.x = -1;
|
||||
fWindowPosition.y = -1;
|
||||
|
||||
fPreferencesFile = file;
|
||||
if (LoadPreferences() != B_OK)
|
||||
Defaults();
|
||||
fStartPreferences = fPreferences;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
PreferencesStorage<Preferences>::~PreferencesStorage()
|
||||
{
|
||||
SavePreferences();
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
void
|
||||
PreferencesStorage<Preferences>::Revert()
|
||||
{
|
||||
fPreferences = fStartPreferences;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
void
|
||||
PreferencesStorage<Preferences>::Defaults()
|
||||
{
|
||||
fPreferences = fDefaultPreferences;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
status_t
|
||||
PreferencesStorage<Preferences>::GetPreferencesPath(BPath &path)
|
||||
{
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return path.Append(fPreferencesFile.String());
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
status_t
|
||||
PreferencesStorage<Preferences>::LoadPreferences()
|
||||
{
|
||||
BPath path;
|
||||
status_t status = GetPreferencesPath(path);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BFile settingsFile(path.Path(), B_READ_ONLY);
|
||||
status = settingsFile.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (settingsFile.Read(&fWindowPosition, sizeof(BPoint))
|
||||
!= sizeof(BPoint)) {
|
||||
LOG("failed to load settings\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (settingsFile.Read(&fPreferences, sizeof(Preferences))
|
||||
!= sizeof(Preferences)) {
|
||||
LOG("failed to load settings\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
status_t
|
||||
PreferencesStorage<Preferences>::SavePreferences()
|
||||
{
|
||||
BPath path;
|
||||
status_t status = GetPreferencesPath(path);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BFile settingsFile(path.Path(), B_READ_WRITE | B_CREATE_FILE);
|
||||
status = settingsFile.InitCheck();
|
||||
if (status != B_OK) {
|
||||
LOG("InitCheck() settings file failed \n");
|
||||
return status;
|
||||
}
|
||||
|
||||
if (settingsFile.Write(&fWindowPosition, sizeof(BPoint))
|
||||
!= sizeof(BPoint)) {
|
||||
LOG("can't save window position\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (settingsFile.Write(&fPreferences, sizeof(Preferences))
|
||||
!= sizeof(Preferences)) {
|
||||
LOG("can't save settings\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
PrefFileWatcher<Preferences>::PrefFileWatcher(PreferencesStorage<Preferences>* storage,
|
||||
BHandler* target)
|
||||
: BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE),
|
||||
fPreferencesStorage(storage),
|
||||
fTarget(target)
|
||||
{
|
||||
BPath path;
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
BEntry entry(path.Path());
|
||||
entry.GetNodeRef(&fPreferencesDirectoryNode);
|
||||
watch_node(&fPreferencesDirectoryNode, B_WATCH_DIRECTORY,
|
||||
fTarget);
|
||||
path.Append(fPreferencesStorage->PreferencesFile().String());
|
||||
entry.SetTo(path.Path());
|
||||
entry.GetNodeRef(&fPreferencesNode);
|
||||
watch_node(&fPreferencesNode, B_WATCH_STAT,
|
||||
fTarget);
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
PrefFileWatcher<Preferences>::~PrefFileWatcher()
|
||||
{
|
||||
stop_watching(fTarget);
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
filter_result
|
||||
PrefFileWatcher<Preferences>::Filter(BMessage *msg, BHandler **target)
|
||||
{
|
||||
const char *name;
|
||||
ino_t dir = -1;
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
int32 opcode;
|
||||
BPath path;
|
||||
node_ref nref;
|
||||
|
||||
if (msg->what != B_NODE_MONITOR
|
||||
|| msg->FindInt32("opcode", &opcode) != B_OK)
|
||||
return result;
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case B_ENTRY_MOVED:
|
||||
msg->FindInt64("to directory", dir);
|
||||
if (dir != fPreferencesDirectoryNode.node)
|
||||
break;
|
||||
|
||||
case B_ENTRY_CREATED:
|
||||
msg->FindString("name", &name);
|
||||
fPreferencesStorage->GetPreferencesPath(path);
|
||||
if (path.Path() == name) {
|
||||
msg->FindInt32("device", &fPreferencesNode.device);
|
||||
msg->FindInt64("node", &fPreferencesNode.node);
|
||||
watch_node(&fPreferencesNode, B_WATCH_STAT, fTarget);
|
||||
}
|
||||
fPreferencesStorage->LoadPreferences();
|
||||
msg->what = kUpdatedPreferences;
|
||||
break;
|
||||
|
||||
case B_ENTRY_REMOVED:
|
||||
msg->FindInt32("device", &nref.device);
|
||||
msg->FindInt64("node", &nref.node);
|
||||
if (fPreferencesNode == nref) {
|
||||
// stop all watching
|
||||
stop_watching(fTarget);
|
||||
// and start watching the directory again
|
||||
watch_node(&fPreferencesDirectoryNode, B_WATCH_DIRECTORY,
|
||||
fTarget);
|
||||
msg->what = kUpdatedPreferences;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_STAT_CHANGED:
|
||||
msg->FindInt32("device", &nref.device);
|
||||
msg->FindInt64("node", &nref.node);
|
||||
if (fPreferencesNode == nref) {
|
||||
fPreferencesStorage->LoadPreferences();
|
||||
msg->what = kUpdatedPreferences;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
PreferencesWindow<Preferences>::PreferencesWindow(const char* title,
|
||||
const char* file,
|
||||
const Preferences& defaultPreferences)
|
||||
: BWindow(BRect(50, 50, 400, 350), title, B_TITLED_WINDOW,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AVOID_FRONT
|
||||
| B_ASYNCHRONOUS_CONTROLS),
|
||||
PreferencesStorage<Preferences>(file, defaultPreferences),
|
||||
fPreferencesView(NULL)
|
||||
{
|
||||
BGroupView* buttonView = new BGroupView(B_HORIZONTAL);
|
||||
fDefaultButton = new BButton("Defaults",
|
||||
new BMessage(kDefaultMsg));
|
||||
|
||||
buttonView->AddChild(fDefaultButton);
|
||||
buttonView->GetLayout()->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(7));
|
||||
fRevertButton = new BButton("Revert", new BMessage(kRevertMsg));
|
||||
|
||||
fRevertButton->SetEnabled(false);
|
||||
buttonView->AddChild(fRevertButton);
|
||||
buttonView->GetLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
|
||||
|
||||
SetLayout(new BGroupLayout(B_VERTICAL));
|
||||
fRootLayout = new BGroupLayout(B_VERTICAL);
|
||||
fRootLayout->SetInsets(10, 10, 10, 10);
|
||||
fRootLayout->SetSpacing(10);
|
||||
BView* rootView = new BView("root view", 0, fRootLayout);
|
||||
AddChild(rootView);
|
||||
rootView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
fRootLayout->AddView(buttonView);
|
||||
|
||||
BSize size = fRootLayout->PreferredSize();
|
||||
ResizeTo(size.width, size.height);
|
||||
_MoveToPosition();
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
PreferencesWindow<Preferences>::~PreferencesWindow()
|
||||
{
|
||||
SetWindowPosition(Frame().LeftTop());
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
void
|
||||
PreferencesWindow<Preferences>::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch(msg->what)
|
||||
{
|
||||
case kConfigChangedMsg:
|
||||
fRevertButton->SetEnabled(true);
|
||||
break;
|
||||
|
||||
case kDefaultMsg:
|
||||
Defaults();
|
||||
fRevertButton->SetEnabled(true);
|
||||
if (fPreferencesView)
|
||||
PostMessage(kDefaultMsg, fPreferencesView);
|
||||
break;
|
||||
|
||||
case kRevertMsg:
|
||||
Revert();
|
||||
fRevertButton->SetEnabled(false);
|
||||
if (fPreferencesView)
|
||||
PostMessage(kRevertMsg, fPreferencesView);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
bool
|
||||
PreferencesWindow<Preferences>::QuitRequested()
|
||||
{
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
bool
|
||||
PreferencesWindow<Preferences>::SetPreferencesView(BView* prefView)
|
||||
{
|
||||
if (fPreferencesView)
|
||||
return false;
|
||||
|
||||
fPreferencesView = prefView;
|
||||
fRootLayout->AddView(0, fPreferencesView);
|
||||
|
||||
BSize size = fRootLayout->PreferredSize();
|
||||
ResizeTo(size.width, size.height);
|
||||
_MoveToPosition();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename Preferences>
|
||||
void
|
||||
PreferencesWindow<Preferences>::_MoveToPosition()
|
||||
{
|
||||
BPoint position = WindowPosition();
|
||||
// center window on screen if it had a bad position
|
||||
if(position.x < 0 && position.y < 0){
|
||||
BRect rect = BScreen().Frame();
|
||||
BRect windowFrame = Frame();
|
||||
position.x = (rect.Width() - windowFrame.Width()) / 2;
|
||||
position.y = (rect.Height() - windowFrame.Height()) / 2;
|
||||
}
|
||||
MoveTo(position);
|
||||
}
|
||||
|
||||
#endif
|
666
src/preferences/cpufrequency/StatusView.cpp
Normal file
666
src/preferences/cpufrequency/StatusView.cpp
Normal file
@ -0,0 +1,666 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "StatusView.h"
|
||||
#include "CPUFrequencyView.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Deskbar.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Roster.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
||||
|
||||
// messages FrequencySwitcher
|
||||
const uint32 kMsgDynamicPolicyPuls = '&dpp';
|
||||
|
||||
// messages menu
|
||||
const uint32 kMsgPolicyDynamic = 'pody';
|
||||
const uint32 kMsgPolicyPerformance = 'popr';
|
||||
const uint32 kMsgPolicyLowEnergy = 'pole';
|
||||
const uint32 kMsgPolicySetState = 'poss';
|
||||
|
||||
// messages StatusView
|
||||
const uint32 kMsgOpenSSPreferences = 'ossp';
|
||||
const char* kDeskbarItemName = "CPUFreqStatusView";
|
||||
|
||||
|
||||
FrequencySwitcher::FrequencySwitcher(CPUFreqDriverInterface* interface,
|
||||
BHandler* target)
|
||||
: BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE),
|
||||
fDriverInterface(interface),
|
||||
fTarget(target),
|
||||
fMessageRunner(NULL),
|
||||
fCurrentFrequency(NULL),
|
||||
fDynamicPolicyStarted(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
FrequencySwitcher::~FrequencySwitcher()
|
||||
{
|
||||
freq_preferences dummyPref;
|
||||
_StartDynamicPolicy(false, dummyPref);
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
FrequencySwitcher::Filter(BMessage *message, BHandler **target)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
if (message->what == kMsgDynamicPolicyPuls) {
|
||||
_CalculateDynamicState();
|
||||
result = B_SKIP_MESSAGE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FrequencySwitcher::SetMode(const freq_preferences& pref)
|
||||
{
|
||||
int16 stateCount = fDriverInterface->GetNumberOfFrequencyStates();
|
||||
StateList* list = fDriverInterface->GetCpuFrequencyStates();
|
||||
freq_info* currentState = fDriverInterface->GetCurrentFrequencyState();
|
||||
freq_info* state = NULL;
|
||||
bool isDynamic = false;
|
||||
|
||||
switch (pref.mode) {
|
||||
case DYNAMIC:
|
||||
isDynamic = true;
|
||||
fSteppingThreshold = pref.stepping_threshold;
|
||||
if (fMessageRunner && fIntegrationTime != pref.integration_time)
|
||||
{
|
||||
fIntegrationTime = pref.integration_time;
|
||||
fMessageRunner->SetInterval(fIntegrationTime);
|
||||
}
|
||||
if (!fDynamicPolicyStarted)
|
||||
_StartDynamicPolicy(true, pref);
|
||||
break;
|
||||
|
||||
case PERFORMANCE:
|
||||
state = list->ItemAt(int32(0));
|
||||
if (state != currentState)
|
||||
fDriverInterface->SetFrequencyState(state);
|
||||
break;
|
||||
|
||||
case LOW_ENERGIE:
|
||||
state = list->ItemAt(stateCount - 1);
|
||||
if (state != currentState)
|
||||
fDriverInterface->SetFrequencyState(state);
|
||||
break;
|
||||
|
||||
case CUSTOM:
|
||||
if (pref.custom_stepping < stateCount) {
|
||||
state = list->ItemAt(pref.custom_stepping);
|
||||
fDriverInterface->SetFrequencyState(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isDynamic && fDynamicPolicyStarted) {
|
||||
fDynamicPolicyStarted = false;
|
||||
_StartDynamicPolicy(false, pref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FrequencySwitcher::_CalculateDynamicState()
|
||||
{
|
||||
system_info sysInfo;
|
||||
get_system_info(&sysInfo);
|
||||
bigtime_t now = system_time();
|
||||
bigtime_t activeTime = sysInfo.cpu_infos[0].active_time;
|
||||
|
||||
// if the dynamic mode is not started firt init the prev values
|
||||
if (!fDynamicPolicyStarted) {
|
||||
fPrevActiveTime = activeTime;
|
||||
fPrevTime = now;
|
||||
fDynamicPolicyStarted = true;
|
||||
}
|
||||
else {
|
||||
float usage = (float)(activeTime - fPrevActiveTime )
|
||||
/ (now - fPrevTime);
|
||||
if (usage >= 1.0)
|
||||
usage = 0.9999999;
|
||||
|
||||
int32 numberOfStates = fDriverInterface->GetNumberOfFrequencyStates();
|
||||
for (int i = 0; i < numberOfStates; i++) {
|
||||
float usageOfStep = ColorStepView::UsageOfStep(i, numberOfStates,
|
||||
fSteppingThreshold);
|
||||
LOG("usage %f, step %f\n", usage, usageOfStep);
|
||||
|
||||
if (usage < usageOfStep)
|
||||
{
|
||||
StateList* list = fDriverInterface->GetCpuFrequencyStates();
|
||||
freq_info* newState = list->ItemAt(numberOfStates - 1 - i);
|
||||
if (newState != fCurrentFrequency) {
|
||||
LOG("change freq\n");
|
||||
fDriverInterface->SetFrequencyState(newState);
|
||||
fCurrentFrequency = newState;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fPrevActiveTime = activeTime;
|
||||
fPrevTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FrequencySwitcher::_StartDynamicPolicy(bool start,
|
||||
const freq_preferences& pref)
|
||||
{
|
||||
if (start) {
|
||||
if (!fMessageRunner) {
|
||||
fIntegrationTime = pref.integration_time;
|
||||
fMessageRunner = new BMessageRunner(fTarget,
|
||||
new BMessage(kMsgDynamicPolicyPuls)
|
||||
, pref.integration_time, -1);
|
||||
fCurrentFrequency = fDriverInterface->GetCurrentFrequencyState();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fMessageRunner) {
|
||||
delete fMessageRunner;
|
||||
fMessageRunner = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FrequencyMenu::FrequencyMenu(BMenu* menu, BHandler* target,
|
||||
PreferencesStorage<freq_preferences> * storage,
|
||||
CPUFreqDriverInterface* interface)
|
||||
: BMessageFilter(B_PROGRAMMED_DELIVERY, B_LOCAL_SOURCE),
|
||||
fTarget(target),
|
||||
fStorage(storage),
|
||||
fInterface(interface)
|
||||
{
|
||||
fDynamicPerformance = new BMenuItem("Dynamic Performance",
|
||||
new BMessage(kMsgPolicyDynamic));
|
||||
fHighPerformance = new BMenuItem("High Performance",
|
||||
new BMessage(kMsgPolicyPerformance));
|
||||
fLowEnergie = new BMenuItem("Low Energie",
|
||||
new BMessage(kMsgPolicyLowEnergy));
|
||||
|
||||
menu->AddItem(fDynamicPerformance);
|
||||
menu->AddItem(fHighPerformance);
|
||||
menu->AddItem(fLowEnergie);
|
||||
|
||||
fCustomStateMenu = new BMenu("Set State");
|
||||
|
||||
StateList* stateList = fInterface->GetCpuFrequencyStates();
|
||||
for (int i = 0; i < stateList->CountItems(); i++) {
|
||||
freq_info* info = stateList->ItemAt(i);
|
||||
BString label;
|
||||
label << info->frequency;
|
||||
label += " MHz";
|
||||
fCustomStateMenu->AddItem(new BMenuItem(label.String(),
|
||||
new BMessage(kMsgPolicySetState)));
|
||||
}
|
||||
|
||||
menu->AddItem(fCustomStateMenu);
|
||||
|
||||
// set the target of the items
|
||||
fDynamicPerformance->SetTarget(fTarget);
|
||||
fHighPerformance->SetTarget(fTarget);
|
||||
fLowEnergie->SetTarget(fTarget);
|
||||
|
||||
fCustomStateMenu->SetTargetForItems(fTarget);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
FrequencyMenu::_SetL1MenuLabelFrom(BMenuItem* item)
|
||||
{
|
||||
BMenuItem* superItem, *markedItem;
|
||||
superItem = item->Menu()->Superitem();
|
||||
if (superItem)
|
||||
superItem->SetLabel(item->Label());
|
||||
markedItem = item->Menu()->FindMarked();
|
||||
if (markedItem)
|
||||
markedItem->SetMarked(false);
|
||||
item->SetMarked(true);
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
FrequencyMenu::Filter(BMessage *msg, BHandler **target)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
|
||||
BMenuItem* item, *superItem, *markedItem;
|
||||
msg->FindPointer("source", (void**)&item);
|
||||
if (!item) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool safeChanges = false;
|
||||
freq_preferences* pref = fStorage->GetPreferences();
|
||||
|
||||
switch (msg->what) {
|
||||
case kMsgPolicyDynamic:
|
||||
pref->mode = DYNAMIC;
|
||||
_SetL1MenuLabelFrom(item);
|
||||
safeChanges = true;
|
||||
msg->what = kUpdatedPreferences;
|
||||
break;
|
||||
|
||||
case kMsgPolicyPerformance:
|
||||
pref->mode = PERFORMANCE;
|
||||
_SetL1MenuLabelFrom(item);
|
||||
safeChanges = true;
|
||||
msg->what = kUpdatedPreferences;
|
||||
break;
|
||||
|
||||
case kMsgPolicyLowEnergy:
|
||||
pref->mode = LOW_ENERGIE;
|
||||
_SetL1MenuLabelFrom(item);
|
||||
safeChanges = true;
|
||||
msg->what = kUpdatedPreferences;
|
||||
break;
|
||||
|
||||
case kMsgPolicySetState:
|
||||
pref->mode = CUSTOM;
|
||||
pref->custom_stepping = item->Menu()->IndexOf(item);
|
||||
|
||||
superItem = item->Menu()->Supermenu()->Superitem();
|
||||
if (superItem)
|
||||
superItem->SetLabel(item->Label());
|
||||
markedItem = item->Menu()->Supermenu()->FindMarked();
|
||||
if (markedItem)
|
||||
markedItem->SetMarked(false);
|
||||
markedItem = item->Menu()->FindMarked();
|
||||
if (markedItem)
|
||||
markedItem->SetMarked(false);
|
||||
item->SetMarked(true);
|
||||
|
||||
safeChanges = true;
|
||||
msg->what = kUpdatedPreferences;
|
||||
break;
|
||||
}
|
||||
|
||||
if (safeChanges)
|
||||
fStorage->SavePreferences();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FrequencyMenu::UpdateMenu()
|
||||
{
|
||||
BMenuItem* customItem, *markedItem, *superItem;
|
||||
|
||||
freq_preferences* pref = fStorage->GetPreferences();
|
||||
switch (pref->mode) {
|
||||
case DYNAMIC:
|
||||
_SetL1MenuLabelFrom(fDynamicPerformance);
|
||||
break;
|
||||
|
||||
case PERFORMANCE:
|
||||
_SetL1MenuLabelFrom(fHighPerformance);
|
||||
break;
|
||||
|
||||
case LOW_ENERGIE:
|
||||
_SetL1MenuLabelFrom(fLowEnergie);
|
||||
break;
|
||||
|
||||
case CUSTOM:
|
||||
markedItem = fCustomStateMenu->FindMarked();
|
||||
if (markedItem)
|
||||
markedItem->SetMarked(false);
|
||||
customItem = fCustomStateMenu->ItemAt(pref->custom_stepping);
|
||||
if (customItem)
|
||||
customItem->SetMarked(true);
|
||||
superItem = fCustomStateMenu->Supermenu()->Superitem();
|
||||
if (superItem && customItem)
|
||||
superItem->SetLabel(customItem->Label());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusView::StatusView(BRect frame, bool inDeskbar,
|
||||
PreferencesStorage<freq_preferences>* storage = NULL)
|
||||
: BView(frame, kDeskbarItemName, B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS),
|
||||
fInDeskbar(inDeskbar),
|
||||
fCurrentFrequency(NULL),
|
||||
fDragger(NULL)
|
||||
{
|
||||
if (!inDeskbar) {
|
||||
// we were obviously added to a standard window - let's add a dragger
|
||||
BRect bounds = Bounds();
|
||||
bounds.top = bounds.bottom - 7;
|
||||
bounds.left = bounds.right - 7;
|
||||
fDragger = new BDragger(bounds, this,
|
||||
B_FOLLOW_NONE);
|
||||
AddChild(fDragger);
|
||||
}
|
||||
|
||||
if (storage) {
|
||||
fOwningStorage = false;
|
||||
fStorage = storage;
|
||||
}
|
||||
else {
|
||||
fOwningStorage = true;
|
||||
fStorage = new PreferencesStorage<freq_preferences>("CPUFrequency",
|
||||
kDefaultPreferences);
|
||||
}
|
||||
|
||||
_Init();
|
||||
}
|
||||
|
||||
|
||||
StatusView::StatusView(BMessage* archive)
|
||||
: BView(archive),
|
||||
fInDeskbar(false),
|
||||
fCurrentFrequency(NULL),
|
||||
fDragger(NULL)
|
||||
{
|
||||
app_info info;
|
||||
if (be_app->GetAppInfo(&info) == B_OK
|
||||
&& !strcasecmp(info.signature, "application/x-vnd.Be-TSKB"))
|
||||
fInDeskbar = true;
|
||||
|
||||
fOwningStorage = true;
|
||||
fStorage = new PreferencesStorage<freq_preferences>(kPreferencesFileName,
|
||||
kDefaultPreferences);
|
||||
_Init();
|
||||
}
|
||||
|
||||
|
||||
StatusView::~StatusView()
|
||||
{
|
||||
if (fOwningStorage)
|
||||
delete fStorage;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::_AboutRequested()
|
||||
{
|
||||
BAlert *alert = new BAlert("about", "CPU Frequency\n"
|
||||
"\twritten by Clemens Zeidler\n"
|
||||
"\tCopyright 2009, Haiku, Inc.\n", "Ok");
|
||||
BTextView *view = alert->TextView();
|
||||
BFont font;
|
||||
|
||||
view->SetStylable(true);
|
||||
|
||||
view->GetFont(&font);
|
||||
font.SetSize(18);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
view->SetFontAndColor(0, 13, &font);
|
||||
|
||||
alert->Go();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::_Quit()
|
||||
{
|
||||
if (fInDeskbar) {
|
||||
BDeskbar deskbar;
|
||||
deskbar.RemoveItem(kDeskbarItemName);
|
||||
} else
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
|
||||
StatusView *
|
||||
StatusView::Instantiate(BMessage* archive)
|
||||
{
|
||||
if (!validate_instantiation(archive, "StatusView"))
|
||||
return NULL;
|
||||
|
||||
return new StatusView(archive);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
StatusView::Archive(BMessage* archive, bool deep) const
|
||||
{
|
||||
status_t status = BView::Archive(archive, deep);
|
||||
if (status == B_OK)
|
||||
status = archive->AddString("add_on", kPrefSignature);
|
||||
if (status == B_OK)
|
||||
status = archive->AddString("class", "StatusView");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::AttachedToWindow()
|
||||
{
|
||||
BView::AttachedToWindow();
|
||||
if (Parent())
|
||||
SetViewColor(Parent()->ViewColor());
|
||||
else
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
SetLowColor(ViewColor());
|
||||
|
||||
// watching if the driver change the frequency
|
||||
fDriverInterface.StartWatching(this);
|
||||
|
||||
// monitor preferences file
|
||||
fPrefFileWatcher = new PrefFileWatcher<freq_preferences>(fStorage, this);
|
||||
AddFilter(fPrefFileWatcher);
|
||||
|
||||
// FrequencySwitcher
|
||||
fFrequencySwitcher = new FrequencySwitcher(&fDriverInterface, this);
|
||||
fFrequencySwitcher->SetMode(*(fStorage->GetPreferences()));
|
||||
AddFilter(fFrequencySwitcher);
|
||||
|
||||
// perferences menu
|
||||
fPreferencesMenu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||
fPreferencesMenuFilter = new FrequencyMenu(fPreferencesMenu, this,
|
||||
fStorage,
|
||||
&fDriverInterface);
|
||||
|
||||
fPreferencesMenu->SetFont(be_plain_font);
|
||||
|
||||
fPreferencesMenu->AddSeparatorItem();
|
||||
fOpenPrefItem = new BMenuItem("Open Speedstep Preferences" B_UTF8_ELLIPSIS,
|
||||
new BMessage(kMsgOpenSSPreferences));
|
||||
fPreferencesMenu->AddItem(fOpenPrefItem);
|
||||
fOpenPrefItem->SetTarget(this);
|
||||
|
||||
if (fInDeskbar) {
|
||||
fQuitItem= new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED));
|
||||
fPreferencesMenu->AddItem(fQuitItem);
|
||||
fQuitItem->SetTarget(this);
|
||||
}
|
||||
AddFilter(fPreferencesMenuFilter);
|
||||
|
||||
fPreferencesMenuFilter->UpdateMenu();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::DetachedFromWindow()
|
||||
{
|
||||
fDriverInterface.StopWatching();
|
||||
|
||||
if (RemoveFilter(fPrefFileWatcher))
|
||||
delete fPrefFileWatcher;
|
||||
if (RemoveFilter(fFrequencySwitcher))
|
||||
delete fFrequencySwitcher;
|
||||
if (RemoveFilter(fPreferencesMenuFilter))
|
||||
delete fPreferencesMenuFilter;
|
||||
delete fPreferencesMenu;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgOpenSSPreferences:
|
||||
_OpenPreferences();
|
||||
break;
|
||||
|
||||
case kMSGFrequencyChanged:
|
||||
message->FindPointer("freq_info", (void**)&fCurrentFrequency);
|
||||
_SetupNewFreqString();
|
||||
Invalidate();
|
||||
break;
|
||||
|
||||
case kUpdatedPreferences:
|
||||
fFrequencySwitcher->SetMode(*(fStorage->GetPreferences()));
|
||||
fPreferencesMenuFilter->UpdateMenu();
|
||||
break;
|
||||
|
||||
case B_ABOUT_REQUESTED:
|
||||
_AboutRequested();
|
||||
break;
|
||||
|
||||
case B_QUIT_REQUESTED:
|
||||
_Quit();
|
||||
break;
|
||||
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::FrameResized(float width, float height)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::Draw(BRect updateRect)
|
||||
{
|
||||
|
||||
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
float height = fontHeight.ascent + fontHeight.descent;
|
||||
|
||||
MovePenTo(0, height);
|
||||
|
||||
DrawString(fFreqString.String());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
StatusView::MouseDown(BPoint point)
|
||||
{
|
||||
if (fShowPopUpMenu) {
|
||||
ConvertToScreen(&point);
|
||||
fPreferencesMenu->Go(point, true, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::GetPreferredSize(float *width, float *height)
|
||||
{
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
*height = fontHeight.ascent + fontHeight.descent;
|
||||
if (!fInDeskbar)
|
||||
*height += 7;
|
||||
|
||||
*width = StringWidth(fFreqString.String());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::ResizeToPreferred(void)
|
||||
{
|
||||
float width, height;
|
||||
GetPreferredSize(&width, &height);
|
||||
ResizeTo(width, height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::ShowPopUpMenu(bool show = true)
|
||||
{
|
||||
fShowPopUpMenu = show;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::UpdateCPUFreqState()
|
||||
{
|
||||
fFrequencySwitcher->SetMode(*(fStorage->GetPreferences()));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::_Init()
|
||||
{
|
||||
fShowPopUpMenu = true;
|
||||
fCurrentFrequency = fDriverInterface.GetCurrentFrequencyState();
|
||||
|
||||
_SetupNewFreqString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::_SetupNewFreqString()
|
||||
{
|
||||
if (fCurrentFrequency)
|
||||
fFreqString = ColorStepView::CreateFrequencyString(
|
||||
fCurrentFrequency->frequency);
|
||||
else
|
||||
fFreqString = "? MHz";
|
||||
|
||||
ResizeToPreferred();
|
||||
|
||||
if (fDragger) {
|
||||
BRect frame = Frame();
|
||||
fDragger->MoveTo(frame.right - 7, frame.bottom - 7);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StatusView::_OpenPreferences()
|
||||
{
|
||||
status_t ret = be_roster->Launch(kPrefSignature);
|
||||
if (ret < B_OK) {
|
||||
BString errorMessage("Launching the CPU Frequency preflet failed.\n\n"
|
||||
"Error: ");
|
||||
errorMessage << strerror(ret);
|
||||
BAlert* alert = new BAlert("launch error", errorMessage.String(),
|
||||
"Ok");
|
||||
// asynchronous alert in order to not block replicant host
|
||||
// application
|
||||
alert->Go(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern "C" _EXPORT BView *
|
||||
instantiate_deskbar_item(void)
|
||||
{
|
||||
return new StatusView(BRect(0, 0, 15, 15), true, NULL);
|
||||
}
|
140
src/preferences/cpufrequency/StatusView.h
Normal file
140
src/preferences/cpufrequency/StatusView.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef STATUS_VIEW_H
|
||||
#define STATUS_VIEW_H
|
||||
|
||||
#include <Dragger.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <String.h>
|
||||
#include <View.h>
|
||||
|
||||
#include "CPUFrequencyView.h"
|
||||
#include "DriverInterface.h"
|
||||
#include "PreferencesWindow.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include <Debug.h>
|
||||
|
||||
#if DEBUG
|
||||
# define LOG(text...) PRINT((text))
|
||||
#else
|
||||
# define LOG(text...)
|
||||
#endif
|
||||
|
||||
extern const char* kDeskbarItemName;
|
||||
extern const char* kAddonSignature;
|
||||
|
||||
|
||||
class FrequencySwitcher : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
FrequencySwitcher(CPUFreqDriverInterface* interface,
|
||||
BHandler* target);
|
||||
virtual ~FrequencySwitcher();
|
||||
|
||||
virtual filter_result Filter(BMessage *message, BHandler **target);
|
||||
|
||||
void SetMode(const freq_preferences& pref);
|
||||
|
||||
private:
|
||||
void _CalculateDynamicState();
|
||||
void _StartDynamicPolicy(bool start,
|
||||
const freq_preferences& pref);
|
||||
|
||||
CPUFreqDriverInterface* fDriverInterface;
|
||||
BHandler* fTarget;
|
||||
BMessageRunner* fMessageRunner;
|
||||
|
||||
freq_info* fCurrentFrequency;
|
||||
|
||||
bool fDynamicPolicyStarted;
|
||||
bigtime_t fPrevActiveTime;
|
||||
bigtime_t fPrevTime;
|
||||
float fSteppingThreshold;
|
||||
bigtime_t fIntegrationTime;
|
||||
};
|
||||
|
||||
|
||||
class FrequencyMenu : public BMessageFilter
|
||||
{
|
||||
public:
|
||||
FrequencyMenu(BMenu* menu, BHandler* target,
|
||||
PreferencesStorage<freq_preferences>* storage,
|
||||
CPUFreqDriverInterface* interface);
|
||||
virtual filter_result Filter(BMessage *message, BHandler **target);
|
||||
|
||||
void UpdateMenu();
|
||||
private:
|
||||
inline void _SetL1MenuLabelFrom(BMenuItem* item);
|
||||
|
||||
BHandler* fTarget;
|
||||
BMenuItem* fDynamicPerformance;
|
||||
BMenuItem* fHighPerformance;
|
||||
BMenuItem* fLowEnergie;
|
||||
BMenu* fCustomStateMenu;
|
||||
|
||||
PreferencesStorage<freq_preferences>* fStorage;
|
||||
CPUFreqDriverInterface* fInterface;
|
||||
};
|
||||
|
||||
|
||||
class StatusView : public BView {
|
||||
public:
|
||||
StatusView(BRect frame, bool inDeskbar = false,
|
||||
PreferencesStorage<freq_preferences>* storage = NULL);
|
||||
StatusView(BMessage* archive);
|
||||
virtual ~StatusView();
|
||||
|
||||
static StatusView* Instantiate(BMessage* archive);
|
||||
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
virtual void GetPreferredSize(float *width, float *height);
|
||||
virtual void ResizeToPreferred(void);
|
||||
|
||||
virtual void ShowPopUpMenu(bool show = true);
|
||||
|
||||
virtual void UpdateCPUFreqState();
|
||||
|
||||
private:
|
||||
void _Init();
|
||||
void _SetupNewFreqString();
|
||||
void _OpenPreferences();
|
||||
void _AboutRequested();
|
||||
void _Quit();
|
||||
|
||||
bool fInDeskbar;
|
||||
|
||||
CPUFreqDriverInterface fDriverInterface;
|
||||
freq_info* fCurrentFrequency;
|
||||
FrequencySwitcher* fFrequencySwitcher;
|
||||
|
||||
bool fShowPopUpMenu;
|
||||
BPopUpMenu* fPreferencesMenu;
|
||||
BMenuItem* fOpenPrefItem;
|
||||
BMenuItem* fQuitItem;
|
||||
|
||||
FrequencyMenu* fPreferencesMenuFilter;
|
||||
bool fOwningStorage;
|
||||
PreferencesStorage<freq_preferences>* fStorage;
|
||||
PrefFileWatcher<freq_preferences>* fPrefFileWatcher;
|
||||
|
||||
BString fFreqString;
|
||||
BDragger* fDragger;
|
||||
};
|
||||
|
||||
#endif // STATUS_VIEW_H
|
102
src/preferences/cpufrequency/cpufrequency.rdef
Normal file
102
src/preferences/cpufrequency/cpufrequency.rdef
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
resource app_signature "application/x-vnd.Haiku-CPUFrequencyPref";
|
||||
|
||||
resource app_version {
|
||||
major = 1,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
variety = B_APPV_FINAL,
|
||||
internal = 0,
|
||||
|
||||
short_info = "CPUFrequency",
|
||||
long_info = "CPUFrequency ©2008 Haiku, Inc."
|
||||
};
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
resource vector_icon {
|
||||
$"6E6369660E03010000020002023980000000000000004000004BE00008908100"
|
||||
$"010000FFFF01000000020016023CC7EE389BC0BA16573E39B04977C842ADC700"
|
||||
$"FFFFD3020006023C529D3753A2B8966F3D9D084B6044496AAF00474747FFA5A0"
|
||||
$"A002001602BC4E76BC411B3C90DABCA00D47587D4ABA850090FFD40200160238"
|
||||
$"313C3B5CF0BFCD963C7AAC4C13943FCAF901ECFFC3054B04017E020006033E2F"
|
||||
$"99387F17BA42DB3FF5B94A0E32482C90001D1E2C3D454658FF01010102000602"
|
||||
$"3879063B8224BE2CC83B10DB4A1F6F49B894FF9A9A9A00242222020006033C69"
|
||||
$"A60000000000003E186148800049800058F3F3F300D4CECEFFD9D9D902000603"
|
||||
$"3C1F1A33E78CB7ACC03FFE4F48BB3EBD7B6C0078D905818CFF05FF7ADD050200"
|
||||
$"1602349C2E37B5FABA1F6036FC624A3E004B320001D3FF910200160235777837"
|
||||
$"0A67B7E8CE363A844A1D684B45D800F3FF2E0D0A04486050605C51544E04033E"
|
||||
$"5349594856475C49604B5C4E604B0A06262A264C485E5252523030240A04262A"
|
||||
$"4838523030240A044838485E525252300A04262A264C485E48380A04453A4553"
|
||||
$"2844282E0A04B6F9C0F42845282EB701B8EC0A044550455328452AC0F30A0445"
|
||||
$"3A45502A43B701B8EC0408AEBAB6BCBCC32FBD4F2E3930BDA8B9ACC0A5BA9EBC"
|
||||
$"03BB1EBFD937BF0DBD4FC072BCC3C019BDDBC0CB46460204BF23C726BF91C70D"
|
||||
$"BEB5C73FBE9FC87EBE7AC7D9BEC5C922BFAAC97BBF3CC994C018C962C02DC823"
|
||||
$"C053C8C8C008C77F0204BFCEC6FBC042C6E0BF5BC715BF48C85ABF1FC7B3BF71"
|
||||
$"C902C063C95ABFF0C974C0D7C93FC0EAC7FAC113C8A2C0C1C7530E0A07010000"
|
||||
$"0A0101011001178300040A0001021001178400040A020103000A080109000A0B"
|
||||
$"010A1001178120040A030104000A04020506000A090107000A0A0108000A0D01"
|
||||
$"0C0815FF0A0C010B0815FF0A0D010C0A3FEAF70000000000003FEAF7C573B4C2"
|
||||
$"770615FF0A0C010B0A3FEAF70000000000003FEAF7C573B4C2770615FF"
|
||||
};
|
||||
|
||||
#else // HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
resource large_icon array {
|
||||
$"FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFF001B1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFF001B1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFF001B1C1B1C1C1B1C1C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFF001B1C1B1C1C1B1C1C1B1C1B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFF001B1C1B1C1C1B1C1C1B1C1B1C1C1B0000FFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FF001B1C1B1C1C1B1C1C1B1C1B1C1C1B1C1C1B0000FFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"003F1B1C1B1C1C1B1C1C1B1C1B1C1C1B1C1C1B1C1B0000FFFFFFFFFFFFFFFFFF"
|
||||
$"00173F3F1B1C1B1C1C1B1C1C1B1C1B1C1C1B1C1C1B1C3F00FFFFFFFFFFFFFFFF"
|
||||
$"001717183F3F1B1C1B1C1C1B1C1C1B1C1B1C1C1B1C3F0E00FFFFFFFFFFFFFFFF"
|
||||
$"00170F1718173F3F1B1C1B1C1C1B1C1C1B1C1B1C3F0E0F00FFFFFFFFFFFFFFFF"
|
||||
$"00170F0F0F1717183F3F1B1C1B1C1C1B1C1C1B3F0E0F0F00FFFFFFFFFFFFFFFF"
|
||||
$"00170F00000F0F1717183F3F1B1C1B1C1C1B3F0E0F0F0F00FFFFFFFFFFFFFFFF"
|
||||
$"00170F000000000F0F1717183F3F1B1C1B3F0E0F0F0F0F00FFFFFFFFFFFFFFFF"
|
||||
$"00170F0000000000000F0F1717183F1B3F0E0F0F0F0F0F00FFFFFFFFFFFFFFFF"
|
||||
$"00170F00003700000000000F0F17173F0E0F0F0F0F0F0F00FFFFFFFF000000FF"
|
||||
$"00170F000037000000000000003F173F0E0F0F0F0F0F0F00FFFF00000F0F0FFF"
|
||||
$"00170F373600370000000000003F173F0E0F0F0F0F0F0F00FF000F0FFFFFFFFF"
|
||||
$"00170F000000370036003700003F173F0E0F0F0F0F0F0F00FF000FFFFFFFFFFF"
|
||||
$"00170F000000373637003700003F173F0E0F0F0F0F0F0F00FF000FFFFFFFFFFF"
|
||||
$"00170F000000370036373700003F173F0E0F0F0F0F0F0F00FFFF000EFFFFFFFF"
|
||||
$"00170F000000000037000036003F173F0E0F0F0F0F0F0F00FFFFFF000EFFFFFF"
|
||||
$"00173F3F0000000037000000003F173F0E0F0F0F0F0F0F00FFFFFF000FFFFFFF"
|
||||
$"001717183F3F000000000000003F173F0E0F0F0F0F0F0F000F0EFF000FFFFFFF"
|
||||
$"FF00001717183F3F00000000003F173F0E0F0F0F0F0F0F000F0E000FFFFFFFFF"
|
||||
$"FFFFFF00001717183F3F0000003F173F0E0F0F0F0F0F000F0F000FFFFFFFFFFF"
|
||||
$"FFFFFFFFFF00001717183F3F003F173F0E0F0F0F0F000000000FFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFF00001717183F3F173F0E0F0F0F000F0F0F0FFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFF0000171718173F0E0F0F000F0F0FFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFF000017173F0E0F000F0F0FFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFF00003F0E000F0F0FFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000E0F0FFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
};
|
||||
|
||||
resource mini_icon array {
|
||||
$"FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFF001B1C0000FFFFFFFFFFFFFFFFFF"
|
||||
$"FF001B1C1B1C1C0000FFFFFFFFFFFFFF"
|
||||
$"003F1B1C1B1C1C1B1C0000FFFFFFFFFF"
|
||||
$"00173F3F1B1C1B1C1C1B1C00FFFFFFFF"
|
||||
$"000E18173F3F1B1C1B1C0F00FFFFFFFF"
|
||||
$"000E000018173F3F1B0F0F00FFFFFFFF"
|
||||
$"000E0000000018170F0F0F00FFFF0000"
|
||||
$"000E3600370000180F0F0E00FF000E0E"
|
||||
$"000E0036370000180F0F0E00FF000EFF"
|
||||
$"000F0000363737180E0F0F00FF000EFF"
|
||||
$"00170000370000170F0F0F00FF000FFF"
|
||||
$"00001717000000180F0E0F0000000FFF"
|
||||
$"FFFF0000171700180F0E0000000EFFFF"
|
||||
$"FFFFFFFF000017170F000F0F0EFFFFFF"
|
||||
$"FFFFFFFFFFFF0000000E0FFFFFFFFFFF"
|
||||
};
|
||||
|
||||
#endif // HAIKU_TARGET_PLATFORM_HAIKU
|
30
src/preferences/cpufrequency/main.cpp
Normal file
30
src/preferences/cpufrequency/main.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "PreferencesWindow.h"
|
||||
#include "CPUFrequencyView.h"
|
||||
#include <Application.h>
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
BApplication *app = new BApplication(kPrefSignature);
|
||||
PreferencesWindow<freq_preferences> *window;
|
||||
window = new PreferencesWindow<freq_preferences>("CPU Frequency",
|
||||
kPreferencesFileName,
|
||||
kDefaultPreferences);
|
||||
CPUFrequencyView* prefView = new CPUFrequencyView(BRect(0, 0, 400, 350),
|
||||
window);
|
||||
window->SetPreferencesView(prefView);
|
||||
window->Show();
|
||||
app->Run();
|
||||
|
||||
delete app;
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user