diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in index bc2603292..5c183936d 100644 --- a/contrib/fwupd.spec.in +++ b/contrib/fwupd.spec.in @@ -340,6 +340,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom %{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so %if 0%{?have_uefi} %{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so +%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so %endif %{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so %{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so diff --git a/plugins/meson.build b/plugins/meson.build index 68daba8c6..edc3519ae 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -57,6 +57,7 @@ endif if get_option('plugin_uefi') subdir('uefi') +subdir('uefi-recovery') endif if get_option('plugin_flashrom') diff --git a/plugins/uefi-recovery/README.md b/plugins/uefi-recovery/README.md new file mode 100644 index 000000000..311a2974f --- /dev/null +++ b/plugins/uefi-recovery/README.md @@ -0,0 +1,17 @@ +UEFI Support +============ + +Introduction +------------ + +Some devices have firmware bugs which mean they do not include a valid ESRT +table in old firmware versions. + +Create a 'fake' UEFI device with the lowest possible version so that it can be +updated to a version of firmware which does have an ESRT table. + +GUID Generation +--------------- + +All the HwId GUIDs are used for the fake UEFI device, and so should be used in +the firmware metadata for releases that should recover the system. diff --git a/plugins/uefi-recovery/fu-plugin-uefi-recovery.c b/plugins/uefi-recovery/fu-plugin-uefi-recovery.c new file mode 100644 index 000000000..cd2103b2a --- /dev/null +++ b/plugins/uefi-recovery/fu-plugin-uefi-recovery.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include "fu-device-metadata.h" +#include "fu-plugin-vfuncs.h" + +void +fu_plugin_init (FuPlugin *plugin) +{ + /* make sure that UEFI plugin is ready to receive devices */ + fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "uefi"); + fu_plugin_set_build_hash (plugin, FU_BUILD_HASH); +} + +gboolean +fu_plugin_startup (FuPlugin *plugin, GError **error) +{ + if (!fu_plugin_has_custom_flag (plugin, "requires-uefi-recovery")) { + g_set_error_literal (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "not required"); + return FALSE; + } + return TRUE; +} + +gboolean +fu_plugin_coldplug (FuPlugin *plugin, GError **error) +{ + GPtrArray *hwids = fu_plugin_get_hwids (plugin); + g_autoptr(FuDevice) device = fu_device_new (); + fu_device_set_id (device, "uefi-recovery"); + fu_device_set_name (device, "System Firmware ESRT Recovery"); + fu_device_set_version (device, "0.0.0", FWUPD_VERSION_FORMAT_TRIPLET); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_INTERNAL); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_NEEDS_REBOOT); + fu_device_set_metadata (device, FU_DEVICE_METADATA_UEFI_DEVICE_KIND, "system-firmware"); + fu_device_add_icon (device, "computer"); + for (guint i = 0; i < hwids->len; i++) { + const gchar *hwid = g_ptr_array_index (hwids, i); + fu_device_add_guid (device, hwid); + } + fu_plugin_device_register (plugin, device); + return TRUE; +} diff --git a/plugins/uefi-recovery/meson.build b/plugins/uefi-recovery/meson.build new file mode 100644 index 000000000..a674b2a57 --- /dev/null +++ b/plugins/uefi-recovery/meson.build @@ -0,0 +1,28 @@ +cargs = ['-DG_LOG_DOMAIN="FuPluginUefiRecovery"'] + +install_data(['uefi-recovery.quirk'], + install_dir: join_paths(datadir, 'fwupd', 'quirks.d') +) + +shared_module('fu_plugin_uefi_recovery', + fu_hash, + sources : [ + 'fu-plugin-uefi-recovery.c', + ], + include_directories : [ + include_directories('../..'), + include_directories('../../src'), + include_directories('../../libfwupd'), + ], + install : true, + install_dir: plugin_dir, + link_with : [ + libfwupdprivate, + ], + c_args : [ + cargs, + ], + dependencies : [ + plugin_deps, + ], +) diff --git a/plugins/uefi-recovery/uefi-recovery.quirk b/plugins/uefi-recovery/uefi-recovery.quirk new file mode 100644 index 000000000..8370ecf40 --- /dev/null +++ b/plugins/uefi-recovery/uefi-recovery.quirk @@ -0,0 +1,3 @@ +# Silicom Minnowboard Turbot MNW2MAX1.X64.0100.R01.1811141729 +[HwId=ea358e00-39f1-55b6-97be-a39225a585e1] +Flags = requires-uefi-recovery diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index d4d4be5a4..96b476755 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -12,6 +12,7 @@ #include #include +#include "fu-device-metadata.h" #include "fu-plugin-vfuncs.h" #include "fu-uefi-bgrt.h" @@ -448,7 +449,7 @@ fu_plugin_uefi_register_proxy_device (FuPlugin *plugin, FuDevice *device) void fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) { - if (fu_device_get_metadata (device, "UefiDeviceKind") != NULL) { + if (fu_device_get_metadata (device, FU_DEVICE_METADATA_UEFI_DEVICE_KIND) != NULL) { if (fu_device_get_guid_default (device) == NULL) { g_autofree gchar *dbg = fu_device_to_string (device); g_warning ("cannot create proxy device as no GUID: %s", dbg);