[rom_ext] Rescue protocol production readiness
@cfrantz is already working on this.
Since Feb 28, 2025.
- Dominant language
- SystemVerilog
- Stars
- 3.6k
- Forks
- 1.1k
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 141
Description
### Description
A number of small issues have come to my attention:
- If UART RX is externally jammed to ground, ROM_EXT will indefinitely wait in rescue mode, preventing the booting of a Chromebook (initially reported as comment in #24551).
- OpenTitanTool rescue of Ti50 takes about 8 seconds, but the first 3 of which there is almost no communication. It appears that on three occasions, opentitantool waits for the character "C" to be printed by ROM_EXT, which it does every second.
- ROM_EXT has for instance a "WAIT" command, which is used to control the behavior of subsequent "RESQ" (whether to immediately boot into the new firmware, or wait for further commands after completed transfer). Since opentitantool can always reboot, ROM_EXT could be simplified by "WAIT" always being implicitly enabled. But to stay compatible with older versions of opentitantool (or other clients), the command was introduced. I think it is undesirable that ROM_EXT should carry features to support a range of host tool versions, it should be the other way around, that host tools knows about a range of ROM_EXT rescue protocol versions, and how to deal with them slightly differently.
I propose the following changes:
Upon entering rescue mode due to UART RX being low. ROM_EXT should print a banner including a rescue protocol version number, in a major.minor format (more on this later). It should then wait at most 50ms from the time the banner finished printing, and if RX has not going high by then, it should resume normal boot.
We commit to updating the major.minor rescue protocol version number such that changing meaning of existing commands, such as e.g. changing "RESQ" so that it by default remains in rescue more after completion, instead of by default rebooting, must be accompanied by incrementing the major version. Adding new commands, such as adding "WAIT", is to be accompanied by incrementing the minor version.
By doing as above, if opentitantool is e.g. built with an understanding of rescue protocol 2.1, and it connects to a ROM_EXT that advertises version 2.2. Opentitantool will know that it it can expect all the commands it knows about to work as it was designed for. If a ROM_EXT advertises version 2.0, then depending on how much effort we have put into compatibility in opentitantool, it will know that maybe one particular command is not present, and will have to employ workarounds or cannot support a particular operation. The same is true if ROM_EXT advertises 1.0 or some other earlier version. If ROM_EXT advertises 3.0, or any newer version, opentitantool would have to abort, stating that a newer version of opentitantool is needed in order to rescue this chip. This scheme will allow us maximal flexibility for backwards compatibility, without requiring ROM_EXT to carry along code for obsolete commands.
With the above in place, we can remove the "WAIT" command by making "RESQ" always remain in rescue mode after completion, we can also remove the "REBO" (reboot) command, as opentitantool can achieve the same by pulling the reset line. I also think that we could drop the "BAUD" command, since the six defined baud rates are unique four-letter command anyway, they could just serve as "top level" commands.
Also, I question the usefulness of the "C" characters being emitted every second from the rescue bootloader. Maybe there are use cases that I am unaware of. But assuming opentitantool is used, it will have RESET and the two UART signals, and will always start out by resetting the OT chip to enter rescue mode, to inspect the banner. In this state, opentitantool will send commands, getting quick response to each of them, so at no point should opentitantool be "in doubt" whether the ROM_EXT in the other end is still in rescue mode. I propose dropping the "C" characters, and skipping the waiting for a "C" that appears to be in opentitantool code, in order to shave 1/3 of the time for a Ti50 rescue off.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.