mirror of
https://github.com/anrieff/libcpuid
synced 2024-12-16 16:35:45 +00:00
Improve ARM core ID identification and add cpuid_get_raw_data_core()
This commit is contained in:
parent
ea9ada7118
commit
c5d9b387d1
6 changed files with 84 additions and 28 deletions
|
@ -1170,18 +1170,44 @@ static bool cpu_ident_id_arm(struct cpu_raw_data_t* raw, struct internal_topolog
|
||||||
{
|
{
|
||||||
/* Documentation: Multiprocessor Affinity Register
|
/* Documentation: Multiprocessor Affinity Register
|
||||||
https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/MPIDR-EL1--Multiprocessor-Affinity-Register
|
https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/MPIDR-EL1--Multiprocessor-Affinity-Register
|
||||||
|
|
||||||
|
This function is inspired by the store_cpu_topology() function from Linux:
|
||||||
|
https://github.com/torvalds/linux/blob/c6653f49e4fd3b0d52c12a1fc814d6c5b234ea15/arch/arm/kernel/topology.c#L185-L233
|
||||||
*/
|
*/
|
||||||
const bool aff0_is_threads = EXTRACTS_BIT(raw->arm_mpidr, 24);
|
if (!raw->arm_mpidr)
|
||||||
if (aff0_is_threads) {
|
return false;
|
||||||
/* Aff0: the level identifies individual threads within a multithreaded core
|
|
||||||
On single-threaded CPUs this field has the value 0x00 */
|
const bool is_uniprocessor = (EXTRACTS_BIT(raw->arm_mpidr, 30) == 0b1);
|
||||||
topology->smt_id = EXTRACTS_BITS(raw->arm_mpidr, 7, 0); // Aff0
|
const bool is_mt = (EXTRACTS_BIT(raw->arm_mpidr, 24) == 0b1);
|
||||||
topology->core_id = EXTRACTS_BITS(raw->arm_mpidr, 15, 8); // Aff1
|
|
||||||
topology->package_id = EXTRACTS_BITS(raw->arm_mpidr, 23, 16); // Aff2
|
/* create cpu topology mapping */
|
||||||
|
if (!is_uniprocessor) {
|
||||||
|
/*
|
||||||
|
* This is a multiprocessor system
|
||||||
|
* multiprocessor format & multiprocessor mode field are set
|
||||||
|
*/
|
||||||
|
if (is_mt) {
|
||||||
|
/* core performance interdependency */
|
||||||
|
topology->smt_id = EXTRACTS_BITS(raw->arm_mpidr, 7, 0); // Aff0
|
||||||
|
topology->core_id = EXTRACTS_BITS(raw->arm_mpidr, 15, 8); // Aff1
|
||||||
|
topology->package_id = EXTRACTS_BITS(raw->arm_mpidr, 23, 16); // Aff2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* largely independent cores */
|
||||||
|
topology->smt_id = -1;
|
||||||
|
topology->core_id = EXTRACTS_BITS(raw->arm_mpidr, 7, 0); // Aff0
|
||||||
|
topology->package_id = EXTRACTS_BITS(raw->arm_mpidr, 15, 8); // Aff1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
topology->core_id = EXTRACTS_BITS(raw->arm_mpidr, 7, 0); // Aff0
|
/*
|
||||||
topology->package_id = EXTRACTS_BITS(raw->arm_mpidr, 15, 8); // Aff1
|
* This is an uniprocessor system
|
||||||
|
* we are in multiprocessor format but uniprocessor system
|
||||||
|
* or in the old uniprocessor format
|
||||||
|
*/
|
||||||
|
topology->smt_id = -1;
|
||||||
|
topology->core_id = 0;
|
||||||
|
topology->package_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always implemented since ARMv7
|
/* Always implemented since ARMv7
|
||||||
|
@ -1247,8 +1273,23 @@ void cpu_exec_cpuid_ext(uint32_t* regs)
|
||||||
|
|
||||||
int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
||||||
{
|
{
|
||||||
|
return(cpuid_get_raw_data_core(data, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpuid_get_raw_data_core(struct cpu_raw_data_t* data, logical_cpu_t logical_cpu)
|
||||||
|
{
|
||||||
|
bool affinity_saved = false;
|
||||||
|
|
||||||
if (!cpuid_present())
|
if (!cpuid_present())
|
||||||
return cpuid_set_error(ERR_NO_CPUID);
|
return cpuid_set_error(ERR_NO_CPUID);
|
||||||
|
|
||||||
|
if (logical_cpu != (logical_cpu_t) -1) {
|
||||||
|
debugf(2, "Getting raw dump for logical CPU %u\n", logical_cpu);
|
||||||
|
if (!set_cpu_affinity(logical_cpu))
|
||||||
|
return ERR_INVCNB;
|
||||||
|
affinity_saved = save_cpu_affinity();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(PLATFORM_X86) || defined(PLATFORM_X64)
|
#if defined(PLATFORM_X86) || defined(PLATFORM_X64)
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
|
@ -1322,6 +1363,10 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
||||||
# warning This CPU architecture is not supported by libcpuid
|
# warning This CPU architecture is not supported by libcpuid
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (affinity_saved)
|
||||||
|
restore_cpu_affinity();
|
||||||
|
|
||||||
return cpuid_set_error(ERR_OK);
|
return cpuid_set_error(ERR_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1330,26 +1375,23 @@ int cpuid_get_all_raw_data(struct cpu_raw_data_array_t* data)
|
||||||
int cur_error = cpuid_set_error(ERR_OK);
|
int cur_error = cpuid_set_error(ERR_OK);
|
||||||
int ret_error = cpuid_set_error(ERR_OK);
|
int ret_error = cpuid_set_error(ERR_OK);
|
||||||
logical_cpu_t logical_cpu = 0;
|
logical_cpu_t logical_cpu = 0;
|
||||||
struct cpu_raw_data_t* raw_ptr = NULL;
|
struct cpu_raw_data_t raw_tmp;
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return cpuid_set_error(ERR_HANDLE);
|
return cpuid_set_error(ERR_HANDLE);
|
||||||
|
|
||||||
bool affinity_saved = save_cpu_affinity();
|
|
||||||
|
|
||||||
cpu_raw_data_array_t_constructor(data, true);
|
cpu_raw_data_array_t_constructor(data, true);
|
||||||
while (set_cpu_affinity(logical_cpu) || logical_cpu == 0) {
|
do {
|
||||||
debugf(2, "Getting raw dump for logical CPU %i\n", logical_cpu);
|
memset(&raw_tmp, 0, sizeof(struct cpu_raw_data_t));
|
||||||
|
cur_error = cpuid_get_raw_data_core(&raw_tmp, logical_cpu);
|
||||||
|
if (cur_error == ERR_INVCNB)
|
||||||
|
break;
|
||||||
cpuid_grow_raw_data_array(data, logical_cpu + 1);
|
cpuid_grow_raw_data_array(data, logical_cpu + 1);
|
||||||
raw_ptr = &data->raw[logical_cpu];
|
memcpy(&data->raw[logical_cpu], &raw_tmp, sizeof(struct cpu_raw_data_t));
|
||||||
cur_error = cpuid_get_raw_data(raw_ptr);
|
|
||||||
if (ret_error == ERR_OK)
|
if (ret_error == ERR_OK)
|
||||||
ret_error = cur_error;
|
ret_error = cur_error;
|
||||||
logical_cpu++;
|
logical_cpu++;
|
||||||
}
|
} while (cur_error == ERR_OK);
|
||||||
|
|
||||||
if (affinity_saved)
|
|
||||||
restore_cpu_affinity();
|
|
||||||
|
|
||||||
return ret_error;
|
return ret_error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,3 +47,4 @@ affinity_mask_str_r @43
|
||||||
cpuid_get_hypervisor @44
|
cpuid_get_hypervisor @44
|
||||||
cpu_clock_by_tsc @45
|
cpu_clock_by_tsc @45
|
||||||
cpu_feature_level_str @46
|
cpu_feature_level_str @46
|
||||||
|
cpuid_get_raw_data_core @47
|
||||||
|
|
|
@ -1260,6 +1260,18 @@ void cpu_exec_cpuid_ext(uint32_t* regs);
|
||||||
*/
|
*/
|
||||||
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
|
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Obtains the raw CPUID data from the specified CPU
|
||||||
|
* @param data - a pointer to cpu_raw_data_t structure
|
||||||
|
* @param logical_cpu specify the core number.
|
||||||
|
* The first core number is 0.
|
||||||
|
* The last core number is \ref cpuid_get_total_cpus - 1.
|
||||||
|
* @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 cpuid_get_raw_data_core(struct cpu_raw_data_t* data, logical_cpu_t logical_cpu);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Obtains the raw CPUID data from all CPUs
|
* @brief Obtains the raw CPUID data from all CPUs
|
||||||
* @param data - a pointer to cpu_raw_data_array_t structure
|
* @param data - a pointer to cpu_raw_data_array_t structure
|
||||||
|
|
|
@ -44,3 +44,4 @@ affinity_mask_str_r
|
||||||
cpuid_get_hypervisor
|
cpuid_get_hypervisor
|
||||||
cpu_clock_by_tsc
|
cpu_clock_by_tsc
|
||||||
cpu_feature_level_str
|
cpu_feature_level_str
|
||||||
|
cpuid_get_raw_data_core
|
||||||
|
|
|
@ -40,7 +40,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #1 _________________
|
_________________ Logical CPU #1 _________________
|
||||||
arm_midr=00000000414fc0f0
|
arm_midr=00000000414fc0f0
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000001
|
||||||
arm_revidr=00000002414fc0f0
|
arm_revidr=00000002414fc0f0
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -80,7 +80,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #2 _________________
|
_________________ Logical CPU #2 _________________
|
||||||
arm_midr=00000000414fc0f0
|
arm_midr=00000000414fc0f0
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000002
|
||||||
arm_revidr=00000002414fc0f0
|
arm_revidr=00000002414fc0f0
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -120,7 +120,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #3 _________________
|
_________________ Logical CPU #3 _________________
|
||||||
arm_midr=00000000414fc0f0
|
arm_midr=00000000414fc0f0
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000003
|
||||||
arm_revidr=00000002414fc0f0
|
arm_revidr=00000002414fc0f0
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -165,7 +165,7 @@ general
|
||||||
4
|
4
|
||||||
3087
|
3087
|
||||||
0
|
0
|
||||||
1
|
4
|
||||||
4
|
4
|
||||||
Eagle
|
Eagle
|
||||||
advmultu advmults jazelle thumb2 debugv7p1 thumbee divide lpae
|
advmultu advmults jazelle thumb2 debugv7p1 thumbee divide lpae
|
||||||
|
|
|
@ -40,7 +40,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #1 _________________
|
_________________ Logical CPU #1 _________________
|
||||||
arm_midr=00000000410fc075
|
arm_midr=00000000410fc075
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000001
|
||||||
arm_revidr=00000002410fc075
|
arm_revidr=00000002410fc075
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -80,7 +80,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #2 _________________
|
_________________ Logical CPU #2 _________________
|
||||||
arm_midr=00000000410fc075
|
arm_midr=00000000410fc075
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000002
|
||||||
arm_revidr=00000002410fc075
|
arm_revidr=00000002410fc075
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -120,7 +120,7 @@ arm_id_aa64smfr0=0000000000000000
|
||||||
arm_id_aa64zfr0=0000000000000000
|
arm_id_aa64zfr0=0000000000000000
|
||||||
_________________ Logical CPU #3 _________________
|
_________________ Logical CPU #3 _________________
|
||||||
arm_midr=00000000410fc075
|
arm_midr=00000000410fc075
|
||||||
arm_mpidr=0000000180000000
|
arm_mpidr=0000000180000003
|
||||||
arm_revidr=00000002410fc075
|
arm_revidr=00000002410fc075
|
||||||
arm_id_afr0=00000000
|
arm_id_afr0=00000000
|
||||||
arm_id_dfr0=02000505
|
arm_id_dfr0=02000505
|
||||||
|
@ -165,7 +165,7 @@ general
|
||||||
0
|
0
|
||||||
3079
|
3079
|
||||||
5
|
5
|
||||||
1
|
4
|
||||||
4
|
4
|
||||||
Kingfisher
|
Kingfisher
|
||||||
advmultu advmults jazelle thumb2 debugv7p1 thumbee divide lpae
|
advmultu advmults jazelle thumb2 debugv7p1 thumbee divide lpae
|
||||||
|
|
Loading…
Reference in a new issue