summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2017-04-12 17:41:13 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-04-21 06:03:58 -0700
commitcca405862ad3d4df1d1382561e7c8d3e383a8338 (patch)
tree9d8fe84260b20e25900538f78784fb1cf26cee0a /common
parent30bd74b23314f6cd75e1153e3e7be5e19252537f (diff)
downloadchrome-ec-cca405862ad3d4df1d1382561e7c8d3e383a8338.tar.gz
common/update_fw: Board/chip-specific first_response_pdu
cr50 and hammer/common code are such different chips that reusing the same first_response_pdu does not make much sense. Instead, we can use 2 different headers, the updater knows which response to expect based on USB product ID. In the common code answer, we can reply with the EC version string, as well as rollback information and key version ID, which will be required for reliable updating. BRANCH=none BUG=b:35587171 BUG=b:36375666 TEST=usb_updater2 can update hammer, and read its version, rollback version and key version. Change-Id: I20b04070606767c71df3e6286d53e238e13375c0 Reviewed-on: https://chromium-review.googlesource.com/476452 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Nick Sanders <nsanders@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/update_fw.c57
1 files changed, 35 insertions, 22 deletions
diff --git a/common/update_fw.c b/common/update_fw.c
index 8135370b7c..7a51e6977f 100644
--- a/common/update_fw.c
+++ b/common/update_fw.c
@@ -9,10 +9,13 @@
#include "flash.h"
#include "hooks.h"
#include "include/compile_time_macros.h"
+#include "rollback.h"
+#include "rwsig.h"
#include "system.h"
#include "uart.h"
#include "update_fw.h"
#include "util.h"
+#include "vb21_struct.h"
#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
@@ -98,17 +101,26 @@ static int contents_allowed(uint32_t block_offset,
*/
void fw_update_start(struct first_response_pdu *rpdu)
{
+ const char *version;
+#ifdef CONFIG_RWSIG_TYPE_RWSIG
+ const struct vb21_packed_key *vb21_key;
+#endif
+
+ rpdu->header_type = htobe16(UPDATE_HEADER_TYPE_COMMON);
+
/* Determine the valid update section. */
switch (system_get_image_copy()) {
case SYSTEM_IMAGE_RO:
/* RO running, so update RW */
update_section.base_offset = CONFIG_RW_MEM_OFF;
update_section.top_offset = CONFIG_RW_MEM_OFF + CONFIG_RW_SIZE;
+ version = system_get_version(SYSTEM_IMAGE_RW);
break;
case SYSTEM_IMAGE_RW:
/* RW running, so update RO */
update_section.base_offset = CONFIG_RO_MEM_OFF;
update_section.top_offset = CONFIG_RO_MEM_OFF + CONFIG_RO_SIZE;
+ version = system_get_version(SYSTEM_IMAGE_RO);
break;
default:
CPRINTF("%s:%d\n", __func__, __LINE__);
@@ -116,27 +128,23 @@ void fw_update_start(struct first_response_pdu *rpdu)
return;
}
- /*
- * TODO(b/36375666): We reuse the same structure as cr50 updater, but
- * there isn't a whole lot that can be shared... We should probably
- * switch to a board-specific response packet (at least common vs
- * cr50-specific).
- */
- rpdu->backup_ro_offset = htobe32(update_section.base_offset);
- rpdu->backup_rw_offset = 0x0;
-
- /* RO header information. */
- rpdu->shv[0].minor = 0;
- rpdu->shv[0].major = 0;
- rpdu->shv[0].epoch = 0;
- rpdu->keyid[0] = 0;
-
- /* RW header information. */
- rpdu->shv[1].minor = 0;
- rpdu->shv[1].major = 0;
- rpdu->shv[1].epoch = 0;
-
- rpdu->keyid[1] = 0;
+ rpdu->common.maximum_pdu_size = htobe32(CONFIG_UPDATE_PDU_SIZE);
+ rpdu->common.flash_protection = htobe32(flash_get_protect());
+ rpdu->common.offset = htobe32(update_section.base_offset);
+ if (version)
+ memcpy(rpdu->common.version, version,
+ sizeof(rpdu->common.version));
+
+#ifdef CONFIG_ROLLBACK
+ rpdu->common.min_rollback = htobe32(rollback_get_minimum_version());
+#else
+ rpdu->common.min_rollback = htobe32(-1);
+#endif
+
+#ifdef CONFIG_RWSIG_TYPE_RWSIG
+ vb21_key = (const struct vb21_packed_key *)CONFIG_RO_PUBKEY_ADDR;
+ rpdu->common.key_version = htobe32(vb21_key->key_version);
+#endif
}
void fw_update_command_handler(void *body,
@@ -169,8 +177,13 @@ void fw_update_command_handler(void *body,
/* First, prepare the response structure. */
memset(rpdu, 0, sizeof(*rpdu));
+ /*
+ * TODO(b/36375666): The response size can be shorter depending
+ * on which board-specific type of response we provide. This
+ * may send trailing 0 bytes, which should be harmless.
+ */
*response_size = sizeof(*rpdu);
- rpdu->protocol_version = htobe32(UPDATE_PROTOCOL_VERSION);
+ rpdu->protocol_version = htobe16(UPDATE_PROTOCOL_VERSION);
/* Setup internal state (e.g. valid sections, and fill rpdu) */
fw_update_start(rpdu);