lscpu: get the processor information by DMI
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: 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 use 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 BIOS Vendor ID: Ampere(R) Model name: Neoverse-N1 BIOS Model name: Ampere(R) Altra(R) Processor Q00-00 CPU @ 3.0GHz Model: 1 Thread(s) per core: 1 Core(s) per socket: 80 Socket(s): 2 ........................................ --------------------------------------------- [kzak@redhat.com: - s/sprintf/snprintf/] Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
66e259c746
commit
a772d7c493
|
@ -361,6 +361,8 @@ static void arm_decode(struct lscpu_cxt *cxt, struct lscpu_cputype *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);
|
||||
|
|
|
@ -67,6 +67,13 @@ 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_manufacturer = dmi_string(&h, data[0x7]);
|
||||
di->processor_version = dmi_string(&h, data[0x10]);
|
||||
di->current_speed = *((uint16_t *)(&data[0x16]));
|
||||
di->part_num = dmi_string(&h, data[0x22]);
|
||||
}
|
||||
di->sockets++;
|
||||
break;
|
||||
default:
|
||||
|
@ -81,6 +88,39 @@ 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;
|
||||
}
|
||||
|
||||
ct->bios_vendor = xstrdup(di.processor_manufacturer);
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"%s %s CPU @ %d.%dGHz", di.processor_version, di.part_num,
|
||||
di.current_speed/1000, (di.current_speed % 1000) / 100);
|
||||
ct->bios_modelname = 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;
|
||||
|
|
|
@ -316,6 +316,12 @@ struct dmi_info {
|
|||
char *product;
|
||||
char *manufacturer;
|
||||
int sockets;
|
||||
|
||||
/* Processor Information */
|
||||
char *processor_manufacturer;
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue