summaryrefslogtreecommitdiff
path: root/chip/g/usb_upgrade.c
Commit message (Collapse)AuthorAgeFilesLines
* cr50: pass params to vendor commands as structRandall Spangler2018-05-231-64/+53
| | | | | | | | | | | | | | | | | | | | | | | This makes it easier to add params or flags for vendor commands without changing all of the command handlers. It also reduces code size by 56 bytes. For now, existing command handlers continue to use DECLARE_VENDOR_COMMAND(). Added DECLARE_VENDOR_COMMAND_P() for handlers which take the params struct directly. The CCD command will be the first user of that, since it will have different rules for 'open' based on where the command comes from. No change to existing command behavior. BUG=b:79983505 BRANCH=cr50 TEST=gsctool -I still works Change-Id: I7ed288a9c45e381162e246b50ae88cf76e67490d Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1069538 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
* cr50: Refactor tracking vendor command originRandall Spangler2018-05-221-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | Added flags parameter to extension_route_command(). The caller now specifies whether the command comes from the USB interface or the AP. Moved USB-specific shuffling of response to embed result code into usb_upgrade.c, so extension_route_command() can be more generic. No change to permissions/behavior for existing commands. ccd_command_wrapper() still sends vendor commands as if they come from the AP. That's fixed in the next CL. Reduces code size by 128 bytes BUG=b:79983505 BRANCH=cr50 TEST=manual Build with DEBUG_EXTENSION defined, to turn on printing each command 'ccd lock' comes from AP and works From host, 'gscutil -I' comes from USB and fails From AP, 'gscutil -t -I' comes from AP and works Change-Id: I7136bb54073de9c5951a174c308151b1871c56f3 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1068101 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
* consumer: Remove flush operationNicolas Boichat2017-12-181-5/+0
| | | | | | | | | | | | | | | | Nobody is calling the flush function for consumer_ops structure, so let's remove it to save flash space, until we find a use for it. CQ-DEPEND=CL:*529221 BRANCH=none BUG=chromium:795624 TEST=make buildall -j, saves from 40 to 128 bytes on some boards. Change-Id: Iad18b30f419ccebc54a90914ec46da84b8d19601 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/826905 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
* cr50: usb_upgrade: allow responses lager than requestsVadim Bendebury2017-06-061-5/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When invoking vendor command handlers in try_vendor_command(), the buffer containing the command is passed to the handler to communicate the command contents and to hold the command execution return data. It was fine when invoking vendor command handlers from the TPM stack, as the receive buffer is 4K in size and is large enough for any expected vendor command response. It is different in case of USB: the command is in the receive buffer of the USB queue, and the response data could easily exceed the command size, which would cause corruption of the USB receive queue contents when the response data is placed into the same buffer where the command is. Let's introduce a local storage to pass the command and receive the response data from the handler. 32 bytes is enough for the foreseeable future, should a need arise for a larger buffer, testing would result in an error (a new error type is added to indicate insufficient buffer space for command processing). BRANCH=none BUG=b:35587387,b:35587053 TEST=with the rest of the patches applied verified proper processing of the 'Get Board ID' command for which response size exceeds the request size. Change-Id: I2131496f3a99c7f3a1869905120a453d75efbdce Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/525092 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
* cr50: usb_upgrade: pass proper number of bytes to the vendor commandsVadim Bendebury2017-06-021-2/+5
| | | | | | | | | | | | | | | | | | | | The code invoking vendor commands callbacks rightly passes the pointer to the command payload as the address right after the subcommand field, but does not deduct the size of the subcommand field from the size of the payload passed to the handler. This patch fixes the issue, the command handlers do not see two extra bytes at the tail of the command any more. BRANCH=cr50 BUG=b:62294740, b:35545754 TEST=verified that vendor commands sent over USB and TPM still work properly (in particular the TURN_UPDATE_ON command). Change-Id: I11a45f65163044f808a82b214f9c5faf775f9020 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/522943 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
* g: extension: Add a whitelist for vendor commands.Aseda Aboagye2017-02-181-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The USB FW upgrade endpoint should really only accept vendor commands required to perform the firmware update. This commit adds a whitelist that is checked whenever a vendor command is received over this endpoint. The allowed commands over USB are the following: - EXTENSION_POST_RESET - VENDOR_CC_IMMEDIATE_RESET (only for dev images) There is also functionality to have a whitelist for vendor commands that come over the TPM interface. BUG=chrome-os-partner:62815 BRANCH=None TEST=Flash Cr50 with image containing this change. Verify that an upgrade over USB to newer image works. TEST=Try using usb_updater to send a vendor command that's not in the whitelist. Verify that the vendor command is dropped. Change-Id: I71f8ba090a1cc6c9e7c30ce0dd3c25259e8f292f Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/443447 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
* cr50: do not invoke fw_upgrade_complete() if there was no data transferVadim Bendebury2016-12-241-2/+19
| | | | | | | | | | | | | | | | | | | | | | With expanding USB interface to processing vendor commands and to query current version running on the chip, there are now occurrences of fw_upgrade_complete() invoked at the device startup without actual data transfer. This causes clearing rollback counter before it is actually examined. Let's not invoke fw_upgrade_complete() unless there was actual data transferred for flash programming. BRANCH=none BUG=none TEST=verified on chromebook reboots that the counter value is not changed until the rollback condition is checked. Change-Id: I50bf450882b001ba1c2f38657d27f87f8596b3e2 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/422454 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* usb_updater: protocol version 6 (vendor commands over usb)Vadim Bendebury2016-11-281-13/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch introduces version 6 of the cr50 USB update protocol. This version allows to multiplex TPM vendor and extension commands over the same USB endpoint which is used for firmware updates. When channeling TPM vendor commands the USB update frame looks as follows: 4 bytes 4 bytes 4 bytes 2 bytes variable size +-----------+--------------+---------------+-----------+------~~~-------+ + total size| block digest | EXT_CMD | Vend. sub.| data | +-----------+--------------+---------------+-----------+------~~~-------+ Where 'Vend. sub' is the vendor subcommand, and data field is subcommand dependent. The target tells between update PDUs and encapsulated vendor subcommands by looking at the EXT_CMD value - it is set to 0xbaccd00a and as such is guaranteed not to be a valid update PDU destination address. In the previous protocol versions target reset was requested by the host sending a 4 byte PDU after the target receives the UPGRADE_DONE message and moves the state machine to the 'awaiting_reset' state. With the ability to transfer vendor commands, there is no need for the target to have a special state for reset. The host can send the posted or immediate reboot request using the appropriate vendor command. As a result the 'awaiting_reset' state has been removed, the target accepts vendor commands only when state machine is in the rx_idle state. Vendor command response size is not fixed, it is subcommand dependent. In the current implementation the total size of the vendor command PDU can not exceed 64 bytes, as there is no reassembly on the target side. For backwards compatibility in case the target is running protocol version earlier than 6, the 4 byte PDU is still sent to the target after UPGRADE_DONE is sent. BRANCH=none BUG=chrome-os-partner:60013 TEST=tested updates on Reef and Gru, observed that it is possible to update earlier versions of firmware, and that it is possible to request immediate and posted reset (depending on the presence of the -u flag in the usb_updater invocation). Change-Id: I6ea9e9f742c96b8ab0670e9cec87a83cd47bb20e Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/414948 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* usb_updater: improve debugabilityVadim Bendebury2016-11-281-0/+2
| | | | | | | | | | | | | | | | | | When usb update errors happen it helps a lot to be able to see the actual error code returned by the target and where the error was generated. This patch adds a few printouts to help with debugging. BRANCH=none BUG=none TEST=observed proper error messages generated while debugging introduction of extension/vendor commands transfer over USB. Change-Id: I06c77e7467f7f9547704c88c4b673866fb2e6032 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/414947 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* g: fix reboot request posting bugVadim Bendebury2016-11-181-0/+1
| | | | | | | | | | | | | | | | | When the host requests the uploader to post a reboot request, the uploader should exit right away once the request is posted. BRANCH=none BUG=chrome-os-partner:59911 TEST=verified that cr50 gets successfully updated from this image to a newer one on both reef and gru: the reboot happens under upstart control, not by cr50 rebooting on its own. Change-Id: I9e4a2da686fe512b633daa05c675871e5946926f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/412348 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* chip/g to chip/lm4: fix more misspellings in commentsMartin Roth2016-11-151-2/+2
| | | | | | | | | | | | | No functional changes. BUG=none BRANCH=none TEST=make buildall passes Change-Id: I0c4fcc900ec0326d6904aa14f298206e62be0fda Signed-off-by: Martin Roth <martinroth@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/403418 Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
* cr50: provide means of posting reboot requestVadim Bendebury2016-10-081-6/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Usually CR50 TPM reset happens when the AP reboots, the CR50 RO does not get a chance to run in this case, so the running RW does not change either, Once the idle RW section was updated, the only way to start it is to reboot the CR50 completely, Rebooting CR50 causes the whole system reset, so it should not be happening at random moments in time. This patch introduces a mechanism to delay reboot to the moment when the TPM is reset. The reboot request would be posted in the end of the update, and then the AP would reboot, triggering a TPM reboot, which in turn would trigger the CR50 reset. The USB update handler now posts the reboot request instead of triggering the reboot immediately. BRANCH=none BUG=chrome-os-partner:58226 TEST=with the rest of the patches applied verified that the system gets reset and the new image version kicks in on both gru (over SPI) and reef (over USB). Change-Id: Iff859f2e7a48c5035a27fffd17aefe7e318af569 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/395627 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* g: clear reset_counter after updateMary Ruthven2016-09-021-0/+1
| | | | | | | | | | | | | | | | If the firmware was just updated clear the reset counter before rebooting. This will ensure that the update can complete even if the TPM isn't being used. BUG=chrome-os-partner:56864 BRANCH=none TEST=Set the reset counter to 7 by running 'rw 0x40000128 1' and 'rw 0x4000012c 7'. Then make sure cr50 can still be updated Change-Id: Ic304fc7a20a4f2af7792f80e970d28e0eb10967e Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/380235 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* g: implement firmware upgrade protocol version 3Vadim Bendebury2016-08-221-39/+44
| | | | | | | | | | | | | | | | | | | | | | This patch modifies CR50 code to switch to firmware update protocol version 3. In this version both SPI and USB updates use exactly the same messages (apart from the size field added by USB to help reassembly of the fragmented frames). Bot unused RO and RW sections can be now programmed. BRANCH=none BUG=chrome-os-partner:55789 TEST=on a Kevin running the existing cr50 image programmed the new cr50 image, restarted the device, programmed the cr50 image again (this time using version 3), restarted the device, then programmed both RO and RW images and restarted the device. Each time verified that the proper image is running. Change-Id: I0cf196ec6de1786510433f8252164a33ccdc6dec Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/371941 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* usb_updater: host side support protocol version 3Vadim Bendebury2016-08-211-29/+29
| | | | | | | | | | | | | | | | | | | | | This patch introduces support for the cr50 firmware update protocol version 3. It is described in more details in the comment in the patch, the bottom line is that both RO and RW updates are supported, and SPI and USB modes use the same protocol now. The notions of PDU (protocol data unit) passed between the host and the programming function on the CR50 is introduced, and USB mode framing is described. BRANCH=none BUG=chrome-os-partner:55789 TEST=verified that version 1 and 2 updates still work. Version 3 mode was tested later, when the device side patches were applied. Change-Id: If51854b6a0b140730e85853bc42039233550fe8c Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/371509 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
* g: usb_updater: clean up update protocol handlingVadim Bendebury2016-08-211-51/+21
| | | | | | | | | | | | | | | | | | | | | | In preparation of introducing new update protocol version this patch cleans up the existing implementation. The receive and transmit PDU headers are separated into their own structures and are now shared between the server and client sides. Some comments have been added to better explain different protocol versions' details. BRANCH=none BUG=chrome-os-partner:55789 TEST=verified that it is still possible to update RW_A and RW_B on a Kevin CR50, works using both USB and SPI. Change-Id: Ied65b2c2a7800bae045f1d2dd64e58dd5e793d27 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/368989 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: enhance upgrade protocol to allow upgrade block restartsVadim Bendebury2016-05-021-3/+38
| | | | | | | | | | | | | | | | | | | | | With this new protocol version the target watches the size of the received messages while reassembling an upgrade block. If a message of the header size arrives and it is not the last message of the block, the target considers it a re-start of the block transfer by the host (presumably because a chunk was lost and the host did not receive a confirmation of the block transfer in the preceding block transfer attempt.) BRANCH=none BUG=chrome-os-partner:52586 TEST=the upgrade command on the host reports target running protocol version 2, upgrades on B1 board still run smoothly. Change-Id: I2e16c1be5135c0b5a4f09ea293f09ecabf59ecb3 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341630 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: verify that first message of each upgrade block is rightVadim Bendebury2016-05-021-11/+13
| | | | | | | | | | | | | | | | | | | When a new upgrade block starts, the host sends first a 12 byte message including the block size and header. The target must verify that the message is of the proper size and the contents make sense (the header is not all zeros). It also should drain the USB queue completely in case it holds a message of a different size. BRANCH=none BUG=chrome-os-partner:52856 TEST=upgrade still works fine on B1 Change-Id: I80538a3a1a5d507a84bd21b868a3db626bc6a4b0 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341619 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: upgrade - improve verification of the first upgrade messageVadim Bendebury2016-05-021-6/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | When an upgrade transfer starts, the target expects to receive a 12 byte transfer start message from the host, carrying an empty payload of all zeros. The target and host can be out of sync for whatever reason, so when the target is expecting a transfer start message, the host can be sending a chunk of a code block instead. In this case the target pulls just 12 bytes off the receive queue, leaving the rest of the chunk there, which even more complicates error recovery. This patch makes sure that when expecting the upgrade transfer start message the target extracts all receive data from the queue, no matter how many bytes have been received, and then verifies that the size matches the expected size, and that the payload is all zeros, to confirm that the message is indeed the transfer start message. BRANCH=none BUG=chrome-os-partner:52586 TEST=cr50 firmware upgrade still works fine on B1 Change-Id: If5ec86d0385f97f0f361635b3903cea3a962b707 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341618 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: introduce versioning and backwards compatibility of usb_upgradeVadim Bendebury2016-05-021-4/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The original version of usb_upgrade does not provide for any error recovery and also does not support any protocol version notion. Real life experience has shown that error recovery is essential, it needs to be introduced as a protocol enhancement. We want to stay backwards compatible though, so there is a need for protocol versioning. In the original version of the protocol target response is always the same: a 4 byte number which is the error code (and zero means no error). This patch modifies response to the very first packet from the host, the startup packet. The startup response is 8 bytes long. The first 4 bytes is still the same as before, the second 4 bytes carry the protocol version supported by the target, an integer in network byte order. Thus, receiving a 4 byte reply to the startup message tells the host that the target is running protocol version zero, 8 byte reply carries the actual version number in the last 4 bytes. The USB transfer function on the host is enhanced to accept responses shorter then expected, when allowed. BRANCH=none BUG=chrome-os-partner:52856 TEST=usb_updater can successfully update both old and new cr50 images, properly reporting protocol version as 0 or 1 respectively. Change-Id: I9920d2708b21f29615282161fc0eb027018f9378 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341617 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: fix debug messages not to include two newlinesVadim Bendebury2016-05-021-6/+6
| | | | | | | | | | | | | | The CPRITS() macro adds newline to all strings, there is no need to explicitly add newlines. BRANCH=none BUG=none TEST=usb upgrade debug messages do not span two lines any more Change-Id: I1991214ddaa5945bedba861d67b392973f6a3d0f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341615 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* g: recover from usb_upgrade interruptionsVadim Bendebury2016-05-021-1/+27
| | | | | | | | | | | | | | | | | | | | | The usb upgrade protocol is very fragile, any error while transferring data causes the state machine on the target to lock up, and the only way to resume the upgrade is to power cycle the device. With this patch USB callbacks which happen more than 5 seconds since the previous callback would be considered a start of new transfer, thus allowing to attempt a new upgrade without the power cycle. BRANCH=none BUG=chrome-os-partner:52856 TEST=the following script allows to upgrade successfully: $ while not ./extra/usb_updater/usb_updater build/cr50/ec.bin; do sleep 6; done Change-Id: Ibe1078cf62073ce89a31416522b0d6917bc923b9 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/341572 Reviewed-by: Marius Schilder <mschilder@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
* Cr50: Update the USB VID:PID:subclass constantsBill Richardson2016-04-151-3/+2
| | | | | | | | | | | | | | | | | | | | | | | The device-specific subclass used for Non-HC firmware updates is in the spreadsheet now, so we can rename the macros to be "official". BUG=chrome-os-partner:49962 BRANCH=none TEST=make buildall; test on cr50 make BOARD=cr50 (plus whatever signing magic works for you) make -C extra/usb_updater ./extra/usb_updater/usb_updater build/cr50/ec.bin (sudo if needed) Note that you may need to rebuild ec.bin in order to see any difference after the update. If the A & B images are identical, the RO bootloader always picks A. Change-Id: I385ce89a9abe2059d52da2d82a0b92b9b3e3c93f Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/339220 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
* Cr50: New usb_upgrade module for RW updatesBill Richardson2016-04-121-0/+230
This re-factors the existing firmware upgrade facility, which worked as a TPM command extension. The same code processing upgrade blocks prepended by the truncated SHA1 and the load address is now used by both extended TPM command and the USB upgrader. To accommodate USB communications using a smaller message payloads a reassembly layer is introduced which accumulates short USB payloads into a single block which can be passed to the firmware upgrade routine. USB encapsulation adds one 4 byte header at the beginning of the block to hold the total block size. The reassembly layer keeps receiving USB messages, concatenating their payloads until the full block is received. A config option is added to make sure the module is not compiled when not needed. BUG=chrome-os-partner:50707 BRANCH=none TEST=make buildall; test on Cr50 - with the rest of the patches applied it is possible to upgrade firmware using the USB utility on the host.. Change-Id: Ib30b381c4ab196ea9d352f3c6b8f46dc23ddd599 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/338087