Skip to content

Commit

Permalink
Implement test mode (reads table dump from file)
Browse files Browse the repository at this point in the history
Implement test mode (-t) that reads PM tables from a raw-dump file. Also, re-implement forcing of PM table version with -f.
  • Loading branch information
hattedsquirrel committed Feb 27, 2021
1 parent 1736ece commit 280c230
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 71 deletions.
1 change: 1 addition & 0 deletions src/readinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ unsigned int get_processor_topology(system_info *sysinfo, unsigned int zen_versi
sysinfo->enabled_cores_count = 8*(sysinfo->ccds) - count_set_bits(sysinfo->core_disable_map);
break;
}
sysinfo->available=1;
}

void print_memory_timings() {
Expand Down
1 change: 1 addition & 0 deletions src/readinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define READINFO_H

typedef struct {
char available;
const char *cpu_name;
const char *codename;
const char *smu_fw_ver;
Expand Down
193 changes: 122 additions & 71 deletions src/ryzen_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Ryzen SMU Userspace Sensor Monitor
* Copyright (C) 2020-2021
* Florian Huehn <[email protected]> (https://hattedsquirrel.net)
* Based on work of:
* Leonardo Gates <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -36,7 +37,7 @@
#include "readinfo.h"
#include "pm_tables.h"

#define PROGRAM_VERSION "1.0.2"
#define PROGRAM_VERSION "1.0.3"

smu_obj_t obj;
static int update_time_s = 1;
Expand Down Expand Up @@ -74,22 +75,22 @@ void draw_screen(pm_table *pmt, system_info *sysinfo) {
float l3_logic_power, l3_vddm_power;
char strbuf[100];

fprintf(stdout, "\e[1;1H\e[2J"); //Move cursor to (1,1); Clear entire screen

fprintf(stdout, "╭───────────────────────────────────────────────┬────────────────────────────────────────────────╮\n");
print_line("CPU Model", sysinfo->cpu_name);
print_line("Processor Code Name", sysinfo->codename);
print_line("Cores", "%d", sysinfo->cores);
print_line("Core CCDs", "%d", sysinfo->ccds);
if (pmt->zen_version!=3) {
print_line("Core CCXs", "%d", sysinfo->ccxs);
print_line("Cores Per CCX", "%d", sysinfo->cores_per_ccx);
if (sysinfo->available) {
fprintf(stdout, "╭───────────────────────────────────────────────┬────────────────────────────────────────────────╮\n");
print_line("CPU Model", sysinfo->cpu_name);
print_line("Processor Code Name", sysinfo->codename);
print_line("Cores", "%d", sysinfo->cores);
print_line("Core CCDs", "%d", sysinfo->ccds);
if (pmt->zen_version!=3) {
print_line("Core CCXs", "%d", sysinfo->ccxs);
print_line("Cores Per CCX", "%d", sysinfo->cores_per_ccx);
}
else
print_line("Cores Per CCD", "%d", sysinfo->cores_per_ccx); //Zen3 does not have CCXs anymore
print_line("SMU FW Version", "v%s", sysinfo->smu_fw_ver);
print_line("MP1 IF Version", "v%d", sysinfo->if_ver);
fprintf(stdout, "╰───────────────────────────────────────────────┴────────────────────────────────────────────────╯\n");
}
else
print_line("Cores Per CCD", "%d", sysinfo->cores_per_ccx); //Zen3 does not have CCXs anymore
print_line("SMU FW Version", "v%s", sysinfo->smu_fw_ver);
print_line("MP1 IF Version", "v%d", sysinfo->if_ver);
fprintf(stdout, "╰───────────────────────────────────────────────┴────────────────────────────────────────────────╯\n");


peak_core_frequency = peak_core_temp = peak_core_voltage = 0;
Expand Down Expand Up @@ -263,12 +264,6 @@ void draw_screen(pm_table *pmt, system_info *sysinfo) {
print_line("Socket Power (SMU)", "%7.3f W", pmta(SOCKET_POWER));
if (pmt->PACKAGE_POWER) print_line("Package Power (SMU)", "%7.3f W", pmta(PACKAGE_POWER));
fprintf(stdout, "╰───────────────────────────────────────────────┴────────────────────────────────────────────────╯\n");


// Hide Cursor
fprintf(stdout, "\e[?25l");

fflush(stdout);
}

int select_pm_table_version(unsigned int version, pm_table *pmt, unsigned char *pm_buf) {
Expand All @@ -277,7 +272,7 @@ int select_pm_table_version(unsigned int version, pm_table *pmt, unsigned char *
memset(pmt, 0, sizeof(pmt));

//Select matching PM Table
switch(obj.pm_table_version) {
switch(version) {
case 0x380904: pm_table_0x380904(pmt, pm_buf); break; //Ryzen 5600X
case 0x380804: pm_table_0x380804(pmt, pm_buf); break; //Ryzen 5900X / 5950X
case 0x240903: pm_table_0x240903(pmt, pm_buf); break; //Ryzen 3700X / 3800X
Expand All @@ -294,7 +289,6 @@ int select_pm_table_version(unsigned int version, pm_table *pmt, unsigned char *
}

void start_pm_monitor(unsigned int force) {
int i, j;
unsigned char *pm_buf;
pm_table pmt;
system_info sysinfo;
Expand Down Expand Up @@ -348,11 +342,57 @@ void start_pm_monitor(unsigned int force) {
if (smu_read_pm_table(&obj, pm_buf, obj.pm_table_size) != SMU_Return_OK)
continue;

fprintf(stdout, "\e[1;1H\e[2J"); //Move cursor to (1,1); Clear entire screen
draw_screen(&pmt, &sysinfo);
fprintf(stdout, "\e[?25l"); // Hide Cursor
fflush(stdout);

sleep(update_time_s);
}
}

void read_from_dumpfile(char *dumpfile, unsigned int version) {
unsigned char readbuf[10240];
unsigned int bytes_read;
pm_table pmt;
system_info sysinfo;
FILE *fd;

if (!version) {
fprintf(stderr, "You need to specify a PM Table version with -f.\n");
exit(0);
}

//Read file
fd = fopen(dumpfile, "rb");
if(!fd) {
fprintf(stderr, "Could not read the dumpfile (\"%s\").\n", dumpfile);
exit(0);
}
bytes_read=fread(readbuf,sizeof(char),sizeof(readbuf),fd);
fclose(fd);

//Select matching PM Table
if(!select_pm_table_version(version, &pmt, readbuf)) {
fprintf(stderr, "This PM Table version (0x%x) is currently not supported.\n", version);
exit(0);
}
else fprintf(stderr, "Using PM Table version 0x%x.\n", version);

//Prevent illegal memory access
if (bytes_read < pmt.min_size) {
fprintf(stderr, "Read %d bytes from \"%s\", but the selected PM Table is %d bytes long.\n", bytes_read, dumpfile, pmt.min_size);
exit(0);
}

sysinfo.available=0; //Did not read sysinfo
sysinfo.enabled_cores_count = pmt.max_cores;
sysinfo.core_disable_map=0;
sysinfo.cores=sysinfo.enabled_cores_count;

draw_screen(&pmt, &sysinfo);
}

void print_version() {
fprintf(stdout, "Ryzen Monitor " PROGRAM_VERSION "\n");
exit(0);
Expand All @@ -365,23 +405,45 @@ void show_help(char* program) {
"Usage: %s <option(s)>\n\n"

"Options:\n"
"\t-h - Show this help screen.\n"
"\t-v - Show program version.\n"
"\t-m - Print DRAM Timings and exit.\n"
// "\t-f - Force PM table monitoring even if the PM table version is not supported.\n"
"\t-d - Show disabled cores.\n"
"\t-u<seconds> - Update the monitoring only after this number of second(s) have passed. Defaults to 1.\n",
"\t-h - Show this help screen.\n"
"\t-v - Show program version.\n"
"\t-m - Print DRAM Timings and exit.\n"
"\t-d - Show disabled cores.\n"
"\t-u<seconds> - Update the monitoring only after this number of second(s) have passed. Defaults to 1.\n"
"\t-f<hex-value> - Force to use a specific PM table version.\n"
"\t-t<filename> - Test mode. Read PM Table from raw-dumfile. Use in conjunction with -f\n",
program
);
}

void parse_args(int argc, char** argv) {
int c = 0, force, core;
void signal_interrupt(int sig) {
switch (sig) {
case SIGINT:
case SIGABRT:
case SIGTERM:
// Re-enable the cursor.
fprintf(stdout, "\e[?25h");
exit(0);
default:
break;
}
}

int main(int argc, char** argv) {
smu_return_val ret;
int c=0, force=0, core=0;
char *dumpfile=0;

core = 0;
force = 0;
//Set up signal handlers
if ((signal(SIGABRT, signal_interrupt) == SIG_ERR) ||
(signal(SIGTERM, signal_interrupt) == SIG_ERR) ||
(signal(SIGINT, signal_interrupt) == SIG_ERR)) {
fprintf(stderr, "Can't set up signal hooks.\n");
exit(-1);
}

while ((c = getopt(argc, argv, "vmd::fu:h")) != -1) {
//Parse arguments
while ((c = getopt(argc, argv, "vmd::f:t:u:h")) != -1) {
switch (c) {
case 'v':
print_version();
Expand All @@ -396,7 +458,17 @@ void parse_args(int argc, char** argv) {
show_disabled_cores = 1;
break;
case 'f':
force = 1;
if(!optarg || sscanf(optarg,"%x", &force)!=1) {
show_help(argv[0]);
exit(0);
}
break;
case 't':
if(!optarg || strlen(optarg)==0) {
show_help(argv[0]);
exit(0);
}
dumpfile=optarg;
break;
case 'u':
update_time_s = atoi(optarg);
Expand All @@ -411,44 +483,23 @@ void parse_args(int argc, char** argv) {
}
}

start_pm_monitor(force);
}

void signal_interrupt(int sig) {
switch (sig) {
case SIGINT:
case SIGABRT:
case SIGTERM:
// Re-enable the cursor.
fprintf(stdout, "\e[?25h");
exit(0);
default:
break;
}
}

int main(int argc, char** argv) {
smu_return_val ret;

if ((signal(SIGABRT, signal_interrupt) == SIG_ERR) ||
(signal(SIGTERM, signal_interrupt) == SIG_ERR) ||
(signal(SIGINT, signal_interrupt) == SIG_ERR)) {
fprintf(stderr, "Can't set up signal hooks.\n");
exit(-1);
}
if(dumpfile)
read_from_dumpfile(dumpfile, force);
else
{
if (getuid() != 0 && geteuid() != 0) {
fprintf(stderr, "Program must be run as root.\n");
exit(-2);
}

if (getuid() != 0 && geteuid() != 0) {
fprintf(stderr, "Program must be run as root.\n");
exit(-2);
}
ret = smu_init(&obj);
if (ret != SMU_Return_OK) {
fprintf(stderr, "%s\n", smu_return_to_str(ret));
exit(-2);
}

ret = smu_init(&obj);
if (ret != SMU_Return_OK) {
fprintf(stderr, "%s\n", smu_return_to_str(ret));
exit(-2);
start_pm_monitor(force);
}

parse_args(argc, argv);

return 0;
}

0 comments on commit 280c230

Please sign in to comment.