diff options
author | Mary Ruthven <mruthven@chromium.org> | 2019-11-20 18:40:41 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-22 07:00:51 +0000 |
commit | 1503fa64670763133409d7b3fd59a91a7a28171d (patch) | |
tree | 3758661714504e82a2c1e6a65b4c38cce4e9ce9b /extra | |
parent | b25323c4fa6797c8ecf9a2df24f7d864d56ca922 (diff) | |
download | chrome-ec-1503fa64670763133409d7b3fd59a91a7a28171d.tar.gz |
gsctool: delay RO update for old cr50 images
If Cr50 is running older than 0.3.20, delay the RO update 1 minute after
the RW update, so Cr50 doesn't reject the RO blocks because their
offsets are less than the RW offsets.
BUG=b:144873413
BRANCH=none
TEST=update board running RO 0.0.10 RW 0.3.18 to the RO 0.0.11 RW 0.3.22
image.
Change-Id: I0179cc235c692133b08cd3430d71069b2f94bf69
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1929481
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'extra')
-rw-r--r-- | extra/usb_updater/gsctool.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index 4b2d207a85..6db8f7cb10 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -1164,12 +1164,33 @@ static void send_done(struct usb_endpoint *uep) do_xfer(uep, &out, sizeof(out), &out, 1, 0, NULL); } +/* + * Old cr50 images fail the update if sections are sent out of order. They + * require each block to have an offset greater than the block that was sent + * before. RO has a lower offset than RW, so old cr50 images reject RO if it's + * sent right after RW. + * This offset restriction expires after 60 seconds. Delay the RO update long + * enough for cr50 to not care that it has a lower offset than RW. + * + * Make the delay 65 seconds instead of 60 to cover differences in the speed of + * H1's clock and the host clock. + */ +#define NEXT_SECTION_DELAY 65 + +/* Support for flashing RO immediately after RW was added in 0.3.20/0.4.20. */ +static int supports_reordered_section_updates(struct signed_header_version *rw) +{ + return (rw->epoch || rw->major > 4 || + (rw->major >= 3 && rw->minor >= 20)); +} + /* Returns number of successfully transmitted image sections. */ static int transfer_image(struct transfer_descriptor *td, uint8_t *data, size_t data_len) { size_t j; int num_txed_sections = 0; + int needs_delay = !supports_reordered_section_updates(&targ.shv[1]); /* * In case both RO and RW updates are required, make sure the RW @@ -1190,6 +1211,20 @@ static int transfer_image(struct transfer_descriptor *td, if (sections[i].ustatus != needed) break; + if (num_txed_sections && needs_delay) { + /* + * Delays more than 5 seconds cause the update + * to timeout. End the update before the delay + * and set it up after to recover from the + * timeout. + */ + if (td->ep_type == usb_xfer) + send_done(&td->uep); + printf("Waiting %ds for %s update.\n", + NEXT_SECTION_DELAY, sections[i].name); + sleep(NEXT_SECTION_DELAY); + setup_connection(td); + } transfer_section(td, data + sections[i].offset, |