plugins/flashrom: create separate device for ME region

Created only if intel_spi plugin indicates that the region exists by
creating its own device for it.

Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
Sergii Dmytruk 2022-04-18 15:54:49 +03:00 committed by Richard Hughes
parent 103e4ed889
commit 2bac03eee1
2 changed files with 55 additions and 19 deletions

View File

@ -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}&REGION_{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&REGION_BIOS`
* `FLASHROM\VENDOR_Notebook&PRODUCT_NS50MU&REGION_ME`
## Update Behavior
The firmware is deployed to the SPI chip when the machine is in normal runtime

View File

@ -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