mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-03 13:41:12 +00:00
flashrom: Simplify the plugin to remove the indirection
For a while we flirted with the idea of updating non-internal libflashrom-derived devices but the impedance mismatch was just too great. We removed the extra unused subclasses of FuFlashromDevice, but never removed the indirection we added for the writing. Remove the unused code now that we agree on the longer term plan.
This commit is contained in:
parent
4ce9972ce5
commit
6fdae41ae0
@ -54,16 +54,6 @@ mode, but it is only used when the device is rebooted.
|
||||
|
||||
The vendor ID is set from the BIOS vendor, for example `DMI:Google`
|
||||
|
||||
## Quirk Use
|
||||
|
||||
This plugin uses the following plugin-specific quirks:
|
||||
|
||||
### FlashromProgrammer
|
||||
|
||||
Used to specify the libflashrom programmer to be used.
|
||||
|
||||
Since: 1.5.9
|
||||
|
||||
## External Interface Access
|
||||
|
||||
This plugin requires access to all interfaces that `libflashrom` has been compiled for.
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -8,81 +9,24 @@
|
||||
|
||||
#include <libflashrom.h>
|
||||
|
||||
#include "fu-flashrom-cmos.h"
|
||||
#include "fu-flashrom-device.h"
|
||||
|
||||
typedef struct {
|
||||
gchar *programmer_name;
|
||||
gchar *programmer_args;
|
||||
/*
|
||||
* Flag to determine if the CMOS checksum should be reset after the flash
|
||||
* is reprogrammed. This will force the CMOS defaults to be reloaded on
|
||||
* the next boot.
|
||||
*/
|
||||
#define FU_FLASHROM_DEVICE_FLAG_RESET_CMOS (1 << 0)
|
||||
|
||||
struct _FuFlashromDevice {
|
||||
FuUdevDevice parent_instance;
|
||||
gsize flash_size;
|
||||
struct flashrom_flashctx *flashctx;
|
||||
struct flashrom_programmer *flashprog;
|
||||
} FuFlashromDevicePrivate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(FuFlashromDevice, fu_flashrom_device, FU_TYPE_UDEV_DEVICE)
|
||||
|
||||
#define GET_PRIVATE(o) (fu_flashrom_device_get_instance_private(o))
|
||||
|
||||
void
|
||||
fu_flashrom_device_set_programmer_name(FuFlashromDevice *self, const gchar *name)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_FLASHROM_DEVICE(self));
|
||||
if (g_strcmp0(priv->programmer_name, name) == 0)
|
||||
return;
|
||||
g_free(priv->programmer_name);
|
||||
priv->programmer_name = g_strdup(name);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
fu_flashrom_device_get_programmer_name(FuFlashromDevice *self)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_FLASHROM_DEVICE(self), NULL);
|
||||
return priv->programmer_name;
|
||||
}
|
||||
|
||||
void
|
||||
fu_flashrom_device_set_programmer_args(FuFlashromDevice *self, const gchar *args)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_FLASHROM_DEVICE(self));
|
||||
if (g_strcmp0(priv->programmer_args, args) == 0)
|
||||
return;
|
||||
g_free(priv->programmer_args);
|
||||
priv->programmer_args = g_strdup(args);
|
||||
}
|
||||
|
||||
gsize
|
||||
fu_flashrom_device_get_flash_size(FuFlashromDevice *self)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_FLASHROM_DEVICE(self), 0);
|
||||
return priv->flash_size;
|
||||
}
|
||||
|
||||
struct flashrom_flashctx *
|
||||
fu_flashrom_device_get_flashctx(FuFlashromDevice *self)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_FLASHROM_DEVICE(self), NULL);
|
||||
return priv->flashctx;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_init(FuFlashromDevice *self)
|
||||
{
|
||||
fu_device_add_protocol(FU_DEVICE(self), "org.flashrom");
|
||||
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_MD_SET_SIGNED);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_finalize(GObject *object)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(FU_FLASHROM_DEVICE(object));
|
||||
g_free(priv->programmer_name);
|
||||
g_free(priv->programmer_args);
|
||||
G_OBJECT_CLASS(fu_flashrom_device_parent_class)->finalize(object);
|
||||
}
|
||||
G_DEFINE_TYPE(FuFlashromDevice, fu_flashrom_device, FU_TYPE_UDEV_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_flashrom_device_set_quirk_kv(FuDevice *device,
|
||||
@ -97,10 +41,6 @@ fu_flashrom_device_set_quirk_kv(FuDevice *device,
|
||||
fu_device_set_metadata_integer(device, "PciBcrAddr", tmp);
|
||||
return TRUE;
|
||||
}
|
||||
if (g_strcmp0(key, "FlashromProgrammer") == 0) {
|
||||
fu_flashrom_device_set_programmer_name(FU_FLASHROM_DEVICE(device), value);
|
||||
return TRUE;
|
||||
}
|
||||
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "no supported");
|
||||
return FALSE;
|
||||
}
|
||||
@ -133,27 +73,17 @@ fu_flashrom_device_probe(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_flashrom_device_open(FuDevice *device, GError **error)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(FU_FLASHROM_DEVICE(device));
|
||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
||||
gint rc;
|
||||
|
||||
if (priv->programmer_name == NULL) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"programmer not specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (flashrom_programmer_init(&priv->flashprog,
|
||||
priv->programmer_name,
|
||||
priv->programmer_args)) {
|
||||
if (flashrom_programmer_init(&self->flashprog, "internal", NULL)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"programmer initialization failed");
|
||||
return FALSE;
|
||||
}
|
||||
rc = flashrom_flash_probe(&priv->flashctx, priv->flashprog, NULL);
|
||||
rc = flashrom_flash_probe(&self->flashctx, self->flashprog, NULL);
|
||||
if (rc == 3) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -175,8 +105,8 @@ fu_flashrom_device_open(FuDevice *device, GError **error)
|
||||
"flash probe failed: unknown error");
|
||||
return FALSE;
|
||||
}
|
||||
priv->flash_size = flashrom_flash_getsize(priv->flashctx);
|
||||
if (priv->flash_size == 0) {
|
||||
self->flash_size = flashrom_flash_getsize(self->flashctx);
|
||||
if (self->flash_size == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
@ -190,9 +120,150 @@ fu_flashrom_device_open(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_flashrom_device_close(FuDevice *device, GError **error)
|
||||
{
|
||||
FuFlashromDevicePrivate *priv = GET_PRIVATE(FU_FLASHROM_DEVICE(device));
|
||||
flashrom_flash_release(priv->flashctx);
|
||||
flashrom_programmer_shutdown(priv->flashprog);
|
||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
||||
flashrom_flash_release(self->flashctx);
|
||||
flashrom_programmer_shutdown(self->flashprog);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_flashrom_device_prepare(FuDevice *device, FwupdInstallFlags flags, GError **error)
|
||||
{
|
||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
||||
g_autofree gchar *firmware_orig = NULL;
|
||||
g_autofree gchar *localstatedir = NULL;
|
||||
g_autofree gchar *basename = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* if the original firmware doesn't exist, grab it now */
|
||||
basename = g_strdup_printf("flashrom-%s.bin", fu_device_get_id(device));
|
||||
localstatedir = fu_common_get_path(FU_PATH_KIND_LOCALSTATEDIR_PKG);
|
||||
firmware_orig = g_build_filename(localstatedir, "builder", basename, NULL);
|
||||
if (!fu_common_mkdir_parent(firmware_orig, error))
|
||||
return FALSE;
|
||||
if (!g_file_test(firmware_orig, G_FILE_TEST_EXISTS)) {
|
||||
struct flashrom_layout *layout;
|
||||
g_autofree guint8 *newcontents = g_malloc0(self->flash_size);
|
||||
g_autoptr(GBytes) buf = NULL;
|
||||
|
||||
if (flashrom_layout_read_from_ifd(&layout, self->flashctx, NULL, 0)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to read layout from Intel ICH descriptor");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* include bios region for safety reasons */
|
||||
if (flashrom_layout_include_region(layout, "bios")) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid region name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read region */
|
||||
flashrom_layout_set(self->flashctx, layout);
|
||||
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
if (flashrom_image_read(self->flashctx, newcontents, self->flash_size)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to back up original firmware");
|
||||
return FALSE;
|
||||
}
|
||||
buf = g_bytes_new_static(newcontents, self->flash_size);
|
||||
if (!fu_common_set_contents_bytes(firmware_orig, buf, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_flashrom_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
||||
struct flashrom_layout *layout;
|
||||
gsize sz = 0;
|
||||
gint rc;
|
||||
const guint8 *buf;
|
||||
g_autoptr(GBytes) blob_fw = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
|
||||
/* read early */
|
||||
blob_fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (blob_fw == NULL)
|
||||
return FALSE;
|
||||
buf = g_bytes_get_data(blob_fw, &sz);
|
||||
|
||||
if (flashrom_layout_read_from_ifd(&layout, self->flashctx, NULL, 0)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to read layout from Intel ICH descriptor");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* include bios region for safety reasons */
|
||||
if (flashrom_layout_include_region(layout, "bios")) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid region name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* write region */
|
||||
flashrom_layout_set(self->flashctx, layout);
|
||||
if (sz != self->flash_size) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid image size 0x%x, expected 0x%x",
|
||||
(guint)sz,
|
||||
(guint)self->flash_size);
|
||||
return FALSE;
|
||||
}
|
||||
rc = flashrom_image_write(self->flashctx, (void *)buf, sz, NULL /* refbuffer */);
|
||||
if (rc != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_WRITE,
|
||||
"image write failed, err=%i",
|
||||
rc);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
if (flashrom_image_verify(self->flashctx, (void *)buf, sz)) {
|
||||
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "image verify failed");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
flashrom_layout_release(layout);
|
||||
|
||||
/* Check if CMOS needs a reset */
|
||||
if (fu_device_has_private_flag(device, FU_FLASHROM_DEVICE_FLAG_RESET_CMOS)) {
|
||||
g_debug("Attempting CMOS Reset");
|
||||
if (!fu_flashrom_cmos_reset(error)) {
|
||||
g_prefix_error(error, "failed CMOS reset: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -207,6 +278,32 @@ fu_flashrom_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_init(FuFlashromDevice *self)
|
||||
{
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_INTERNAL);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
|
||||
fu_device_add_protocol(FU_DEVICE(self), "org.flashrom");
|
||||
fu_device_add_instance_id(FU_DEVICE(self), "main-system-firmware");
|
||||
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_TRIPLET);
|
||||
fu_device_add_icon(FU_DEVICE(self), "computer");
|
||||
fu_device_register_private_flag(FU_DEVICE(self),
|
||||
FU_FLASHROM_DEVICE_FLAG_RESET_CMOS,
|
||||
"reset-cmos");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_finalize(GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS(fu_flashrom_device_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
|
||||
{
|
||||
@ -218,4 +315,12 @@ fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
|
||||
klass_device->open = fu_flashrom_device_open;
|
||||
klass_device->close = fu_flashrom_device_close;
|
||||
klass_device->set_progress = fu_flashrom_device_set_progress;
|
||||
klass_device->prepare = fu_flashrom_device_prepare;
|
||||
klass_device->write_firmware = fu_flashrom_device_write_firmware;
|
||||
}
|
||||
|
||||
FuDevice *
|
||||
fu_flashrom_device_new(FuContext *ctx)
|
||||
{
|
||||
return FU_DEVICE(g_object_new(FU_TYPE_FLASHROM_DEVICE, "context", ctx, NULL));
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -8,20 +9,8 @@
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
struct _FuFlashromDeviceClass {
|
||||
FuUdevDeviceClass parent_class;
|
||||
};
|
||||
|
||||
#define FU_TYPE_FLASHROM_DEVICE (fu_flashrom_device_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(FuFlashromDevice, fu_flashrom_device, FU, FLASHROM_DEVICE, FuUdevDevice)
|
||||
G_DECLARE_FINAL_TYPE(FuFlashromDevice, fu_flashrom_device, FU, FLASHROM_DEVICE, FuUdevDevice)
|
||||
|
||||
void
|
||||
fu_flashrom_device_set_programmer_name(FuFlashromDevice *self, const gchar *name);
|
||||
const gchar *
|
||||
fu_flashrom_device_get_programmer_name(FuFlashromDevice *self);
|
||||
void
|
||||
fu_flashrom_device_set_programmer_args(FuFlashromDevice *self, const gchar *args);
|
||||
gsize
|
||||
fu_flashrom_device_get_flash_size(FuFlashromDevice *self);
|
||||
struct flashrom_flashctx *
|
||||
fu_flashrom_device_get_flashctx(FuFlashromDevice *self);
|
||||
FuDevice *
|
||||
fu_flashrom_device_new(FuContext *ctx);
|
||||
|
@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libflashrom.h>
|
||||
|
||||
#include "fu-flashrom-cmos.h"
|
||||
#include "fu-flashrom-device.h"
|
||||
#include "fu-flashrom-internal-device.h"
|
||||
|
||||
/*
|
||||
* Flag to determine if the CMOS checksum should be reset after the flash
|
||||
* is reprogrammed. This will force the CMOS defaults to be reloaded on
|
||||
* the next boot.
|
||||
*/
|
||||
#define FU_FLASHROM_DEVICE_FLAG_RESET_CMOS (1 << 0)
|
||||
|
||||
struct _FuFlashromInternalDevice {
|
||||
FuFlashromDevice parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuFlashromInternalDevice, fu_flashrom_internal_device, FU_TYPE_FLASHROM_DEVICE)
|
||||
|
||||
static void
|
||||
fu_flashrom_internal_device_init(FuFlashromInternalDevice *self)
|
||||
{
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_INTERNAL);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
|
||||
fu_device_add_instance_id(FU_DEVICE(self), "main-system-firmware");
|
||||
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_ENSURE_SEMVER);
|
||||
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_TRIPLET);
|
||||
fu_device_add_icon(FU_DEVICE(self), "computer");
|
||||
fu_device_register_private_flag(FU_DEVICE(self),
|
||||
FU_FLASHROM_DEVICE_FLAG_RESET_CMOS,
|
||||
"reset-cmos");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_flashrom_internal_device_prepare(FuDevice *device, FwupdInstallFlags flags, GError **error)
|
||||
{
|
||||
g_autofree gchar *firmware_orig = NULL;
|
||||
g_autofree gchar *localstatedir = NULL;
|
||||
g_autofree gchar *basename = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* if the original firmware doesn't exist, grab it now */
|
||||
basename = g_strdup_printf("flashrom-%s.bin", fu_device_get_id(device));
|
||||
localstatedir = fu_common_get_path(FU_PATH_KIND_LOCALSTATEDIR_PKG);
|
||||
firmware_orig = g_build_filename(localstatedir, "builder", basename, NULL);
|
||||
if (!fu_common_mkdir_parent(firmware_orig, error))
|
||||
return FALSE;
|
||||
if (!g_file_test(firmware_orig, G_FILE_TEST_EXISTS)) {
|
||||
FuFlashromDevice *parent = FU_FLASHROM_DEVICE(device);
|
||||
struct flashrom_flashctx *flashctx = fu_flashrom_device_get_flashctx(parent);
|
||||
gsize flash_size = fu_flashrom_device_get_flash_size(parent);
|
||||
struct flashrom_layout *layout;
|
||||
g_autofree guint8 *newcontents = g_malloc0(flash_size);
|
||||
g_autoptr(GBytes) buf = NULL;
|
||||
|
||||
if (flashrom_layout_read_from_ifd(&layout, flashctx, NULL, 0)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to read layout from Intel ICH descriptor");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* include bios region for safety reasons */
|
||||
if (flashrom_layout_include_region(layout, "bios")) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid region name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read region */
|
||||
flashrom_layout_set(flashctx, layout);
|
||||
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
if (flashrom_image_read(flashctx, newcontents, flash_size)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to back up original firmware");
|
||||
return FALSE;
|
||||
}
|
||||
buf = g_bytes_new_static(newcontents, flash_size);
|
||||
if (!fu_common_set_contents_bytes(firmware_orig, buf, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_flashrom_internal_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuFlashromDevice *parent = FU_FLASHROM_DEVICE(device);
|
||||
struct flashrom_flashctx *flashctx = fu_flashrom_device_get_flashctx(parent);
|
||||
gsize flash_size = fu_flashrom_device_get_flash_size(parent);
|
||||
struct flashrom_layout *layout;
|
||||
gsize sz = 0;
|
||||
gint rc;
|
||||
const guint8 *buf;
|
||||
g_autoptr(GBytes) blob_fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (blob_fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
|
||||
buf = g_bytes_get_data(blob_fw, &sz);
|
||||
|
||||
if (flashrom_layout_read_from_ifd(&layout, flashctx, NULL, 0)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_READ,
|
||||
"failed to read layout from Intel ICH descriptor");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* include bios region for safety reasons */
|
||||
if (flashrom_layout_include_region(layout, "bios")) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid region name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* write region */
|
||||
flashrom_layout_set(flashctx, layout);
|
||||
if (sz != flash_size) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"invalid image size 0x%x, expected 0x%x",
|
||||
(guint)sz,
|
||||
(guint)flash_size);
|
||||
return FALSE;
|
||||
}
|
||||
rc = flashrom_image_write(flashctx, (void *)buf, sz, NULL /* refbuffer */);
|
||||
if (rc != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_WRITE,
|
||||
"image write failed, err=%i",
|
||||
rc);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
if (flashrom_image_verify(flashctx, (void *)buf, sz)) {
|
||||
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "image verify failed");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
flashrom_layout_release(layout);
|
||||
|
||||
/* Check if CMOS needs a reset */
|
||||
if (fu_device_has_private_flag(device, FU_FLASHROM_DEVICE_FLAG_RESET_CMOS)) {
|
||||
g_debug("Attempting CMOS Reset");
|
||||
if (!fu_flashrom_cmos_reset(error)) {
|
||||
g_prefix_error(error, "failed CMOS reset: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_internal_device_class_init(FuFlashromInternalDeviceClass *klass)
|
||||
{
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->prepare = fu_flashrom_internal_device_prepare;
|
||||
klass_device->write_firmware = fu_flashrom_internal_device_write_firmware;
|
||||
}
|
||||
|
||||
FuDevice *
|
||||
fu_flashrom_internal_device_new(FuContext *ctx)
|
||||
{
|
||||
return FU_DEVICE(g_object_new(FU_TYPE_FLASHROM_INTERNAL_DEVICE, "context", ctx, NULL));
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fu-flashrom-device.h"
|
||||
|
||||
#define FU_TYPE_FLASHROM_INTERNAL_DEVICE (fu_flashrom_internal_device_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuFlashromInternalDevice,
|
||||
fu_flashrom_internal_device,
|
||||
FU,
|
||||
FLASHROM_INTERNAL_DEVICE,
|
||||
FuFlashromDevice)
|
||||
|
||||
FuDevice *
|
||||
fu_flashrom_internal_device_new(FuContext *ctx);
|
@ -13,19 +13,16 @@
|
||||
#include <libflashrom.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fu-flashrom-internal-device.h"
|
||||
#include "fu-flashrom-device.h"
|
||||
|
||||
#define SELFCHECK_TRUE 1
|
||||
|
||||
static void
|
||||
fu_plugin_flashrom_init(FuPlugin *plugin)
|
||||
{
|
||||
FuContext *ctx = fu_plugin_get_context(plugin);
|
||||
|
||||
fu_plugin_add_rule(plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "linux_lockdown");
|
||||
fu_plugin_add_rule(plugin, FU_PLUGIN_RULE_CONFLICTS, "coreboot"); /* obsoleted */
|
||||
fu_plugin_add_flag(plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
|
||||
fu_context_add_quirk_key(ctx, "FlashromProgrammer");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -150,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_internal_device_new(ctx);
|
||||
g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx);
|
||||
|
||||
fu_device_set_context(device, ctx);
|
||||
fu_device_set_name(device, fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_PRODUCT_NAME));
|
||||
@ -165,7 +162,6 @@ fu_plugin_flashrom_coldplug(FuPlugin *plugin, GError **error)
|
||||
fu_plugin_flashrom_device_set_version(plugin, device);
|
||||
fu_plugin_flashrom_device_set_hwids(plugin, device);
|
||||
fu_plugin_flashrom_device_set_bios_info(plugin, device);
|
||||
fu_flashrom_device_set_programmer_name(FU_FLASHROM_DEVICE(device), "internal");
|
||||
if (!fu_device_setup(device, error))
|
||||
return FALSE;
|
||||
|
||||
|
@ -10,7 +10,6 @@ shared_module('fu_plugin_flashrom',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-flashrom-device.c',
|
||||
'fu-flashrom-internal-device.c',
|
||||
'fu-plugin-flashrom.c',
|
||||
'fu-flashrom-cmos.c',
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user