svn commit: r344371 - in stable/11/stand/efi: include libefi loader

Kyle Evans kevans at FreeBSD.org
Wed Feb 20 18:34:22 UTC 2019


Author: kevans
Date: Wed Feb 20 18:34:20 2019
New Revision: 344371
URL: https://svnweb.freebsd.org/changeset/base/344371

Log:
  MFC r335228-r335231, r335272: stand: efiloader fixes
  
  r335228:
  Migrate has_keyboard to bool.
  
  r335229:
  Provide a more direct interface to tell ZFS what the preferred handle
  is. We tell the ZFS code now, and it checks rather than having a
  callback to do the checks.
  
  This will allow us to have a more graceful fallback code. In the
  future, it's anticipated that we may fallback to a more global search
  (or implement a command to do so) when reqeusted by the user, or we
  detect a violation of the UEFI Boot Manager protocol severe enough to
  warrant this backstop. For now, it just allows us to get rid of img as
  a global.
  
  r335230:
  Move arg parsing into its own routine for possible later reuse.
  
  r335231:
  There's no need to walk through the tables looking for the smbios
  table if we're just going to ignore it on arm, so expand, slightly,
  the reach of the ifdef. Move the buffer to the inner block so we
  don't have a separate #ifdef far away from these lines.
  
  The issue on arm is that smbios_detect does unaligned accesses, which
  in the u-boot implementing EFI context causes a crash.
  
  r335272:
  Many netboot scenarios don't have /boot/defaults/loader.conf. As
  a fallback, also check /boot/kernel/kernel existing as well, since
  that's the fallback behavior of the loader.

Modified:
  stable/11/stand/efi/include/efizfs.h
  stable/11/stand/efi/libefi/efizfs.c
  stable/11/stand/efi/loader/main.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/stand/efi/include/efizfs.h
==============================================================================
--- stable/11/stand/efi/include/efizfs.h	Wed Feb 20 18:30:54 2019	(r344370)
+++ stable/11/stand/efi/include/efizfs.h	Wed Feb 20 18:34:20 2019	(r344371)
@@ -44,11 +44,11 @@ typedef struct zfsinfo
 
 extern uint64_t pool_guid;
 
-extern void efi_zfs_probe(void);
-extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void);
-extern bool efi_zfs_is_preferred(EFI_HANDLE *h);
-extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t);
-extern bool efizfs_get_guid_by_handle(EFI_HANDLE, uint64_t *);
+void efi_zfs_probe(void);
+EFI_HANDLE efizfs_get_handle_by_guid(uint64_t);
+bool efizfs_get_guid_by_handle(EFI_HANDLE, uint64_t *);
+zfsinfo_list_t *efizfs_get_zfsinfo_list(void);
+void efizfs_set_preferred(EFI_HANDLE);
 
 #endif
 

Modified: stable/11/stand/efi/libefi/efizfs.c
==============================================================================
--- stable/11/stand/efi/libefi/efizfs.c	Wed Feb 20 18:30:54 2019	(r344370)
+++ stable/11/stand/efi/libefi/efizfs.c	Wed Feb 20 18:34:20 2019	(r344371)
@@ -45,6 +45,14 @@ static zfsinfo_list_t zfsinfo;
 
 uint64_t pool_guid;
 
+static EFI_HANDLE preferred;
+
+void
+efizfs_set_preferred(EFI_HANDLE h)
+{
+	preferred = h;
+}
+
 zfsinfo_list_t *
 efizfs_get_zfsinfo_list(void)
 {
@@ -110,16 +118,13 @@ efi_zfs_probe(void)
 	 */
 	STAILQ_FOREACH(hd, hdi, pd_link) {
 		STAILQ_FOREACH(pd, &hd->pd_part, pd_link) {
-
 			snprintf(devname, sizeof(devname), "%s%dp%d:",
 			    efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit);
-
-                        if (zfs_probe_dev(devname, &guid) == 0) {
-                                insert_zfs(pd->pd_handle, guid);
-
-                                if (efi_zfs_is_preferred(pd->pd_handle))
-                                        pool_guid = guid;
-                        }
+			if (zfs_probe_dev(devname, &guid) == 0) {
+				insert_zfs(pd->pd_handle, guid);
+				if (pd->pd_handle == preferred)
+					pool_guid = guid;
+			}
 
 		}
 	}

Modified: stable/11/stand/efi/loader/main.c
==============================================================================
--- stable/11/stand/efi/loader/main.c	Wed Feb 20 18:30:54 2019	(r344370)
+++ stable/11/stand/efi/loader/main.c	Wed Feb 20 18:34:20 2019	(r344371)
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
 
 #ifdef EFI_ZFS_BOOT
 #include <libzfs.h>
-
 #include "efizfs.h"
 #endif
 
@@ -73,8 +72,6 @@ EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
 EFI_GUID fdtdtb = FDT_TABLE_GUID;
 EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
 
-static EFI_LOADED_IMAGE *img;
-
 /*
  * Number of seconds to wait for a keystroke before exiting with failure
  * in the event no currdev is found. -2 means always break, -1 means
@@ -84,22 +81,14 @@ static EFI_LOADED_IMAGE *img;
  */
 static int fail_timeout = 5;
 
-#ifdef	EFI_ZFS_BOOT
-bool
-efi_zfs_is_preferred(EFI_HANDLE *h)
-{
-        return (h == img->DeviceHandle);
-}
-#endif
-
-static int
+static bool
 has_keyboard(void)
 {
 	EFI_STATUS status;
 	EFI_DEVICE_PATH *path;
 	EFI_HANDLE *hin, *hin_end, *walker;
 	UINTN sz;
-	int retval = 0;
+	bool retval = false;
 
 	/*
 	 * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and
@@ -146,7 +135,7 @@ has_keyboard(void)
 				acpi = (ACPI_HID_DEVICE_PATH *)(void *)path;
 				if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 &&
 				    (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) {
-					retval = 1;
+					retval = true;
 					goto out;
 				}
 			/*
@@ -162,7 +151,7 @@ has_keyboard(void)
 				if (usb->DeviceClass == 3 && /* HID */
 				    usb->DeviceSubClass == 1 && /* Boot devices */
 				    usb->DeviceProtocol == 1) { /* Boot keyboards */
-					retval = 1;
+					retval = true;
 					goto out;
 				}
 			}
@@ -231,7 +220,8 @@ sanity_check_currdev(void)
 {
 	struct stat st;
 
-	return (stat("/boot/defaults/loader.conf", &st) == 0);
+	return (stat("/boot/defaults/loader.conf", &st) == 0 ||
+	    stat("/boot/kernel/kernel", &st) == 0);
 }
 
 #ifdef EFI_ZFS_BOOT
@@ -408,58 +398,14 @@ interactive_interrupt(const char *msg)
 	return (false);
 }
 
-EFI_STATUS
-main(int argc, CHAR16 *argv[])
+int
+parse_args(int argc, CHAR16 *argv[], bool has_kbd)
 {
-	char var[128];
-	EFI_GUID *guid;
 	int i, j, howto;
 	bool vargood;
-	UINTN k;
-	int has_kbd;
-	char *s;
-	EFI_DEVICE_PATH *imgpath;
-	CHAR16 *text;
-	EFI_STATUS status;
-	UINT16 boot_current;
-	size_t sz;
-	UINT16 boot_order[100];
-#if !defined(__arm__)
-	char buf[40];
-#endif
+	char var[128];
 
-	archsw.arch_autoload = efi_autoload;
-	archsw.arch_getdev = efi_getdev;
-	archsw.arch_copyin = efi_copyin;
-	archsw.arch_copyout = efi_copyout;
-	archsw.arch_readin = efi_readin;
-#ifdef EFI_ZFS_BOOT
-	/* Note this needs to be set before ZFS init. */
-	archsw.arch_zfs_probe = efi_zfs_probe;
-#endif
-
-        /* Get our loaded image protocol interface structure. */
-	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
-
-	/* Init the time source */
-	efi_time_init();
-
-	has_kbd = has_keyboard();
-
 	/*
-	 * XXX Chicken-and-egg problem; we want to have console output
-	 * early, but some console attributes may depend on reading from
-	 * eg. the boot device, which we can't do yet.  We can use
-	 * printf() etc. once this is done.
-	 */
-	cons_probe();
-
-	/*
-	 * Initialise the block cache. Set the upper limit.
-	 */
-	bcache_init(32768, 512);
-
-	/*
 	 * Parse the args to set the console settings, etc
 	 * boot1.efi passes these in, if it can read /boot.config or /boot/config
 	 * or iPXE may be setup to pass these in. Or the optional argument in the
@@ -547,7 +493,63 @@ main(int argc, CHAR16 *argv[])
 			}
 		}
 	}
+	return (howto);
+}
 
+
+EFI_STATUS
+main(int argc, CHAR16 *argv[])
+{
+	EFI_GUID *guid;
+	int howto, i;
+	UINTN k;
+	bool has_kbd;
+	char *s;
+	EFI_DEVICE_PATH *imgpath;
+	CHAR16 *text;
+	EFI_STATUS status;
+	UINT16 boot_current;
+	size_t sz;
+	UINT16 boot_order[100];
+	EFI_LOADED_IMAGE *img;
+
+	archsw.arch_autoload = efi_autoload;
+	archsw.arch_getdev = efi_getdev;
+	archsw.arch_copyin = efi_copyin;
+	archsw.arch_copyout = efi_copyout;
+	archsw.arch_readin = efi_readin;
+#ifdef EFI_ZFS_BOOT
+	/* Note this needs to be set before ZFS init. */
+	archsw.arch_zfs_probe = efi_zfs_probe;
+#endif
+
+        /* Get our loaded image protocol interface structure. */
+	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
+
+#ifdef EFI_ZFS_BOOT
+	/* Tell ZFS probe code where we booted from */
+	efizfs_set_preferred(img->DeviceHandle);
+#endif
+	/* Init the time source */
+	efi_time_init();
+
+	has_kbd = has_keyboard();
+
+	/*
+	 * XXX Chicken-and-egg problem; we want to have console output
+	 * early, but some console attributes may depend on reading from
+	 * eg. the boot device, which we can't do yet.  We can use
+	 * printf() etc. once this is done.
+	 */
+	cons_probe();
+
+	/*
+	 * Initialise the block cache. Set the upper limit.
+	 */
+	bcache_init(32768, 512);
+
+	howto = parse_args(argc, argv, has_kbd);
+
 	bootenv_set(howto);
 
 	/*
@@ -651,18 +653,20 @@ main(int argc, CHAR16 *argv[])
 	efi_init_environment();
 	setenv("LINES", "24", 1);	/* optional */
 
+#if !defined(__arm__)
 	for (k = 0; k < ST->NumberOfTableEntries; k++) {
 		guid = &ST->ConfigurationTable[k].VendorGuid;
-#if !defined(__arm__)
 		if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
+			char buf[40];
+
 			snprintf(buf, sizeof(buf), "%p",
 			    ST->ConfigurationTable[k].VendorTable);
 			setenv("hint.smbios.0.mem", buf, 1);
 			smbios_detect(ST->ConfigurationTable[k].VendorTable);
 			break;
 		}
-#endif
 	}
+#endif
 
 	interact();			/* doesn't return */
 


More information about the svn-src-all mailing list