mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-17 18:20:47 +00:00
cros-ec: Add cros-ec-firmware
cros-ec firmware are in fmap layout, and have two sections that this plugin will look for, the EC_RO, and EC_RW sections. Tested using a servo_micro firmware: $ fwupdtool firmware-parse servo_micro_v2.4.17-df61092c3.bin <select fmap option> FuCrosEcFirmware: Version: 2.4.17 FuFirmwareImage: ID: EC_RO Index: 0x1 Version: servo_micro_v2.4.17-df61092c3 Data: 0xf000 FuFirmwareImage: ID: FR_MAIN Index: 0x2 Data: 0xf000 FuFirmwareImage: ID: RO_FRID Index: 0x3 Address: 0xc4 Data: 0x20 FuFirmwareImage: ID: FMAP Index: 0x4 Address: 0x9a40 Version: 1.0 Data: 0x15e FuFirmwareImage: ID: WP_RO Index: 0x5 Data: 0x10000 FuFirmwareImage: ID: EC_RW Index: 0x6 Address: 0x10000 Version: servo_micro_v2.4.17-df61092c3 Data: 0x10000 FuFirmwareImage: ID: RW_FWID Index: 0x7 Address: 0x100c4 Data: 0x20
This commit is contained in:
parent
23ca19acf8
commit
3a02ad5129
136
plugins/cros-ec/fu-cros-ec-firmware.c
Normal file
136
plugins/cros-ec/fu-cros-ec-firmware.c
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Benson Leung <bleung@chromium.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "fu-fmap-firmware.h"
|
||||||
|
#include "fu-cros-ec-common.h"
|
||||||
|
#include "fu-cros-ec-firmware.h"
|
||||||
|
|
||||||
|
#define MAXSECTIONS 2
|
||||||
|
|
||||||
|
struct _FuCrosEcFirmware {
|
||||||
|
FuFmapFirmware parent_instance;
|
||||||
|
struct cros_ec_version version;
|
||||||
|
FuCrosEcFirmwareSection sections[MAXSECTIONS];
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FuCrosEcFirmware, fu_cros_ec_firmware, FU_TYPE_FMAP_FIRMWARE)
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_cros_ec_firmware_parse (FuFirmware *firmware,
|
||||||
|
GBytes *fw,
|
||||||
|
guint64 addr_start,
|
||||||
|
guint64 addr_end,
|
||||||
|
FwupdInstallFlags flags,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuCrosEcFirmware *self = FU_CROS_EC_FIRMWARE (firmware);
|
||||||
|
FuFirmware *fmap_firmware = FU_FIRMWARE (firmware);
|
||||||
|
|
||||||
|
self->sections[0].name = "RO";
|
||||||
|
self->sections[1].name = "RW";
|
||||||
|
|
||||||
|
for (gsize i = 0; i < G_N_ELEMENTS (self->sections); i++) {
|
||||||
|
gboolean rw = FALSE;
|
||||||
|
FuCrosEcFirmwareSection *section = &self->sections[i];
|
||||||
|
const gchar *fmap_name;
|
||||||
|
const gchar *fmap_fwid_name;
|
||||||
|
g_autoptr(FuFirmwareImage) img = NULL;
|
||||||
|
g_autoptr(FuFirmwareImage) fwid_img = NULL;
|
||||||
|
g_autoptr(GBytes) payload_bytes = NULL;
|
||||||
|
g_autoptr(GBytes) fwid_bytes = NULL;
|
||||||
|
|
||||||
|
if (g_strcmp0 (section->name, "RO") == 0) {
|
||||||
|
fmap_name = "EC_RO";
|
||||||
|
fmap_fwid_name = "RO_FRID";
|
||||||
|
} else if (g_strcmp0 (section->name, "RW") == 0) {
|
||||||
|
rw = TRUE;
|
||||||
|
fmap_name = "EC_RW";
|
||||||
|
fmap_fwid_name = "RW_FWID";
|
||||||
|
} else {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_INVALID_DATA,
|
||||||
|
"incorrect section name");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
img = fu_firmware_get_image_by_id (fmap_firmware,
|
||||||
|
fmap_name, error);
|
||||||
|
if (img == NULL) {
|
||||||
|
g_prefix_error (error, "%s image not found: ",
|
||||||
|
fmap_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwid_img = fu_firmware_get_image_by_id (fmap_firmware,
|
||||||
|
fmap_fwid_name, error);
|
||||||
|
if (fwid_img == NULL) {
|
||||||
|
g_prefix_error (error, "%s image not found: ",
|
||||||
|
fmap_fwid_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fwid_bytes = fu_firmware_image_write (fwid_img, error);
|
||||||
|
if (fwid_bytes == NULL) {
|
||||||
|
g_prefix_error (error,
|
||||||
|
"unable to get bytes from %s: ",
|
||||||
|
fmap_fwid_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!fu_memcpy_safe ((guint8 *) section->version,
|
||||||
|
FMAP_STRLEN, 0x0,
|
||||||
|
g_bytes_get_data (fwid_bytes, NULL),
|
||||||
|
g_bytes_get_size (fwid_bytes), 0x0,
|
||||||
|
g_bytes_get_size (fwid_bytes), error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
payload_bytes = fu_firmware_image_write (img, error);
|
||||||
|
if (payload_bytes == NULL) {
|
||||||
|
g_prefix_error (error,
|
||||||
|
"unable to get bytes from %s: ",
|
||||||
|
fmap_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
section->offset = fu_firmware_image_get_addr (img);
|
||||||
|
section->size = g_bytes_get_size (payload_bytes);
|
||||||
|
fu_firmware_image_set_version (img, section->version);
|
||||||
|
|
||||||
|
if (rw) {
|
||||||
|
if (!fu_cros_ec_parse_version (section->version,
|
||||||
|
&self->version,
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error,
|
||||||
|
"failed parsing firmware's version: %32s: ",
|
||||||
|
section->version);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fu_firmware_set_version (firmware,
|
||||||
|
self->version.triplet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_cros_ec_firmware_init (FuCrosEcFirmware *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_cros_ec_firmware_class_init (FuCrosEcFirmwareClass *klass)
|
||||||
|
{
|
||||||
|
FuFmapFirmwareClass *klass_firmware = FU_FMAP_FIRMWARE_CLASS (klass);
|
||||||
|
klass_firmware->parse = fu_cros_ec_firmware_parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
FuFirmware *
|
||||||
|
fu_cros_ec_firmware_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (FU_TYPE_CROS_EC_FIRMWARE, NULL);
|
||||||
|
}
|
41
plugins/cros-ec/fu-cros-ec-firmware.h
Normal file
41
plugins/cros-ec/fu-cros-ec-firmware.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Benson Leung <bleung@chromium.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fu-firmware.h"
|
||||||
|
#include "fu-fmap-firmware.h"
|
||||||
|
|
||||||
|
#define FU_TYPE_CROS_EC_FIRMWARE (fu_cros_ec_firmware_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (FuCrosEcFirmware, fu_cros_ec_firmware, FU, CROS_EC_FIRMWARE, FuFmapFirmware)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each RO or RW section of the new image can be in one of the following
|
||||||
|
* states.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
FU_CROS_EC_FW_NOT_NEEDED= 0, /* Version below or equal that on the target. */
|
||||||
|
FU_CROS_EC_FW_NOT_POSSIBLE, /*
|
||||||
|
* RO is newer, but can't be transferred due to
|
||||||
|
* target RW shortcomings.
|
||||||
|
*/
|
||||||
|
FU_CROS_EC_FW_NEEDED /*
|
||||||
|
* This section needs to be transferred to the
|
||||||
|
* target.
|
||||||
|
*/
|
||||||
|
} FuCrosEcFirmwareUpgradeStatus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const gchar *name;
|
||||||
|
guint32 offset;
|
||||||
|
gsize size;
|
||||||
|
FuCrosEcFirmwareUpgradeStatus ustatus;
|
||||||
|
gchar version[FMAP_STRLEN];
|
||||||
|
gint32 rollback;
|
||||||
|
guint32 key_version;
|
||||||
|
} FuCrosEcFirmwareSection;
|
||||||
|
|
||||||
|
FuFirmware *fu_cros_ec_firmware_new (void);
|
@ -10,10 +10,12 @@
|
|||||||
#include "fu-hash.h"
|
#include "fu-hash.h"
|
||||||
|
|
||||||
#include "fu-cros-ec-usb-device.h"
|
#include "fu-cros-ec-usb-device.h"
|
||||||
|
#include "fu-cros-ec-firmware.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
fu_plugin_init (FuPlugin *plugin)
|
fu_plugin_init (FuPlugin *plugin)
|
||||||
{
|
{
|
||||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||||
fu_plugin_set_device_gtype (plugin, FU_TYPE_CROS_EC_USB_DEVICE);
|
fu_plugin_set_device_gtype (plugin, FU_TYPE_CROS_EC_USB_DEVICE);
|
||||||
|
fu_plugin_add_firmware_gtype (plugin, "cros-ec", FU_TYPE_CROS_EC_FIRMWARE);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ shared_module('fu_plugin_cros_ec',
|
|||||||
'fu-plugin-cros-ec.c',
|
'fu-plugin-cros-ec.c',
|
||||||
'fu-cros-ec-usb-device.c',
|
'fu-cros-ec-usb-device.c',
|
||||||
'fu-cros-ec-common.c',
|
'fu-cros-ec-common.c',
|
||||||
|
'fu-cros-ec-firmware.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
root_incdir,
|
root_incdir,
|
||||||
|
Loading…
Reference in New Issue
Block a user