| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| #ifndef OPENTITAN_SW_HOST_SPIFLASH_UPDATER_H_ |
| #define OPENTITAN_SW_HOST_SPIFLASH_UPDATER_H_ |
| |
| #include <openssl/sha.h> |
| |
| #include <algorithm> |
| #include <cstdint> |
| #include <cstring> |
| #include <iomanip> |
| #include <iostream> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "sw/host/spiflash/spi_interface.h" |
| |
| namespace opentitan { |
| namespace spiflash { |
| |
| /** Implements the bootstrap SPI frame message. */ |
| struct Frame { |
| /** Frame header definition. */ |
| struct { |
| /** Hash of the `Frame` message starting at the `frame_num` offset. */ |
| uint8_t hash[32]; |
| |
| /** Frame number. Starting at 0. */ |
| uint32_t frame_num; |
| |
| /** Flash target offset. */ |
| uint32_t offset; |
| } hdr; |
| |
| /** Frame payload. */ |
| uint8_t data[2048 - sizeof(hdr)]; |
| |
| /** Returns available the frame available payload size in bytes. */ |
| size_t PayloadSize() const { return 2048 - sizeof(hdr); } |
| }; |
| |
| /** |
| * Implements SPI flash update protocol. |
| * |
| * The firmare image is split into frames, and then sent to the SPI device. |
| * More details will be added on the ack protocol once implemented. |
| * This class is not thread safe due to the spi driver dependency. |
| */ |
| class Updater { |
| public: |
| /** Updater configuration settings. */ |
| struct Options { |
| /** Firmware image in binary format. */ |
| std::string code; |
| /** Flash erase delay in microseconds. */ |
| int32_t flash_erase_delay_us = 100000; |
| }; |
| |
| /** |
| * Constructs updater instance with given configuration `options` and `spi` |
| * interface. |
| * |
| * @param options `Updater` options @see Updater::Options. |
| * @param spi SPI interface @see SpiInterface. |
| */ |
| Updater(Options options, std::unique_ptr<SpiInterface> spi) |
| : options_(options), spi_(std::move(spi)) {} |
| virtual ~Updater() = default; |
| |
| // Not copy or movable |
| Updater(const Updater &) = delete; |
| Updater &operator=(const Updater &) = delete; |
| |
| /** |
| * Runs update flow returning true on success. |
| * |
| * @return true on success, false otherwise. |
| */ |
| bool Run(); |
| |
| /** |
| * Generates `frames` from `code` image. |
| * |
| * @param code software image in binary format. |
| * @param[out] frames output SPI frames. |
| * |
| * @return true on success, false otherwise. |
| */ |
| static bool GenerateFrames(const std::string &code, |
| std::vector<Frame> *frames); |
| |
| private: |
| Options options_; |
| std::unique_ptr<SpiInterface> spi_; |
| }; |
| |
| } // namespace spiflash |
| } // namespace opentitan |
| |
| #endif // OPENTITAN_SW_HOST_SPIFLASH_UPDATER_H_ |