Skip to contentSkip to conversation

Entend cpuinfo

PATCH New Kefeng Wang 4 participants 11 messages Mar 25, 2016 – Mar 29, 2016 arm64

lore
Share & tools
lore
#0 lore raw

cover Entend cpuinfo

The patches aimed at enhencing cpuinfo.

* ARMv8 supports several different types of physical/virtual address bits, up to 52bit in ARMv8.2 especially, it's better to expose it.

* Show the name of chip vendor and CPU model to customers, identify them by CPU implementer and part is not intuitive(compared with x86).

Ideally, add new line to cpuinfo won't break userspace, I hope so, the cpuinfo shown in qemu with patches,

root at linux$ cat /proc/cpuinfo
processor : 0
vendor_id : ARM
model name : Cortex-A57 rev 0 (aarch64)
BogoMIPS : 125.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd07
CPU revision : 0
address sizes : 44 bits physical, 48 bits virtual

processor : 1
vendor_id : ARM
model name : Cortex-A57 rev 0 (aarch64)
BogoMIPS : 125.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd07
CPU revision : 0
address sizes : 44 bits physical, 48 bits virtual

Kefeng Wang (3):
arm64: Append more field of id_aa64mmfr2 for cpufeature
arm64: Expose physical/virtual address bits through cpuinfo
arm64: Expose cpu vender id and model name through cpuinfo

 arch/arm64/include/asm/cpu.h        |  2 ++
 arch/arm64/include/asm/cpufeature.h | 18 ++++++++++
 arch/arm64/include/asm/sysreg.h     |  4 +++
 arch/arm64/kernel/cpufeature.c      |  4 +++
 arch/arm64/kernel/cpuinfo.c         | 68 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 95 insertions(+), 1 deletion(-)
Signature · 1 line
1.7.12.4
#1 lore raw

RFC PATCH 1/3 arm64: Append more field of id_aa64mmfr2 for cpufeature

There are some new cpu features which can be identified by id_aa64mmfr2, this patch appends all fields of it.

---
 arch/arm64/include/asm/sysreg.h | 4 ++++
 arch/arm64/kernel/cpufeature.c  | 4 ++++
 2 files changed, 8 insertions(+)
arch/arm64/include/asm/sysreg.h +4 -0
index 1a78d6e..c141243 100644
@@ -142,7 +142,11 @@
 #define ID_AA64MMFR1_HADBS_SHIFT	0
 
 /* id_aa64mmfr2 */
+#define ID_AA64MMFR2_LVA_SHIFT		16
+#define ID_AA64MMFR2_IESB_SHIFT		12
+#define ID_AA64MMFR2_LSM_SHIFT		8
 #define ID_AA64MMFR2_UAO_SHIFT		4
+#define ID_AA64MMFR2_CNP_SHIFT		0
 
 /* id_aa64dfr0 */
 #define ID_AA64DFR0_CTX_CMPS_SHIFT	28
arch/arm64/kernel/cpufeature.c +4 -0
index 943f514..677f17c 100644
@@ -130,7 +130,11 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 };
 
 static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LSM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_UAO_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_CNP_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
 
Signature · 1 line
1.7.12.4
reviewer
#2 lore raw

RFC PATCH 1/3 arm64: Append more field of id_aa64mmfr2 for cpufeature

Quoted 2 lines · Kefeng Wang

There are some new cpu features which can be identified by id_aa64mmfr2, this patch appends all fields of it.

FWIW, this looks like a good thing regardless of the cpuinfo patches.

The shifts look right to me. I'm not all that familiar with each of the features, so I don't know whether or not we need strict exact matching (though it's a safer to assume that we do for now).

Mark.

Quoted 42 lines
---
 arch/arm64/include/asm/sysreg.h | 4 ++++
 arch/arm64/kernel/cpufeature.c  | 4 ++++
 2 files changed, 8 insertions(+)
arch/arm64/include/asm/sysreg.h +4 -0
index 1a78d6e..c141243 100644
@@ -142,7 +142,11 @@
 #define ID_AA64MMFR1_HADBS_SHIFT	0
 
 /* id_aa64mmfr2 */
+#define ID_AA64MMFR2_LVA_SHIFT		16
+#define ID_AA64MMFR2_IESB_SHIFT		12
+#define ID_AA64MMFR2_LSM_SHIFT		8
 #define ID_AA64MMFR2_UAO_SHIFT		4
+#define ID_AA64MMFR2_CNP_SHIFT		0
 
 /* id_aa64dfr0 */
 #define ID_AA64DFR0_CTX_CMPS_SHIFT	28
arch/arm64/kernel/cpufeature.c +4 -0
index 943f514..677f17c 100644
@@ -130,7 +130,11 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 };
 
 static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LSM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_UAO_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_CNP_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
 
Signature · 1 line
1.7.12.4
#3 lore raw

RFC PATCH 2/3 arm64: Expose physical/virtual address bits through cpuinfo

In reply to Kefeng Wang

ARMv8 Physical Address range allows 0x0~0x6, the 0x6 is supported in ARMv8.2, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.
0110  52 bits, 4096TB.

All other values are reserved.

Meanwhile, ARMv8 can support 48bit or 52bit virtual addresses, larger virtual address(52bit) is introduced in ARMv8.2.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check the capacity of them that cpu supported from cpuinfo.

---
 arch/arm64/include/asm/cpufeature.h | 18 ++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c         |  6 +++++-
 2 files changed, 23 insertions(+), 1 deletion(-)
arch/arm64/include/asm/cpufeature.h +18 -0
index b9b6494..5b2c206 100644
@@ -170,6 +170,24 @@ static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
 		cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
 }
 
+static inline u8 get_parange_bits(u64 mmfr0)
+{
+	/*
+	 * PARange[3:0] allows 0x0~0x6, the 0x6 introduced to support 52bit PA
+	 * in ARMv8.2, other values are reserved.
+	 */
+	u8 pa_bits[] = {32, 36, 40, 42, 44, 48, 52};
+	int fld = cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_PARANGE_SHIFT);
+	return pa_bits[fld];
+}
+
+static inline u8 get_varange_bits(u64 mmfr2)
+{
+	/* 52bit Larger virtual address supported in ARMv8.2 */
+	int fld = cpuid_feature_extract_unsigned_field(mmfr2, ID_AA64MMFR2_LVA_SHIFT);
+	return fld == 0x1 ? 52 : 48;
+}
+
 void __init setup_cpu_features(void);
 
 void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
arch/arm64/kernel/cpuinfo.c +5 -1
index 84c8684..488d49a 100644
@@ -107,6 +107,8 @@ static int c_show(struct seq_file *m, void *v)
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
 		u32 midr = cpuinfo->reg_midr;
+		u64 mmfr0 = cpuinfo->reg_id_aa64mmfr0;
+		u64 mmfr2 = cpuinfo->reg_id_aa64mmfr2;
 
 		/*
 		 * glibc reads /proc/cpuinfo to determine the number of
@@ -148,7 +150,9 @@ static int c_show(struct seq_file *m, void *v)
 		seq_printf(m, "CPU architecture: 8\n");
 		seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
 		seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
-		seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+		seq_printf(m, "CPU revision\t: %d\n", MIDR_REVISION(midr));
+		seq_printf(m, "address sizes\t: %d bits physical, %d bits virtual\n\n",
+			   get_parange_bits(mmfr0), get_varange_bits(mmfr2));
 	}
 
 	return 0;
Signature · 1 line
1.7.12.4
#4 lore raw

RFC PATCH 2/3 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 67 lines · Kefeng Wang

ARMv8 Physical Address range allows 0x0~0x6, the 0x6 is supported in ARMv8.2, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.
0110  52 bits, 4096TB.

All other values are reserved.

Meanwhile, ARMv8 can support 48bit or 52bit virtual addresses, larger virtual address(52bit) is introduced in ARMv8.2.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check the capacity of them that cpu supported from cpuinfo.

---
 arch/arm64/include/asm/cpufeature.h | 18 ++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c         |  6 +++++-
 2 files changed, 23 insertions(+), 1 deletion(-)
arch/arm64/include/asm/cpufeature.h +18 -0
index b9b6494..5b2c206 100644
@@ -170,6 +170,24 @@ static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
 		cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
 }
 
+static inline u8 get_parange_bits(u64 mmfr0)
+{
+	/*
+	 * PARange[3:0] allows 0x0~0x6, the 0x6 introduced to support 52bit PA
+	 * in ARMv8.2, other values are reserved.
+	 */
+	u8 pa_bits[] = {32, 36, 40, 42, 44, 48, 52};
+	int fld = cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_PARANGE_SHIFT);
+	return pa_bits[fld];
+}
+
+static inline u8 get_varange_bits(u64 mmfr2)
+{
+	/* 52bit Larger virtual address supported in ARMv8.2 */
+	int fld = cpuid_feature_extract_unsigned_field(mmfr2, ID_AA64MMFR2_LVA_SHIFT);
+	return fld == 0x1 ? 52 : 48;
+}
+
 void __init setup_cpu_features(void);
 
 void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
arch/arm64/kernel/cpuinfo.c +2 -0
index 84c8684..488d49a 100644
@@ -107,6 +107,8 @@ static int c_show(struct seq_file *m, void *v)
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
 		u32 midr = cpuinfo->reg_midr;
+		u64 mmfr0 = cpuinfo->reg_id_aa64mmfr0;
+		u64 mmfr2 = cpuinfo->reg_id_aa64mmfr2;
 
 		/*
 		 * glibc reads /proc/cpuinfo to determine the number of

arch/arm64/kernel/cpuinfo.c static int c_show(struct seq_file *m, void *v) · line 155

Quoted 7 lines
arch/arm64/kernel/cpuinfo.c +3 -1
@@ -148,7 +150,9 @@ static int c_show(struct seq_file *m, void *v)
 		seq_printf(m, "CPU architecture: 8\n");
 		seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
 		seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
-		seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
+		seq_printf(m, "CPU revision\t: %d\n", MIDR_REVISION(midr));
+		seq_printf(m, "address sizes\t: %d bits physical, %d bits virtual\n\n",
+			   get_parange_bits(mmfr0), get_varange_bits(mmfr2));

Can you say why this information is useful for userspace?

Once anything is added to cpuinfo it becomes ABI and must be supported forever, so we want to avoid adding anything that is not absolutely definitely needed...

Cheers
---Dave

#5 lore raw

RFC PATCH 2/3 arm64: Expose physical/virtual address bits through cpuinfo

Quoted 19 lines · Dave Martin
Quoted 9 lines · Kefeng Wang

ARMv8 Physical Address range allows 0x0~0x6, the 0x6 is supported in ARMv8.2, permitted values in ID_AA64MMFR0_EL1 are:

0000  32 bits, 4GB.
0001  36 bits, 64GB.
0010  40 bits, 1TB.
0011  42 bits, 4TB.
0100  44 bits, 16TB.
0101  48 bits, 256TB.
0110  52 bits, 4096TB.
Quoted 8 lines

All other values are reserved.

Meanwhile, ARMv8 can support 48bit or 52bit virtual addresses, larger virtual address(52bit) is introduced in ARMv8.2.

Exposing the physical and virtual address bits to userspace through procfs like x86, then it is easy to check the capacity of them that cpu supported from cpuinfo.

Quoted 5 lines

Can you say why this information is useful for userspace?

Once anything is added to cpuinfo it becomes ABI and must be supported forever, so we want to avoid adding anything that is not absolutely definitely needed...

It's also something that becomes different between ARM32 and ARM64, and I'm not adding it to ARM32 without a _very_ good justification why we need such information exported to userspace.

Given that userspace is fully insulated on 32-bit ARM from any knowledge of LPAE, I see zero reason why userspace needs to have any knowledge of the LPAE physical address space. Even my work on kexec on the most weird of ARMv7 LPAE platforms (where system memory is above 4GB phys) there's no reason for userspace to have any specific knowledge of LPAE. IOW, /dev/mem is just a file, just like any other file larger than 4GB.

Signature · 3 lines
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
#6 lore raw

RFC PATCH 3/3 arm64: Expose cpu vender id and model name through cpuinfo

In reply to Kefeng Wang

It is helpful to show the name of chip vendor and CPU model to customers in cpuinfo, identify them by using CPU implementer and CPU part is not intuitive(compared with x86).

We are complained for this several times, so expose them.

---
 arch/arm64/include/asm/cpu.h |  2 ++
 arch/arm64/kernel/cpuinfo.c  | 62 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
arch/arm64/include/asm/cpu.h +2 -0
index 13a6103..b8c3d79 100644
@@ -25,6 +25,8 @@
  */
 struct cpuinfo_arm64 {
 	struct cpu	cpu;
+	char		vendor[16];
+	char		model_name[16];
 	u32		reg_ctr;
 	u32		reg_cntfrq;
 	u32		reg_dczid;
arch/arm64/kernel/cpuinfo.c +62 -0

86 lines not on this page · raw message

Signature · 1 line
1.7.12.4
reviewer
#7 lore raw

RFC PATCH 3/3 arm64: Expose cpu vender id and model name through cpuinfo

Quoted 3 lines · Kefeng Wang

It is helpful to show the name of chip vendor and CPU model to customers in cpuinfo, identify them by using CPU implementer and CPU part is not intuitive(compared with x86).

On x86 these strings are acquired from the CPU itself, via CPUID instructions, which means that it works for future CPUs. For ARM systems, we have no consistent way of acquiring a model name from a CPU itself. Given the rate at which implementations are appearing, and recent experience [1] with issues mapping MIDRs to human-readable names, this is going to be very problematic.

We already expose the raw field values from MIDR_EL1, which are sufficient for a userspace application to identify a particular processor regardless of whether the kernel recognises it, and regardless of what firmware told the kernel. GCC for instance identifies CPUs based on MIDR_EL1 fields.

We also don't do this for arch/arm, and the two should look the same.

Quoted 1 line

We are complained for this several times, so expose them.

If you which to have human-readable strings for a CPU, a better approach would be to teach some userspace tool to map MIDR_EL1 values to vendor strings. It would be possible to update that tool when new CPUs appear, completely independently of the kernel.

NAK for this approach. It is not scalable, and there are other approaches which work today for the set of problems this tries to address.

Thanks,
Mark.

[1] https://community.arm.com/groups/processors/blog/2014/09/30/arm-cortex-a17-cortex-a12-processor-update

Quoted 117 lines
---
 arch/arm64/include/asm/cpu.h |  2 ++
 arch/arm64/kernel/cpuinfo.c  | 62 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
arch/arm64/include/asm/cpu.h +2 -0
index 13a6103..b8c3d79 100644
@@ -25,6 +25,8 @@
  */
 struct cpuinfo_arm64 {
 	struct cpu	cpu;
+	char		vendor[16];
+	char		model_name[16];
 	u32		reg_ctr;
 	u32		reg_cntfrq;
 	u32		reg_dczid;
arch/arm64/kernel/cpuinfo.c +62 -0
index 488d49a..da5f7df 100644
@@ -19,6 +19,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
+#include <asm/elf.h>
 
 #include <linux/bitops.h>
 #include <linux/bug.h>
@@ -100,6 +101,62 @@ static const char *const compat_hwcap2_str[] = {
 };
 #endif /* CONFIG_COMPAT */
 
+static void cpuinfo_get_vendor_model(struct cpuinfo_arm64 *info)
+{
+	char *vendor = info->vendor;
+	char *name = info->model_name;
+	u32 midr = info->reg_midr;
+	u32 impl = MIDR_IMPLEMENTOR(midr);
+	u32 part = MIDR_PARTNUM(midr);
+
+	switch (impl) {
+	case ARM_CPU_IMP_ARM:
+		strcpy(vendor, "ARM");
+		switch (part) {
+		case ARM_CPU_PART_AEM_V8:
+			strcpy(name, "AEM-V8");
+			break;
+		case ARM_CPU_PART_FOUNDATION:
+			strcpy(name, "Foundation");
+			break;
+		case ARM_CPU_PART_CORTEX_A53:
+			strcpy(name, "Cortex-A53");
+			break;
+		case ARM_CPU_PART_CORTEX_A57:
+			strcpy(name, "Cortex-A57");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_APM:
+		strcpy(vendor, "APM");
+		switch (part) {
+		case APM_CPU_PART_POTENZA:
+			strcpy(name, "Potenza");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_CAVIUM:
+		strcpy(vendor, "CAVIUM");
+		switch (part) {
+		case CAVIUM_CPU_PART_THUNDERX:
+			strcpy(name, "Thunderx");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_BRCM:
+		strcpy(vendor, "BROADCOM");
+		switch (part) {
+		case BRCM_CPU_PART_VULCAN:
+			strcpy(name, "Vulcan");
+			break;
+		};
+		break;
+	default:
+		strcpy(vendor, "Unknown");
+		strcpy(name, "Unknown");
+	}
+}
+
 static int c_show(struct seq_file *m, void *v)
 {
 	int i, j;
@@ -116,6 +173,9 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 */
 		seq_printf(m, "processor\t: %d\n", i);
+		seq_printf(m, "vendor_id\t: %s\n", cpuinfo->vendor);
+		seq_printf(m, "model name\t: %s rev %d (%s)\n", cpuinfo->model_name,
+			   MIDR_REVISION(midr), ELF_PLATFORM);
 
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 			   loops_per_jiffy / (500000UL/HZ),
@@ -238,6 +298,8 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
 	info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
 
+	cpuinfo_get_vendor_model(info);
+
 	cpuinfo_detect_icache_policy(info);
 
 	check_local_cpu_errata();
Signature · 1 line
1.7.12.4
#8 lore raw

RFC PATCH 3/3 arm64: Expose cpu vender id and model name through cpuinfo

Quoted 22 lines · Mark Rutland
Quoted 3 lines · Kefeng Wang

It is helpful to show the name of chip vendor and CPU model to customers in cpuinfo, identify them by using CPU implementer and CPU part is not intuitive(compared with x86).

On x86 these strings are acquired from the CPU itself, via CPUID instructions, which means that it works for future CPUs. For ARM systems, we have no consistent way of acquiring a model name from a CPU itself. Given the rate at which implementations are appearing, and recent experience [1] with issues mapping MIDRs to human-readable names, this is going to be very problematic.

We already expose the raw field values from MIDR_EL1, which are sufficient for a userspace application to identify a particular processor regardless of whether the kernel recognises it, and regardless of what firmware told the kernel. GCC for instance identifies CPUs based on MIDR_EL1 fields.

We also don't do this for arch/arm, and the two should look the same.

Quoted 1 line

We are complained for this several times, so expose them.

Quoted 8 lines

If you which to have human-readable strings for a CPU, a better approach would be to teach some userspace tool to map MIDR_EL1 values to vendor strings. It would be possible to update that tool when new CPUs appear, completely independently of the kernel.

NAK for this approach. It is not scalable, and there are other approaches which work today for the set of problems this tries to address.

Ok, clear enough, so we will push the customer to convert the impl and part in there userspace tool, not do it in kernel.

Thanks.

Quoted 6 lines

Thanks,
Mark.

[1] https://community.arm.com/groups/processors/blog/2014/09/30/arm-cortex-a17-cortex-a12-processor-update

#9 lore raw

RFC PATCH 3/3 arm64: Expose cpu vender id and model name through cpuinfo

In reply to Kefeng Wang
Quoted 5 lines · Kefeng Wang

It is helpful to show the name of chip vendor and CPU model to customers in cpuinfo, identify them by using CPU implementer and CPU part is not intuitive(compared with x86).

We are complained for this several times, so expose them.

Isn't the same information already provided in numeric form?

We don't want redundant forms of the same information in an ABI unless there's a clear reason why software needs it...

Cheers
---Dave

Quoted 122 lines
---
 arch/arm64/include/asm/cpu.h |  2 ++
 arch/arm64/kernel/cpuinfo.c  | 62 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
arch/arm64/include/asm/cpu.h +2 -0
index 13a6103..b8c3d79 100644
@@ -25,6 +25,8 @@
  */
 struct cpuinfo_arm64 {
 	struct cpu	cpu;
+	char		vendor[16];
+	char		model_name[16];
 	u32		reg_ctr;
 	u32		reg_cntfrq;
 	u32		reg_dczid;
arch/arm64/kernel/cpuinfo.c +62 -0
index 488d49a..da5f7df 100644
@@ -19,6 +19,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
+#include <asm/elf.h>
 
 #include <linux/bitops.h>
 #include <linux/bug.h>
@@ -100,6 +101,62 @@ static const char *const compat_hwcap2_str[] = {
 };
 #endif /* CONFIG_COMPAT */
 
+static void cpuinfo_get_vendor_model(struct cpuinfo_arm64 *info)
+{
+	char *vendor = info->vendor;
+	char *name = info->model_name;
+	u32 midr = info->reg_midr;
+	u32 impl = MIDR_IMPLEMENTOR(midr);
+	u32 part = MIDR_PARTNUM(midr);
+
+	switch (impl) {
+	case ARM_CPU_IMP_ARM:
+		strcpy(vendor, "ARM");
+		switch (part) {
+		case ARM_CPU_PART_AEM_V8:
+			strcpy(name, "AEM-V8");
+			break;
+		case ARM_CPU_PART_FOUNDATION:
+			strcpy(name, "Foundation");
+			break;
+		case ARM_CPU_PART_CORTEX_A53:
+			strcpy(name, "Cortex-A53");
+			break;
+		case ARM_CPU_PART_CORTEX_A57:
+			strcpy(name, "Cortex-A57");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_APM:
+		strcpy(vendor, "APM");
+		switch (part) {
+		case APM_CPU_PART_POTENZA:
+			strcpy(name, "Potenza");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_CAVIUM:
+		strcpy(vendor, "CAVIUM");
+		switch (part) {
+		case CAVIUM_CPU_PART_THUNDERX:
+			strcpy(name, "Thunderx");
+			break;
+		};
+		break;
+	case ARM_CPU_IMP_BRCM:
+		strcpy(vendor, "BROADCOM");
+		switch (part) {
+		case BRCM_CPU_PART_VULCAN:
+			strcpy(name, "Vulcan");
+			break;
+		};
+		break;
+	default:
+		strcpy(vendor, "Unknown");
+		strcpy(name, "Unknown");
+	}
+}
+
 static int c_show(struct seq_file *m, void *v)
 {
 	int i, j;
@@ -116,6 +173,9 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 */
 		seq_printf(m, "processor\t: %d\n", i);
+		seq_printf(m, "vendor_id\t: %s\n", cpuinfo->vendor);
+		seq_printf(m, "model name\t: %s rev %d (%s)\n", cpuinfo->model_name,
+			   MIDR_REVISION(midr), ELF_PLATFORM);
 
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 			   loops_per_jiffy / (500000UL/HZ),
@@ -238,6 +298,8 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
 	info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
 
+	cpuinfo_get_vendor_model(info);
+
 	cpuinfo_detect_icache_policy(info);
 
 	check_local_cpu_errata();
Signature · 7 lines
1.7.12.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
#10 lore raw

cover Entend cpuinfo

In reply to Kefeng Wang

Hi all,

According to the explain of Mark and Dave, please ignore this patches. No need do this in kernel, do it in userspace.

Thanks,
Kefeng

Quoted 48 lines · Kefeng Wang

The patches aimed at enhencing cpuinfo.

* ARMv8 supports several different types of physical/virtual address bits, up to 52bit in ARMv8.2 especially, it's better to expose it.

* Show the name of chip vendor and CPU model to customers, identify them by CPU implementer and part is not intuitive(compared with x86).

Ideally, add new line to cpuinfo won't break userspace, I hope so, the cpuinfo shown in qemu with patches,

root at linux$ cat /proc/cpuinfo
processor : 0
vendor_id : ARM
model name : Cortex-A57 rev 0 (aarch64)
BogoMIPS : 125.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd07
CPU revision : 0
address sizes : 44 bits physical, 48 bits virtual

processor : 1
vendor_id : ARM
model name : Cortex-A57 rev 0 (aarch64)
BogoMIPS : 125.00
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd07
CPU revision : 0
address sizes : 44 bits physical, 48 bits virtual

Kefeng Wang (3):
arm64: Append more field of id_aa64mmfr2 for cpufeature
arm64: Expose physical/virtual address bits through cpuinfo
arm64: Expose cpu vender id and model name through cpuinfo

 arch/arm64/include/asm/cpu.h        |  2 ++
 arch/arm64/include/asm/cpufeature.h | 18 ++++++++++
 arch/arm64/include/asm/sysreg.h     |  4 +++
 arch/arm64/kernel/cpufeature.c      |  4 +++
 arch/arm64/kernel/cpuinfo.c         | 68 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 95 insertions(+), 1 deletion(-)