mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-02 18:57:26 +00:00
143 lines
4.1 KiB
C
143 lines
4.1 KiB
C
/*
|
|
* Copyright (C) 2020 Benson Leung <bleung@chromium.org>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <fwupdplugin.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#define UPDATE_PROTOCOL_VERSION 6
|
|
#define FU_CROS_EC_STRLEN 32
|
|
|
|
/*
|
|
* This is the format of the update PDU header.
|
|
*
|
|
* block digest: the first four bytes of the sha1 digest of the rest of the
|
|
* structure (can be 0 on boards where digest is ignored).
|
|
* block_base: offset of this PDU into the flash SPI.
|
|
*/
|
|
typedef struct __attribute__((packed)) {
|
|
guint32 block_digest;
|
|
guint32 block_base;
|
|
/* The actual payload goes here. */
|
|
} update_command;
|
|
|
|
/*
|
|
* This is the frame format the host uses when sending update PDUs over USB.
|
|
*
|
|
* The PDUs are up to 1K bytes in size, they are fragmented into USB chunks of
|
|
* 64 bytes each and reassembled on the receive side before being passed to
|
|
* the flash update function.
|
|
*
|
|
* The flash update function receives the unframed PDU body (starting at the
|
|
* cmd field below), and puts its reply into the same buffer the PDU was in.
|
|
*/
|
|
struct update_frame_header {
|
|
guint32 block_size; /* Total frame size, including this field. */
|
|
update_command cmd;
|
|
};
|
|
|
|
/*
|
|
* A convenience structure which allows to group together various revision
|
|
* fields of the header created by the signer (cr50-specific).
|
|
*
|
|
* These fields are compared when deciding if versions of two images are the
|
|
* same or when deciding which one of the available images to run.
|
|
*/
|
|
struct signed_header_version {
|
|
guint32 minor;
|
|
guint32 major;
|
|
guint32 epoch;
|
|
};
|
|
|
|
/*
|
|
* Response to the connection establishment request.
|
|
*
|
|
* When responding to the very first packet of the update sequence, the
|
|
* original USB update implementation was responding with a four byte value,
|
|
* just as to any other block of the transfer sequence.
|
|
*
|
|
* It became clear that there is a need to be able to enhance the update
|
|
* protocol, while staying backwards compatible.
|
|
*
|
|
* All newer protocol versions (starting with version 2) respond to the very
|
|
* first packet with an 8 byte or larger response, where the first 4 bytes are
|
|
* a version specific data, and the second 4 bytes - the protocol version
|
|
* number.
|
|
*
|
|
* This way the host receiving of a four byte value in response to the first
|
|
* packet is considered an indication of the target running the 'legacy'
|
|
* protocol, version 1. Receiving of an 8 byte or longer response would
|
|
* communicates the protocol version in the second 4 bytes.
|
|
*/
|
|
struct first_response_pdu {
|
|
guint32 return_value;
|
|
|
|
/* The below fields are present in versions 2 and up. */
|
|
|
|
/* Type of header following (one of first_response_pdu_header_type) */
|
|
guint16 header_type;
|
|
|
|
/* Must be UPDATE_PROTOCOL_VERSION */
|
|
guint16 protocol_version;
|
|
|
|
/* In version 6 and up, a board-specific header follows. */
|
|
union {
|
|
/* cr50 (header_type = UPDATE_HEADER_TYPE_CR50) */
|
|
struct {
|
|
/* The below fields are present in versions 3 and up. */
|
|
guint32 backup_ro_offset;
|
|
guint32 backup_rw_offset;
|
|
|
|
/* The below fields are present in versions 4 and up. */
|
|
/*
|
|
* Versions of the currently active RO and RW sections.
|
|
*/
|
|
struct signed_header_version shv[2];
|
|
|
|
/* The below fields are present in versions 5 and up */
|
|
/* keyids of the currently active RO and RW sections. */
|
|
guint32 keyid[2];
|
|
} cr50;
|
|
/* Common code (header_type = UPDATE_HEADER_TYPE_COMMON) */
|
|
struct {
|
|
/* Maximum PDU size */
|
|
guint32 maximum_pdu_size;
|
|
|
|
/* Flash protection status */
|
|
guint32 flash_protection;
|
|
|
|
/* Offset of the other region */
|
|
guint32 offset;
|
|
|
|
/* Version string of the other region */
|
|
gchar version[FU_CROS_EC_STRLEN];
|
|
|
|
/* Minimum rollback version that RO will accept */
|
|
gint32 min_rollback;
|
|
|
|
/* RO public key version */
|
|
guint32 key_version;
|
|
} common;
|
|
};
|
|
};
|
|
|
|
enum first_response_pdu_header_type {
|
|
UPDATE_HEADER_TYPE_CR50 = 0, /* Must be 0 for backwards compatibility */
|
|
UPDATE_HEADER_TYPE_COMMON = 1,
|
|
};
|
|
|
|
struct cros_ec_version {
|
|
gchar boardname[FU_CROS_EC_STRLEN];
|
|
gchar triplet[FU_CROS_EC_STRLEN];
|
|
gchar sha1[FU_CROS_EC_STRLEN];
|
|
gboolean dirty;
|
|
};
|
|
|
|
gboolean
|
|
fu_cros_ec_parse_version(const gchar *version_raw, struct cros_ec_version *version, GError **error);
|