Page MenuHomeFreeBSD

D29277.id.diff
No OneTemporary

D29277.id.diff

diff --git a/sys/dev/smbios/smbios.h b/sys/dev/smbios/smbios.h
--- a/sys/dev/smbios/smbios.h
+++ b/sys/dev/smbios/smbios.h
@@ -64,6 +64,54 @@
uint16_t handle;
} __packed;
+struct smbios_bios_information {
+ struct smbios_structure_header header;
+ uint8_t vendor_str;
+ uint8_t version_str;
+ uint16_t starting_addr_segment;
+ uint8_t release_date_str;
+ uint8_t rom_size;
+ uint64_t characteristics;
+} __packed;
+
+struct smbios_system_information {
+ struct smbios_structure_header header;
+ uint8_t manufacturer_str;
+ uint8_t product_str;
+ uint8_t version_str;
+ uint8_t serial_str;
+ /* SMBIOS 2.1+ */
+ uint8_t uuid[16];
+ uint8_t wakeup_type;
+ /* SMBIOS 2.4+ */
+ uint8_t sku_str;
+ uint8_t family_str;
+} __packed;
+
+struct smbios_board_information {
+ struct smbios_structure_header header;
+ uint8_t manufacturer_str;
+ uint8_t product_str;
+ uint8_t version_str;
+ uint8_t serial_str;
+ uint8_t asset_tag_str;
+ uint8_t features;
+ uint8_t location_in_chassis_str;
+ uint16_t chassis_handle;
+ uint8_t board_type;
+ uint8_t num_handles;
+ uint16_t handles[];
+} __packed;
+
+struct smbios_chassis_information {
+ struct smbios_structure_header header;
+ uint8_t manufacturer_str;
+ uint8_t chassis_type;
+ uint8_t version_str;
+ uint8_t serial_str;
+ uint8_t asset_tag_str;
+} __packed;
+
typedef void (*smbios_callback_t)(struct smbios_structure_header *, void *);
static inline void
@@ -91,4 +139,21 @@
}
}
+static inline const char *
+smbios_nth_string(uint8_t *strings, size_t n)
+{
+ const char *res = (const char*)strings;
+ int i, len;
+
+ /* Find a string by its 1-based (!) index */
+ for (i = 0; i < n - 1; i++) {
+ len = strlen(res);
+ if (len == 0)
+ return (NULL);
+ res += len + 1;
+ }
+
+ return (res);
+}
+
#endif /* _SMBIOS_H_ */
diff --git a/sys/dev/smbios/smbios.c b/sys/dev/smbios/smbios.c
--- a/sys/dev/smbios/smbios.c
+++ b/sys/dev/smbios/smbios.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2003 Matthew N. Dodd <winter@jurai.net>
* All rights reserved.
+ * Copyright (c) 2021 Greg V <greg@unrelenting.technology>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +35,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/socket.h>
+#include <sys/sysctl.h>
#if defined(__amd64__) || defined(__aarch64__)
#include <sys/efi.h>
#endif
@@ -59,6 +61,36 @@
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf
*/
+static SYSCTL_NODE(_hw, OID_AUTO, dmi, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
+ "SMBIOS DMI system information");
+
+#define DMI_SYSCTL(name, desc) \
+ static char name[128] = { 0 }; \
+ SYSCTL_STRING(_hw_dmi, OID_AUTO, name, CTLFLAG_RD, name, 0, desc)
+
+#define DMI_SYSCTL_INT(name, desc) \
+ static int name = 0; \
+ SYSCTL_INT(_hw_dmi, OID_AUTO, name, CTLFLAG_RD, &name, 0, desc)
+
+#define STRLCPY(dst, src) strlcpy((dst), (src), sizeof(dst))
+
+/* The names match Linux sysfs */
+DMI_SYSCTL(bios_vendor, "Firmware vendor name");
+DMI_SYSCTL(bios_version, "Firmware version");
+DMI_SYSCTL(bios_date, "Firmware release date");
+DMI_SYSCTL(sys_vendor, "System vendor name");
+DMI_SYSCTL(product_name, "System product name");
+DMI_SYSCTL(product_version, "System product version");
+DMI_SYSCTL(product_family, "System product family");
+DMI_SYSCTL(board_asset_tag, "Board asset tag");
+DMI_SYSCTL(board_vendor, "Baseboard/module vendor name");
+DMI_SYSCTL(board_name, "Baseboard/module product name");
+DMI_SYSCTL(board_version, "Baseboard/module version");
+DMI_SYSCTL(chassis_asset_tag, "Chassis asset tag");
+DMI_SYSCTL(chassis_vendor, "Chassis vendor name");
+DMI_SYSCTL(chassis_version, "Chassis version");
+DMI_SYSCTL_INT(chassis_type, "Chassis type");
+
struct smbios_softc {
device_t dev;
struct resource * res;
@@ -162,11 +194,96 @@
return (error);
}
+static void
+smbios_bios_info(struct smbios_bios_information *tbl, struct smbios_softc *sc)
+{
+ uint8_t *strings = (uint8_t*)tbl + tbl->header.length;
+
+ if (tbl->vendor_str)
+ STRLCPY(bios_vendor, smbios_nth_string(strings, tbl->vendor_str));
+ if (tbl->version_str)
+ STRLCPY(bios_version, smbios_nth_string(strings, tbl->version_str));
+ if (tbl->release_date_str)
+ STRLCPY(bios_date, smbios_nth_string(strings, tbl->release_date_str));
+
+ device_printf(sc->dev, "Firmware: %s (%s) %s\n", bios_version, bios_date, bios_vendor);
+}
+
+static void
+smbios_system_info(struct smbios_system_information *tbl, struct smbios_softc *sc)
+{
+ uint8_t *strings = (uint8_t*)tbl + tbl->header.length;
+
+ if (tbl->manufacturer_str)
+ STRLCPY(sys_vendor, smbios_nth_string(strings, tbl->manufacturer_str));
+ if (tbl->product_str)
+ STRLCPY(product_name, smbios_nth_string(strings, tbl->product_str));
+ if (tbl->version_str)
+ STRLCPY(product_version, smbios_nth_string(strings, tbl->version_str));
+ if (tbl->header.length >= 0x1b && tbl->family_str)
+ STRLCPY(product_family, smbios_nth_string(strings, tbl->family_str));
+}
+
+static void
+smbios_board_info(struct smbios_board_information *tbl, struct smbios_softc *sc)
+{
+ uint8_t *strings = (uint8_t*)tbl + tbl->header.length;
+
+ if (tbl->manufacturer_str)
+ STRLCPY(board_vendor, smbios_nth_string(strings, tbl->manufacturer_str));
+ if (tbl->product_str)
+ STRLCPY(board_name, smbios_nth_string(strings, tbl->product_str));
+ if (tbl->version_str)
+ STRLCPY(board_version, smbios_nth_string(strings, tbl->version_str));
+ if (tbl->asset_tag_str)
+ STRLCPY(board_asset_tag, smbios_nth_string(strings, tbl->asset_tag_str));
+
+ device_printf(sc->dev, "Board: %s %s %s\n", board_vendor, board_name, board_version);
+}
+
+static void
+smbios_chassis_info(struct smbios_chassis_information *tbl, struct smbios_softc *sc)
+{
+ uint8_t *strings = (uint8_t*)tbl + tbl->header.length;
+
+ chassis_type = tbl->chassis_type;
+ if (tbl->asset_tag_str)
+ STRLCPY(chassis_asset_tag, smbios_nth_string(strings, tbl->asset_tag_str));
+ if (tbl->manufacturer_str)
+ STRLCPY(chassis_vendor, smbios_nth_string(strings, tbl->manufacturer_str));
+ if (tbl->version_str)
+ STRLCPY(chassis_version, smbios_nth_string(strings, tbl->version_str));
+}
+
+static void
+smbios_dmi_info(struct smbios_structure_header *h, void *arg)
+{
+ struct smbios_softc *sc = arg;
+
+ switch (h->type) {
+ case 0:
+ smbios_bios_info((struct smbios_bios_information *)h, sc);
+ break;
+ case 1:
+ smbios_system_info((struct smbios_system_information *)h, sc);
+ break;
+ case 2:
+ smbios_board_info((struct smbios_board_information *)h, sc);
+ break;
+ case 3:
+ smbios_chassis_info((struct smbios_chassis_information *)h, sc);
+ break;
+ default:
+ break;
+ }
+}
+
static int
smbios_attach (device_t dev)
{
struct smbios_softc *sc;
int error;
+ void *table;
sc = device_get_softc(dev);
error = 0;
@@ -190,6 +307,11 @@
bcd2bin(sc->eps->BCD_revision & 0x0f));
printf("\n");
+ table = pmap_mapbios(sc->eps->structure_table_address,
+ sc->eps->structure_table_length);
+ smbios_walk_table(table, sc->eps->number_structures, smbios_dmi_info, sc);
+ pmap_unmapbios((vm_offset_t)table, sc->eps->structure_table_length);
+
return (0);
bad:
if (sc->res)

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 5:49 AM (13 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31040505
Default Alt Text
D29277.id.diff (7 KB)

Event Timeline