plugins/flashrom: make region we're flashing a property

Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
Sergii Dmytruk 2022-04-12 22:59:00 +03:00 committed by Richard Hughes
parent b678170ee7
commit 523ed0d7b4
3 changed files with 98 additions and 9 deletions

View File

@ -21,12 +21,15 @@
struct _FuFlashromDevice {
FuUdevDevice parent_instance;
FuIfdRegion region;
struct flashrom_flashctx *flashctx;
struct flashrom_programmer *flashprog;
};
G_DEFINE_TYPE(FuFlashromDevice, fu_flashrom_device, FU_TYPE_UDEV_DEVICE)
enum { PROP_0, PROP_REGION, PROP_LAST };
static gboolean
fu_flashrom_device_set_quirk_kv(FuDevice *device,
const gchar *key,
@ -161,8 +164,8 @@ fu_flashrom_device_prepare(FuDevice *device,
return FALSE;
}
/* include bios region for safety reasons */
if (flashrom_layout_include_region(layout, "bios")) {
/* update only one specific region of the flash and do not touch others */
if (flashrom_layout_include_region(layout, fu_ifd_region_to_string(self->region))) {
g_set_error_literal(error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
@ -223,8 +226,8 @@ fu_flashrom_device_write_firmware(FuDevice *device,
return FALSE;
}
/* include bios region for safety reasons */
if (flashrom_layout_include_region(layout, "bios")) {
/* update only one specific region of the flash and do not touch others */
if (flashrom_layout_include_region(layout, fu_ifd_region_to_string(self->region))) {
g_set_error_literal(error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
@ -296,7 +299,6 @@ fu_flashrom_device_init(FuFlashromDevice *self)
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_ENSURE_SEMVER);
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_MD_SET_SIGNED);
fu_device_set_physical_id(FU_DEVICE(self), "flashrom");
fu_device_set_logical_id(FU_DEVICE(self), "bios");
fu_device_set_version_format(FU_DEVICE(self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_add_icon(FU_DEVICE(self), "computer");
fu_device_register_private_flag(FU_DEVICE(self),
@ -311,6 +313,38 @@ fu_flashrom_device_constructed(GObject *obj)
fu_device_add_instance_id(FU_DEVICE(self), "main-system-firmware");
}
static void
fu_flashrom_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
switch (prop_id) {
case PROP_REGION:
g_value_set_uint(value, self->region);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
fu_flashrom_device_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
switch (prop_id) {
case PROP_REGION:
self->region = g_value_get_uint(value);
fu_device_set_logical_id(FU_DEVICE(self), fu_ifd_region_to_string(self->region));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
fu_flashrom_device_finalize(GObject *object)
{
@ -320,8 +354,27 @@ fu_flashrom_device_finalize(GObject *object)
static void
fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
{
GParamSpec *pspec;
GObjectClass *object_class = G_OBJECT_CLASS(klass);
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
object_class->get_property = fu_flashrom_device_get_property;
object_class->set_property = fu_flashrom_device_set_property;
/**
* FuFlashromDevice:region:
*
* The IFD region that's being managed.
*/
pspec = g_param_spec_uint("region",
NULL,
NULL,
0,
G_MAXUINT,
0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME);
g_object_class_install_property(object_class, PROP_REGION, pspec);
object_class->constructed = fu_flashrom_device_constructed;
object_class->finalize = fu_flashrom_device_finalize;
klass_device->set_quirk_kv = fu_flashrom_device_set_quirk_kv;
@ -334,7 +387,14 @@ fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
}
FuDevice *
fu_flashrom_device_new(FuContext *ctx)
fu_flashrom_device_new(FuContext *ctx, FuIfdRegion region)
{
return FU_DEVICE(g_object_new(FU_TYPE_FLASHROM_DEVICE, "context", ctx, NULL));
return FU_DEVICE(
g_object_new(FU_TYPE_FLASHROM_DEVICE, "context", ctx, "region", region, NULL));
}
FuIfdRegion
fu_flashrom_device_get_region(FuFlashromDevice *self)
{
return self->region;
}

View File

@ -13,4 +13,7 @@
G_DECLARE_FINAL_TYPE(FuFlashromDevice, fu_flashrom_device, FU, FLASHROM_DEVICE, FuUdevDevice)
FuDevice *
fu_flashrom_device_new(FuContext *ctx);
fu_flashrom_device_new(FuContext *ctx, FuIfdRegion region);
FuIfdRegion
fu_flashrom_device_get_region(FuFlashromDevice *self);

View File

@ -147,7 +147,7 @@ fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error)
{
FuContext *ctx = fu_plugin_get_context(plugin);
const gchar *dmi_vendor;
g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx);
g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx, FU_IFD_REGION_BIOS);
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));
@ -169,6 +169,31 @@ fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error)
return TRUE;
}
static void
fu_plugin_flashrom_device_registered(FuPlugin *plugin, FuDevice *device)
{
GPtrArray *our_devices;
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
* region of IFD */
if (g_strcmp0(fu_device_get_plugin(device), "intel_spi") != 0)
return;
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);
}
}
}
static gboolean
fu_plugin_flashrom_startup(FuPlugin *plugin, GError **error)
{
@ -188,6 +213,7 @@ fu_plugin_init_vfuncs(FuPluginVfuncs *vfuncs)
{
vfuncs->build_hash = FU_BUILD_HASH;
vfuncs->init = fu_plugin_flashrom_init;
vfuncs->device_registered = fu_plugin_flashrom_device_registered;
vfuncs->startup = fu_plugin_flashrom_startup;
vfuncs->coldplug = fu_plugin_flashrom_coldplug;
}