The patch :367c85c47286 ("lscpu: use SMBIOS tables on ARM for lscpu") relies on the existence of "/sys/firmware/dmi/entries/4-0/raw", which may not exist in standard linux kernel. But "/sys/firmware/dmi/tables/DMI" should exist and can provide the required processor information. This patch uses "/sys/firmware/dmi/tables/DMI" to get the processor information: 1.) Use the DMI to provide more accurate "Model name" information. 2.) Add "CPU family" (keep the same output as dmidecode ). Before this patch, in Ampere Altra platform, the lscpu output is: --------------------------------------------- Architecture: aarch64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 160 On-line CPU(s) list: 0-159 Vendor ID: ARM Model name: Neoverse-N1 Model: 1 Thread(s) per core: 1 Core(s) per socket: 80 Socket(s): 2 ........................................ --------------------------------------------- After this patch, we can get the lscpu output in Ampere Altra platform: --------------------------------------------- Architecture: aarch64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 160 On-line CPU(s) list: 0-159 Vendor ID: ARM Model name: Ampere(R) Altra(R) Processor Q00-00 CPU @ 3.0GHz CPU family: 257 Model: 1 Thread(s) per core: 1 Core(s) per socket: 80 Socket(s): 2 ........................................ --------------------------------------------- Signed-off-by: Huang Shijie <shijie@xxxxxxxxxxxxxxxxxxxxxx> --- sys-utils/lscpu-arm.c | 6 +++++- sys-utils/lscpu-dmi.c | 49 +++++++++++++++++++++++++++++++++++++++++++ sys-utils/lscpu.h | 7 +++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c index 230eb5fdd..0993ea5ad 100644 --- a/sys-utils/lscpu-arm.c +++ b/sys-utils/lscpu-arm.c @@ -358,11 +358,15 @@ static int arm_smbios_decode(struct lscpu_cputype *ct) static void arm_decode(struct lscpu_cxt *cxt, struct lscpu_cputype *ct) { + /* dmi_decode_cputype may get more accurate information later */ + arm_ids_decode(ct); + /* use SMBIOS Type 4 data if available */ if (!cxt->noalive && access(_PATH_SYS_DMI_TYPE4, R_OK) == 0) arm_smbios_decode(ct); + else if (!cxt->noalive && access(_PATH_SYS_DMI, R_OK) == 0) + dmi_decode_cputype(ct); - arm_ids_decode(ct); arm_rXpY_decode(ct); if (cxt->is_cluster) ct->nr_socket_on_cluster = get_number_of_physical_sockets_from_dmi(); diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c index e7ffa88d3..155b21e32 100644 --- a/sys-utils/lscpu-dmi.c +++ b/sys-utils/lscpu-dmi.c @@ -67,6 +67,17 @@ int parse_dmi_table(uint16_t len, uint16_t num, di->product = dmi_string(&h, data[0x05]); break; case 4: + /* Get the first processor information */ + if (di->sockets == 0) { + di->processor_version = dmi_string(&h, data[0x10]); + di->current_speed = *((uint16_t *)(&data[0x16])); + di->part_num = dmi_string(&h, data[0x22]); + + if (data[0x6] == 0xfe) + di->processor_family = *((uint16_t *)(&data[0x28])); + else + di->processor_family = data[0x6]; + } di->sockets++; break; default: @@ -81,6 +92,44 @@ done: return rc; } +int dmi_decode_cputype(struct lscpu_cputype *ct) +{ + static char const sys_fw_dmi_tables[] = _PATH_SYS_DMI; + struct dmi_info di = { }; + struct stat st; + uint8_t *data; + int rc = 0; + char buf[100] = { }; + + if (stat(sys_fw_dmi_tables, &st)) + return rc; + + data = get_mem_chunk(0, st.st_size, sys_fw_dmi_tables); + if (!data) + return rc; + + rc = parse_dmi_table(st.st_size, st.st_size/4, data, &di); + if (rc < 0) { + free(data); + return rc; + } + + /* Get module name */ + sprintf(buf, "%s %s CPU @ %d.%dGHz", di.processor_version, di.part_num, + di.current_speed/1000, (di.current_speed % 1000) / 100); + free(ct->modelname); + ct->modelname = xstrdup(buf); + + /* Get CPU family */ + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%d", di.processor_family); + free(ct->family); + ct->family = xstrdup(buf); + + free(data); + return 0; +} + size_t get_number_of_physical_sockets_from_dmi(void) { static char const sys_fw_dmi_tables[] = _PATH_SYS_DMI; diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index 62f532581..9e6362bf4 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -316,6 +316,12 @@ struct dmi_info { char *product; char *manufacturer; int sockets; + + /* Processor Information */ + uint16_t processor_family; + char *processor_version; + uint16_t current_speed; + char *part_num; }; @@ -323,4 +329,5 @@ void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data); char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s); int parse_dmi_table(uint16_t len, uint16_t num, uint8_t *data, struct dmi_info *di); size_t get_number_of_physical_sockets_from_dmi(void); +int dmi_decode_cputype(struct lscpu_cputype *); #endif /* LSCPU_H */ -- 2.30.2