From owner-svn-src-head@freebsd.org Thu Aug 31 17:32:25 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 855ABE02983; Thu, 31 Aug 2017 17:32:25 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5B6711C9C; Thu, 31 Aug 2017 17:32:25 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7VHWOJf037353; Thu, 31 Aug 2017 17:32:24 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7VHWOQZ037351; Thu, 31 Aug 2017 17:32:24 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201708311732.v7VHWOQZ037351@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Thu, 31 Aug 2017 17:32:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r323065 - in head/sys/boot/efi: boot1 include X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: in head/sys/boot/efi: boot1 include X-SVN-Commit-Revision: 323065 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Aug 2017 17:32:25 -0000 Author: imp Date: Thu Aug 31 17:32:24 2017 New Revision: 323065 URL: https://svnweb.freebsd.org/changeset/base/323065 Log: Save where we're booted from Record the file path for boot1.efi as the UEFI environemnt variable FreeBSDBootVarGUID:Boot1Path. Record the device this came from as FreeBSDBootVarGUID:Boot1Dev. While later stages of the boot may be able to guess these values by retrieving UEFIGlobal:BootCurrent and groveling through the correct UEFIGlobal:BootXXXX, this provides certanty in the face of behavior from any part of the boot loader chain that might "guess" what to do next. These env variables are volatile and will disappear on reboot. Sponsored by: Netflix Modified: head/sys/boot/efi/boot1/boot1.c head/sys/boot/efi/include/efiapi.h Modified: head/sys/boot/efi/boot1/boot1.c ============================================================================== --- head/sys/boot/efi/boot1/boot1.c Thu Aug 31 17:32:19 2017 (r323064) +++ head/sys/boot/efi/boot1/boot1.c Thu Aug 31 17:32:24 2017 (r323065) @@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$"); #include #include +typedef CHAR16 efi_char; +#include #include "boot_module.h" #include "paths.h" @@ -53,6 +55,7 @@ static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCO static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; +static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; /* * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures @@ -77,6 +80,34 @@ Free(void *buf, const char *file __unused, int line __ (void)BS->FreePool(buf); } +static int +wcslen(const CHAR16 *str) +{ + int i; + + i = 0; + while (*str++) + i++; + return i; +} + +static EFI_STATUS +efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr) +{ + CHAR16 *var = NULL; + size_t len; + EFI_STATUS rv; + + utf8_to_ucs2(varname, &var, &len); + if (var == NULL) + return (EFI_OUT_OF_RESOURCES); + rv = RS->SetVariable(var, &FreeBSDBootVarGUID, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + wcslen(valstr) * 2, valstr); + free(var); + return (rv); +} + /* * devpath_last returns the last non-path end node in devpath. */ @@ -394,6 +425,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) if (status == EFI_SUCCESS) { text = efi_devpath_name(img->FilePath); printf(" Load Path: %S\n", text); + efi_setenv_freebsd_wcs("Boot1Path", text); efi_free_devpath_name(text); status = BS->HandleProtocol(img->DeviceHandle, &DevicePathGUID, @@ -404,6 +436,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) } else { text = efi_devpath_name(imgpath); printf(" Load Device: %S\n", text); + efi_setenv_freebsd_wcs("Boot1Dev", text); efi_free_devpath_name(text); } Modified: head/sys/boot/efi/include/efiapi.h ============================================================================== --- head/sys/boot/efi/include/efiapi.h Thu Aug 31 17:32:19 2017 (r323064) +++ head/sys/boot/efi/include/efiapi.h Thu Aug 31 17:32:24 2017 (r323065) @@ -247,7 +247,7 @@ EFI_STATUS typedef EFI_STATUS (EFIAPI *EFI_SET_VARIABLE) ( - IN CHAR16 *VariableName, + IN const CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize,