summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2026-03-10 19:13:53 +0100
committerJörg Frings-Fürst <debian@jff.email>2026-03-10 19:13:53 +0100
commit3a3565140b52ca1ff87c1fa2f604089550d8efcb (patch)
tree33d4186168de7d5c954c12d29534cc19797b5f74
parentd4b11cf3e4dcc4ca0ca41d6403c98b3214a8b92d (diff)
parentc61bb295f8ecde9a8dfb922aad56c58f1b8008e7 (diff)
Merge branch 'release/debian/3.7-1'HEADdebian/3.7-1master
-rw-r--r--AUTHORS1
-rw-r--r--Makefile5
-rw-r--r--NEWS15
-rw-r--r--README8
-rw-r--r--biosdecode.c10
-rw-r--r--config.h5
-rw-r--r--debian/.gitignore1
-rw-r--r--debian/changelog19
-rw-r--r--debian/control4
-rw-r--r--debian/copyright5
-rw-r--r--debian/files1
-rw-r--r--debian/patches/0001-hurd.patch2
-rw-r--r--debian/patches/0005-build.patch25
-rw-r--r--debian/patches/0100-ansi-c.patch18
-rw-r--r--debian/patches/0105-dmidecode-avoid-sigbus.patch50
-rw-r--r--debian/patches/0110-nosysfs.patch32
-rw-r--r--debian/patches/0115-no_smbios_DMI_entry_point.patch55
-rw-r--r--debian/patches/0120-return_actual_data_size.patch103
-rw-r--r--debian/patches/0125-use_read_file_to_read_DMI_table_from_sysfs.patch78
-rw-r--r--debian/patches/0130-use_DWORD_for_table_max_size.patch27
-rw-r--r--debian/patches/0135-hide_fixup_msg.patch46
-rw-r--r--debian/patches/0140-Fix_scan_entry_point.patch54
-rw-r--r--debian/patches/0145-Fix_condition_error_in_ascii_filter.patch18
-rw-r--r--debian/patches/0150-Fix_crash.patch21
-rw-r--r--debian/patches/0155-use_read_file.patch43
-rw-r--r--debian/patches/0160-HPE_OEM_Firmware_change.patch32
-rw-r--r--debian/patches/0600-Fix-groff-error.patch16
-rw-r--r--debian/patches/0605-man.patch319
-rw-r--r--debian/patches/series16
-rw-r--r--dmidecode.c377
-rw-r--r--dmidecode.h12
-rw-r--r--dmioem.c750
-rw-r--r--dmioem.h4
-rw-r--r--man/dmidecode.817
-rw-r--r--types.h97
-rw-r--r--util.c16
-rw-r--r--util.h1
-rw-r--r--version.h2
38 files changed, 1396 insertions, 909 deletions
diff --git a/AUTHORS b/AUTHORS
index 7065f72..b3573a3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -24,6 +24,7 @@ Petr Oros <poros@redhat.com>
Prabhakar Pujeri <prabhakar.pujeri@dell.com>
Erwan Velu <e.velu@criteo.com>
Jerry Hoemann <jerry.hoemann@hpe.com>
+Armin Wolf <W_Armin@gmx.de>
MANY THANKS TO (IN CHRONOLOGICAL ORDER)
Werner Heuser
diff --git a/Makefile b/Makefile
index 6fc946b..985992e 100644
--- a/Makefile
+++ b/Makefile
@@ -19,14 +19,11 @@ CFLAGS ?= -O2
#CFLAGS ?= -g
CFLAGS += -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
- -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef
+ -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wundef
# Let lseek and mmap support 64-bit wide offsets
CFLAGS += -D_FILE_OFFSET_BITS=64
-#CFLAGS += -DBIGENDIAN
-#CFLAGS += -DALIGNMENT_WORKAROUND
-
# Pass linker flags here (can be set from environment too)
LDFLAGS ?=
diff --git a/NEWS b/NEWS
index 8c4059e..912c540 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,18 @@
+Version 3.7 (Thu Dec 18 2025)
+ - [COMPATIBILITY] Use binary unit prefixes.
+ - [COMPATIBILITY] Rename BIOS to Firmware.
+ - [PORTABILITY] Improve variable declarations.
+ - [PORTABILITY] Stop open-coding the u64 type.
+ - [PORTABILITY] Use unaligned memory accesses unconditionally.
+ - [PORTABILITY] No longer build with -Winline.
+ - Support for SMBIOS 3.8.0. This includes a new processor family.
+ - Support for SMBIOS 3.9.0. This includes chassis type name adjustments,
+ new rack attributes, slot ID for more slot types, and new memory device
+ form factors and types.
+ - Decode HPE OEM records 193, 195, 202, 211, 226, 229, 232 and 244.
+ - Update HPE OEM records 203, 216, 242 and 245.
+ - EDSFF slot names now include their .S/.L suffix.
+
Version 3.6 (Wed Apr 24 2024)
- [PORTABILITY] Use -DALIGNMENT_WORKAROUND on arm.
- [PORTABILITY] Read SMBIOS entry point via kenv on DragonFly BSD.
diff --git a/README b/README
index c87e52c..65060b2 100644
--- a/README
+++ b/README
@@ -41,14 +41,6 @@ Optionally, you can run "make strip" prior to "make install" if you want
smaller binaries. However, be aware that this will prevent any further
attempt to debug the programs.
-Two parameters can be set in the Makefile file to make dmidecode work on
-non-i386 systems. They should be used if your system uses the big endian
-byte ordering (Motorola) or doesn't support unaligned memory accesses,
-respectively. For example, compiling for a SPARC processor would require
-both (but I am not aware of SPARC-based systems implementing SMBIOS).
-Compiling for an IA64 processor requires the memory alignment workaround,
-and it is enabled automatically.
-
** DOCUMENTATION **
diff --git a/biosdecode.c b/biosdecode.c
index 99a27fe..c387276 100644
--- a/biosdecode.c
+++ b/biosdecode.c
@@ -2,7 +2,7 @@
* BIOS Decode
*
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
- * Copyright (C) 2002-2017 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2002-2025 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -111,8 +111,8 @@ static int smbios3_decode(const u8 *p, size_t len)
p[0x07], p[0x08], p[0x09]);
printf("\tStructure Table Maximum Length: %u bytes\n",
DWORD(p + 0x0C));
- printf("\tStructure Table 64-bit Address: 0x%08X%08X\n",
- QWORD(p + 0x10).h, QWORD(p + 0x10).l);
+ printf("\tStructure Table 64-bit Address: 0x%016llX\n",
+ QWORD(p + 0x10));
return 1;
}
@@ -284,8 +284,8 @@ static int acpi_decode(const u8 *p, size_t len)
if (DWORD(p + 20) < 32) return 1;
- printf("\tXSD Table 64-bit Address: 0x%08X%08X\n",
- QWORD(p + 24).h, QWORD(p + 24).l);
+ printf("\tXSD Table 64-bit Address: 0x%016llX\n",
+ QWORD(p + 24));
return 1;
}
diff --git a/config.h b/config.h
index 0a1af7d..416d4a6 100644
--- a/config.h
+++ b/config.h
@@ -21,11 +21,6 @@
#define USE_MMAP
#endif
-/* Use memory alignment workaround or not */
-#if defined(__ia64__) || defined(__arm__)
-#define ALIGNMENT_WORKAROUND
-#endif
-
/* Avoid unaligned memcpy on /dev/mem */
#ifdef __aarch64__
#define USE_SLOW_MEMCPY
diff --git a/debian/.gitignore b/debian/.gitignore
new file mode 100644
index 0000000..027271b
--- /dev/null
+++ b/debian/.gitignore
@@ -0,0 +1 @@
+files
diff --git a/debian/changelog b/debian/changelog
index f604c07..1299476 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,22 @@
+dmidecode (3.7-1) unstable; urgency=medium
+
+ * New upstream release.
+ - Refresh patches.
+ - Remove not longer used patches:
+ + debian/patches/0100-ansi-c.patch
+ + debian/patches/Fix-groff-error.patch
+ * debian/copyright:
+ - Add year 2026 to myself.
+ - Rebase to the new release.
+ * Declare compliance with Debian Policy 4.7.3.0 (No changes needed).
+ * debian/control:
+ - Remove redundant Priority field.
+ - Remove redundant Rules-Requires-Root field.
+ * New debian/patches/0605-man.patch (Closes: #1088088)
+ * Remove old patches.
+
+ -- Jörg Frings-Fürst <debian@jff.email> Tue, 10 Mar 2026 11:52:04 +0100
+
dmidecode (3.6-2) unstable; urgency=medium
* debian/control:
diff --git a/debian/control b/debian/control
index 5ad9b9b..91b2755 100644
--- a/debian/control
+++ b/debian/control
@@ -1,10 +1,8 @@
Source: dmidecode
Section: utils
-Priority: optional
Maintainer: Jörg Frings-Fürst <debian@jff.email>
Build-Depends: debhelper-compat (= 13)
-Standards-Version: 4.7.0
-Rules-Requires-Root: no
+Standards-Version: 4.7.3.0
Vcs-Git: https://git.jff.email/cgit/dmidecode.git
Vcs-Browser: https://git.jff.email/cgit/dmidecode.git/
Homepage: https://nongnu.org/dmidecode/
diff --git a/debian/copyright b/debian/copyright
index 6a6a15f..fc67c0a 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -4,16 +4,17 @@ Upstream-Contact: dmidecode-devel@nongnu.org
Source: http://download.savannah.gnu.org/releases/demidecode/
Files: *
-Copyright: 2002-2024 Jean Delvare <jdelvare@suse.de>
+Copyright: 2002-2025 Jean Delvare <jdelvare@suse.de>
2002 Alan Cox <alan@redhat.com>
2010 Anton Arapov <anton@redhat.com>
2015 Xie XiuQi <xiexiuqi@huawei.com>
+ 2017-2025 Jerry Hoemann <jerry.hoemann@hpe.com>
License: GPL-2+
Files: debian/*
Copyright: 2003-2007 Petter Reinholdtsen <pere@debian.org>
2011-2012 Daniel Baumann <daniel.baumann@progress-technologies.net>
- 2014-2024 Jörg Frings-Fürst <debian@jff.email>
+ 2014-2026 Jörg Frings-Fürst <debian@jff.email>
License: GPL-2+
License: GPL-2+
diff --git a/debian/files b/debian/files
deleted file mode 100644
index ab29bff..0000000
--- a/debian/files
+++ /dev/null
@@ -1 +0,0 @@
-dmidecode_3.6-2_source.buildinfo utils optional
diff --git a/debian/patches/0001-hurd.patch b/debian/patches/0001-hurd.patch
index 0abfea9..6df550a 100644
--- a/debian/patches/0001-hurd.patch
+++ b/debian/patches/0001-hurd.patch
@@ -5,7 +5,7 @@ Index: trunk/Makefile
===================================================================
--- trunk.orig/Makefile
+++ trunk/Makefile
-@@ -45,7 +45,7 @@ INSTALL_PROGRAM := $(INSTALL) -m 755
+@@ -42,7 +42,7 @@ INSTALL_PROGRAM := $(INSTALL) -m 755
RM := rm -f
# BSD make provides $MACHINE, but GNU make doesn't
diff --git a/debian/patches/0005-build.patch b/debian/patches/0005-build.patch
deleted file mode 100644
index b9361eb..0000000
--- a/debian/patches/0005-build.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Author: Daniel Baumann <daniel.baumann@progress-technologies.net>
-Description: Avoid overwriting build environment rather than to just extend it.
-
-Index: trunk/Makefile
-===================================================================
---- trunk.orig/Makefile
-+++ trunk/Makefile
-@@ -13,7 +13,7 @@
- #
-
- CC = gcc
--CFLAGS = -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
-+CFLAGS += -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \
- -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef
-
- # Let lseek and mmap support 64-bit wide offsets
-@@ -27,7 +27,7 @@ CFLAGS += -O2
- #CFLAGS += -g
-
- # Pass linker flags here
--LDFLAGS =
-+#LDFLAGS =
-
- DESTDIR =
- prefix = /usr/local
diff --git a/debian/patches/0100-ansi-c.patch b/debian/patches/0100-ansi-c.patch
deleted file mode 100644
index 9a2345c..0000000
--- a/debian/patches/0100-ansi-c.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Author: Petter Reinholdtsen <pere@hungry.com>
-Description:
- Make sure the code compiles when using -ansi. Renames non-ANSI C 'inline' to
- '__inline'.
-
-Index: trunk/types.h
-===================================================================
---- trunk.orig/types.h
-+++ trunk/types.h
-@@ -31,7 +31,7 @@ typedef struct {
- #endif
-
- #if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN)
--static inline u64 U64(u32 low, u32 high)
-+static __inline u64 U64(u32 low, u32 high)
- {
- u64 self;
-
diff --git a/debian/patches/0105-dmidecode-avoid-sigbus.patch b/debian/patches/0105-dmidecode-avoid-sigbus.patch
deleted file mode 100644
index 518d972..0000000
--- a/debian/patches/0105-dmidecode-avoid-sigbus.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-Description: Avoid SIGBUS on mmap failure
- mmap will fail with SIGBUS if trying to map a non-existent portion of
- a file. While this should never happen with /dev/mem, it can happen if
- passing a regular file with option -d. While people should no longer
- do that, failure gracefully seems better than crashing. So check for
- the file size before calling mmap.
-Author: Jean Delvare <jdelvare@suse.de>
-Origin: https://savannah.nongnu.org/bugs/download.php?file_id=35008
-Bug: https://savannah.nongnu.org/bugs/index.php?46066
-Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=796963
-Last-Update: 2015-10-01
-----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
---- dmidecode.orig/util.c 2015-09-29 11:27:02.136566009 +0200
-+++ dmidecode/util.c 2015-09-29 11:37:24.746191083 +0200
-@@ -152,6 +152,7 @@ void *mem_chunk(off_t base, size_t len,
- void *p;
- int fd;
- #ifdef USE_MMAP
-+ struct stat statbuf;
- off_t mmoffset;
- void *mmp;
- #endif
-@@ -169,6 +170,26 @@ void *mem_chunk(off_t base, size_t len,
- }
-
- #ifdef USE_MMAP
-+ if (fstat(fd, &statbuf) == -1)
-+ {
-+ fprintf(stderr, "%s: ", devmem);
-+ perror("stat");
-+ free(p);
-+ return NULL;
-+ }
-+
-+ /*
-+ * mmap() will fail with SIGBUS if trying to map beyond the end of
-+ * the file.
-+ */
-+ if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size)
-+ {
-+ fprintf(stderr, "mmap: Can't map beyond end of file %s\n",
-+ devmem);
-+ free(p);
-+ return NULL;
-+ }
-+
- #ifdef _SC_PAGESIZE
- mmoffset = base % sysconf(_SC_PAGESIZE);
- #else
diff --git a/debian/patches/0110-nosysfs.patch b/debian/patches/0110-nosysfs.patch
deleted file mode 100644
index 04c710a..0000000
--- a/debian/patches/0110-nosysfs.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 33b5aafc6ee6b5de9f2526fb1cf4b14d1e16e4f0 Mon Sep 17 00:00:00 2001
-From: Roy Franz <roy.franz@linaro.org>
-Date: Thu, 01 Oct 2015 06:41:43 +0000
-Subject: Add "--no-sysfs" option description to -h output
-
-A description of --no-sysfs was not added to the output of "-h" when
-the feature was added, so add it now.
----
-Index: trunk/CHANGELOG
-===================================================================
---- trunk.orig/CHANGELOG
-+++ trunk/CHANGELOG
-@@ -1,3 +1,7 @@
-+2015-10-01 Roy Franz <roy.franz@linaro.org>
-+
-+ * dmiopt.c: Add "--no-sysfs" option description to -h output.
-+
- 2015-09-03 Jean Delvare <jdelvare@suse.de>
-
- * version.h: Set version to 3.0.
-Index: trunk/dmiopt.c
-===================================================================
---- trunk.orig/dmiopt.c
-+++ trunk/dmiopt.c
-@@ -314,6 +314,7 @@ void print_help(void)
- " -u, --dump Do not decode the entries\n"
- " --dump-bin FILE Dump the DMI data to a binary file\n"
- " --from-dump FILE Read the DMI data from a binary file\n"
-+ " --no-sysfs Do not attempt to read DMI data from sysfs files\n"
- " -V, --version Display the version and exit\n";
-
- printf("%s", help);
diff --git a/debian/patches/0115-no_smbios_DMI_entry_point.patch b/debian/patches/0115-no_smbios_DMI_entry_point.patch
deleted file mode 100644
index ecbfc11..0000000
--- a/debian/patches/0115-no_smbios_DMI_entry_point.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From bf7bad24ce141dab5b5acc3ffb98ce5fe4a8e0f9 Mon Sep 17 00:00:00 2001
-From: Xie XiuQi <xiexiuqi@huawei.com>
-Date: Wed, 21 Oct 2015 13:12:50 +0000
-Subject: Fix 'No SMBIOS nor DMI entry point found' on SMBIOS3
-
-address_from_efi may return a SMBIOS or SMBIOS3 format entry
-point, so add this condition.
----
-Index: trunk/AUTHORS
-===================================================================
---- trunk.orig/AUTHORS
-+++ trunk/AUTHORS
-@@ -19,6 +19,7 @@ Jarod Wilson <jarod@redhat.com>
- Anton Arapov <anton@redhat.com>
- Roy Franz <roy.franz@linaro.org>
- Tyler Bell <tyler.bell@hp.com>
-+Xie XiuQi <xiexiuqi@huawei.com>
-
- MANY THANKS TO (IN CHRONOLOGICAL ORDER)
- Werner Heuser
-Index: trunk/CHANGELOG
-===================================================================
---- trunk.orig/CHANGELOG
-+++ trunk/CHANGELOG
-@@ -1,3 +1,7 @@
-+2015-10-21 Xie XiuQi <xiexiuqi@huawei.com>
-+
-+ * dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
-+
- 2015-10-01 Roy Franz <roy.franz@linaro.org>
-
- * dmiopt.c: Add "--no-sysfs" option description to -h output.
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -4864,8 +4864,16 @@ int main(int argc, char * const argv[])
- goto exit_free;
- }
-
-- if (smbios_decode(buf, opt.devmem, 0))
-- found++;
-+ if (memcmp(buf, "_SM3_", 5) == 0)
-+ {
-+ if (smbios3_decode(buf, opt.devmem, 0))
-+ found++;
-+ }
-+ else if (memcmp(buf, "_SM_", 4) == 0)
-+ {
-+ if (smbios_decode(buf, opt.devmem, 0))
-+ found++;
-+ }
- goto done;
-
- memory_scan:
diff --git a/debian/patches/0120-return_actual_data_size.patch b/debian/patches/0120-return_actual_data_size.patch
deleted file mode 100644
index dc539d9..0000000
--- a/debian/patches/0120-return_actual_data_size.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From de9a74e1c60210bee229fcf55b1678a99d1b44dd Mon Sep 17 00:00:00 2001
-From: Jean Delvare <jdelvare@suse.de>
-Date: Mon, 02 Nov 2015 08:45:26 +0000
-Subject: Let read_file return the actual data size
-
-Let read_file return the actual data size to the caller. This gives
-the caller the possibility to check that the data size is as expected
-and large enough for the purpose, and report to the user if not.
----
-Index: trunk/CHANGELOG
-===================================================================
---- trunk.orig/CHANGELOG
-+++ trunk/CHANGELOG
-@@ -1,3 +1,8 @@
-+2015-11-02 Jean Delvare <jdelvare@suse.de>
-+
-+ * dmidecode.c, util.c, util.h: Let read_file return the actual data
-+ size.
-+
- 2015-10-21 Xie XiuQi <xiexiuqi@huawei.com>
-
- * dmidecode.c: Handle SMBIOS 3.0 entry points on EFI systems.
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -4748,6 +4748,7 @@ int main(int argc, char * const argv[])
- int ret = 0; /* Returned value */
- int found = 0;
- off_t fp;
-+ size_t size;
- int efi;
- u8 *buf;
-
-@@ -4817,8 +4818,9 @@ int main(int argc, char * const argv[])
- * contain one of several types of entry points, so read enough for
- * the largest one, then determine what type it contains.
- */
-+ size = 0x20;
- if (!(opt.flags & FLAG_NO_SYSFS)
-- && (buf = read_file(0x20, SYS_ENTRY_FILE)) != NULL)
-+ && (buf = read_file(&size, SYS_ENTRY_FILE)) != NULL)
- {
- if (!(opt.flags & FLAG_QUIET))
- printf("Getting SMBIOS data from sysfs.\n");
-Index: trunk/util.c
-===================================================================
---- trunk.orig/util.c
-+++ trunk/util.c
-@@ -94,10 +94,11 @@ int checksum(const u8 *buf, size_t len)
- * needs to be freed by the caller.
- * This provides a similar usage model to mem_chunk()
- *
-- * Returns pointer to buffer of max_len bytes, or NULL on error
-+ * Returns pointer to buffer of max_len bytes, or NULL on error, and
-+ * sets max_len to the length actually read.
- *
- */
--void *read_file(size_t max_len, const char *filename)
-+void *read_file(size_t *max_len, const char *filename)
- {
- int fd;
- size_t r2 = 0;
-@@ -115,7 +116,7 @@ void *read_file(size_t max_len, const ch
- return(NULL);
- }
-
-- if ((p = malloc(max_len)) == NULL)
-+ if ((p = malloc(*max_len)) == NULL)
- {
- perror("malloc");
- return NULL;
-@@ -123,7 +124,7 @@ void *read_file(size_t max_len, const ch
-
- do
- {
-- r = read(fd, p + r2, max_len - r2);
-+ r = read(fd, p + r2, *max_len - r2);
- if (r == -1)
- {
- if (errno != EINTR)
-@@ -140,6 +141,8 @@ void *read_file(size_t max_len, const ch
- while (r != 0);
-
- close(fd);
-+ *max_len = r2;
-+
- return p;
- }
-
-Index: trunk/util.h
-===================================================================
---- trunk.orig/util.h
-+++ trunk/util.h
-@@ -25,7 +25,7 @@
- #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-
- int checksum(const u8 *buf, size_t len);
--void *read_file(size_t len, const char *filename);
-+void *read_file(size_t *len, const char *filename);
- void *mem_chunk(off_t base, size_t len, const char *devmem);
- int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add);
- u64 u64_range(u64 start, u64 end);
diff --git a/debian/patches/0125-use_read_file_to_read_DMI_table_from_sysfs.patch b/debian/patches/0125-use_read_file_to_read_DMI_table_from_sysfs.patch
deleted file mode 100644
index fe01f63..0000000
--- a/debian/patches/0125-use_read_file_to_read_DMI_table_from_sysfs.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 364055211b1956539c6a6268e111e244e1292c8c Mon Sep 17 00:00:00 2001
-From: Jean Delvare <jdelvare@suse.de>
-Date: Mon, 02 Nov 2015 08:45:31 +0000
-Subject: dmidecode: Use read_file() to read the DMI table from sysfs
-
-We shouldn't use mem_chunk() to read the DMI table from sysfs. This
-will fail for SMBIOS v3 implementations which specify a maximum length
-for the table rather than its exact length. The kernel will trim the
-table to the actual length, so the DMI file will be shorter than the
-length announced in entry point.
-
-read_file() fits the bill in this case, as it deals with end of file
-nicely.
-
-This also helps with corrupted DMI tables, as the kernel will not
-export the part of the table that it wasn't able to parse, effectively
-trimming it.
-
-This fixes bug #46176:
-https://savannah.nongnu.org/bugs/?46176
-Unexpected end of file error
----
-Index: trunk/CHANGELOG
-===================================================================
---- trunk.orig/CHANGELOG
-+++ trunk/CHANGELOG
-@@ -2,6 +2,9 @@
-
- * dmidecode.c, util.c, util.h: Let read_file return the actual data
- size.
-+ * dmidecode.c: Use read_file to read the DMI table from sysfs.
-+ This fixes Savannah bug #46176:
-+ https://savannah.nongnu.org/bugs/?46176
-
- 2015-10-21 Xie XiuQi <xiexiuqi@huawei.com>
-
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -4521,16 +4521,29 @@ static void dmi_table(off_t base, u32 le
- printf("\n");
- }
-
-- /*
-- * When we are reading the DMI table from sysfs, we want to print
-- * the address of the table (done above), but the offset of the
-- * data in the file is 0. When reading from /dev/mem, the offset
-- * in the file is the address.
-- */
- if (flags & FLAG_NO_FILE_OFFSET)
-- base = 0;
-+ {
-+ /*
-+ * When reading from sysfs, the file may be shorter than
-+ * announced. For SMBIOS v3 this is expcted, as we only know
-+ * the maximum table size, not the actual table size. For older
-+ * implementations (and for SMBIOS v3 too), this would be the
-+ * result of the kernel truncating the table on parse error.
-+ */
-+ size_t size = len;
-+ buf = read_file(&size, devmem);
-+ if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
-+ {
-+ printf("Wrong DMI structures length: %u bytes "
-+ "announced, only %lu bytes available.\n",
-+ len, (unsigned long)size);
-+ }
-+ len = size;
-+ }
-+ else
-+ buf = mem_chunk(base, len, devmem);
-
-- if ((buf = mem_chunk(base, len, devmem)) == NULL)
-+ if (buf == NULL)
- {
- fprintf(stderr, "Table is unreachable, sorry."
- #ifndef USE_MMAP
diff --git a/debian/patches/0130-use_DWORD_for_table_max_size.patch b/debian/patches/0130-use_DWORD_for_table_max_size.patch
deleted file mode 100644
index 715d137..0000000
--- a/debian/patches/0130-use_DWORD_for_table_max_size.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From ab02b117511230e46bbef7febbd854b9c832c13c Mon Sep 17 00:00:00 2001
-From: Xie XiuQi <xiexiuqi@huawei.com>
-Date: Mon, 01 Feb 2016 08:30:31 +0000
-Subject: Use DWORD for Structure table maximum size in SMBIOS3
-
-0Ch DWORD "Structure table maximum size"
-
-Maximum size of SMBIOS Structure Table, pointed to by
-the Structure Table Address, in bytes. The actual size is
-guaranteed to be less or equal to the maximum size.
-
-Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
-Signed-off-by: Jean Delvare <jdelvare@suse.de>
----
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -4612,7 +4612,7 @@ static int smbios3_decode(u8 *buf, const
- }
-
- dmi_table(((off_t)offset.h << 32) | offset.l,
-- WORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
-+ DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
-
- if (opt.flags & FLAG_DUMP_BIN)
- {
diff --git a/debian/patches/0135-hide_fixup_msg.patch b/debian/patches/0135-hide_fixup_msg.patch
deleted file mode 100644
index ff3122c..0000000
--- a/debian/patches/0135-hide_fixup_msg.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From cff11afa886a0147d734b650755d232b5e7f2099 Mon Sep 17 00:00:00 2001
-From: Jean Delvare <jdelvare@suse.de>
-Date: Tue, 03 May 2016 13:32:21 +0000
-Subject: dmidecode: Hide irrelevant fixup message
-
-Only display the message about type 34 length fixup if the entry in
-question is going to be displayed. Otherwise it's only confusing.
-
-This fixes bug #109024:
-http://savannah.nongnu.org/support/?109024
-
-Fixes: 3f70b3515d91 ("dmidecode: Fix up invalid DMI type 34 structure length")
----
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -2946,7 +2946,7 @@ static void dmi_64bit_memory_error_addre
- * first 5 characters of the device name to be trimmed. It's easy to
- * check and fix, so do it, but warn.
- */
--static void dmi_fixup_type_34(struct dmi_header *h)
-+static void dmi_fixup_type_34(struct dmi_header *h, int display)
- {
- u8 *p = h->data;
-
-@@ -2954,7 +2954,9 @@ static void dmi_fixup_type_34(struct dmi
- if (h->length == 0x10
- && is_printable(p + 0x0B, 0x10 - 0x0B))
- {
-- printf("Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B);
-+ if (!(opt.flags & FLAG_QUIET) && display)
-+ printf("Invalid entry length (%u). Fixed up to %u.\n",
-+ 0x10, 0x0B);
- h->length = 0x0B;
- }
- }
-@@ -4443,7 +4445,7 @@ static void dmi_table_decode(u8 *buf, u3
-
- /* Fixup a common mistake */
- if (h.type == 34)
-- dmi_fixup_type_34(&h);
-+ dmi_fixup_type_34(&h, display);
-
- /* look for the next handle */
- next = data + h.length;
diff --git a/debian/patches/0140-Fix_scan_entry_point.patch b/debian/patches/0140-Fix_scan_entry_point.patch
deleted file mode 100644
index 4183af5..0000000
--- a/debian/patches/0140-Fix_scan_entry_point.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-Description: Cherry picked fix Only scan /dev/mem for entry point on x86
-Author: <name and email of author, optional>
-Origin: upstream, http://git.savannah.nongnu.org/cgit/dmidecode.git/commit/?id=e12ec26e19e02281d3e7258c3aabb88a5cf5ec1d
-Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=946911
-Last-Update: 2019-12-19
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -2,7 +2,7 @@
- * DMI Decode
- *
- * Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
-- * Copyright (C) 2002-2018 Jean Delvare <jdelvare@suse.de>
-+ * Copyright (C) 2002-2019 Jean Delvare <jdelvare@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
-@@ -5534,7 +5534,7 @@ int main(int argc, char * const argv[])
- off_t fp;
- size_t size;
- int efi;
-- u8 *buf;
-+ u8 *buf = NULL;
-
- /*
- * We don't want stdout and stderr to be mixed up if both are
-@@ -5638,7 +5638,7 @@ int main(int argc, char * const argv[])
- printf("Failed to get SMBIOS data from sysfs.\n");
- }
-
-- /* Next try EFI (ia64, Intel-based Mac) */
-+ /* Next try EFI (ia64, Intel-based Mac, arm64) */
- efi = address_from_efi(&fp);
- switch (efi)
- {
-@@ -5671,6 +5671,7 @@ int main(int argc, char * const argv[])
- goto done;
-
- memory_scan:
-+#if defined __i386__ || defined __x86_64__
- if (!(opt.flags & FLAG_QUIET))
- printf("Scanning %s for entry point.\n", opt.devmem);
- /* Fallback to memory scan (x86, x86_64) */
-@@ -5713,6 +5714,7 @@ memory_scan:
- }
- }
- }
-+#endif
-
- done:
- if (!found && !(opt.flags & FLAG_QUIET))
diff --git a/debian/patches/0145-Fix_condition_error_in_ascii_filter.patch b/debian/patches/0145-Fix_condition_error_in_ascii_filter.patch
deleted file mode 100644
index c7d976e..0000000
--- a/debian/patches/0145-Fix_condition_error_in_ascii_filter.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Description: Fix the condition error in ascii_filter
-Origin: upstream, http://git.savannah.gnu.org/cgit/dmidecode.git/commit/?id=1117390ccd9cea139638db6f460bb6de70e28f94
-Last-Update: 2021-05-07
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -116,7 +116,7 @@ static void ascii_filter(char *bp, size_
- size_t i;
-
- for (i = 0; i < len; i++)
-- if (bp[i] < 32 || bp[i] == 127)
-+ if (bp[i] < 32 || bp[i] >= 127)
- bp[i] = '.';
- }
-
diff --git a/debian/patches/0150-Fix_crash.patch b/debian/patches/0150-Fix_crash.patch
deleted file mode 100644
index c6c5af7..0000000
--- a/debian/patches/0150-Fix_crash.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Description: Fix crash with -u option
-Origin: upstream, http://git.savannah.gnu.org/cgit/dmidecode.git/commit/?id=11e134e54d15e67a64c39a623f492a28df922517
-Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=987033
-Last-Update: 2021-05-07
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -248,9 +248,9 @@ static void dmi_dump(const struct dmi_he
- {
- int j, l = strlen(s) + 1;
-
-- off = 0;
- for (row = 0; row < ((l - 1) >> 4) + 1; row++)
- {
-+ off = 0;
- for (j = 0; j < 16 && j < l - (row << 4); j++)
- off += sprintf(raw_data + off,
- j ? " %02X" : "%02X",
diff --git a/debian/patches/0155-use_read_file.patch b/debian/patches/0155-use_read_file.patch
deleted file mode 100644
index 18b1fb3..0000000
--- a/debian/patches/0155-use_read_file.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-Description: Use read_file() instead of mem_chunk()
-Origin: upstream, https://git.savannah.gnu.org/cgit/dmidecode.git/commit/?id=c76ddda0ba0aa99a55945e3290095c2ec493c892
-Forwarded: not-needed
-Last-Update: 2023-07-15
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/dmidecode.c
-===================================================================
---- trunk.orig/dmidecode.c
-+++ trunk/dmidecode.c
-@@ -6025,15 +6025,23 @@ int main(int argc, char * const argv[])
- pr_comment("dmidecode %s", VERSION);
-
- /* Read from dump if so instructed */
-+ size = 0x20;
- if (opt.flags & FLAG_FROM_DUMP)
- {
- if (!(opt.flags & FLAG_QUIET))
- pr_info("Reading SMBIOS/DMI data from file %s.",
- opt.dumpfile);
-- if ((buf = mem_chunk(0, 0x20, opt.dumpfile)) == NULL)
-+ if ((buf = read_file(0, &size, opt.dumpfile)) == NULL)
- {
- ret = 1;
- goto exit_free;
-+ }
-+
-+ /* Truncated entry point can't be processed */
-+ if (size < 0x20)
-+ {
-+ ret = 1;
-+ goto done;
- }
-
- if (memcmp(buf, "_SM3_", 5) == 0)
-@@ -6059,7 +6067,6 @@ int main(int argc, char * const argv[])
- * contain one of several types of entry points, so read enough for
- * the largest one, then determine what type it contains.
- */
-- size = 0x20;
- if (!(opt.flags & FLAG_NO_SYSFS)
- && (buf = read_file(0, &size, SYS_ENTRY_FILE)) != NULL)
- {
diff --git a/debian/patches/0160-HPE_OEM_Firmware_change.patch b/debian/patches/0160-HPE_OEM_Firmware_change.patch
deleted file mode 100644
index 075b566..0000000
--- a/debian/patches/0160-HPE_OEM_Firmware_change.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-Description: HPE OEM Record 237 Firmware change
-Origin: upstream, http://git.savannah.gnu.org/cgit/dmidecode.git/commit/?id=80de376231e903d2cbea95e51ffea31860502159
-Forwarded: not-needed
-Last-Update: 2023-07-15
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/dmioem.c
-===================================================================
---- trunk.orig/dmioem.c
-+++ trunk/dmioem.c
-@@ -1094,7 +1094,8 @@ static int dmi_decode_hp(const struct dm
- * 0x06 | Manufacture|STRING | DIMM Manufacturer
- * 0x07 | Part Number|STRING | DIMM Manufacturer's Part Number
- * 0x08 | Serial Num |STRING | DIMM Vendor Serial Number
-- * 0x09 | Spare Part |STRING | DIMM Spare Part Number
-+ * 0x09 | Man Date | BYTE | DIMM Manufacture Date (YEAR) in BCD
-+ * 0x0A | Man Date | BYTE | DIMM Manufacture Date (WEEK) in BCD
- */
- if (gen < G9) return 0;
- pr_handle_name("%s DIMM Vendor Information", company);
-@@ -1105,8 +1106,9 @@ static int dmi_decode_hp(const struct dm
- pr_attr("DIMM Manufacturer Part Number", "%s", dmi_string(h, data[0x07]));
- if (h->length < 0x09) break;
- pr_attr("DIMM Vendor Serial Number", "%s", dmi_string(h, data[0x08]));
-- if (h->length < 0x0A) break;
-- pr_attr("DIMM Spare Part Number", "%s", dmi_string(h, data[0x09]));
-+ if (h->length < 0x0B) break;
-+ if (WORD(data + 0x09))
-+ pr_attr("DIMM Manufacture Date", "20%02x-W%02x", data[0x09], data[0x0A]);
- break;
-
- case 238:
diff --git a/debian/patches/0600-Fix-groff-error.patch b/debian/patches/0600-Fix-groff-error.patch
deleted file mode 100644
index ce5f561..0000000
--- a/debian/patches/0600-Fix-groff-error.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Description: dmidecode.8 Fix groff error
-Author: Soren Stoutner <soren@debian.org>
-Forwarded: https://savannah.nongnu.org/patch/index.php?10463
-Last-Update: 2024-07-07
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
-Index: trunk/man/dmidecode.8
-===================================================================
---- trunk.orig/man/dmidecode.8
-+++ trunk/man/dmidecode.8
-@@ -1,3 +1,5 @@
-+'\" t
-+.\" ** The above line should force tbl to be a preprocessor **
- .TH DMIDECODE 8 "February 2023" "dmidecode"
- .\"
- .SH NAME
diff --git a/debian/patches/0605-man.patch b/debian/patches/0605-man.patch
new file mode 100644
index 0000000..b8808ec
--- /dev/null
+++ b/debian/patches/0605-man.patch
@@ -0,0 +1,319 @@
+Description: Some remarks and editorial changes
+Author: Bjarni Ingi Gislason <bjarniig@simnet.is>
+Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1088088
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1088088
+Forwarded: no: due to constant network errors
+Last-Update: 2026-03-10
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+Index: trunk/man/dmidecode.8
+===================================================================
+--- trunk.orig/man/dmidecode.8
++++ trunk/man/dmidecode.8
+@@ -45,39 +45,52 @@ Base Board Information
+
+ Each record has:
+ .IP \(bu "\w'\(bu'u+1n"
+-A handle. This is a unique identifier, which allows records to
+-reference each other. For example, processor records usually reference
+-cache memory records using their handles.
++A handle.
++This is a unique identifier,
++which allows records to reference each other.
++For example,
++processor records usually reference cache memory records
++using their handles.
+ .IP \(bu
+-A type. The \s-1SMBIOS\s0 specification defines different types of elements
+-a computer can be made of. In this example, the type is 2, which
+-means that the record contains "Base Board Information".
++A type.
++The \s-1SMBIOS\s0 specification defines different types of elements
++a computer can be made of.
++In this example,
++the type is 2,
++which means that the record contains "Base Board Information".
+ .IP \(bu
+-A size. Each record has a 4-byte header (2 for the handle, 1 for the type,
+-1 for the size), the rest is used by the record data. This value doesn't
+-take text strings into account (these are placed at the end of the record),
+-so the actual length of the record may be (and is often) greater than the
+-displayed value.
++A size.
++Each record has a 4-byte header
++(2 for the handle, 1 for the type, 1 for the size),
++the rest is used by the record data.
++This value doesn't take text strings into account
++(these are placed at the end of the record),
++so the actual length of the record may be
++(and is often)
++greater than the displayed value.
+ .IP \(bu
+-Decoded values. The information presented of course depends on the type
+-of record. Here, we learn about the board's manufacturer, model, version
+-and serial number.
++Decoded values.
++The information presented of course depends on the type of record.
++Here, we learn about the board's manufacturer,
++model, version and serial number.
+ .\"
+ .SH OPTIONS
+ .TP
+-.BR "-d" ", " "--dev-mem \fIFILE\fP"
++.BR "\-d" ", " "\-\-dev-mem \fIFILE\fP"
+ Read memory from device \fIFILE\fP (default: \fI/dev/mem\fP)
+ .TP
+-.BR "-q" ", " "--quiet"
+-Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not
+-displayed. Meta-data and handle references are hidden.
+-.TP
+-.BR " " " " "--no-quirks"
+-Decode everything exactly as it is in the table, without trying to fix up
+-common mistakes or hide irrelevant fields.
++.BR "\-q" ", " "\-\-quiet"
++Be less verbose.
++Unknown, inactive and \s-1OEM\s0-specific entries are not displayed.
++Meta-data and handle references are hidden.
++.TP
++.BR " " " " "\-\-no-quirks"
++Decode everything exactly as it is in the table,
++without trying to fix up common mistakes
++or hide irrelevant fields.
+ This mode is primarily aimed at firmware developers.
+ .TP
+-.BR "-s" ", " "--string \fIKEYWORD\fP"
++.BR "\-s" ", " "\-\-string \fIKEYWORD\fP"
+ Only display the value of the \s-1DMI\s0 string identified by \fIKEYWORD\fP.
+ It must be a keyword from the following list:
+ .nh
+@@ -113,33 +126,35 @@ firmware (regardless of it technically i
+ while "firmware" designates the embedded controller firmware, if applicable.
+ Each keyword corresponds to a given \s-1DMI\s0 type and a given offset
+ within this entry type.
+-Not all strings may be meaningful or even defined on all systems. Some
+-keywords may return more than one result on some systems (e.g.
++Not all strings may be meaningful or even defined on all systems.
++Some keywords may return more than one result on some systems
++(e.g.,
+ .nh
+ .B processor\-version
+ .hy
+ on a multi-processor system).
+-If \fIKEYWORD\fP is not provided or not valid, a list of all valid
+-keywords is printed and
++If \fIKEYWORD\fP is not provided or not valid,
++a list of all valid keywords is printed and
+ .B dmidecode
+ exits with an error.
+ This option cannot be used more than once.
+
+-Note: on Linux, most of these strings can alternatively be read directly
+-from
++Note: on Linux,
++most of these strings can alternatively be read directly from
+ .BR sysfs ,
+ typically from files under
+ .IR /sys/devices/virtual/dmi/id .
+ Most of these files are even readable by regular users.
+ .TP
+-.BR " " " " "--list-strings"
+-List available string keywords, which can then be passed to the \fB--string\fP
+-option.
+-.TP
+-.BR "-t" ", " "--type \fITYPE\fP"
+-Only display the entries of type \fITYPE\fP. It can be either a
+-\s-1DMI\s0 type number, or a comma-separated list of type numbers, or a
+-keyword from the following list:
++.BR " " " " "\-\-list-strings"
++List available string keywords,
++which can then be passed to the \fB\-\-string\fP option.
++.TP
++.BR "\-t" ", " "\-\-type \fITYPE\fP"
++Only display the entries of type \fITYPE\fP.
++It can be either a \s-1DMI\s0 type number,
++or a comma-separated list of type numbers,
++or a keyword from the following list:
+ .nh
+ .BR bios ,
+ .BR system ,
+@@ -169,49 +184,54 @@ option.
+ Only display the entry whose handle matches \fIHANDLE\fP.
+ \fIHANDLE\fP is a 16-bit integer.
+ .TP
+-.BR "-u" ", " "--dump"
+-Do not decode the entries, dump their contents as hexadecimal instead.
+-Note that this is still a text output, no binary data will be thrown upon
+-you. The strings attached to each entry are displayed as both
+-hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging.
+-.TP
+-.BR " " " " "--dump-bin \fIFILE\fP"
+-Do not decode the entries, instead dump the DMI data to a file in binary
+-form. The generated file is suitable to pass to \fB--from-dump\fP
+-later.
++.BR "\-u" ", " "\-\-dump"
++Do not decode the entries,
++dump their contents as hexadecimal instead.
++Note that this is still a text output,
++no binary data will be thrown upon you.
++The strings attached to each entry
++are displayed as both hexadecimal and \s-1ASCII\s0.
++This option is mainly useful for debugging.
++.TP
++.BR " " " " "\-\-dump-bin \fIFILE\fP"
++Do not decode the entries,
++instead dump the DMI data to a file in binary form.
++The generated file is suitable to pass to \fB\-\-from-dump\fP later.
+ \fIFILE\fP must not exist.
+ .TP
+-.BR " " " " "--from-dump \fIFILE\fP"
++.BR " " " " "\-\-from-dump \fIFILE\fP"
+ Read the DMI data from a binary file previously generated using
+-\fB--dump-bin\fP.
++\fB\-\-dump-bin\fP.
+ .TP
+-.BR " " " " "--no-sysfs"
+-Do not attempt to read DMI data from sysfs files. This is mainly useful for
+-debugging.
+-.TP
+-.BR " " " " "--oem-string \fIN\fP"
+-Only display the value of the \s-1OEM\s0 string number \fIN\fP. The first
+-\s-1OEM\s0 string has number \fB1\fP. With special value \fBcount\fP, return the
+-number of OEM strings instead.
++.BR " " " " "\-\-no-sysfs"
++Do not attempt to read DMI data from sysfs files.
++This is mainly useful for debugging.
++.TP
++.BR " " " " "\-\-oem-string \fIN\fP"
++Only display the value of the \s-1OEM\s0 string number \fIN\fP.
++The first \s-1OEM\s0 string has number \fB1\fP.
++With special value \fBcount\fP,
++return the number of OEM strings instead.
+ .TP
+-.BR "-h" ", " "--help"
++.BR "\-h" ", " "\-\-help"
+ Display usage information and exit
+ .TP
+-.BR "-V" ", " "--version"
++.BR "\-V" ", " "\-\-version"
+ Display the version and exit
+ .P
+ Options
+-.BR --string ,
+-.BR --type,
+-.BR --dump-bin " and " --oem-string
++.BR \-\-string ,
++.BR \-\-type,
++.BR \-\-dump-bin " and " \-\-oem-string
+ determine the output format and are mutually exclusive.
+ .P
+ Please note in case of
+ .B dmidecode
+-is run on a system with firmware that boasts new SMBIOS specification, which
+-is not supported by the tool yet, it will print out relevant message in
+-addition to requested data on the very top of the output. Thus informs the
+-output data is not reliable.
++is run on a system with BIOS that boasts new SMBIOS specification,
++which is not supported by the tool yet,
++it will print out relevant message
++in addition to requested data on the very top of the output.
++Thus informs the output data is not reliable.
+ .\"
+ .SH "DMI TYPES"
+ The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types:
+@@ -265,13 +285,15 @@ Type Information
+ 42 Management Controller Host Interface
+ .TE
+
+-Additionally, type 126 is used for disabled entries and type 127 is an
+-end-of-table marker. Types 128 to 255 are for \s-1OEM\s0-specific data.
++Additionally, type 126 is used for disabled entries
++and type 127 is an end-of-table marker.
++Types 128 to 255 are for \s-1OEM\s0-specific data.
+ .B dmidecode
+-will display these entries by default, but it can only decode them
++will display these entries by default,
++but it can only decode them
+ when the vendors have contributed documentation or code for them.
+
+-Keywords can be used instead of type numbers with \fB--type\fP.
++Keywords can be used instead of type numbers with \fB\-\-type\fP.
+ Each keyword is equivalent to a list of type numbers:
+
+ .TS
+@@ -290,18 +312,20 @@ connector 8
+ slot 9
+ .TE
+
+-Keywords are matched case-insensitively. The following command lines are equivalent:
++Keywords are matched case-insensitively.
++The following command lines are equivalent:
+ .IP \(bu "\w'\(bu'u+1n"
+-dmidecode --type 0 --type 13
++dmidecode \-\-type 0 \-\-type 13
+ .IP \(bu
+-dmidecode --type 0,13
++dmidecode \-\-type 0,13
+ .IP \(bu
+-dmidecode --type bios
++dmidecode \-\-type bios
+ .IP \(bu
+-dmidecode --type BIOS
++dmidecode \-\-type BIOS
+ .\"
+ .SH BINARY DUMP FILE FORMAT
+-The binary dump files generated by \fB--dump-bin\fP and read using \fB--from-dump\fP
++The binary dump files generated by \fB\-\-dump-bin\fP
++and read using \fB\-\-from-dump\fP
+ are formatted as follows:
+ .IP \(bu "\w'\(bu'u+1n"
+ The SMBIOS or DMI entry point is located at offset 0x00.
+@@ -310,18 +334,27 @@ It is crafted to hard-code the table add
+ The DMI table is located at offset 0x20.
+ .\"
+ .SH UUID FORMAT
+-There is some ambiguity about how to interpret the UUID fields prior to SMBIOS
+-specification version 2.6. There was no mention of byte swapping, and RFC 4122
+-says that no byte swapping should be applied by default. However, SMBIOS
+-specification version 2.6 (and later) explicitly states that the first 3 fields
+-of the UUID should be read as little-endian numbers (byte-swapped).
+-Furthermore, it implies that the same was already true for older versions of
+-the specification, even though it was not mentioned. In practice, many hardware
+-vendors were not byte-swapping the UUID. So, in order to preserve
+-compatibility, it was decided to interpret the UUID fields according to RFC
+-4122 (no byte swapping) when the SMBIOS version is older than 2.6, and to
+-interpret the first 3 fields as little-endian (byte-swapped) when the SMBIOS
+-version is 2.6 or later. The Linux kernel follows the same logic.
++There is some ambiguity about how to interpret the UUID fields prior to
++SMBIOS specification version 2.6.
++There was no mention of byte swapping,
++and RFC 4122 says that no byte swapping should be applied by default.
++However, SMBIOS specification version 2.6 (and later)
++explicitly states
++that the first 3 fields of the UUID should be read as little-endian numbers
++(byte-swapped).
++Furthermore,
++it implies that the same was already true for older versions of the
++specification,
++even though it was not mentioned.
++In practice, many hardware vendors were not byte-swapping the UUID.
++So, in order to preserve compatibility,
++it was decided to interpret the UUID fields according to RFC 4122
++(no byte swapping)
++when the SMBIOS version is older than 2.6,
++and to interpret the first 3 fields as little-endian
++(byte-swapped)
++when the SMBIOS version is 2.6 or later.
++The Linux kernel follows the same logic.
+ .\"
+ .SH FILES
+ .I /dev/mem
+@@ -333,7 +366,8 @@ version is 2.6 or later. The Linux kerne
+ (Linux only)
+ .\"
+ .SH BUGS
+-More often than not, information contained in the \s-1DMI\s0 tables is inaccurate,
++More often than not,
++information contained in the \s-1DMI\s0 tables is inaccurate,
+ incomplete or simply wrong.
+ .\"
+ .SH AUTHORS
diff --git a/debian/patches/series b/debian/patches/series
index 696939d..ae7e887 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,16 +1,2 @@
-#0145-Fix_condition_error_in_ascii_filter.patch
-#0150-Fix_crash.patch
-0100-ansi-c.patch
+0605-man.patch
0001-hurd.patch
-#0005-build.patch
-#0105-dmidecode-avoid-sigbus.patch
-#0110-nosysfs.patch
-#0115-no_smbios_DMI_entry_point.patch
-#0120-return_actual_data_size.patch
-#0125-use_read_file_to_read_DMI_table_from_sysfs.patch
-#0130-use_DWORD_for_table_max_size.patch
-#0135-hide_fixup_msg.patch
-#0140-Fix_scan_entry_point.patch
-#0155-use_read_file.patch
-#0160-HPE_OEM_Firmware_change.patch
-0600-Fix-groff-error.patch
diff --git a/dmidecode.c b/dmidecode.c
index 45a6c06..463f12b 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -2,7 +2,7 @@
* DMI Decode
*
* Copyright (C) 2000-2002 Alan Cox <alan@redhat.com>
- * Copyright (C) 2002-2024 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2002-2025 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -85,12 +85,11 @@
#include "dmioem.h"
#include "dmioutput.h"
-#define out_of_spec "<OUT OF SPEC>"
static const char *bad_index = "<BAD INDEX>";
enum cpuid_type cpuid_type = cpuid_none;
-#define SUPPORTED_SMBIOS_VER 0x030700
+#define SUPPORTED_SMBIOS_VER 0x030900
#define FLAG_NO_FILE_OFFSET (1 << 0)
#define FLAG_STOP_AT_EOT (1 << 1)
@@ -163,7 +162,7 @@ const char *dmi_string(const struct dmi_header *dm, u8 s)
static const char *dmi_smbios_structure_type(u8 code)
{
static const char *type[] = {
- "BIOS", /* 0 */
+ "Platform Firmware", /* 0 */
"System",
"Base Board",
"Chassis",
@@ -176,7 +175,7 @@ static const char *dmi_smbios_structure_type(u8 code)
"On Board Devices",
"OEM Strings",
"System Configuration Options",
- "BIOS Language",
+ "Firmware Language",
"Group Associations",
"System Event Log",
"Physical Memory Array",
@@ -274,28 +273,29 @@ static void dmi_dump(const struct dmi_header *h)
}
}
-/* shift is 0 if the value is in bytes, 1 if it is in kilobytes */
-void dmi_print_memory_size(const char *attr, u64 code, int shift)
+/* shift is 0 if the value is in bytes, 1 if it is in kibibytes */
+void dmi_print_memory_size(void (*print_cb)(const char *name, const char *format, ...),
+ const char *attr, u64 code, int shift)
{
unsigned long capacity;
u16 split[7];
static const char *unit[8] = {
- "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"
+ "bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"
};
int i;
/*
- * We split the overall size in powers of thousand: EB, PB, TB, GB,
- * MB, kB and B. In practice, it is expected that only one or two
+ * We split the overall size in powers of 1024: EiB, PiB, TiB, GiB,
+ * MiB, KiB and B. In practice, it is expected that only one or two
* (consecutive) of these will be non-zero.
*/
- split[0] = code.l & 0x3FFUL;
- split[1] = (code.l >> 10) & 0x3FFUL;
- split[2] = (code.l >> 20) & 0x3FFUL;
- split[3] = ((code.h << 2) & 0x3FCUL) | (code.l >> 30);
- split[4] = (code.h >> 8) & 0x3FFUL;
- split[5] = (code.h >> 18) & 0x3FFUL;
- split[6] = code.h >> 28;
+ split[0] = code & 0x3FFULL;
+ split[1] = (code >> 10) & 0x3FFULL;
+ split[2] = (code >> 20) & 0x3FFULL;
+ split[3] = (code >> 30) & 0x3FFULL;
+ split[4] = (code >> 40) & 0x3FFULL;
+ split[5] = (code >> 50) & 0x3FFULL;
+ split[6] = (code >> 60) & 0x3FFULL;
/*
* Now we find the highest unit with a non-zero value. If the following
@@ -315,11 +315,33 @@ void dmi_print_memory_size(const char *attr, u64 code, int shift)
else
capacity = split[i];
- pr_attr(attr, "%lu %s", capacity, unit[i + shift]);
+ print_cb(attr, "%lu %s", capacity, unit[i + shift]);
+}
+
+/* shift is 0 if the value is in bytes, 1 if it is in kB, 2 if it is in MB */
+void dmi_print_storage_size(const char *attr, u64 code, unsigned int shift)
+{
+ u64 divisor;
+ static const char *unit[8] = {
+ "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB"
+ };
+
+ /*
+ * We want to choose the unit which will let us display a number
+ * between 1.0 and 999.9.
+ */
+ divisor = 1;
+ while (code / divisor >= 1000 && shift + 1 < ARRAY_SIZE(unit))
+ {
+ shift++;
+ divisor *= 1000;
+ }
+
+ pr_attr(attr, "%.1f %s", (float)code / divisor, unit[shift]);
}
/*
- * 7.1 BIOS Information (Type 0)
+ * 7.1 Platform Firmware Information (Type 0)
*/
static void dmi_bios_runtime_size(u32 code)
@@ -332,7 +354,7 @@ static void dmi_bios_runtime_size(u32 code)
}
else
{
- format = "%u kB";
+ format = "%u KiB";
code >>= 10;
}
@@ -342,13 +364,12 @@ static void dmi_bios_runtime_size(u32 code)
static void dmi_bios_rom_size(u8 code1, u16 code2)
{
static const char *unit[4] = {
- "MB", "GB", out_of_spec, out_of_spec
+ "MiB", "GiB", out_of_spec, out_of_spec
};
if (code1 != 0xFF)
{
- u64 s = { .l = (code1 + 1) << 6 };
- dmi_print_memory_size("ROM Size", s, 1);
+ dmi_print_memory_size(pr_attr, "ROM Size", (u64)(code1 + 1) << 6, 1);
}
else
pr_attr("ROM Size", "%u %s", code2 & 0x3FFF, unit[code2 >> 14]);
@@ -358,7 +379,7 @@ static void dmi_bios_characteristics(u64 code)
{
/* 7.1.1 */
static const char *characteristics[] = {
- "BIOS characteristics not supported", /* 3 */
+ "Firmware characteristics not supported", /* 3 */
"ISA is supported",
"MCA is supported",
"EISA is supported",
@@ -366,13 +387,13 @@ static void dmi_bios_characteristics(u64 code)
"PC Card (PCMCIA) is supported",
"PNP is supported",
"APM is supported",
- "BIOS is upgradeable",
- "BIOS shadowing is allowed",
+ "Firmware is upgradeable",
+ "Firmware shadowing is allowed",
"VLB is supported",
"ESCD support is available",
"Boot from CD is supported",
"Selectable boot is supported",
- "BIOS ROM is socketed",
+ "Firmware ROM is socketed",
"Boot from PC Card (PCMCIA) is supported",
"EDD is supported",
"Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)",
@@ -393,14 +414,14 @@ static void dmi_bios_characteristics(u64 code)
/*
* This isn't very clear what this bit is supposed to mean
*/
- if (code.l & (1 << 3))
+ if (code & (1ULL << 3))
{
pr_list_item("%s", characteristics[0]);
return;
}
for (i = 4; i <= 31; i++)
- if (code.l & (1 << i))
+ if (code & (1ULL << i))
pr_list_item("%s", characteristics[i - 3]);
}
@@ -447,8 +468,8 @@ static void dmi_bios_characteristics_x2(u8 code)
* 7.2 System Information (Type 1)
*/
-static void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...),
- const char *attr, const u8 *p, u16 ver)
+void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...),
+ const char *attr, const u8 *p, u16 ver)
{
int only0xFF = 1, only0x00 = 1;
int i;
@@ -626,10 +647,10 @@ static const char *dmi_chassis_type(u8 code)
"Rack Mount Chassis",
"Sealed-case PC",
"Multi-system",
- "CompactPCI",
- "AdvancedTCA",
+ "Compact PCI",
+ "Advanced TCA",
"Blade",
- "Blade Enclosing",
+ "Blade Enclosure",
"Tablet",
"Convertible",
"Detachable",
@@ -730,6 +751,18 @@ static void dmi_chassis_elements(u8 count, u8 len, const u8 *p)
pr_list_end();
}
+static const char *dmi_chassis_rack_type(u8 code)
+{
+ static const char *type[] = {
+ "Unspecified", /* 0x00 */
+ "OU" /* 0x01 */
+ };
+
+ if (code <= 0x01)
+ return type[code];
+ return out_of_spec;
+}
+
/*
* 7.5 Processor Information (Type 4)
*/
@@ -942,6 +975,7 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0xCD, "Core i5" },
{ 0xCE, "Core i3" },
{ 0xCF, "Core i9" },
+ { 0xD0, "Xeon D" },
{ 0xD2, "C7-M" },
{ 0xD3, "C7-D" },
@@ -1011,6 +1045,15 @@ static const char *dmi_processor_family(const struct dmi_header *h, u16 ver)
{ 0x26F, "Multi-Core Loongson 3B 5xxx" },
{ 0x270, "Multi-Core Loongson 3C 5xxx" },
{ 0x271, "Multi-Core Loongson 3D 5xxx" },
+
+ { 0x300, "Core 3" },
+ { 0x301, "Core 5" },
+ { 0x302, "Core 7" },
+ { 0x303, "Core 9" },
+ { 0x304, "Core Ultra 3" },
+ { 0x305, "Core Ultra 5" },
+ { 0x306, "Core Ultra 7" },
+ { 0x307, "Core Ultra 9" },
};
/*
* Note to developers: when adding entries to this list, check if
@@ -1140,8 +1183,9 @@ static enum cpuid_type dmi_get_cpuid_type(const struct dmi_header *h)
void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...),
const char *label, enum cpuid_type sig, const u8 *p)
{
- u32 eax, midr, jep106, soc_revision;
- u16 dx;
+ u32 eax, midr, soc_revision;
+ u16 dx, soc_id;
+ u8 jep106_code, jep106_bank;
switch (sig)
{
@@ -1181,12 +1225,12 @@ void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...)
case cpuid_arm_soc_id: /* ARM with SOC ID */
/*
- * If Soc ID is supported, the first DWORD is the JEP-106 code;
- * the second DWORD is the SoC revision value.
- */
- jep106 = DWORD(p);
- soc_revision = DWORD(p + 4);
- /*
+ * If SoC ID is supported, the first WORD is a SiP
+ * defined SoC ID; the next BYTE is the JEP-106
+ * identification code of the SiP; the next BYTE is
+ * its bank index; lastly, the next DWORD is the SoC
+ * revision value.
+ *
* According to SMC Calling Convention (SMCCC) v1.3 specification
* (https://developer.arm.com/documentation/den0028/d/), the format
* of the values returned by the SMCCC_ARCH_SOC_ID call is as follows:
@@ -1201,9 +1245,14 @@ void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...)
* Bit[31] must be zero
* Bits[30:0] SoC revision
*/
+ soc_id = WORD(p);
+ jep106_code = p[2] & 0x7F;
+ jep106_bank = p[3] & 0x7F;
+ soc_revision = DWORD(p + 4);
+
pr_attr("Signature",
"JEP-106 Bank 0x%02x Manufacturer 0x%02x, SoC ID 0x%04x, SoC Revision 0x%08x",
- (jep106 >> 24) & 0x7F, (jep106 >> 16) & 0x7F, jep106 & 0xFFFF, soc_revision);
+ jep106_bank, jep106_code, soc_id, soc_revision);
return;
case cpuid_x86_intel: /* Intel */
@@ -1369,8 +1418,8 @@ static const char *dmi_processor_status(u8 code)
static const char *status[] = {
"Unknown", /* 0x00 */
"Enabled",
- "Disabled By User",
- "Disabled By BIOS",
+ "Disabled by user",
+ "Disabled by firmware",
"Idle", /* 0x04 */
out_of_spec,
out_of_spec,
@@ -1463,10 +1512,17 @@ static const char *dmi_processor_upgrade(u8 code)
"Socket BGA1190",
"Socket BGA4129",
"Socket LGA4710",
- "Socket LGA7529" /* 0x50 */
+ "Socket LGA7529",
+ "Socket BGA1964",
+ "Socket BGA1792",
+ "Socket BGA2049",
+ "Socket BGA2551",
+ "Socket LGA1851",
+ "Socket BGA2114",
+ "Socket BGA2833" /* 0x57 */
};
- if (code >= 0x01 && code <= 0x50)
+ if (code >= 0x01 && code <= 0x57)
return upgrade[code - 0x01];
return out_of_spec;
}
@@ -1710,7 +1766,7 @@ static void dmi_memory_module_size(const char *attr, u8 code)
pr_attr(attr, "Not Installed");
return;
default:
- pr_attr(attr, "%u MB%s", 1 << (code & 0x7F),
+ pr_attr(attr, "%u MiB%s", 1 << (code & 0x7F),
connection);
}
}
@@ -1765,18 +1821,16 @@ static void dmi_cache_size_2(const char *attr, u32 code)
if (code & 0x80000000)
{
- code &= 0x7FFFFFFFLU;
- size.l = code << 6;
- size.h = code >> 26;
+ code &= 0x7FFFFFFFULL;
+ size = (u64)code << 6;
}
else
{
- size.l = code;
- size.h = 0;
+ size = code;
}
/* Use a more convenient unit for large cache size */
- dmi_print_memory_size(attr, size, 1);
+ dmi_print_memory_size(pr_attr, attr, size, 1);
}
static void dmi_cache_size(const char *attr, u16 code)
@@ -2009,7 +2063,7 @@ static const char *dmi_port_type(u8 code)
* 7.10 System Slots (Type 9)
*/
-static const char *dmi_slot_type(u8 code)
+static void dmi_slot_type(u8 code, u8 length)
{
/* 7.10.1 */
static const char *type[] = {
@@ -2102,14 +2156,35 @@ static const char *dmi_slot_type(u8 code)
* Note to developers: when adding entries to these lists, check if
* function dmi_slot_id below needs updating too.
*/
+ const char *t, *suffix = "";
if (code >= 0x01 && code <= 0x28)
- return type[code - 0x01];
- if (code == 0x30)
- return type_0x30[code - 0x30];
- if (code >= 0xA0 && code <= 0xC6)
- return type_0xA0[code - 0xA0];
- return out_of_spec;
+ t = type[code - 0x01];
+ else if (code == 0x30)
+ t = type_0x30[code - 0x30];
+ else if (code >= 0xA0 && code <= 0xC6)
+ t = type_0xA0[code - 0xA0];
+ else
+ t = out_of_spec;
+
+ /* For EDSFF slots, add the length suffix */
+ switch (code)
+ {
+ case 0xC5: /* EDSFF E1 */
+ case 0xC6: /* EDSFF E3 */
+ switch (length)
+ {
+ case 0x03: /* Short */
+ suffix = ".S";
+ break;
+ case 0x04: /* Long */
+ suffix = ".L";
+ break;
+ }
+ break;
+ }
+
+ pr_attr("Type", "%s%s", t, suffix);
}
static const char *dmi_slot_bus_width(u8 code)
@@ -2188,11 +2263,20 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type)
case 0x11: /* AGP */
case 0x12: /* PCI-X */
case 0x13: /* AGP */
- case 0x1F: /* PCI Express 2 */
- case 0x20: /* PCI Express 3 */
+ case 0x14: /* M.2 */
+ case 0x15: /* M.2 */
+ case 0x16: /* M.2 */
+ case 0x17: /* M.2 */
+ case 0x1F: /* PCI Express 2 (U.2) */
+ case 0x20: /* PCI Express 3 (U.2) */
case 0x21: /* PCI Express Mini */
case 0x22: /* PCI Express Mini */
case 0x23: /* PCI Express Mini */
+ case 0x24: /* PCI Express 4 (U.2) */
+ case 0x25: /* PCI Express 5 (U.2) */
+ case 0x26: /* OCP */
+ case 0x27: /* OCP */
+ case 0x28: /* OCP */
case 0xA5: /* PCI Express */
case 0xA6: /* PCI Express */
case 0xA7: /* PCI Express */
@@ -2224,6 +2308,8 @@ static void dmi_slot_id(u8 code1, u8 code2, u8 type)
case 0xC2: /* PCI Express 5 */
case 0xC3: /* PCI Express 5 */
case 0xC4: /* PCI Express 6+ */
+ case 0xC5: /* EDSFF */
+ case 0xC6: /* EDSFF */
pr_attr("ID", "%u", code1);
break;
case 0x07: /* PCMCIA */
@@ -2461,7 +2547,7 @@ static void dmi_system_configuration_options(const struct dmi_header *h)
}
/*
- * 7.14 BIOS Language Information (Type 13)
+ * 7.14 Firmware Language Information (Type 13)
*/
static void dmi_bios_languages(const struct dmi_header *h)
@@ -2752,10 +2838,10 @@ static void dmi_memory_device_size(u16 code)
pr_attr("Size", "Unknown");
else
{
- u64 s = { .l = code & 0x7FFF };
+ u64 s = (u64)code & 0x7FFFULL;
if (!(code & 0x8000))
- s.l <<= 10;
- dmi_print_memory_size("Size", s, 1);
+ s <<= 10;
+ dmi_print_memory_size(pr_attr, "Size", s, 1);
}
}
@@ -2768,11 +2854,11 @@ static void dmi_memory_device_extended_size(u32 code)
* as an integer without rounding
*/
if (code & 0x3FFUL)
- pr_attr("Size", "%lu MB", (unsigned long)code);
+ pr_attr("Size", "%lu MiB", (unsigned long)code);
else if (code & 0xFFC00UL)
- pr_attr("Size", "%lu GB", (unsigned long)code >> 10);
+ pr_attr("Size", "%lu GiB", (unsigned long)code >> 10);
else
- pr_attr("Size", "%lu TB", (unsigned long)code >> 20);
+ pr_attr("Size", "%lu TiB", (unsigned long)code >> 20);
}
static void dmi_memory_voltage_value(const char *attr, u16 code)
@@ -2803,10 +2889,13 @@ static const char *dmi_memory_device_form_factor(u8 code)
"SODIMM",
"SRIMM",
"FB-DIMM",
- "Die" /* 0x10 */
+ "Die",
+ "CAMM",
+ "CUDIMM",
+ "CSODIMM" /* 0x13 */
};
- if (code >= 0x01 && code <= 0x10)
+ if (code >= 0x01 && code <= 0x13)
return form_factor[code - 0x01];
return out_of_spec;
}
@@ -2860,10 +2949,11 @@ static const char *dmi_memory_device_type(u8 code)
"HBM2",
"DDR5",
"LPDDR5",
- "HBM3" /* 0x24 */
+ "HBM3",
+ "MRDIMM" /* 0x25 */
};
- if (code >= 0x01 && code <= 0x24)
+ if (code >= 0x01 && code <= 0x25)
return type[code - 0x01];
return out_of_spec;
}
@@ -2923,7 +3013,7 @@ static void dmi_memory_device_speed(const char *attr, u16 code1, u32 code2)
}
}
-static void dmi_memory_technology(u8 code)
+static const char *dmi_memory_technology(u8 code)
{
/* 7.18.6 */
static const char * const technology[] = {
@@ -2933,12 +3023,12 @@ static void dmi_memory_technology(u8 code)
"NVDIMM-N",
"NVDIMM-F",
"NVDIMM-P",
- "Intel Optane DC persistent memory" /* 0x07 */
+ "Intel Optane persistent memory",
+ "MRDIMM" /* 0x08 */
};
- if (code >= 0x01 && code <= 0x07)
- pr_attr("Memory Technology", "%s", technology[code - 0x01]);
- else
- pr_attr("Memory Technology", "%s", out_of_spec);
+ if (code >= 0x01 && code <= 0x08)
+ return technology[code - 0x01];
+ return out_of_spec;
}
static void dmi_memory_operating_mode_capability(u16 code)
@@ -2967,7 +3057,7 @@ static void dmi_memory_operating_mode_capability(u16 code)
}
}
-static void dmi_memory_manufacturer_id(const char *attr, u16 code)
+void dmi_memory_manufacturer_id(const char *attr, u16 code)
{
/* 7.18.8 */
/* 7.18.10 */
@@ -2981,7 +3071,7 @@ static void dmi_memory_manufacturer_id(const char *attr, u16 code)
(code & 0x7F) + 1, code >> 8);
}
-static void dmi_memory_product_id(const char *attr, u16 code)
+void dmi_memory_product_id(const char *attr, u16 code)
{
/* 7.18.9 */
/* 7.18.11 */
@@ -2995,12 +3085,12 @@ static void dmi_memory_size(const char *attr, u64 code)
{
/* 7.18.12 */
/* 7.18.13 */
- if (code.h == 0xFFFFFFFF && code.l == 0xFFFFFFFF)
+ if (code == ~0ULL)
pr_attr(attr, "Unknown");
- else if (code.h == 0x0 && code.l == 0x0)
+ else if (code == 0ULL)
pr_attr(attr, "None");
else
- dmi_print_memory_size(attr, code, 0);
+ dmi_print_memory_size(pr_attr, attr, code, 0);
}
static void dmi_memory_revision(const char *attr_type, u16 code, u8 mem_type)
@@ -3127,21 +3217,15 @@ static void dmi_mapped_address_size(u32 code)
if (code == 0)
pr_attr("Range Size", "Invalid");
else
- {
- u64 size;
-
- size.h = 0;
- size.l = code;
- dmi_print_memory_size("Range Size", size, 1);
- }
+ dmi_print_memory_size(pr_attr, "Range Size", (u64)code, 1);
}
static void dmi_mapped_address_extended_size(u64 start, u64 end)
{
- if (start.h == end.h && start.l == end.l)
+ if (start == end)
pr_attr("Range Size", "Invalid");
else
- dmi_print_memory_size("Range Size", u64_range(start, end), 0);
+ dmi_print_memory_size(pr_attr, "Range Size", end - start + 1, 0);
}
/*
@@ -3566,10 +3650,10 @@ static const char *dmi_system_boot_status(u8 code)
static void dmi_64bit_memory_error_address(const char *attr, u64 code)
{
- if (code.h == 0x80000000 && code.l == 0x00000000)
+ if (code == 0x8000000000000000ULL)
pr_attr(attr, "Unknown");
else
- pr_attr(attr, "0x%08X%08X", code.h, code.l);
+ pr_attr(attr, "0x%016llX", code);
}
/*
@@ -3703,9 +3787,9 @@ static void dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb)
else
{
u64 address = QWORD(p);
- pr_attr("Base Address", "0x%08X%08X (%s)",
- address.h, (address.l & ~1) | lsb,
- address.l & 1 ? "I/O" : "Memory-mapped");
+ pr_attr("Base Address", "0x%016llX (%s)",
+ (address & ~1ULL) | lsb,
+ (address & 1ULL) ? "I/O" : "Memory-mapped");
}
}
@@ -4374,14 +4458,14 @@ static void dmi_tpm_characteristics(u64 code)
/*
* This isn't very clear what this bit is supposed to mean
*/
- if (code.l & (1 << 2))
+ if (code & (1ULL << 2))
{
pr_list_item("%s", characteristics[0]);
return;
}
for (i = 3; i <= 5; i++)
- if (code.l & (1 << i))
+ if (code & (1ULL << i))
pr_list_item("%s", characteristics[i - 2]);
}
@@ -4445,8 +4529,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
*/
switch (h->type)
{
- case 0: /* 7.1 BIOS Information */
- pr_handle_name("BIOS Information");
+ case 0: /* 7.1 Platform Firmware Information */
+ pr_handle_name("Platform Firmware Information");
if (h->length < 0x12) break;
pr_attr("Vendor", "%s",
dmi_string(h, data[0x04]));
@@ -4468,17 +4552,17 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18));
pr_list_start("Characteristics", NULL);
dmi_bios_characteristics(QWORD(data + 0x0A));
+ if (h->length >= 0x13)
+ dmi_bios_characteristics_x1(data[0x12]);
+ if (h->length >= 0x14)
+ dmi_bios_characteristics_x2(data[0x13]);
pr_list_end();
- if (h->length < 0x13) break;
- dmi_bios_characteristics_x1(data[0x12]);
- if (h->length < 0x14) break;
- dmi_bios_characteristics_x2(data[0x13]);
if (h->length < 0x18) break;
if (data[0x14] != 0xFF && data[0x15] != 0xFF)
- pr_attr("BIOS Revision", "%u.%u",
+ pr_attr("Platform Firmware Revision", "%u.%u",
data[0x14], data[0x15]);
if (data[0x16] != 0xFF && data[0x17] != 0xFF)
- pr_attr("Firmware Revision", "%u.%u",
+ pr_attr("Embedded Controller Firmware Revision", "%u.%u",
data[0x16], data[0x17]);
break;
@@ -4562,14 +4646,32 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
pr_attr("OEM Information", "0x%08X",
DWORD(data + 0x0D));
if (h->length < 0x13) break;
- dmi_chassis_height(data[0x11]);
+ if (data[0x11] != 0xFF)
+ dmi_chassis_height(data[0x11]);
dmi_chassis_power_cords(data[0x12]);
if (h->length < 0x15) break;
if (h->length < 0x15 + data[0x13] * data[0x14]) break;
dmi_chassis_elements(data[0x13], data[0x14], data + 0x15);
if (h->length < 0x16 + data[0x13] * data[0x14]) break;
- pr_attr("SKU Number", "%s",
- dmi_string(h, data[0x15 + data[0x13] * data[0x14]]));
+ /*
+ * Many old implementations have stray zero bytes at
+ * the end of this record, probably due to some
+ * confusion regarding the preceding variable length
+ * section. Only decode the following fields if they
+ * are defined in the SMBIOS specification version
+ * which is implemented.
+ */
+ if (ver >= 0x0207)
+ pr_attr("SKU Number", "%s",
+ dmi_string(h, data[0x15 + data[0x13] * data[0x14]]));
+ if (h->length < 0x18 + data[0x13] * data[0x14]) break;
+ if (ver >= 0x0309)
+ {
+ pr_attr("Rack Type", "%s",
+ dmi_chassis_rack_type(data[0x16 + data[0x13] * data[0x14]]));
+ pr_attr("Rack Height", "%hhu",
+ data[0x17 + data[0x13] * data[0x14]]);
+ }
break;
case 4: /* 7.5 Processor Information */
@@ -4586,7 +4688,12 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_processor_id(h);
pr_attr("Version", "%s",
dmi_string(h, data[0x10]));
- dmi_processor_voltage("Voltage", data[0x11]);
+ /*
+ * Since SMBIOS 3.8.0, the processor voltage field
+ * is deprecated, so ignore it if no value is set.
+ */
+ if (data[0x11])
+ dmi_processor_voltage("Voltage", data[0x11]);
dmi_processor_frequency("External Clock", data + 0x12);
dmi_processor_frequency("Max Speed", data + 0x14);
dmi_processor_frequency("Current Speed", data + 0x16);
@@ -4645,9 +4752,9 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_memory_controller_interleave(data[0x06]));
pr_attr("Current Interleave", "%s",
dmi_memory_controller_interleave(data[0x07]));
- pr_attr("Maximum Memory Module Size", "%u MB",
+ pr_attr("Maximum Memory Module Size", "%u MiB",
1 << data[0x08]);
- pr_attr("Maximum Total Memory Size", "%u MB",
+ pr_attr("Maximum Total Memory Size", "%u MiB",
data[0x0E] * (1 << data[0x08]));
dmi_memory_controller_speeds("Supported Speeds",
WORD(data + 0x09));
@@ -4727,7 +4834,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
if (h->length < 0x0C) break;
pr_attr("Designation", "%s",
dmi_string(h, data[0x04]));
- pr_attr("Type", "%s", dmi_slot_type(data[0x05]));
+ dmi_slot_type(data[0x05], data[0x08]);
pr_attr("Data Bus Width", "%s", dmi_slot_bus_width(data[0x06]));
pr_attr("Current Usage", "%s",
dmi_slot_current_usage(data[0x07]));
@@ -4770,8 +4877,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_system_configuration_options(h);
break;
- case 13: /* 7.14 BIOS Language Information */
- pr_handle_name("BIOS Language Information");
+ case 13: /* 7.14 Firmware Language Information */
+ pr_handle_name("Firmware Language Information");
if (h->length < 0x16) break;
if (ver >= 0x0201)
{
@@ -4838,17 +4945,15 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
if (h->length < 0x17)
pr_attr("Maximum Capacity", "Unknown");
else
- dmi_print_memory_size("Maximum Capacity",
+ dmi_print_memory_size(pr_attr,
+ "Maximum Capacity",
QWORD(data + 0x0F), 0);
}
else
{
- u64 capacity;
-
- capacity.h = 0;
- capacity.l = DWORD(data + 0x07);
- dmi_print_memory_size("Maximum Capacity",
- capacity, 1);
+ dmi_print_memory_size(pr_attr,
+ "Maximum Capacity",
+ DWORD(data + 0x07), 1);
}
if (!(opt.flags & FLAG_QUIET))
dmi_memory_array_error_handle(WORD(data + 0x0B));
@@ -4915,7 +5020,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
dmi_memory_voltage_value("Configured Voltage",
WORD(data + 0x26));
if (h->length < 0x34) break;
- dmi_memory_technology(data[0x28]);
+ pr_attr("Memory Technology", "%s",
+ dmi_memory_technology(data[0x28]));
dmi_memory_operating_mode_capability(WORD(data + 0x29));
pr_attr("Firmware Version", "%s",
dmi_string(h, data[0x2B]));
@@ -4974,10 +5080,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
start = QWORD(data + 0x0F);
end = QWORD(data + 0x17);
- pr_attr("Starting Address", "0x%08X%08Xk",
- start.h, start.l);
- pr_attr("Ending Address", "0x%08X%08Xk",
- end.h, end.l);
+ pr_attr("Starting Address", "0x%016llX", start);
+ pr_attr("Ending Address", "0x%016llX", end);
dmi_mapped_address_extended_size(start, end);
}
else
@@ -5007,10 +5111,8 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
start = QWORD(data + 0x13);
end = QWORD(data + 0x1B);
- pr_attr("Starting Address", "0x%08X%08Xk",
- start.h, start.l);
- pr_attr("Ending Address", "0x%08X%08Xk",
- end.h, end.l);
+ pr_attr("Starting Address", "0x%016llX", start);
+ pr_attr("Ending Address", "0x%016llX", end);
dmi_mapped_address_extended_size(start, end);
}
else
@@ -5529,7 +5631,7 @@ static void dmi_decode(const struct dmi_header *h, u16 ver)
break;
default:
- if (dmi_decode_oem(h))
+ if (dmi_decode_oem(h, ver))
break;
if (opt.flags & FLAG_QUIET)
return;
@@ -5932,7 +6034,8 @@ static int smbios3_decode(u8 *buf, size_t buf_len, const char *devmem, u32 flags
buf[0x07], buf[0x08], buf[0x09]);
offset = QWORD(buf + 0x10);
- if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8)
+ if (!(flags & FLAG_NO_FILE_OFFSET) && (offset & 0xFFFFFFFF00000000ULL)
+ && sizeof(off_t) < 8)
{
fprintf(stderr, "64-bit addresses not supported, sorry.\n");
return 0;
@@ -5940,7 +6043,7 @@ static int smbios3_decode(u8 *buf, size_t buf_len, const char *devmem, u32 flags
/* Maximum length, may get trimmed */
len = DWORD(buf + 0x0C);
- table = dmi_table_get(((off_t)offset.h << 32) | offset.l, &len, 0, ver,
+ table = dmi_table_get(offset, &len, 0, ver,
devmem, flags | FLAG_STOP_AT_EOT);
if (table == NULL)
return 1;
diff --git a/dmidecode.h b/dmidecode.h
index e03c957..40f8a62 100644
--- a/dmidecode.h
+++ b/dmidecode.h
@@ -1,7 +1,7 @@
/*
* This file is part of the dmidecode project.
*
- * Copyright (C) 2005-2023 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2005-2025 Jean Delvare <jdelvare@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,8 @@
#include "types.h"
+#define out_of_spec "<OUT OF SPEC>"
+
struct dmi_header
{
u8 type;
@@ -47,8 +49,14 @@ extern enum cpuid_type cpuid_type;
int is_printable(const u8 *data, int len);
const char *dmi_string(const struct dmi_header *dm, u8 s);
-void dmi_print_memory_size(const char *addr, u64 code, int shift);
+void dmi_print_memory_size(void (*print_cb)(const char *name, const char *format, ...),
+ const char *attr, u64 code, int shift);
+void dmi_print_storage_size(const char *attr, u64 code, unsigned int shift);
void dmi_print_cpuid(void (*print_cb)(const char *name, const char *format, ...),
const char *label, enum cpuid_type sig, const u8 *p);
+void dmi_memory_manufacturer_id(const char *attr, u16 code);
+void dmi_memory_product_id(const char *attr, u16 code);
+void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...),
+ const char *attr, const u8 *p, u16 ver);
#endif
diff --git a/dmioem.c b/dmioem.c
index 2f1f9f6..bdf41d2 100644
--- a/dmioem.c
+++ b/dmioem.c
@@ -2,8 +2,8 @@
* Decoding of OEM-specific entries
* This file is part of the dmidecode project.
*
- * Copyright (C) 2007-2024 Jean Delvare <jdelvare@suse.de>
- * Copyright (C) 2017-2024 Jerry Hoemann <jerry.hoemann@hpe.com>
+ * Copyright (C) 2007-2025 Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2017-2025 Jerry Hoemann <jerry.hoemann@hpe.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,6 +38,7 @@ enum DMI_VENDORS
{
VENDOR_UNKNOWN,
VENDOR_ACER,
+ VENDOR_DELL,
VENDOR_HP,
VENDOR_HPE,
VENDOR_IBM,
@@ -56,6 +57,8 @@ void dmi_set_vendor(const char *v, const char *p)
{
const struct { const char *str; enum DMI_VENDORS id; } vendor[] = {
{ "Acer", VENDOR_ACER },
+ { "Dell Computer Corporation", VENDOR_DELL },
+ { "Dell Inc.", VENDOR_DELL },
{ "HP", VENDOR_HP },
{ "Hewlett-Packard", VENDOR_HP },
{ "HPE", VENDOR_HPE },
@@ -130,6 +133,144 @@ static int dmi_decode_acer(const struct dmi_header *h)
}
/*
+ * Dell-specific data structures are decoded here.
+ */
+
+static void dmi_dell_bios_flags(u64 flags)
+{
+ /*
+ * TODO: The meaning of the other bits is unknown.
+ */
+ pr_attr("ACPI WMI Supported", "%s", (flags & (1ULL << 1)) ? "Yes" : "No");
+}
+
+static void dmi_dell_hotkeys(const struct dmi_header *h)
+{
+ int count = (h->length - 0x04) / 0x04;
+ u8 *hotkey = h->data + 0x04;
+ int i;
+
+ if (!count)
+ return;
+
+ pr_list_start("Hotkey Mappings", NULL);
+ for (i = 0; i < count; i++)
+ {
+ pr_list_item("Scancode 0x%04hx -> Keycode 0x%04hx",
+ WORD(hotkey + 0x00), WORD(hotkey + 0x02));
+ hotkey += 0x04;
+ }
+ pr_list_end();
+}
+
+static void dmi_dell_indexed_io_access(const struct dmi_header *h)
+{
+ static const char *checksum_types[] = {
+ "Word Checksum",
+ "Byte Checksum",
+ "CRC Checksum",
+ "Negative Word Checksum", /* 0x03 */
+ };
+ int tokens = (h->length - 0x0C) / 0x05;
+ const char *str = out_of_spec;
+ u8 *data = h->data;
+ u8 *token;
+ u8 type;
+ int i;
+
+ pr_attr("Index Port", "0x%04hx", WORD(data + 0x04));
+ pr_attr("Data Port", "0x%04hx", WORD(data + 0x06));
+
+ type = data[0x08];
+ if (type < ARRAY_SIZE(checksum_types))
+ str = checksum_types[type];
+
+ pr_attr("Type", "%s", str);
+ pr_attr("Checked Range Start Index", "0x%02hhx", data[0x09]);
+ pr_attr("Checked Range End Index", "0x%02hhx", data[0x0a]);
+ pr_attr("Check Value Index", "0x%02hhx", data[0x0b]);
+
+ /*
+ * Final token seems to be a terminator, so we ignore it.
+ */
+ if (tokens <= 1)
+ return;
+
+ pr_list_start("Tokens", NULL);
+ for (i = 0; i < tokens - 1; i++)
+ {
+ token = data + 0x0C + 0x05 * i;
+ pr_list_item("0x%04hx (location 0x%02hhx, AND mask 0x%02hhx, OR mask 0x%02hhx)",
+ WORD(token + 0x00), token[0x02], token[0x03], token[0x04]);
+ }
+ pr_list_end();
+}
+
+static void dmi_dell_token_interface(const struct dmi_header *h)
+{
+ int tokens = (h->length - 0x0B) / 0x06;
+ u8 *data = h->data;
+ u8 *token;
+ int i;
+
+ pr_attr("Command I/O Address", "0x%04x", WORD(data + 0x04));
+ pr_attr("Command I/O Code", "0x%02x", data[0x06]);
+ pr_attr("Supported Command Classes Bitmap", "0x%08x", DWORD(data + 0x07));
+
+ /*
+ * Final token is a terminator, so we ignore it.
+ */
+ if (tokens <= 1)
+ return;
+
+ pr_list_start("Tokens", NULL);
+ for (i = 0; i < tokens - 1; i++)
+ {
+ token = data + 0x0B + 0x06 * i;
+ pr_list_item("0x%04hx (location 0x%04hx, value 0x%04hx)",
+ WORD(token + 0x00), WORD(token + 0x02),
+ WORD(token + 0x04));
+ }
+ pr_list_end();
+}
+
+static int dmi_decode_dell(const struct dmi_header *h)
+{
+ u8 *data = h->data;
+
+ switch (h->type)
+ {
+ case 177:
+ pr_handle_name("Dell BIOS Flags");
+ if (h->length < 0x0C) break;
+ dmi_dell_bios_flags(QWORD(data + 0x04));
+ break;
+
+ case 178:
+ pr_handle_name("Dell Hotkeys");
+ dmi_dell_hotkeys(h);
+ break;
+
+ case 212:
+ pr_handle_name("Dell Indexed I/O Access");
+ if (h->length < 0x0C) break;
+ dmi_dell_indexed_io_access(h);
+ break;
+
+ case 218:
+ pr_handle_name("Dell Token Interface");
+ if (h->length < 0x0B) break;
+ dmi_dell_token_interface(h);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* HPE-specific data structures are decoded here.
*
* Code contributed by John Cagle and Tyler Bell.
@@ -162,11 +303,12 @@ static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac)
}
}
-typedef enum { G6 = 6, G7, G8, G9, G10, G10P, G11 } dmi_hpegen_t;
+typedef enum { G6 = 6, G7, G8, G9, G10, G10P, G11, G12 } dmi_hpegen_t;
static int dmi_hpegen(const char *s)
{
struct { const char *name; dmi_hpegen_t gen; } table[] = {
+ { "Gen12", G12 },
{ "Gen11", G11 },
{ "Gen10 Plus", G10P },
{ "Gen10", G10 },
@@ -217,14 +359,6 @@ static void dmi_hp_203_assoc_hndl(const char *fname, u16 num)
pr_attr(fname, "0x%04X", num);
}
-static void dmi_hp_203_pciinfo(const char *fname, u16 num)
-{
- if (num == 0xFFFF)
- pr_attr(fname, "Device Not Present");
- else
- pr_attr(fname, "0x%04x", num);
-}
-
static void dmi_hp_203_bayenc(const char *fname, u8 num)
{
switch (num)
@@ -261,7 +395,8 @@ static void dmi_hp_203_devtyp(const char *fname, unsigned int code)
"Dynamic Smart Array Controller",
"File",
"NVME Hard Drive",
- "NVDIMM" /* 0x11 */
+ "NVDIMM", /* 0x11 */
+ "Embedded GPU"
};
if (code < ARRAY_SIZE(type))
@@ -328,8 +463,8 @@ static void dmi_hp_216_fw_type(u16 code)
"SPI Descriptor Version",
"Innovation Engine Firmware (IE Firmware)",
"UMB Backplane Firmware",
- "Reserved", /* 0x14 */
- "Reserved",
+ "Embedded Diagnostics",
+ "Reserved", /* 0x15 */
"Reserved",
"Reserved",
"Reserved",
@@ -363,12 +498,19 @@ static void dmi_hp_216_fw_type(u16 code)
"Intel SATA VROC",
"Intel SPS Firmware",
"Secondary System Programmable Logic Device",
- "CPU MEZZ Programmable Logic Device", /* 0x37 */
+ "CPU Mezzanine Board CPLD", /* 0x37 */
"Intel Artic Sound -M Accelerator Models Firmware",
"Ampere System Control Processor (SCP - PMPro+SMPro)",
"Intel CFR information", /* 0x3A */
"OCP cards",
"DC-SCM CPLD",
+ "Power Distribution Board CPLD",
+ "PCIe Switch Board CPLD",
+ "Sideband Board CPLD",
+ "PCIe Riser MCU Firmware", /* 0x40 */
+ "PCIe Switch Board Firmware",
+ "Power Supply Firmware",
+ "BMC Firmware",
};
if (code < ARRAY_SIZE(type))
@@ -438,7 +580,7 @@ static void dmi_hp_216_version(u8 format, u8 *data)
pr_attr(name, "%d", data[0]);
break;
case 14:
- pr_attr(name, "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
+ pr_attr(name, "%d.%d.%d.%d", data[0], data[1], data[2], WORD(data+3));
break;
case 15:
pr_attr(name, "%d.%d.%d.%d (%.2d/%.2d/%d)",
@@ -453,7 +595,13 @@ static void dmi_hp_216_version(u8 format, u8 *data)
pr_attr(name, "%08X", DWORD(data));
break;
case 18:
- pr_attr(name, "%d.%2d", data[0], data[1]);
+ pr_attr(name, "%d.%02d", data[0], data[1]);
+ break;
+ case 19:
+ pr_attr(name, "0x%02x.0x%02x.0x%02x", data[0], data[1], data[2]);
+ break;
+ case 20:
+ pr_attr(name, "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
break;
case 3: /* fall through */
default:
@@ -545,6 +693,7 @@ static void dmi_hp_224_chipid(u16 code)
"Nationz TPM",
"STMicroGen10 Plus TPM",
"STMicroGen11 TPM", /* 0x05 */
+ "STMicroGen12 TPM",
};
if ((code & 0xff) < ARRAY_SIZE(chipid))
str = chipid[code & 0xff];
@@ -576,6 +725,22 @@ static void dmi_hp_230_method_bus_seg_addr(u8 code, u8 bus_seg, u8 addr)
pr_attr("I2C Address", "0x%02x", addr >> 1);
}
+static void dmi_hp_232_encrypt(u8 code)
+{
+ const char *str = "Reserved";
+ static const char * const status[] = {
+ "Not Encrypted",
+ "Encrypted",
+ "Unknown",
+ "Not Supported",
+ };
+
+ if (code < ARRAY_SIZE(status))
+ str = status[code];
+
+ pr_attr("Encryption Status", "%s", str);
+}
+
static void dmi_hp_238_loc(const char *fname, unsigned int code)
{
const char *str = "Reserved";
@@ -722,9 +887,9 @@ static void dmi_hp_240_attr(u64 defined, u64 set)
pr_list_start("Attributes Defined/Set", NULL);
for (i = 0; i < ARRAY_SIZE(attributes); i++)
{
- if (!(defined.l & (1UL << i)))
+ if (!(defined & (1ULL << i)))
continue;
- pr_list_item("%s: %s", attributes[i], set.l & (1UL << i) ? "Yes" : "No");
+ pr_list_item("%s: %s", attributes[i], set & (1ULL << i) ? "Yes" : "No");
}
pr_list_end();
}
@@ -784,6 +949,22 @@ static void dmi_hp_242_speed(const char *attr, u16 speed)
pr_attr(attr, "%s", "Unknown");
}
+static void dmi_hp_244_health(u8 code)
+{
+ const char *str = "Reserved";
+ static const char * const health[] = {
+ "Healthy", /* 0x00 */
+ "DIMM Missing",
+ "Config Inactive",
+ "SPA Missing",
+ "New Goal",
+ "Locked", /* 0x05 */
+ };
+ if (code < ARRAY_SIZE(health))
+ str = health[code];
+ pr_attr("Interleave Set Health", "%s", str);
+}
+
static void dmi_hp_245_pcie_riser(const struct dmi_header *h)
{
const char *str = "Reserved";
@@ -809,10 +990,31 @@ static void dmi_hp_245_pcie_riser(const struct dmi_header *h)
pr_attr("Riser Name", dmi_string(h, data[0x08]));
}
-static int dmi_decode_hp(const struct dmi_header *h)
+static void dmi_hp_245_pcie_mhs_riser(const struct dmi_header *h)
{
u8 *data = h->data;
- int nic, ptr;
+ u8 i, count;
+ int len = h->length;
+
+ pr_attr("Board Type", "PCIe Riser (MHS Platform)");
+ if (h->length < 0x0B) return;
+ pr_attr("Riser ID", "%d", data[0x05]);
+ if (data[0x06])
+ pr_attr("Firmware Version", "%x.%x", data[0x06], data[0x07]);
+ pr_attr("Downgradable", "%s", data[0x08] & 0x01 ? "Yes" : "No");
+ pr_attr("Riser Name", dmi_string(h, data[0x09]));
+ count = data[0x0A];
+ pr_attr("Slot Count", "%d", count);
+ pr_list_start("Slot IDs", NULL);
+ for (i = 0; (i < count) && ((0x0B + i) < len); i++)
+ pr_list_item("0x%x", data[0x0B + i]);
+ pr_list_end();
+}
+
+static int dmi_decode_hp(const struct dmi_header *h, u16 ver)
+{
+ u8 *data = h->data;
+ int nic, ptr, i;
u32 feat;
const char *company = (dmi_vendor == VENDOR_HP) ? "HP" : "HPE";
int gen;
@@ -823,6 +1025,37 @@ static int dmi_decode_hp(const struct dmi_header *h)
switch (h->type)
{
+ case 193:
+ /*
+ * Vendor Specific: Other ROM Info
+ *
+ * Offset | Name | Width | Description
+ * -------------------------------------
+ * 0x00 | Type | BYTE | 0xC1, ROM Structure Indicator
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | ROM | BYTE | 01: Redundant ROM installed
+ * 0x05 | ROM vers | STRING| Version of the Redundant ROM
+ * 0x06 | Reserved | BYTE | Reserved in Gen9 forward
+ * 0x07 | OEM ROM | STRING| If not blank, OEM ROM binary file name
+ * 0x08 | OEM Date | STRING| If not blank, OEM ROM binary build date
+ */
+ if (gen < G9) return 0;
+ pr_handle_name("%s ProLiant Other ROM Info", company);
+ if (h->length < 0x09) break;
+ if ((gen < G12) && (data[0x04] & 0x01))
+ pr_attr("Redundant ROM Version", "%s", dmi_string(h, data[0x05]));
+ if (data[0x07])
+ {
+ const char *str = dmi_string(h, data[0x07]);
+ if (strncmp(str, " ", 2))
+ {
+ pr_attr("OEM ROM Binary Filename", "%s", str);
+ pr_attr("OEM ROM Binary Build Date", "%s", dmi_string(h, data[0x08]));
+ }
+ }
+ break;
+
case 194:
/*
* Vendor Specific: Super IO Enable/Disable Features
@@ -844,6 +1077,37 @@ static int dmi_decode_hp(const struct dmi_header *h)
pr_attr("Virtual Serial Port", "%s", feat & (1 << 4) ? "Enabled" : "Disabled");
break;
+ case 195:
+ /*
+ * Vendor Specific: Server System ID
+ *
+ * Offset | Name | Width | Description
+ * ----------------------------------------------
+ * 0x00 | Type | BYTE | 0xC3, Server System ID
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | System ID | STRING| Server System ID
+ * 0x05 | Platform ID| BYTE | Low byte of Platform ID from XREG in CPLD
+ * 0x06 | Platform ID| BYTE | High byte of Platform ID from XREG in CPLD
+ * 0x07 | GUID |16 BYTE| RESERVED: Deprecated Gen 11 and later.
+ *
+ * This structure exists to define a unique system ID that replaces the
+ * old system EISA ID. It is to be used in systems where the system
+ * EISA ID port is not present.
+ *
+ * It also exposes the Platform ID from the CPLD Xregister. This value is
+ * used by iLO to identify the platform and will be used for identification
+ * and matching of certain flash deliverables.
+ */
+
+ pr_handle_name("%s ProLiant Server System ID", company);
+ if (h->length < 0x05) break;
+ pr_attr("Server System ID", "%s", dmi_string(h, data[0x04]));
+ if (h->length < 0x07) break;
+ /* Display byte order is uncertain, to be confirmed */
+ pr_attr("Platform ID", "%d:%d", data[0x05], data[0x06]);
+ break;
+
case 197:
/*
* Vendor Specific: HPE Processor Specific Information
@@ -922,14 +1186,19 @@ static int dmi_decode_hp(const struct dmi_header *h)
pr_handle_name("%s ProLiant CPU Microcode Patch Support Info", company);
for (ptr = 0x4; ptr + 12 <= h->length; ptr += 12) {
- u32 cpuid = DWORD(data + ptr + 2 * 4);
+ u8 cpuid[4];
u32 date;
+ memcpy(cpuid, data + ptr + 2 * 4, 4);
/* AMD omits BaseFamily. Reconstruction valid on family >= 15. */
if (cpuid_type == cpuid_x86_amd)
- cpuid = ((cpuid & 0xfff00) << 8) | 0x0f00 | (cpuid & 0xff);
+ {
+ cpuid[3] = cpuid[2] & 0x0f;
+ cpuid[2] = cpuid[1];
+ cpuid[1] = 0x0f;
+ }
- dmi_print_cpuid(pr_attr, "CPU ID", cpuid_type, (u8 *) &cpuid);
+ dmi_print_cpuid(pr_attr, "CPU ID", cpuid_type, cpuid);
date = DWORD(data + ptr + 4);
pr_subattr("Date", "%04x-%02x-%02x",
@@ -938,6 +1207,98 @@ static int dmi_decode_hp(const struct dmi_header *h)
}
break;
+ case 202:
+ /*
+ * Vendor Specific: HPE DIMM Location Record
+ *
+ * This record allows software to correlate a Type 17 Memory Device Record
+ * with a specific DIMM (DIMM, Board, and/or Processor number if appropriate).
+ *
+ * There will be one Record Type 202 for each DIMM socket possible in the system.
+ * A system will include a record for each DIMM socket even if that DIMM socket
+ * is on a memory board which is not currently installed.
+ *
+ * Offset | Name | Width | Description
+ * -------------------------------------
+ * 0x00 | Type | BYTE | 0xCA, DIMM Location Record
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | Assoc Record | WORD | Handle of Associated Type 17 Memory Record
+ * 0x06 | Board Number | BYTE | 1-based Memory Board number. 0FFh: DIMM on system board
+ * 0x07 | DIMM Number | BYTE | 1-based DIMM number
+ * 0x08 | Proc Number | BYTE | 1-based procssor number. 0FFh don't display
+ * 0x09 | Log DIMM Num | BYTE | 1-based Logical DIMM number mapping to ACPI numbering
+ * 0x0A | UEFI Dev Path| STRING| String number for UEFI Device Path
+ * 0x0B | UEFI Dev Name| STRING| String number for UEFI Device Structured Name
+ * 0x0C | Device Name | STRING| String number for Device Name
+ * 0x0D | Mem Cntrl Num| BYTE | 1-based Memory controller number
+ * 0x0E | Mem Chan Num | BYTE | 1-based memory channel number (matches silk screen)
+ * 0x0F | IE DIMM Num | BYTE | 0-based DIMM number repored by IE. FF -> not supported
+ * | Reserved G12 or later
+ * 0x10 | IE PLDM ID | BYTE | IE PLDM Sensor ID. FF -> not supported
+ * | Reserved G12 or later
+ * 0x11 | Vendor ID | WORD | Module manufacturers ID code as read by SPD
+ * 0x13 | Device ID | WORD | (NVDIMM only) Module product ID code from SPD
+ * 0x15 | Sub Cntrl Ven| WORD | (NVDIMM only) Controller manufacturer ID from SPD
+ * 0x17 | Sub Cntrl Dev| WORD | (NVDIMM only) Controller product ID from SPD
+ * 0x19 | Interleave | BYTE | 1-based unique interleave set within Procssor Number
+ * 0x1A | Part Number | STRING| String number for HPE part number from OEM SPD
+ * 0x1B | DIMM Index | BYTE | 0-based DIMM Index Per Channel
+ */
+
+ if (gen < G9) return 0;
+ pr_handle_name("%s DIMM Location Record", company);
+
+ if (h->length < 0x09) break;
+ if (!(opt.flags & FLAG_QUIET))
+ pr_attr("Associated Memory Record", "0x%04X", WORD(data + 0x04));
+ if (data[0x06] == 0xFF)
+ pr_attr("Board Number", "%s", "System Board");
+ else
+ pr_attr("Board Number", "%d", data[0x06]);
+ pr_attr("DIMM Number", "%d", data[0x07]);
+ if (data[0x08] != 0xFF)
+ pr_attr("Processor Number", "%d", data[0x08]);
+
+ if (h->length < 0x0A) break;
+ pr_attr("Logical DIMM Number", "%d", data[0x09]);
+
+ if (h->length < 0x0D) break;
+ if (data[0x0A])
+ pr_attr("UEFI Device Path", "%s", dmi_string(h, data[0x0A]));
+ if (data[0x0B])
+ pr_attr("UEFI Device Name", "%s", dmi_string(h, data[0x0B]));
+ if (data[0x0C])
+ pr_attr("Device Name", "%s", dmi_string(h, data[0x0C]));
+
+ if (h->length < 0x19) break;
+ if (data[0x0D])
+ pr_attr("Memory Controller Number", "%d", data[0x0D]);
+ if (data[0x0E])
+ pr_attr("Memory Channel Number", "%d", data[0x0E]);
+ if (gen < G12 && data[0x0F] != 0xFF)
+ pr_attr("IE DIMM Number", "%d", data[0x0F]);
+ if (gen < G12 && data[0x10] != 0xFF)
+ pr_attr("IE PLDM ID", "%d", data[0x10]);
+ if (data[0x11] || data[0x12])
+ pr_attr("Vendor ID", "0x%04X", WORD(data + 0x11));
+ if (data[0x13] || data[0x14])
+ pr_attr("Device ID", "0x%04X", WORD(data + 0x13));
+ if (data[0x15] || data[0x16])
+ dmi_memory_manufacturer_id("Controller Manufacturer ID", WORD(data + 0x15));
+ if (data[0x17] || data[0x18])
+ dmi_memory_product_id("Controller Product ID", WORD(data + 0x17));
+
+ if (h->length < 0x1A) break;
+ if (data[0x19])
+ pr_attr("Best Interleave", "%d", data[0x19]);
+ if (h->length < 0x1B) break;
+ pr_attr("Part Number", "%s", dmi_string(h, data[0x1A]));
+
+ if (h->length < 0x1C) break;
+ pr_attr("DIMM Index", "%d", data[0x1B]);
+ break;
+
case 203:
/*
* Vendor Specific: HP Device Correlation Record
@@ -987,12 +1348,12 @@ static int dmi_decode_hp(const struct dmi_header *h)
}
else
{
- dmi_hp_203_pciinfo("PCI Vendor ID", WORD(data + 0x08));
- dmi_hp_203_pciinfo("PCI Device ID", WORD(data + 0x0A));
- dmi_hp_203_pciinfo("PCI Sub Vendor ID", WORD(data + 0x0C));
- dmi_hp_203_pciinfo("PCI Sub Device ID", WORD(data + 0x0E));
- dmi_hp_203_pciinfo("PCI Class Code", (char)data[0x10]);
- dmi_hp_203_pciinfo("PCI Sub Class Code", (char)data[0x11]);
+ pr_attr("PCI Vendor ID", "0x%04x", WORD(data + 0x08));
+ pr_attr("PCI Device ID", "0x%04x", WORD(data + 0x0A));
+ pr_attr("PCI Sub Vendor ID", "0x%04x", WORD(data + 0x0C));
+ pr_attr("PCI Sub Device ID", "0x%04x", WORD(data + 0x0E));
+ pr_attr("PCI Class Code", "0x%02x", data[0x10]);
+ pr_attr("PCI Sub Class Code", "0x%02x", data[0x11]);
}
dmi_hp_203_assoc_hndl("Parent Handle", WORD(data + 0x12));
pr_attr("Flags", "0x%04X", WORD(data + 0x14));
@@ -1081,6 +1442,55 @@ static int dmi_decode_hp(const struct dmi_header *h)
}
break;
+ case 211:
+ /*
+ * Vendor Specific: HPE ProLiant Processor TControl Information
+ *
+ * Provides information about the Tcontrol value for each installed
+ * processor. This information is utilized to optimize the thermal fan
+ * control systems on the system. For some systems, this can be handled
+ * totally by the System ROM (systems with 7463 fan controllers). For
+ * systems that utilize TAFI, the Health Driver handles fan control.
+ * The Health Driver must know the value for Tcontrol for all processors
+ * to be able to customize the fan control for the installed processors.
+ *
+ * Tcontrol is a value programmed into each processor by Intel that
+ * indicates the processors thermal properties. The value is based on
+ * how "leaky" the particular processor's transistors are. A more "leaky"
+ * processor will get hotter for a given power input and thus will have a
+ * higher Tcontrol value. Intel officially suggests keeping a processor
+ * below the Tcontrol value for reliability reasons. HP is using Tcontrol
+ * as the point at which we begin spinning up the fans.
+ *
+ * Software must check the corresponding Record Type 4 to determine if the
+ * processor is installed. If the processor is not installed, the
+ * corresponding Record Type 211 should not be utilized. Record Type 197
+ * must be used to correlate Type 211 Record to the processor's APIC ID.
+ * This must be done to know which TAFI controller must be programmed with
+ * a particular Tcontrol value. Type 197 Record has an identifier which
+ * relates it to a Type 4 Record, so it is possible to correlate a
+ * Type 211 Record with a Type 197 Record.
+ *
+ * Offset | Name | Width | Description
+ * -------------------------------------
+ * 0x00 | Type | BYTE | 0xD3, TControl Info
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | Handle | WORD | Handle of Corresponding Type 4 Processor Record
+ * 0x06 |Tcontrol| BYTE | Processor Tcontrol Value. 00 -> Value N/A.
+ */
+
+ pr_handle_name("%s ProLiant TControl Information", company);
+ if (h->length < 0x07) break;
+ if (!(opt.flags & FLAG_QUIET))
+ pr_attr("Associated Processor Handle", "0x%04X",
+ WORD(data + 0x04));
+ if (data[0x06])
+ pr_attr("TControl Value", "%d", data[0x06]);
+ else
+ pr_attr("TControl Value", "%s", "N/A");
+ break;
+
case 212:
/*
* Vendor Specific: HPE 64-bit CRU Information
@@ -1100,11 +1510,8 @@ static int dmi_decode_hp(const struct dmi_header *h)
if (DWORD(data + 0x04) == 0x55524324)
{
u64 paddr = QWORD(data + 0x08);
- paddr.l += DWORD(data + 0x14);
- if (paddr.l < DWORD(data + 0x14))
- paddr.h++;
- pr_attr("Physical Address", "0x%08x%08x",
- paddr.h, paddr.l);
+ paddr += DWORD(data + 0x14);
+ pr_attr("Physical Address", "0x%016llx", paddr);
pr_attr("Length", "0x%08x", DWORD(data + 0x10));
}
break;
@@ -1202,6 +1609,90 @@ static int dmi_decode_hp(const struct dmi_header *h)
dmi_hp_224_chipid(WORD(data + 0x0a));
break;
+ case 226:
+ /*
+ * Vendor Specific: Physical Attribute Information
+ *
+ * This structure exists to store physical attributes for which virtual
+ * attributes have been stored in the industry standard SMBIOS fields
+ * which would normally store these physical attributes. This OEM SMBIOS
+ * Record was initially defined for the SYNERGY project where it was
+ * required that a virtual serial number and UUID be applied to the
+ * system. These virtual values must be stored in the standard SMBIOS
+ * fields so that industry standard software would detect these virtual
+ * values, allowing a workload to transition from one physical piece of
+ * hardware to another. This Record was created because a place was needed
+ * to store the physical attributes (serial number and UUID) for use in
+ * asset tracking and warranty events.
+ *
+ * Offset | Name | Width | Description
+ * -------------------------------------
+ * 0x00 | Type | BYTE | 0xE2, Physical Attribute
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | UUID |16 BYTE| if !0 => Physical Universal Unique ID Number
+ * 0x14 | SN | STRING| Physical Serial Number. Match Record Type 1
+ */
+ pr_handle_name("%s Physical Attribute Information", company);
+ if (h->length < 0x15) break;
+ if (QWORD(data + 0x0C) || QWORD(data + 0x04))
+ dmi_system_uuid(pr_attr, "UUID", data + 0x04, ver);
+ pr_attr("Serial Number", "%s", dmi_string(h, data[0x14]));
+ break;
+
+ case 229:
+ /*
+ * Vendor Specific: Reserved Memory Location
+ *
+ * This OEM SMBIOS Record is used to communicate the physical address
+ * location of memory regions reserved during POST by System Firmware.
+ * These memory regions will be reserved for various purposes. It is
+ * intended that this OEM SMBIOS Record be expandable to support any
+ * future POST reserved memory requirements. The regions reserved by
+ * POST will typically be reported by INT15h E820h as reserved memory.
+ * This record was initially defined to communicate to iLO FW and Smart
+ * Array Storage FW the location of a memory buffer reserved for passing
+ * information between the Smart Array Controller and iLO FW for providing
+ * hard drive temperatures to iLO FW fan control.
+ *
+ * Note: Multiple Type 229 Records may exist in the SMBIOS Table because
+ * each SMBIOS Record has a maximum length of 256 bytes and it is possible
+ * that there eventually would be enough reserved memory locations such
+ * that a single record could exceed this limit (each reserved memory
+ * location utilizes 16 bytes). Software utilizing the Type 229 Record
+ * should be written to handle the possibility of multiple records.
+ *
+ * Offset| Name | Width | Description
+ * -----------------------------------------
+ * 0x00 | Type | BYTE | 0xE5, Reserved Memory Location
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | Signature | DWORD | Enumerated value that indicates the type
+ * | of memory described by this Reserved
+ * | Memory Location
+ * 0x08 | Phys Addr | QWORD | 64-Bit physical memory address
+ * 0x10 | Size of Loc | DWORD | Bit[30:0] - Size of the Memory Location
+ * | Bit[31] - Indicates whether the size field in
+ * | Bits[30:0] is in 1 byte or 1 Kbyte granularity
+ * | 0 = Byte Granularity
+ * | 1 = Kbyte Granularity
+ * 0x14 | Mem Entries | 16 Bytes per Reserved Memory Entry
+ */
+ pr_handle_name("%s Reserved Memory Location", company);
+ for (ptr = 0x04, i = 1; ptr + 16 <= h->length; ptr += 16, i++)
+ {
+ pr_attr("Memory Location", "%d", i);
+ pr_subattr("Signature",
+ "%.4s", data + ptr);
+ pr_subattr("Physical Address", "0x%016llX",
+ QWORD(data + ptr + 0x04));
+ feat = DWORD(data + ptr + 0x0C);
+ dmi_print_memory_size(pr_subattr, "Size",
+ feat & 0x7fffffff,
+ feat >> 31);
+ }
+ break;
+
case 230:
/*
* Vendor Specific: Power Supply Information OEM SMBIOS Record
@@ -1230,6 +1721,75 @@ static int dmi_decode_hp(const struct dmi_header *h)
dmi_hp_230_method_bus_seg_addr(data[0x08], data[0x09], data[0x0A]);
break;
+ case 232:
+ /*
+ * Vendor Specific: DIMM Attributes Record
+ *
+ * This record is used to communicate information about DIMMs that is not
+ * available via Industry Standard SMBIOS Records.
+ *
+ * There will be one Record Type 232 for each DIMM socket possible in the
+ * system (just like Type 17 Records).
+ *
+ * Offset| Name | Width | Description
+ * -----------------------------------------
+ * 0x00 | Type | BYTE | 0xE8, DIMM Attributes Record
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | Assoc Handle| WORD | Associated Handle (Type 17)
+ * 0x06 | DIMM Attr | DWORD | Attributes Bitfield (Defined in code)
+ * 0x0A | Min Voltage | WORD | Minimum operating voltage in millivolts
+ * 0x0C | Cfg Voltage | WORD | Configured operating voltage in millivolts
+ * 0x0E | RESERVED |
+ * .... | RESERVED |
+ * 0x21 | RESERVED |
+ * 0x22 | Map-Out | BYTE | Bit Field reason for DIMM being mapped out
+ * 0x23 | Encryption | BYTE | Encryption status
+ */
+ if (gen < G9) return 0;
+ pr_handle_name("%s DIMM Attributes Record", company);
+
+ if (h->length < 0x0E) break;
+ if (!(opt.flags & FLAG_QUIET))
+ pr_attr("Associated Handle", "0x%04X", WORD(data + 0x04));
+
+ feat = DWORD(data + 0x06);
+ pr_attr("Attributes", "0x%08X", feat);
+ /* Bit [1:0] HP SmartMemory */
+ pr_subattr("HPE Smart Memory",
+ (feat & 0x03) == 0 ? "No" :
+ (feat & 0x03) == 1 ? "Yes" : "Unknown");
+ /* Bit [3:2] Indicator if DIMM is Load Reduced (LR) */
+ /* Bit [2]: 1 = Field Supported */
+ if (feat & (1 << 2))
+ pr_subattr("Load Reduced DIMM installed",
+ (feat & (1 << 3)) ? "Yes" : "No");
+ /* Bit [5:4] HP Standard DIMM Indicator */
+ /* Bit [4]: 1 = Field Supported */
+ if (feat & (1 << 4))
+ pr_subattr("HPE Standard Memory Installed",
+ (feat & (1 << 5)) ? "Yes" : "No");
+ if (WORD(data + 0x0A))
+ pr_attr("Minimum Voltage", "%d mV", WORD(data + 0x0A));
+ else
+ pr_attr("Minimum Voltage", "Unknown");
+
+ if (WORD(data + 0x0C))
+ pr_attr("Configured Voltage", "%d mV", WORD(data + 0x0C));
+ else
+ pr_attr("Configured Voltage", "Unknown");
+
+ if (h->length < 0x23) break;
+ feat = data[0x22];
+ if (feat) {
+ pr_attr("Map-Out Reason", "0x%0X", feat);
+ pr_subattr("Configuration Error", (feat & 0x01) ? "Yes" : "No");
+ pr_subattr("Training Error", (feat & 0x02) ? "Yes" : "No");
+ }
+ if (h->length < 0x24) break;
+ dmi_hp_232_encrypt(data[0x23]);
+ break;
+
case 233:
/*
* Vendor Specific: HPE ProLiant NIC MAC Information
@@ -1346,14 +1906,20 @@ static int dmi_decode_hp(const struct dmi_header *h)
* 0x0C | Parent Hub | BYTE | Instance number of internal Hub
* 0x0D | Port Speed | BYTE | Enumerated value of speed configured by BIOS
* 0x0E | Device Path| STRING| UEFI Device Path of USB endpoint
+ * 0x0F | PCI Seg | WORD | PCI Segment number of the USB controller
*/
if (gen < G9) return 0;
- pr_handle_name("%s Proliant USB Port Connector Correlation Record", company);
+ pr_handle_name("%s ProLiant USB Port Connector Correlation Record", company);
if (h->length < 0x0F) break;
if (!(opt.flags & FLAG_QUIET))
pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
- pr_attr("PCI Device", "%02x:%02x.%x", data[0x6],
- data[0x7] >> 3, data[0x7] & 0x7);
+ if (h->length < 0x11)
+ pr_attr("PCI Device", "%02x:%02x.%x", data[0x6],
+ data[0x7] >> 3, data[0x7] & 0x7);
+ else
+ pr_attr("PCI Device", "%04x:%02x:%02x.%x",
+ WORD(data + 0xF), data[0x6],
+ data[0x7] >> 3, data[0x7] & 0x7);
dmi_hp_238_loc("Location", data[0x8]);
dmi_hp_238_flags("Management Port", WORD(data + 0x9));
pr_attr("Port Instance", "%d", data[0xB]);
@@ -1415,7 +1981,7 @@ static int dmi_decode_hp(const struct dmi_header *h)
case 240:
/*
- * Vendor Specific: HPE Proliant Inventory Record
+ * Vendor Specific: HPE ProLiant Inventory Record
*
* Reports firmware version information for devices that report their
* firmware using their UEFI drivers. Additionally provides association
@@ -1435,7 +2001,7 @@ static int dmi_decode_hp(const struct dmi_header *h)
* 0x1B | Attr Set | QWORD | BitField: If defined, is attribute set?
* 0x23 | Version | DWORD | Lowest supported version.
*/
- pr_handle_name("%s Proliant Inventory Record", company);
+ pr_handle_name("%s ProLiant Inventory Record", company);
if (h->length < 0x27) break;
if (!(opt.flags & FLAG_QUIET))
pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
@@ -1443,7 +2009,7 @@ static int dmi_decode_hp(const struct dmi_header *h)
pr_attr("Version String", "%s", dmi_string(h, data[0x0A]));
if (DWORD(data + 0x0B))
- dmi_print_memory_size("Image Size", QWORD(data + 0xB), 0);
+ dmi_print_memory_size(pr_attr, "Image Size", QWORD(data + 0xB), 0);
else
pr_attr("Image Size", "Not Available");
@@ -1493,15 +2059,15 @@ static int dmi_decode_hp(const struct dmi_header *h)
*/
if (gen < G10) return 0;
pr_handle_name("%s ProLiant Hard Drive Inventory Record", company);
- if (h->length < 0x2C) break;
+ if (h->length < 0x2A) break;
if (!(opt.flags & FLAG_QUIET))
pr_attr("Associated Handle", "0x%04X", WORD(data + 0x4));
dmi_hp_242_hdd_type(data[0x06]);
pr_attr("ID", "%llx", QWORD(data + 0x07));
if (h->length < 0x3E)
- pr_attr("Capacity", "%u MB", DWORD(data + 0x0F));
+ dmi_print_storage_size("Capacity", DWORD(data + 0x0F), 2);
else
- dmi_print_memory_size("Capacity", QWORD(data + 0x2C), 0);
+ dmi_print_storage_size("Capacity", QWORD(data + 0x2C), 0);
/* NB: Poweron low QWORD good for 2,104,351,365,926,255 years */
pr_attr("Poweron", "%ld hours", QWORD(data + 0x13));
if (data[0x24])
@@ -1517,6 +2083,7 @@ static int dmi_decode_hp(const struct dmi_header *h)
pr_attr("Serial Number", dmi_string(h, data[0x27]));
pr_attr("Model Number", dmi_string(h, data[0x28]));
pr_attr("Firmware Revision", dmi_string(h, data[0x29]));
+ if (h->length < 0x2C) break;
pr_attr("Location", dmi_string(h, data[0x2A]));
feat = data[0x2B];
pr_attr("Encryption Status", "%s", (feat == 0) ? "Not Encrypted" :
@@ -1532,6 +2099,76 @@ static int dmi_decode_hp(const struct dmi_header *h)
dmi_hp_242_speed("Capable Speed", WORD(data + 0x3C));
break;
+ case 244:
+ /*
+ * Vendor Specific: HPE DIMM Current Configuration Record
+ *
+ * This record is used to communicate information about the currently
+ * configured memory regions on DIMMs installed in the system.
+ *
+ * There will be at least one Type 244 Record for each DIMM installed
+ * in the system with configured non-volatile or volatile memory.
+ *
+ * The number of DIMM Configuration Records for each DIMM is specified by
+ * the Configured Region Count field in its corresponding Type 232 DIMM
+ * Capabilities record. Each record represents a memory region on the
+ * DIMM, labeled by its Region ID. The Memory Type field can be used to
+ * determine the currently configured memory type for the region. When
+ * set to Volatile, the data on the memory region is lost on a power
+ * cycle. When set to Byte Accessible Persistent, the data on
+ * the memory region is retained through a reset. The Region Memory Size
+ * field contains the size of the configured region in MiB.
+ *
+ * The Passphrase State specifies the enable/disable state of the
+ * Passphrase requirement and is only applicable when the DIMM region is
+ * configured as Byte Accessible Persistent. The Interleave Set Index
+ * specifies which interleave set the DIMM region belongs to, if any.
+ * Regions with identical interleave set indices mean the DIMM regions
+ * are interleaved. These indices should match what is found in the DIMM's
+ * PCAT Interleave Information tables. Interleave set indices are
+ * 1-based. This will be a unique value per interleave set. If the DIMM
+ * region is not interleaved, the interleave set index will
+ * still be a unique value.
+ *
+ * Offset | Name | Width | Description
+ * ---------------------------------------
+ * 0x00 | Type | BYTE | 0xF4, DIMM Current Configuration Record
+ * 0x01 | Length | BYTE | Length of structure
+ * 0x02 | Handle | WORD | Unique handle
+ * 0x04 | Hndl Assoc | WORD | Handle of corresponding Type 17 record
+ * 0x06 | Region ID | BYTE | Unique ID of memory region on DIMM
+ * 0x07 | Region Type| WORD | Persistence Type. Bit Field: See code
+ * 0x09 | Region Size| QWORD | Size of memory region in MiB
+ * 0x11 | Passphrase | BYTE | Current state of Passphrase. See code
+ * 0x12 | Set Index | WORD | Interleave set index. Region w/ same index
+ * | are part of same interleave set.
+ * 0x14 | DIMM Count | BYTE | Number of DIMMs in interleave set
+ * 0x15 | Health | BYTE | Health of Interleave set defined in code
+ */
+
+ pr_handle_name("%s DIMM Current Configuration", company);
+ if (h->length < 0x14) break;
+ if (!(opt.flags & FLAG_QUIET))
+ pr_attr("Associated Handle", "0x%04X", WORD(data + 0x04));
+ pr_attr("Region ID", "%hhu", data[0x06]);
+ feat = WORD(data + 0x07);
+ pr_attr("Persistence Type", "%s", (feat & 0x01) ? "Volatile" :
+ ((feat >> 1) & 0x01) ? "Byte Accessible" :
+ ((feat >> 2) & 0x01) ? "Block I/O" :
+ "Reserved");
+ dmi_print_memory_size(pr_attr, "Size", QWORD(data + 0x09), 2);
+ pr_attr("Passphrase Enabled", "%s", data[0x11] ? "Yes" : "No");
+ feat = WORD(data + 0x12);
+ if (feat)
+ pr_attr("Interleave Set Index", "%u", feat);
+ if (h->length < 0x15) break;
+ if (feat)
+ pr_attr("Interleave DIMM Count", "%hhu", data[0x14]);
+ if (h->length < 0x16) break;
+ if (feat)
+ dmi_hp_244_health(data[0x15]);
+ break;
+
case 245:
/*
* Vendor Specific: HPE Extension Board Inventory Record
@@ -1551,18 +2188,33 @@ static int dmi_decode_hp(const struct dmi_header *h)
* 0x00 | Type | BYTE | 0xF5, Extension Board Inventory Record
* 0x01 | Length | BYTE | Length of structure
* 0x02 | Handle | WORD | Unique handle
- * 0x04 | Board Type | WORD | 0: PCIe Riser, Other Reserved
+ * 0x04 | Board Type | WORD | See below
*
* If Board Type == 0
* 0x05 | Riser Pos | WORD |
* 0x06 | Riser ID | BYTE |
* 0x07 | CPLD Vers | BTYE | 0-> No CPLD. Bits [7][6:0] Release:Vers
* 0x08 | Riser Name | STRING|
+ *
+ * If Board Type == 1
+ * 0x05 | Riser ID | BYTE |
+ * 0x06 | Riser FW Major | BYTE |
+ * 0x07 | Riser FW Minor | BYTE |
+ * 0x08 | Misc Attr | BYTE |
+ * 0x09 | Riser Name | STRING|
+ * 0x0A | Slot Count | BYTE |
+ * 0x0B | Slot ID | Varies| One per slot
*/
pr_handle_name("%s ProLiant Extension Board Inventory Record", company);
if (h->length < 0x05) break;
- if (data[0x04] == 0)
+ switch (data[0x04]) {
+ case 0:
dmi_hp_245_pcie_riser(h);
+ break;
+ case 1:
+ dmi_hp_245_pcie_mhs_riser(h);
+ break;
+ }
break;
default:
@@ -1693,15 +2345,17 @@ static int dmi_decode_ibm_lenovo(const struct dmi_header *h)
* Dispatch vendor-specific entries decoding
* Return 1 if decoding was successful, 0 otherwise
*/
-int dmi_decode_oem(const struct dmi_header *h)
+int dmi_decode_oem(const struct dmi_header *h, u16 ver)
{
switch (dmi_vendor)
{
case VENDOR_HP:
case VENDOR_HPE:
- return dmi_decode_hp(h);
+ return dmi_decode_hp(h, ver);
case VENDOR_ACER:
return dmi_decode_acer(h);
+ case VENDOR_DELL:
+ return dmi_decode_dell(h);
case VENDOR_IBM:
case VENDOR_LENOVO:
return dmi_decode_ibm_lenovo(h);
diff --git a/dmioem.h b/dmioem.h
index b79b769..4558a23 100644
--- a/dmioem.h
+++ b/dmioem.h
@@ -19,7 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "types.h"
+
struct dmi_header;
void dmi_set_vendor(const char *s, const char *p);
-int dmi_decode_oem(const struct dmi_header *h);
+int dmi_decode_oem(const struct dmi_header *h, u16 ver);
diff --git a/man/dmidecode.8 b/man/dmidecode.8
index 77c89a5..c4c292d 100644
--- a/man/dmidecode.8
+++ b/man/dmidecode.8
@@ -1,4 +1,6 @@
-.TH DMIDECODE 8 "February 2023" "dmidecode"
+'\" t
+.\" ** The above line should force tbl to be a preprocessor **
+.TH DMIDECODE 8 "June 2025" "dmidecode"
.\"
.SH NAME
dmidecode \- \s-1DMI\s0 table decoder
@@ -12,7 +14,7 @@ dmidecode \- \s-1DMI\s0 table decoder
is a tool for dumping a computer's \s-1DMI\s0 (some say \s-1SMBIOS\s0) table
contents in a human-readable format. This table contains a description of the
system's hardware components, as well as other useful pieces of information
-such as serial numbers and \s-1BIOS\s0 revision. Thanks to this table, you can
+such as serial numbers and firmware revision. Thanks to this table, you can
retrieve this information without having to probe for the actual hardware.
While this is a good point in terms of report speed and safeness, this also
makes the presented information possibly unreliable.
@@ -106,6 +108,9 @@ It must be a keyword from the following list:
.BR processor\-version ,
.BR processor\-frequency .
.hy
+In this context, for historical reasons, "bios" designates the platform
+firmware (regardless of it technically implementing the BIOS standard),
+while "firmware" designates the embedded controller firmware, if applicable.
Each keyword corresponds to a given \s-1DMI\s0 type and a given offset
within this entry type.
Not all strings may be meaningful or even defined on all systems. Some
@@ -147,6 +152,8 @@ keyword from the following list:
.BR slot .
.hy
Refer to the DMI TYPES section below for details.
+In this context, for historical reasons, "bios" designates the platform
+firmware, regardless of it technically implementing the BIOS standard.
If this option is used more than once, the set of displayed entries will be
the union of all the given types.
If \fITYPE\fP is not provided or not valid, a list of all valid keywords
@@ -201,7 +208,7 @@ determine the output format and are mutually exclusive.
.P
Please note in case of
.B dmidecode
-is run on a system with BIOS that boasts new SMBIOS specification, which
+is run on a system with firmware that boasts new SMBIOS specification, which
is not supported by the tool yet, it will print out relevant message in
addition to requested data on the very top of the output. Thus informs the
output data is not reliable.
@@ -213,7 +220,7 @@ r l
__
r l.
Type Information
-0 BIOS
+0 Platform Firmware
1 System
2 Baseboard
3 Chassis
@@ -226,7 +233,7 @@ Type Information
10 On Board Devices
11 OEM Strings
12 System Configuration Options
-13 BIOS Language
+13 Firmware Language
14 Group Associations
15 System Event Log
16 Physical Memory Array
diff --git a/types.h b/types.h
index 51c32d7..28126b1 100644
--- a/types.h
+++ b/types.h
@@ -1,59 +1,84 @@
#ifndef TYPES_H
#define TYPES_H
+#include <string.h>
+
#include "config.h"
+/*
+ * Use the byte-order macros provided by the compiler if available, else
+ * fall back to the ones provided by the C library.
+ */
+#ifdef __BYTE_ORDER__
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define BIGENDIAN
+#endif
+#else /* __BYTE_ORDER__ */
+#include <endian.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define BIGENDIAN
+#endif
+#endif /* __BYTE_ORDER__ */
+
+#ifdef BIGENDIAN
+#ifndef bswap_16
+#include <byteswap.h>
+#endif
+#endif
+
typedef unsigned char u8;
typedef unsigned short u16;
typedef signed short i16;
typedef unsigned int u32;
+typedef unsigned long long int u64;
/*
- * You may use the following defines to adjust the type definitions
- * depending on the architecture:
- * - Define BIGENDIAN on big-endian systems.
- * - Define ALIGNMENT_WORKAROUND if your system doesn't support
- * non-aligned memory access. In this case, we use a slower, but safer,
- * memory access method. This should be done automatically in config.h
- * for architectures which need it.
+ * Per SMBIOS v2.8.0 and later, all structures assume a little-endian
+ * ordering convention.
*/
+static inline u16 WORD(const void *x)
+{
+ u16 ret;
+ memcpy(&ret, x, sizeof(ret));
#ifdef BIGENDIAN
-typedef struct {
- u32 h;
- u32 l;
-} u64;
+#ifdef bswap_16
+ ret = bswap_16(ret);
#else
-typedef struct {
- u32 l;
- u32 h;
-} u64;
+ ret = __builtin_bswap16(ret);
+#endif
#endif
+ return ret;
+}
-#if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN)
-static inline u64 U64(u32 low, u32 high)
+static inline u32 DWORD(const void *x)
{
- u64 self;
-
- self.l = low;
- self.h = high;
-
- return self;
+ u32 ret;
+ memcpy(&ret, x, sizeof(ret));
+#ifdef BIGENDIAN
+#ifdef bswap_32
+ ret = bswap_32(ret);
+#else
+ ret = __builtin_bswap32(ret);
+#endif
+#endif
+ return ret;
}
+
+static inline u64 QWORD(const void *x)
+{
+ u64 ret;
+ memcpy(&ret, x, sizeof(ret));
+#ifdef BIGENDIAN
+#ifdef bswap_64
+ ret = bswap_64(ret);
+#else
+ ret = __builtin_bswap64(ret);
+#endif
#endif
+ return ret;
+}
-/*
- * Per SMBIOS v2.8.0 and later, all structures assume a little-endian
- * ordering convention.
- */
-#if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN)
-#define WORD(x) (u16)((x)[0] + ((x)[1] << 8))
-#define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24))
-#define QWORD(x) (U64(DWORD(x), DWORD(x + 4)))
-#else /* ALIGNMENT_WORKAROUND || BIGENDIAN */
-#define WORD(x) (u16)(*(const u16 *)(x))
-#define DWORD(x) (u32)(*(const u32 *)(x))
-#define QWORD(x) (*(const u64 *)(x))
-#endif /* ALIGNMENT_WORKAROUND || BIGENDIAN */
+#undef BIGENDIAN
#endif
diff --git a/util.c b/util.c
index dce84ff..7903c3e 100644
--- a/util.c
+++ b/util.c
@@ -261,19 +261,3 @@ out:
return p;
}
-
-/* Returns end - start + 1, assuming start < end */
-u64 u64_range(u64 start, u64 end)
-{
- u64 res;
-
- res.h = end.h - start.h;
- res.l = end.l - start.l;
-
- if (end.l < start.l)
- res.h--;
- if (++res.l == 0)
- res.h++;
-
- return res;
-}
diff --git a/util.h b/util.h
index 0d37f35..e6c5e49 100644
--- a/util.h
+++ b/util.h
@@ -27,4 +27,3 @@
int checksum(const u8 *buf, size_t len);
void *read_file(off_t base, size_t *len, const char *filename);
void *mem_chunk(off_t base, size_t len, const char *devmem);
-u64 u64_range(u64 start, u64 end);
diff --git a/version.h b/version.h
index dc5afe3..3c9b749 100644
--- a/version.h
+++ b/version.h
@@ -1 +1 @@
-#define VERSION "3.6"
+#define VERSION "3.7"