summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig15
-rw-r--r--src/arch/x86/smbios.c43
-rw-r--r--src/include/device/device.h11
3 files changed, 60 insertions, 9 deletions
diff --git a/src/Kconfig b/src/Kconfig
index be269b6195..e4ddf0cc70 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -785,6 +785,21 @@ config GENERATE_SMBIOS_TABLES
If unsure, say Y.
+config SMBIOS_TYPE41_PROVIDED_BY_DEVTREE
+ bool
+ depends on ARCH_X86
+ help
+ If enabled, only generate SMBIOS Type 41 entries for PCI devices in
+ the devicetree for which Type 41 information is provided, e.g. with
+ the `smbios_dev_info` devicetree syntax. This is useful to manually
+ assign specific instance IDs to onboard devices irrespective of the
+ device traversal order. It is assumed that instance IDs for devices
+ of the same class are unique.
+ When disabled, coreboot autogenerates SMBIOS Type 41 entries for all
+ appropriate PCI devices in the devicetree. Instance IDs are assigned
+ successive numbers from a monotonically increasing counter, with one
+ counter for each device class.
+
config SMBIOS_PROVIDED_BY_MOBO
bool
default n
diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c
index ea429713ae..c05f905892 100644
--- a/src/arch/x86/smbios.c
+++ b/src/arch/x86/smbios.c
@@ -1177,30 +1177,55 @@ static u8 smbios_get_device_type_from_dev(struct device *dev)
}
}
-static int smbios_generate_type41_from_devtree(struct device *dev, int *handle,
- unsigned long *current)
+static bool smbios_get_type41_instance_id(struct device *dev, u8 device_type, u8 *instance_id)
{
+#if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
+ *instance_id = dev->smbios_instance_id;
+ return dev->smbios_instance_id_valid;
+#else
static u8 type41_inst_cnt[SMBIOS_DEVICE_TYPE_COUNT + 1] = {};
+ if (device_type == SMBIOS_DEVICE_TYPE_OTHER ||
+ device_type == SMBIOS_DEVICE_TYPE_UNKNOWN)
+ return false;
+
+ if (device_type > SMBIOS_DEVICE_TYPE_COUNT)
+ return false;
+
+ *instance_id = type41_inst_cnt[device_type]++;
+ return true;
+#endif
+}
+
+static const char *smbios_get_type41_refdes(struct device *dev)
+{
+#if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
+ if (dev->smbios_refdes)
+ return dev->smbios_refdes;
+#endif
+ return get_pci_subclass_name(dev);
+}
+
+static int smbios_generate_type41_from_devtree(struct device *dev, int *handle,
+ unsigned long *current)
+{
if (dev->path.type != DEVICE_PATH_PCI)
return 0;
if (!dev->on_mainboard)
return 0;
- u8 device_type = smbios_get_device_type_from_dev(dev);
+ const u8 device_type = smbios_get_device_type_from_dev(dev);
- if (device_type == SMBIOS_DEVICE_TYPE_OTHER ||
- device_type == SMBIOS_DEVICE_TYPE_UNKNOWN)
- return 0;
+ u8 instance_id;
- if (device_type > SMBIOS_DEVICE_TYPE_COUNT)
+ if (!smbios_get_type41_instance_id(dev, device_type, &instance_id))
return 0;
- const char *name = get_pci_subclass_name(dev);
+ const char *name = smbios_get_type41_refdes(dev);
return smbios_write_type41(current, handle,
name, // name
- type41_inst_cnt[device_type]++, // inst
+ instance_id, // inst
0, // segment
dev->bus->secondary, //bus
PCI_SLOT(dev->path.pci.devfn), // device
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 8610e0a4c6..237d836147 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -148,6 +148,17 @@ struct device {
u8 smbios_slot_data_width;
u8 smbios_slot_length;
const char *smbios_slot_designation;
+
+#if CONFIG(SMBIOS_TYPE41_PROVIDED_BY_DEVTREE)
+ /*
+ * These fields are intentionally guarded so that attempts to use
+ * the corresponding devicetree syntax without selecting the Kconfig
+ * option result in build-time errors. Smaller size is a side effect.
+ */
+ bool smbios_instance_id_valid;
+ u8 smbios_instance_id;
+ const char *smbios_refdes;
+#endif
#endif
#endif
DEVTREE_CONST void *chip_info;