diff --git a/plugins/flashrom/README.md b/plugins/flashrom/README.md index b08eb9d10..14f580f16 100644 --- a/plugins/flashrom/README.md +++ b/plugins/flashrom/README.md @@ -2,7 +2,10 @@ ## Introduction -This plugin uses `flashrom` to update the system firmware. +This plugin uses `libflashrom` to update the system firmware. It can be used +to update BIOS or ME regions of the flash. Device for ME region is created +only if "Intel SPI" plugin indicates that such a region exists, which makes +"Intel SPI" a dependency of this plugin for doing ME updates. ## Firmware Format @@ -45,6 +48,16 @@ Internal device uses hardware ID values which are derived from SMBIOS. They should match the values provided by `fwupdtool hwids` or the `ComputerHardwareIds.exe` Windows utility. +One more GUID has the following form: + +* `FLASHROM\VENDOR_{manufacturer}&PRODUCT_{product}®ION_{ifd_region_name}` + +Its purpose is to target specific regions of the flash as defined by IFD (Intel +SPI Flash Descriptor), examples: + +* `FLASHROM\VENDOR_Notebook&PRODUCT_NS50MU®ION_BIOS` +* `FLASHROM\VENDOR_Notebook&PRODUCT_NS50MU®ION_ME` + ## Update Behavior The firmware is deployed to the SPI chip when the machine is in normal runtime diff --git a/plugins/flashrom/fu-plugin-flashrom.c b/plugins/flashrom/fu-plugin-flashrom.c index 386847c07..fcd0f4472 100644 --- a/plugins/flashrom/fu-plugin-flashrom.c +++ b/plugins/flashrom/fu-plugin-flashrom.c @@ -142,15 +142,31 @@ fu_plugin_flashrom_device_set_hwids(FuPlugin *plugin, FuDevice *device) } } -static gboolean -fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error) +static FuDevice * +fu_plugin_flashrom_add_device(FuPlugin *plugin, FuIfdRegion region, GError **error) { FuContext *ctx = fu_plugin_get_context(plugin); const gchar *dmi_vendor; - g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx, FU_IFD_REGION_BIOS); + const gchar *product = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_PRODUCT_NAME); + const gchar *vendor = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_MANUFACTURER); + const gchar *region_str = fu_ifd_region_to_string(region); + g_autofree gchar *name = g_strdup_printf("%s (%s)", product, region_str); + g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx, region); - fu_device_set_name(device, fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_PRODUCT_NAME)); - fu_device_set_vendor(device, fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_MANUFACTURER)); + fu_device_set_name(device, name); + fu_device_set_vendor(device, vendor); + + fu_device_add_instance_str(device, "VENDOR", vendor); + fu_device_add_instance_str(device, "PRODUCT", product); + fu_device_add_instance_strup(device, "REGION", region_str); + if (!fu_device_build_instance_id(device, + error, + "FLASHROM", + "VENDOR", + "PRODUCT", + "REGION", + NULL)) + return NULL; /* use same VendorID logic as with UEFI */ dmi_vendor = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_BIOS_VENDOR); @@ -162,17 +178,19 @@ fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error) fu_plugin_flashrom_device_set_hwids(plugin, device); fu_plugin_flashrom_device_set_bios_info(plugin, device); if (!fu_device_setup(device, error)) - return FALSE; + return NULL; /* success */ fu_plugin_device_add(plugin, device); - return TRUE; + + g_object_ref(device); + return device; } static void fu_plugin_flashrom_device_registered(FuPlugin *plugin, FuDevice *device) { - GPtrArray *our_devices; + g_autoptr(FuDevice) me_device = NULL; const gchar *me_region_str = fu_ifd_region_to_string(FU_IFD_REGION_ME); /* we're only interested in a device from intel-spi plugin that corresponds to ME @@ -182,16 +200,21 @@ fu_plugin_flashrom_device_registered(FuPlugin *plugin, FuDevice *device) if (g_strcmp0(fu_device_get_logical_id(device), me_region_str) != 0) return; - our_devices = fu_plugin_get_devices(plugin); - for (guint i = 0; i < our_devices->len; i++) { - FuFlashromDevice *our_device = - FU_FLASHROM_DEVICE(g_ptr_array_index(our_devices, i)); - if (fu_flashrom_device_get_region(our_device) == FU_IFD_REGION_ME) { - /* unlock operation requires device to be locked */ - if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_LOCKED)) - fu_device_add_flag(FU_DEVICE(our_device), FWUPD_DEVICE_FLAG_LOCKED); - } - } + me_device = fu_plugin_flashrom_add_device(plugin, FU_IFD_REGION_ME, NULL); + if (me_device == NULL) + return; + + /* unlock operation requires device to be locked */ + if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_LOCKED)) + fu_device_add_flag(me_device, FWUPD_DEVICE_FLAG_LOCKED); +} + +static gboolean +fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error) +{ + g_autoptr(FuDevice) device = + fu_plugin_flashrom_add_device(plugin, FU_IFD_REGION_BIOS, error); + return (device != NULL); } static gboolean