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