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