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:
Huang Shijie 2021-06-15 10:06:38 +00:00 committed by Karel Zak
parent 66e259c746
commit a772d7c493
3 changed files with 49 additions and 0 deletions

View File

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

View File

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

View File

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