[PATCH 1/2] lscpu: get the processor information by DMI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Signed-off-by: Huang Shijie <shijie@xxxxxxxxxxxxxxxxxxxxxx>
---
 sys-utils/lscpu-arm.c |  2 ++
 sys-utils/lscpu-dmi.c | 39 +++++++++++++++++++++++++++++++++++++++
 sys-utils/lscpu.h     |  7 +++++++
 3 files changed, 48 insertions(+)

diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c
index 230eb5fdd..885aadc36 100644
--- a/sys-utils/lscpu-arm.c
+++ b/sys-utils/lscpu-arm.c
@@ -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);
diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
index e7ffa88d3..d05380891 100644
--- a/sys-utils/lscpu-dmi.c
+++ b/sys-utils/lscpu-dmi.c
@@ -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,38 @@ 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);
+
+	sprintf(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;
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 62f532581..4dc8e0a23 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 */
+	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 */
-- 
2.30.2




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux