1
0
Fork 0
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:
The Tumultuous Unicorn Of Darkness 2024-07-07 17:48:41 +02:00
parent ea9ada7118
commit c5d9b387d1
No known key found for this signature in database
GPG key ID: 1E55EE2EFF18BC1A
6 changed files with 84 additions and 28 deletions

View file

@ -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;
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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