mirror of
https://github.com/ipxe/ipxe.git
synced 2025-02-25 18:55:24 -06:00
WIP - EFI settings
This commit is contained in:
parent
96bb6ba441
commit
587ef78ad0
@ -352,6 +352,9 @@ REQUIRE_OBJECT ( vram_settings );
|
|||||||
#ifdef ACPI_SETTINGS
|
#ifdef ACPI_SETTINGS
|
||||||
REQUIRE_OBJECT ( acpi_settings );
|
REQUIRE_OBJECT ( acpi_settings );
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EFI_SETTINGS
|
||||||
|
REQUIRE_OBJECT ( efi_settings );
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Drag in selected keyboard map
|
* Drag in selected keyboard map
|
||||||
|
@ -48,6 +48,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
|
|
||||||
#define REBOOT_CMD /* Reboot command */
|
#define REBOOT_CMD /* Reboot command */
|
||||||
|
|
||||||
|
#define EFI_SETTINGS /* EFI variable settings */
|
||||||
|
|
||||||
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
||||||
#define IOAPI_X86
|
#define IOAPI_X86
|
||||||
#define NAP_EFIX86
|
#define NAP_EFIX86
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
#include <config/defaults.h>
|
||||||
|
|
||||||
#define PCI_SETTINGS /* PCI device settings */
|
#define PCI_SETTINGS /* PCI device settings */
|
||||||
//#define CPUID_SETTINGS /* CPUID settings */
|
//#define CPUID_SETTINGS /* CPUID settings */
|
||||||
//#define MEMMAP_SETTINGS /* Memory map settings */
|
//#define MEMMAP_SETTINGS /* Memory map settings */
|
||||||
|
188
src/include/ipxe/efi/Guid/GlobalVariable.h
Normal file
188
src/include/ipxe/efi/Guid/GlobalVariable.h
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/** @file
|
||||||
|
GUID for EFI (NVRAM) Variables.
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@par Revision Reference:
|
||||||
|
GUID defined in UEFI 2.1
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __GLOBAL_VARIABLE_GUID_H__
|
||||||
|
#define __GLOBAL_VARIABLE_GUID_H__
|
||||||
|
|
||||||
|
FILE_LICENCE ( BSD2_PATENT );
|
||||||
|
|
||||||
|
#define EFI_GLOBAL_VARIABLE \
|
||||||
|
{ \
|
||||||
|
0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern EFI_GUID gEfiGlobalVariableGuid;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Follow UEFI 2.4 spec:
|
||||||
|
// To prevent name collisions with possible future globally defined variables,
|
||||||
|
// other internal firmware data variables that are not defined here must be
|
||||||
|
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
|
||||||
|
// any other GUID defined by the UEFI Specification. Implementations must
|
||||||
|
// only permit the creation of variables with a UEFI Specification-defined
|
||||||
|
// VendorGuid when these variables are documented in the UEFI Specification.
|
||||||
|
//
|
||||||
|
// Note: except the globally defined variables defined below, the spec also defines
|
||||||
|
// L"Boot####" - A boot load option.
|
||||||
|
// L"Driver####" - A driver load option.
|
||||||
|
// L"SysPrep####" - A System Prep application load option.
|
||||||
|
// L"Key####" - Describes hot key relationship with a Boot#### load option.
|
||||||
|
// The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h
|
||||||
|
// is included in the hex value. They can not be expressed as a #define like other globally
|
||||||
|
// defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one.
|
||||||
|
//
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The language codes that the firmware supports. This value is deprecated.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes"
|
||||||
|
///
|
||||||
|
/// The language code that the system is configured for. This value is deprecated.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_LANG_VARIABLE_NAME L"Lang"
|
||||||
|
///
|
||||||
|
/// The firmware's boot managers timeout, in seconds, before initiating the default boot selection.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_TIME_OUT_VARIABLE_NAME L"Timeout"
|
||||||
|
///
|
||||||
|
/// The language codes that the firmware supports.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes"
|
||||||
|
///
|
||||||
|
/// The language code that the system is configured for.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang"
|
||||||
|
///
|
||||||
|
/// The device path of the default input/output/error output console.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_CON_IN_VARIABLE_NAME L"ConIn"
|
||||||
|
#define EFI_CON_OUT_VARIABLE_NAME L"ConOut"
|
||||||
|
#define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut"
|
||||||
|
///
|
||||||
|
/// The device path of all possible input/output/error output devices.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev"
|
||||||
|
#define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev"
|
||||||
|
#define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev"
|
||||||
|
///
|
||||||
|
/// The ordered boot option load list.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder"
|
||||||
|
///
|
||||||
|
/// The boot option for the next boot only.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext"
|
||||||
|
///
|
||||||
|
/// The boot option that was selected for the current boot.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent"
|
||||||
|
///
|
||||||
|
/// The types of boot options supported by the boot manager. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport"
|
||||||
|
///
|
||||||
|
/// The ordered driver load option list.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder"
|
||||||
|
///
|
||||||
|
/// The ordered System Prep Application load option list.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder"
|
||||||
|
///
|
||||||
|
/// Identifies the level of hardware error record persistence
|
||||||
|
/// support implemented by the platform. This variable is
|
||||||
|
/// only modified by firmware and is read-only to the OS.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport"
|
||||||
|
///
|
||||||
|
/// Whether the system is operating in setup mode (1) or not (0).
|
||||||
|
/// All other values are reserved. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_SETUP_MODE_NAME L"SetupMode"
|
||||||
|
///
|
||||||
|
/// The Key Exchange Key Signature Database.
|
||||||
|
/// Its attribute is NV+BS+RT+AT.
|
||||||
|
///
|
||||||
|
#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
|
||||||
|
///
|
||||||
|
/// The public Platform Key.
|
||||||
|
/// Its attribute is NV+BS+RT+AT.
|
||||||
|
///
|
||||||
|
#define EFI_PLATFORM_KEY_NAME L"PK"
|
||||||
|
///
|
||||||
|
/// Array of GUIDs representing the type of signatures supported
|
||||||
|
/// by the platform firmware. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport"
|
||||||
|
///
|
||||||
|
/// Whether the platform firmware is operating in Secure boot mode (1) or not (0).
|
||||||
|
/// All other values are reserved. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
|
||||||
|
///
|
||||||
|
/// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault"
|
||||||
|
///
|
||||||
|
/// The OEM's default public Platform Key. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault"
|
||||||
|
///
|
||||||
|
/// The OEM's default secure boot signature store. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault"
|
||||||
|
///
|
||||||
|
/// The OEM's default secure boot blacklist signature store. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault"
|
||||||
|
///
|
||||||
|
/// The OEM's default secure boot timestamp signature store. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault"
|
||||||
|
///
|
||||||
|
/// Allows the firmware to indicate supported features and actions to the OS.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported"
|
||||||
|
///
|
||||||
|
/// Allows the OS to request the firmware to enable certain features and to take certain actions.
|
||||||
|
/// Its attribute is NV+BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications"
|
||||||
|
///
|
||||||
|
/// Whether the system is configured to use only vendor provided
|
||||||
|
/// keys or not. Should be treated as read-only.
|
||||||
|
/// Its attribute is BS+RT.
|
||||||
|
///
|
||||||
|
#define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys"
|
||||||
|
|
||||||
|
#endif
|
@ -404,6 +404,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#define ERRFILE_dhe ( ERRFILE_OTHER | 0x005a0000 )
|
#define ERRFILE_dhe ( ERRFILE_OTHER | 0x005a0000 )
|
||||||
#define ERRFILE_efi_cmdline ( ERRFILE_OTHER | 0x005b0000 )
|
#define ERRFILE_efi_cmdline ( ERRFILE_OTHER | 0x005b0000 )
|
||||||
#define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 )
|
#define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 )
|
||||||
|
#define ERRFILE_efi_settings ( ERRFILE_OTHER | 0x005d0000 )
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
189
src/interface/efi/efi_settings.c
Normal file
189
src/interface/efi/efi_settings.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Michael Brown <mbrown@fensystems.co.uk>.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* You can also choose to distribute this program under the terms of
|
||||||
|
* the Unmodified Binary Distribution Licence (as given in the file
|
||||||
|
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* EFI variable settings
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ipxe/settings.h>
|
||||||
|
#include <ipxe/init.h>
|
||||||
|
#include <ipxe/efi/efi.h>
|
||||||
|
#include <ipxe/efi/Guid/GlobalVariable.h>
|
||||||
|
|
||||||
|
/** An EFI variable settings block */
|
||||||
|
struct efivar_settings {
|
||||||
|
/** Settings block */
|
||||||
|
struct settings settings;
|
||||||
|
/** Vendor GUID */
|
||||||
|
EFI_GUID guid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** EFI settings scope */
|
||||||
|
static const struct settings_scope efivar_scope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check applicability of EFI variable setting
|
||||||
|
*
|
||||||
|
* @v settings Settings block
|
||||||
|
* @v setting Setting
|
||||||
|
* @ret applies Setting applies within this settings block
|
||||||
|
*/
|
||||||
|
static int efivar_applies ( struct settings *settings __unused,
|
||||||
|
const struct setting *setting ) {
|
||||||
|
|
||||||
|
return ( setting->scope == &efivar_scope );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch value of EFI variable setting
|
||||||
|
*
|
||||||
|
* @v settings Settings block
|
||||||
|
* @v setting Setting to fetch
|
||||||
|
* @v data Buffer to fill with setting data
|
||||||
|
* @v len Length of buffer
|
||||||
|
* @ret len Length of setting data, or negative error
|
||||||
|
*/
|
||||||
|
static int efivar_fetch ( struct settings *settings, struct setting *setting,
|
||||||
|
void *data, size_t len ) {
|
||||||
|
EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
|
||||||
|
struct efivar_settings *efivars =
|
||||||
|
container_of ( settings, struct efivar_settings, settings );
|
||||||
|
size_t name_len = strlen ( setting->name );
|
||||||
|
CHAR16 wname[ name_len + 1 /* wNUL */ ];
|
||||||
|
UINT32 attrs;
|
||||||
|
UINTN size;
|
||||||
|
void *buf;
|
||||||
|
unsigned int i;
|
||||||
|
EFI_STATUS efirc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Convert name to UCS-2 */
|
||||||
|
for ( i = 0 ; i <= name_len ; i++ )
|
||||||
|
wname[i] = setting->name[i];
|
||||||
|
|
||||||
|
/* Get variable length */
|
||||||
|
size = 0;
|
||||||
|
efirc = rs->GetVariable ( wname, &efivars->guid, &attrs, &size, NULL );
|
||||||
|
if ( ( efirc != 0 ) && ( efirc != EFI_BUFFER_TOO_SMALL ) ) {
|
||||||
|
rc = -EEFI ( efirc );
|
||||||
|
DBGC ( efivars, "EFIVAR %s:%s not present: %s\n",
|
||||||
|
efi_guid_ntoa ( &efivars->guid ), setting->name,
|
||||||
|
strerror ( rc ) );
|
||||||
|
goto err_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate temporary buffer, since GetVariable() is not
|
||||||
|
* guaranteed to return partial data for an underlength
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
buf = malloc ( size );
|
||||||
|
if ( ! buf ) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get variable value */
|
||||||
|
if ( ( efirc = rs->GetVariable ( wname, &efivars->guid, &attrs, &size,
|
||||||
|
buf ) ) != 0 ) {
|
||||||
|
rc = -EEFI ( efirc );
|
||||||
|
DBGC ( efivars, "EFIVAR %s:%s could not get %zd bytes: %s\n",
|
||||||
|
efi_guid_ntoa ( &efivars->guid ), setting->name,
|
||||||
|
( ( size_t ) size ), strerror ( rc ) );
|
||||||
|
goto err_get;
|
||||||
|
}
|
||||||
|
DBGC ( efivars, "EFIVAR %s:%s:\n", efi_guid_ntoa ( &efivars->guid ),
|
||||||
|
setting->name );
|
||||||
|
DBGC_HDA ( efivars, 0, buf, size );
|
||||||
|
|
||||||
|
/* Return setting value */
|
||||||
|
if ( len > size )
|
||||||
|
len = size;
|
||||||
|
memcpy ( data, buf, len );
|
||||||
|
if ( ! setting->type )
|
||||||
|
setting->type = &setting_type_hex;
|
||||||
|
|
||||||
|
/* Free temporary buffer */
|
||||||
|
free ( buf );
|
||||||
|
|
||||||
|
return size;
|
||||||
|
|
||||||
|
err_get:
|
||||||
|
free ( buf );
|
||||||
|
err_alloc:
|
||||||
|
err_len:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** EFI variable settings operations */
|
||||||
|
static struct settings_operations efivar_operations = {
|
||||||
|
.applies = efivar_applies,
|
||||||
|
.fetch = efivar_fetch,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Well-known EFI variable settings blocks */
|
||||||
|
static struct efivar_settings efivar_settings[] = {
|
||||||
|
{ .settings = { .name = "efi" }, .guid = EFI_GLOBAL_VARIABLE },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise EFI variable settings
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void efivar_init ( void ) {
|
||||||
|
struct efivar_settings *efivars;
|
||||||
|
const char *name;
|
||||||
|
unsigned int i;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Register all settings blocks */
|
||||||
|
for ( i = 0 ; i < ( sizeof ( efivar_settings ) /
|
||||||
|
sizeof ( efivar_settings[0] ) ) ; i++ ) {
|
||||||
|
|
||||||
|
/* Initialise settings block */
|
||||||
|
efivars = &efivar_settings[i];
|
||||||
|
settings_init ( &efivars->settings, &efivar_operations, NULL,
|
||||||
|
&efivar_scope );
|
||||||
|
|
||||||
|
/* Register settings block */
|
||||||
|
name = efivars->settings.name;
|
||||||
|
if ( ( rc = register_settings ( &efivars->settings, NULL,
|
||||||
|
name ) ) != 0 ) {
|
||||||
|
DBGC ( &efivar_settings, "EFIVAR could not register "
|
||||||
|
"%s: %s\n", name, strerror ( rc ) );
|
||||||
|
/* Continue trying to register remaining blocks */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** EFI variable settings initialiser */
|
||||||
|
struct init_fn efivar_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||||
|
.initialise = efivar_init,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user