[U-Boot] [PATCH v4 5/8] smbios: Generate type 4 on non-x86 systems

Alexander Graf agraf at suse.de
Wed Aug 17 12:29:24 CEST 2016


The type 4 table generation code is very x86 centric today. Refactor things
out into the device model cpu class to allow the tables to get generated for
other architectures as well.

Signed-off-by: Alexander Graf <agraf at suse.de>

---

v3 -> v4:

  - Use device model

v4 -> v5:

  - s/get_info/get_vendor/ typo
  - s/smbios_write_type4_arch/smbios_write_type4_dm/
---
 arch/x86/cpu/baytrail/cpu.c          |  1 +
 arch/x86/cpu/broadwell/cpu.c         |  1 +
 arch/x86/cpu/cpu_x86.c               | 13 ++++++++++
 arch/x86/cpu/ivybridge/model_206ax.c |  1 +
 arch/x86/include/asm/cpu_x86.h       | 12 +++++++++
 drivers/cpu/cpu-uclass.c             | 10 ++++++++
 include/cpu.h                        | 20 +++++++++++++++
 include/smbios.h                     |  3 +++
 lib/smbios.c                         | 49 ++++++++++++++++++++++++++----------
 9 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
index b1faf8c..c454db0 100644
--- a/arch/x86/cpu/baytrail/cpu.c
+++ b/arch/x86/cpu/baytrail/cpu.c
@@ -141,6 +141,7 @@ static const struct cpu_ops cpu_x86_baytrail_ops = {
 	.get_desc	= cpu_x86_get_desc,
 	.get_info	= baytrail_get_info,
 	.get_count	= baytrail_get_count,
+	.get_vendor	= cpu_x86_get_vendor,
 };
 
 static const struct udevice_id cpu_x86_baytrail_ids[] = {
diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
index 3ba21aa..6977e86 100644
--- a/arch/x86/cpu/broadwell/cpu.c
+++ b/arch/x86/cpu/broadwell/cpu.c
@@ -743,6 +743,7 @@ static const struct cpu_ops cpu_x86_broadwell_ops = {
 	.get_desc	= cpu_x86_get_desc,
 	.get_info	= broadwell_get_info,
 	.get_count	= broadwell_get_count,
+	.get_vendor	= cpu_x86_get_vendor,
 };
 
 static const struct udevice_id cpu_x86_broadwell_ids[] = {
diff --git a/arch/x86/cpu/cpu_x86.c b/arch/x86/cpu/cpu_x86.c
index 0941041..3b0458d 100644
--- a/arch/x86/cpu/cpu_x86.c
+++ b/arch/x86/cpu/cpu_x86.c
@@ -15,9 +15,21 @@ DECLARE_GLOBAL_DATA_PTR;
 int cpu_x86_bind(struct udevice *dev)
 {
 	struct cpu_platdata *plat = dev_get_parent_platdata(dev);
+	struct cpuid_result res;
 
 	plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
 				      "intel,apic-id", -1);
+	plat->family = gd->arch.x86;
+	res = cpuid(1);
+	plat->id[0] = res.eax;
+	plat->id[1] = res.edx;
+
+	return 0;
+}
+
+int cpu_x86_get_vendor(struct udevice *dev, const char **vendor)
+{
+	*vendor = cpu_vendor_name(gd->arch.x86_vendor);
 
 	return 0;
 }
@@ -60,6 +72,7 @@ static int cpu_x86_get_count(struct udevice *dev)
 static const struct cpu_ops cpu_x86_ops = {
 	.get_desc	= cpu_x86_get_desc,
 	.get_count	= cpu_x86_get_count,
+	.get_vendor	= cpu_x86_get_vendor,
 };
 
 static const struct udevice_id cpu_x86_ids[] = {
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index 38e244b..d8eb2e7 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -478,6 +478,7 @@ static const struct cpu_ops cpu_x86_model_206ax_ops = {
 	.get_desc	= cpu_x86_get_desc,
 	.get_info	= model_206ax_get_info,
 	.get_count	= model_206ax_get_count,
+	.get_vendor	= cpu_x86_get_vendor,
 };
 
 static const struct udevice_id cpu_x86_model_206ax_ids[] = {
diff --git a/arch/x86/include/asm/cpu_x86.h b/arch/x86/include/asm/cpu_x86.h
index 1940480..79aaf2d 100644
--- a/arch/x86/include/asm/cpu_x86.h
+++ b/arch/x86/include/asm/cpu_x86.h
@@ -31,4 +31,16 @@ int cpu_x86_bind(struct udevice *dev);
  */
 int cpu_x86_get_desc(struct udevice *dev, char *buf, int size);
 
+/**
+ * cpu_x86_get_vendor() - Get a vendor string for an x86 CPU
+ *
+ * This uses cpu_vendor_name() and is suitable to use as the get_vendor()
+ * method for the CPU uclass.
+ *
+ * @dev:	Device to check (UCLASS_CPU)
+ * @vendor:	Pointer to vendor string pointer
+ * @return:	0 if OK, -ve on error
+ */
+int cpu_x86_get_vendor(struct udevice *dev, const char **vendor);
+
 #endif /* _ASM_CPU_X86_H */
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index 7660f99..b25c3b4 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -44,6 +44,16 @@ int cpu_get_count(struct udevice *dev)
 	return ops->get_count(dev);
 }
 
+int cpu_get_vendor(struct udevice *dev, const char **vendor)
+{
+	struct cpu_ops *ops = cpu_get_ops(dev);
+
+	if (!ops->vendor)
+		return -ENOSYS;
+
+	return ops->get_vendor(dev, vendor);
+}
+
 U_BOOT_DRIVER(cpu_bus) = {
 	.name	= "cpu_bus",
 	.id	= UCLASS_SIMPLE_BUS,
diff --git a/include/cpu.h b/include/cpu.h
index bda5315..2285aee 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -21,6 +21,8 @@ struct cpu_platdata {
 	int cpu_id;
 	int ucode_version;
 	ulong device_id;
+	u16 family;
+	u32 id[2];
 };
 
 /* CPU features - mostly just a placeholder for now */
@@ -71,6 +73,15 @@ struct cpu_ops {
 	 * @return CPU count if OK, -ve on error
 	 */
 	int (*get_count)(struct udevice *dev);
+
+	/**
+	 * get_vendor() - Get vendor name of a CPU
+	 *
+	 * @dev:	Device to check (UCLASS_CPU)
+	 * @vendor:	Pointer to put the pointer to the vendor string
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*get_vendor)(struct udevice *dev, const char **vendor);
 };
 
 #define cpu_get_ops(dev)        ((struct cpu_ops *)(dev)->driver->ops)
@@ -102,4 +113,13 @@ int cpu_get_info(struct udevice *dev, struct cpu_info *info);
  */
 int cpu_get_count(struct udevice *dev);
 
+/**
+ * cpu_get_vendor() - Get vendor name of a CPU
+ *
+ * @dev:	Device to check (UCLASS_CPU)
+ * @vendor:	Pointer to put the pointer to the vendor string
+ * @return 0 if OK, -ve on error
+ */
+int cpu_get_vendor(struct udevice *dev, const char **vendor);
+
 #endif
diff --git a/include/smbios.h b/include/smbios.h
index 5962d4c..3cbc687 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -139,6 +139,9 @@ struct __packed smbios_type3 {
 #define SMBIOS_PROCESSOR_STATUS_ENABLED	1
 #define SMBIOS_PROCESSOR_UPGRADE_NONE	6
 
+#define SMBIOS_PROCESSOR_FAMILY_OTHER	1
+#define SMBIOS_PROCESSOR_FAMILY_UNKNOWN	2
+
 struct __packed smbios_type4 {
 	u8 type;
 	u8 length;
diff --git a/lib/smbios.c b/lib/smbios.c
index 8dfd486..6e8f00a 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -10,7 +10,11 @@
 #include <smbios.h>
 #include <tables_csum.h>
 #include <version.h>
-#include <asm/cpu.h>
+#ifdef CONFIG_CPU
+#include <cpu.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -152,26 +156,45 @@ static int smbios_write_type3(uintptr_t *current, int handle)
 	return len;
 }
 
+static void smbios_write_type4_dm(struct smbios_type4 *t)
+{
+	u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
+	const char *vendor = "Unknown";
+	const char *name = "Unknown";
+
+#ifdef CONFIG_CPU
+	char processor_name[49];
+	struct udevice *dev = NULL;
+
+	uclass_find_first_device(UCLASS_CPU, &dev);
+	if (dev) {
+		struct cpu_platdata *plat = dev_get_parent_platdata(dev);
+
+		if (plat->family)
+			processor_family = plat->family;
+		t->processor_id[0] = plat->id[0];
+		t->processor_id[1] = plat->id[1];
+
+		cpu_get_vendor(dev, &vendor);
+		if (!cpu_get_desc(dev, processor_name, sizeof(processor_name)))
+			name = processor_name;
+	}
+#endif
+
+	t->processor_family = processor_family;
+	t->processor_manufacturer = smbios_add_string(t->eos, vendor);
+	t->processor_version = smbios_add_string(t->eos, name);
+}
+
 static int smbios_write_type4(uintptr_t *current, int handle)
 {
 	struct smbios_type4 *t = (struct smbios_type4 *)*current;
 	int len = sizeof(struct smbios_type4);
-	const char *vendor;
-	char *name;
-	char processor_name[CPU_MAX_NAME_LEN];
-	struct cpuid_result res;
 
 	memset(t, 0, sizeof(struct smbios_type4));
 	fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
 	t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
-	t->processor_family = gd->arch.x86;
-	vendor = cpu_vendor_name(gd->arch.x86_vendor);
-	t->processor_manufacturer = smbios_add_string(t->eos, vendor);
-	res = cpuid(1);
-	t->processor_id[0] = res.eax;
-	t->processor_id[1] = res.edx;
-	name = cpu_get_name(processor_name);
-	t->processor_version = smbios_add_string(t->eos, name);
+	smbios_write_type4_dm(t);
 	t->status = SMBIOS_PROCESSOR_STATUS_ENABLED;
 	t->processor_upgrade = SMBIOS_PROCESSOR_UPGRADE_NONE;
 	t->l1_cache_handle = 0xffff;
-- 
1.8.5.6



More information about the U-Boot mailing list