1
0
Fork 0
mirror of https://github.com/anrieff/libcpuid synced 2024-11-10 22:59:13 +00:00

Add a msr_serialize_raw_data() function

This commit is contained in:
Xorg 2017-02-09 20:55:28 +01:00
parent fa87a5e183
commit 9b038c94c4
5 changed files with 113 additions and 1 deletions

View file

@ -89,6 +89,7 @@ typedef enum {
NEED_CLOCK_RDTSC,
NEED_CLOCK_IC,
NEED_RDMSR,
NEED_RDMSR_RAW,
NEED_SSE_UNIT_SIZE,
} output_data_switch;
@ -146,6 +147,7 @@ matchtable[] = {
{ NEED_CLOCK_RDTSC , "--clock-rdtsc" , 1},
{ NEED_CLOCK_IC , "--clock-ic" , 1},
{ NEED_RDMSR , "--rdmsr" , 0},
{ NEED_RDMSR_RAW , "--rdmsr-raw" , 0},
{ NEED_SSE_UNIT_SIZE, "--sse-size" , 1},
};
@ -460,6 +462,16 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
}
break;
}
case NEED_RDMSR_RAW:
{
if ((handle = cpu_msr_driver_open()) == NULL) {
fprintf(fout, "Cannot open MSR driver: %s\n", cpuid_error());
} else {
msr_serialize_raw_data(handle, "");
cpu_msr_driver_close(handle);
}
break;
}
case NEED_SSE_UNIT_SIZE:
{
fprintf(fout, "%d (%s)\n", data->sse_size,

View file

@ -32,3 +32,4 @@ cpu_msr_driver_open_core @28
cpuid_get_vendor @29
cpu_rdmsr_range @30
cpuid_get_epc @31
msr_serialize_raw_data @32

View file

@ -1104,6 +1104,25 @@ int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t hig
int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which);
#define CPU_INVALID_VALUE 0x3fffffff
/**
* @brief Writes the raw MSR data to a text file
* @param data - a pointer to msr_driver_t structure
* @param filename - the path of the file, where the serialized data should be
* written. If empty, stdout will be used.
* @note This is intended primarily for debugging. On some processor, which is
* not currently supported or not completely recognized by cpu_identify,
* one can still successfully get the raw data and write it to a file.
* libcpuid developers can later import this file and debug the detection
* code as if running on the actual hardware.
* The file is simple text format of "something=value" pairs. Version info
* is also written, but the format is not intended to be neither backward-
* nor forward compatible.
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename);
/**
* @brief Closes an open MSR driver
*

View file

@ -29,3 +29,4 @@ cpu_msr_driver_open_core
cpuid_get_vendor
cpu_rdmsr_range
cpuid_get_epc
msr_serialize_raw_data

View file

@ -26,6 +26,7 @@
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libcpuid.h"
#include "asm-bits.h"
#include "libcpuid_util.h"
@ -502,6 +503,11 @@ int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which)
return set_error(ERR_NOT_IMP);
}
int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename)
{
return set_error(ERR_NOT_IMP);
}
#endif /* Unsupported OS */
#ifndef RDMSR_UNSUPPORTED_OS
@ -537,7 +543,26 @@ int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which)
#define MSR_PSTATE_L 0xC0010061
#define MSR_PSTATE_S 0xC0010063
#define MSR_PSTATE_0 0xC0010064
#define MSR_PSTATE_1 0xC0010065
#define MSR_PSTATE_2 0xC0010066
#define MSR_PSTATE_3 0xC0010067
#define MSR_PSTATE_4 0xC0010068
#define MSR_PSTATE_5 0xC0010069
#define MSR_PSTATE_6 0xC001006A
#define MSR_PSTATE_7 0xC001006B
static const uint32_t amd_msr[] = {
MSR_PSTATE_L,
MSR_PSTATE_S,
MSR_PSTATE_0,
MSR_PSTATE_1,
MSR_PSTATE_2,
MSR_PSTATE_3,
MSR_PSTATE_4,
MSR_PSTATE_5,
MSR_PSTATE_6,
MSR_PSTATE_7,
CPU_INVALID_VALUE
};
/* Intel MSRs addresses */
#define IA32_MPERF 0xE7
@ -549,7 +574,18 @@ int cpu_msrinfo(struct msr_driver_t* driver, cpu_msrinfo_request_t which)
#define MSR_TEMPERATURE_TARGET 0x1A2
#define MSR_PERF_STATUS 0x198
#define MSR_PLATFORM_INFO 0xCE
static const uint32_t intel_msr[] = {
IA32_MPERF,
IA32_APERF,
IA32_PERF_STATUS,
IA32_THERM_STATUS,
MSR_EBL_CR_POWERON,
MSR_TURBO_RATIO_LIMIT,
MSR_TEMPERATURE_TARGET,
MSR_PERF_STATUS,
MSR_PLATFORM_INFO,
CPU_INVALID_VALUE
};
static int rdmsr_supported(void)
{
@ -919,4 +955,47 @@ int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which)
}
}
int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename)
{
int i, j;
FILE *f;
uint64_t reg;
const uint32_t *msr;
struct cpu_raw_data_t raw;
struct cpu_id_t id;
struct internal_id_info_t internal;
if (handle == NULL)
return set_error(ERR_HANDLE);
if (!strcmp(filename, ""))
f = stdout;
else
f = fopen(filename, "wt");
if (!f) return set_error(ERR_OPEN);
if (cpuid_get_raw_data(&raw) || cpu_ident_internal(&raw, &id, &internal))
return -1;
fprintf(f, "CPU is %s %s, stock clock is %dMHz.\n", id.vendor_str, id.brand_str, cpu_clock_measure(100, 1));
if (id.vendor == VENDOR_INTEL)
msr = intel_msr;
else if (id.vendor == VENDOR_AMD)
msr = amd_msr;
else
return set_error(ERR_CPU_UNKN);
for (i = 0; msr[i] != CPU_INVALID_VALUE; i++) {
cpu_rdmsr(handle, msr[i], &reg);
fprintf(f, "msr[%#08x]=", msr[i]);
for (j = 56; j >= 0; j -= 8)
fprintf(f, "%02x ", (int) (reg >> j) & 0xff);
printf("\n");
}
if (strcmp(filename, ""))
fclose(f);
return set_error(ERR_OK);
}
#endif // RDMSR_UNSUPPORTED_OS