Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ LOCAL_SRC_FILES := \
src/thd_engine_adaptive.cpp \
src/thd_lzma_dec.cpp \
src/LzmaDec.c \
src/thd_gddv.cpp
src/thd_gddv.cpp \
src/thd_platform.cpp \
src/thd_platform_intel.cpp \
src/thd_platform_arm.cpp

LOCAL_C_INCLUDES += external/libxml2/include

Expand Down
6 changes: 4 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ thermald_SOURCES = \
src/thd_gddv.cpp \
thermald-resource.c \
src/thd_lzma_dec.cpp \
src/LzmaDec.c

src/LzmaDec.c \
src/thd_platform.cpp \
src/thd_platform_intel.cpp \
src/thd_platform_arm.cpp

man5_MANS = man/thermal-conf.xml.5
man8_MANS = man/thermald.8
Expand Down
128 changes: 20 additions & 108 deletions src/thd_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <cpuid.h>
#include <locale>
#include <memory>
#include "thd_engine.h"
Expand All @@ -44,6 +43,9 @@
#include "thd_zone_dynamic.h"
#include "thd_cdev_gen_sysfs.h"
#include "thd_int3400.h"
#include "thd_platform.h"
#include "thd_platform_intel.h"
#include "thd_platform_arm.h"

static void *cthd_engine_thread(void *arg);

Expand All @@ -53,11 +55,10 @@ cthd_engine::cthd_engine(std::string _uuid) :
false), adaptive_mode(false), poll_timeout_msec(-1), wakeup_fd(
-1), uevent_fd(-1), control_mode(COMPLEMENTRY), write_pipe_fd(
0), preference(0), status(true), thz_last_uevent_time(0), thz_last_temp_ind_time(
0), thz_last_update_event_time(0), terminate(false), genuine_intel(
0), has_invariant_tsc(0), has_aperf(0), proc_list_matched(
false), poll_interval_sec(0), poll_sensor_mask(0), fast_poll_sensor_mask(
0), saved_poll_interval(0), poll_fd_cnt(0), rt_kernel(false), parser_init_done(
false) {
0), thz_last_update_event_time(0), terminate(false), has_invariant_tsc(0),
has_aperf(0), proc_list_matched(false), poll_interval_sec(0), poll_sensor_mask(0),
fast_poll_sensor_mask(0), saved_poll_interval(0), poll_fd_cnt(0), rt_kernel(false),
parser_init_done(false) {
thd_engine = pthread_t();
thd_attr = pthread_attr_t();

Expand Down Expand Up @@ -318,7 +319,7 @@ int cthd_engine::thd_engine_start() {
poll_timeout_msec = poll_interval_sec * 1000;
}

if (parser.platform_matched()) {
if (!parser_init() && parser.platform_matched()) {
parser.set_default_preference();
int poll_secs = parser.get_polling_interval();
if (poll_secs) {
Expand Down Expand Up @@ -742,112 +743,23 @@ void cthd_engine::thd_engine_reload_zones() {
}
}

// Add any tested platform ids in this table
#ifndef ANDROID
static const supported_ids_t id_table[] = {
{ 6, 0x2a }, // Sandybridge
{ 6, 0x3a }, // IvyBridge
{ 6, 0x3c }, // Haswell
{ 6, 0x45 }, // Haswell ULT
{ 6, 0x46 }, // Haswell ULT
{ 6, 0x3d }, // Broadwell
{ 6, 0x47 }, // Broadwell-GT3E
{ 6, 0x37 }, // Valleyview BYT
{ 6, 0x4c }, // Brasewell
{ 6, 0x4e }, // skylake
{ 6, 0x5e }, // skylake
{ 6, 0x5c }, // Broxton
{ 6, 0x7a }, // Gemini Lake
{ 6, 0x8e }, // kabylake
{ 6, 0x9e }, // kabylake
{ 6, 0x66 }, // Cannonlake
{ 6, 0x7e }, // Icelake
{ 6, 0x8c }, // Tigerlake_L
{ 6, 0x8d }, // Tigerlake
{ 6, 0xa5 }, // Cometlake
{ 6, 0xa6 }, // Cometlake_L
{ 6, 0xa7 }, // Rocketlake
{ 6, 0x9c }, // Jasper Lake
{ 6, 0x97 }, // Alderlake
{ 6, 0x9a }, // Alderlake
{ 6, 0xb7 }, // Raptorlake
{ 6, 0xba }, // Raptorlake
{ 6, 0xbe }, // Alderlake N
{ 6, 0xbf }, // Raptorlake S
{ 6, 0xaa }, // Mateor Lake L
{ 6, 0xbd }, // Lunar Lake M
{ 6, 0xc6 }, // Arrow Lake
{ 6, 0xc5 }, // Arrow Lake H
{ 6, 0xb5 }, // Arrow Lake U
{ 6, 0xcc }, // Panther Lake L
{ 6, 0xd5 }, // Wildcat Lake L
{ 0, 0 } // Last Invalid entry
};

const char * const blocklist_paths[] {
/* Some Lenovo machines have in-firmware thermal management,
* avoid having two entities trying to manage things.
* We may want to change this to dytc_perfmode once that is
* widely available. */
"/sys/devices/platform/thinkpad_acpi/dytc_lapmode",
};
#endif

int cthd_engine::check_cpu_id() {
#ifndef ANDROID
// Copied from turbostat program
unsigned int ebx, ecx, edx, max_level;
unsigned int fms, family, model, stepping;
genuine_intel = 0;
int i = 0;
bool valid = false;

proc_list_matched = false;
ebx = ecx = edx = 0;

__cpuid(0, max_level, ebx, ecx, edx);
if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
genuine_intel = 1;
if (genuine_intel == 0) {
// Simply return without further capability check
return THD_SUCCESS;
}
__cpuid(1, fms, ebx, ecx, edx);
family = (fms >> 8) & 0xf;
model = (fms >> 4) & 0xf;
stepping = fms & 0xf;
if (family == 6 || family == 0xf)
model += ((fms >> 16) & 0xf) << 4;

thd_log_msg(
"%u CPUID levels; family:model:stepping 0x%x:%x:%x (%u:%u:%u)\n",
max_level, family, model, stepping, family, model, stepping);

while (id_table[i].family) {
if (id_table[i].family == family && id_table[i].model == model) {
proc_list_matched = true;
valid = true;
break;
}
i++;
}
if (!valid) {
thd_log_msg(" Need Linux PowerCap sysfs\n");
// Create platform instance using factory method
cthd_platform *platform = cthd_platform::create_platform();
if (!platform) {
thd_log_error("Failed to create platform instance\n");
proc_list_matched = false;
return THD_ERROR;
}

// Dump platform information
platform->dump_platform_info();

for (const char *path : blocklist_paths) {
struct stat s;
// Call platform-specific CPU ID check
int ret = platform->check_cpu_id(proc_list_matched);

if (!stat(path, &s)) {
proc_list_matched = false;
thd_log_warn("[%s] present: Thermald can't run on this platform\n", path);
break;
}
}

#endif
return THD_SUCCESS;
delete platform;
return ret;
}

void cthd_engine::thd_read_default_thermal_sensors() {
Expand Down
6 changes: 0 additions & 6 deletions src/thd_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,6 @@ typedef struct {
unsigned long msg[MAX_MSG_SIZE];
} message_capsul_t;

typedef struct {
unsigned int family;
unsigned int model;
} supported_ids_t;

class cthd_engine {

protected:
Expand Down Expand Up @@ -100,7 +95,6 @@ class cthd_engine {
time_t thz_last_temp_ind_time;
time_t thz_last_update_event_time;
bool terminate;
int genuine_intel;
int has_invariant_tsc;
int has_aperf;
bool proc_list_matched;
Expand Down
79 changes: 9 additions & 70 deletions src/thd_engine_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include "thd_int3400.h"
#include "thd_sensor_rapl_power.h"
#include "thd_zone_rapl_power.h"
#include "thd_platform.h"
#include "thd_platform_intel.h"


// Default CPU cooling devices, which are not part of thermal sysfs
Expand Down Expand Up @@ -795,83 +797,20 @@ void cthd_engine_default::workarounds()
{
// Every 30 seconds repeat
if (!disable_active_power && !workaround_interval) {
workaround_rapl_mmio_power();
// Create platform instance and call workaround
cthd_platform *platform = cthd_platform::create_platform();
if (platform) {
platform->workaround_rapl_mmio_power();
delete platform;
}

workaround_tcc_offset();
workaround_interval = 7;
} else {
--workaround_interval;
}
}

#ifndef ANDROID
#include <cpuid.h>
#include <sys/mman.h>
#define BIT_ULL(nr) (1ULL << (nr))
#endif

void cthd_engine_default::workaround_rapl_mmio_power(void)
{
if (!workaround_enabled)
return;

cthd_cdev *cdev = search_cdev("rapl_controller_mmio");
if (cdev) {
/* RAPL MMIO is enabled and getting used. No need to disable */
return;
} else {
csys_fs _sysfs("/sys/devices/virtual/powercap/intel-rapl-mmio/intel-rapl-mmio:0/");

if (_sysfs.exists()) {
std::ostringstream temp_str;

temp_str << "enabled";
if (_sysfs.write(temp_str.str(), 0) > 0)
return;

thd_log_debug("Failed to write to RAPL MMIO\n");
}
}

#ifndef ANDROID
int map_fd;
void *rapl_mem;
unsigned char *rapl_pkg_pwr_addr;
unsigned long long pkg_power_limit;

unsigned int ebx, ecx, edx;
unsigned int fms, family, model;

ecx = edx = 0;
__cpuid(1, fms, ebx, ecx, edx);
family = (fms >> 8) & 0xf;
model = (fms >> 4) & 0xf;
if (family == 6 || family == 0xf)
model += ((fms >> 16) & 0xf) << 4;

// Apply for KabyLake only
if (model != 0x8e && model != 0x9e)
return;

map_fd = open("/dev/mem", O_RDWR, 0);
if (map_fd < 0)
return;

rapl_mem = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd,
0xfed15000);
if (!rapl_mem || rapl_mem == MAP_FAILED) {
close(map_fd);
return;
}

rapl_pkg_pwr_addr = ((unsigned char *)rapl_mem + 0x9a0);
pkg_power_limit = *(unsigned long long *)rapl_pkg_pwr_addr;
*(unsigned long long *)rapl_pkg_pwr_addr = pkg_power_limit
& ~BIT_ULL(15);

munmap(rapl_mem, 4096);
close(map_fd);
#endif
}

void cthd_engine_default::workaround_tcc_offset(void)
{
Expand Down
Loading