60918b
From e629bccb2ced5f9e52e142bd841d310434975c63 Mon Sep 17 00:00:00 2001
60918b
From: Alexey Dokuchaev <danfe@nsu.ru>
60918b
Date: Thu, 30 Nov 2017 16:27:48 +0100
60918b
Subject: [PATCH 09/10] UEFI support on FreeBSD
60918b
60918b
Currently, dmidecode(8) does not work on FreeBSD booted in UEFI mode.
60918b
Previously it was understandable, since there are no things like Linuxish
60918b
/proc/efi/systab or /sys/firmware/efi/systab to read from under FreeBSD.
60918b
60918b
However, 7 months ago, ambrisko@ had added support for exposing the SMBIOS
60918b
anchor base address via kernel environment:
60918b
60918b
    https://svnweb.freebsd.org/base?view=revision&revision=307326
60918b
60918b
I've patched dmidecode.c to try to get the address from hint.smbios.0.mem
60918b
and fall back to traditional address space scanning.  I've tested it both
60918b
on EFI (amd64 laptop) and non-EFI (i386 desktop) machines.
60918b
60918b
---
60918b
 dmidecode.c | 33 +++++++++++++++++++++++++++++++++
60918b
 1 file changed, 33 insertions(+)
60918b
60918b
diff --git a/dmidecode.c b/dmidecode.c
60918b
index 6559567..aadef75 100644
60918b
--- a/dmidecode.c
60918b
+++ b/dmidecode.c
60918b
@@ -64,6 +64,11 @@
60918b
 #include <stdlib.h>
60918b
 #include <unistd.h>
60918b
 
60918b
+#ifdef __FreeBSD__
60918b
+#include <errno.h>
60918b
+#include <kenv.h>
60918b
+#endif
60918b
+
60918b
 #include "version.h"
60918b
 #include "config.h"
60918b
 #include "types.h"
60918b
@@ -4934,13 +4939,18 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
60918b
 #define EFI_NO_SMBIOS   (-2)
60918b
 static int address_from_efi(off_t *address)
60918b
 {
60918b
+#if defined(__linux__)
60918b
 	FILE *efi_systab;
60918b
 	const char *filename;
60918b
 	char linebuf[64];
60918b
+#elif defined(__FreeBSD__)
60918b
+	char addrstr[KENV_MVALLEN + 1];
60918b
+#endif
60918b
 	int ret;
60918b
 
60918b
 	*address = 0; /* Prevent compiler warning */
60918b
 
60918b
+#if defined(__linux__)
60918b
 	/*
60918b
 	 * Linux up to 2.6.6: /proc/efi/systab
60918b
 	 * Linux 2.6.7 and up: /sys/firmware/efi/systab
60918b
@@ -4972,6 +4982,29 @@ static int address_from_efi(off_t *address)
60918b
 
60918b
 	if (ret == EFI_NO_SMBIOS)
60918b
 		fprintf(stderr, "%s: SMBIOS entry point missing\n", filename);
60918b
+#elif defined(__FreeBSD__)
60918b
+	/*
60918b
+	 * On FreeBSD, SMBIOS anchor base address in UEFI mode is exposed
60918b
+	 * via kernel environment:
60918b
+	 * https://svnweb.freebsd.org/base?view=revision&revision=307326
60918b
+	 */
60918b
+	ret = kenv(KENV_GET, "hint.smbios.0.mem", addrstr, sizeof(addrstr));
60918b
+	if (ret == -1)
60918b
+	{
60918b
+		if (errno != ENOENT)
60918b
+			perror("kenv");
60918b
+		return EFI_NOT_FOUND;
60918b
+	}
60918b
+
60918b
+	*address = strtoull(addrstr, NULL, 0);
60918b
+	if (!(opt.flags & FLAG_QUIET))
60918b
+		printf("# SMBIOS entry point at 0x%08llx\n",
60918b
+		    (unsigned long long)*address);
60918b
+
60918b
+	ret = 0;
60918b
+#else
60918b
+	ret = EFI_NOT_FOUND;
60918b
+#endif
60918b
 	return ret;
60918b
 }
60918b
 
60918b
-- 
60918b
2.9.5
60918b