| Patrick Venture | 3d1786b | 2018-08-01 11:19:24 -0700 | [diff] [blame] | 1 | #pragma once | 
|  | 2 |  | 
| Patrick Venture | 8ec019f | 2018-08-07 11:22:33 -0700 | [diff] [blame] | 3 | #include <string> | 
| Patrick Venture | 79e131f | 2018-08-01 13:34:35 -0700 | [diff] [blame] | 4 | #include <vector> | 
|  | 5 |  | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 6 | #include "host-ipmid/ipmid-api.h" | 
|  | 7 |  | 
|  | 8 | /* Clearer way to represent the subcommand size. */ | 
|  | 9 | #define SUBCMD_SZ sizeof(uint8_t) | 
|  | 10 |  | 
| Patrick Venture | 3d1786b | 2018-08-01 11:19:24 -0700 | [diff] [blame] | 11 | /* | 
|  | 12 | * flashStartTransfer -- starts file upload. | 
|  | 13 | * flashDataBlock -- adds data to image file. | 
|  | 14 | * flashDataFinish -- closes the file. | 
|  | 15 | * | 
|  | 16 | * flashStartHash -- starts uploading hash. | 
|  | 17 | * flashDataHash -- adds data to the hash. | 
|  | 18 | * flashDataVerify -- triggers verification. | 
|  | 19 | * | 
|  | 20 | * flashAbort -- abort everything. | 
|  | 21 | * | 
|  | 22 | * flashVerifyCheck -- Check if the verification has completed. | 
|  | 23 | * | 
|  | 24 | * flashVersion -- Get the version of this OEM Handler. | 
|  | 25 | * | 
|  | 26 | * flashRequestRegion -- Request the physical address for decode (bridge) | 
|  | 27 | * flashDataExtBlock -- Provide image data via a bridge | 
|  | 28 | * flashHashExtData -- Provide hash data via a bridge | 
|  | 29 | */ | 
|  | 30 | enum FlashSubCmds | 
|  | 31 | { | 
|  | 32 | /* Start a transfer. */ | 
|  | 33 | flashStartTransfer = 0, | 
|  | 34 | /* Data block. */ | 
|  | 35 | flashDataBlock = 1, | 
|  | 36 | /* Close file. */ | 
|  | 37 | flashDataFinish = 2, | 
|  | 38 |  | 
|  | 39 | /* Start a hash transfer. */ | 
|  | 40 | flashStartHash = 3, | 
|  | 41 | /* Add data to the hash. */ | 
|  | 42 | flashHashData = 4, | 
|  | 43 | /* Close out the hash file. */ | 
|  | 44 | flashHashFinish = 5, | 
|  | 45 |  | 
|  | 46 | /* Verify the flash image against the hast sent. */ | 
|  | 47 | flashDataVerify = 6, | 
|  | 48 |  | 
|  | 49 | /* Abort. */ | 
|  | 50 | flashAbort = 7, | 
|  | 51 |  | 
|  | 52 | /* | 
|  | 53 | * Check if the verification is ready and was successful. | 
|  | 54 | * If the response from the IPMI command is OK, check the | 
|  | 55 | * response bytes to know if it's ready or still computing, | 
|  | 56 | * or failed. | 
|  | 57 | */ | 
|  | 58 | flashVerifyCheck = 8, | 
|  | 59 |  | 
|  | 60 | flashVersion = 9, | 
|  | 61 | flashRequestRegion = 10, | 
|  | 62 | flashDataExtBlock = 11, | 
|  | 63 | flashHashExtData = 12, | 
|  | 64 | flashMapRegionLpc = 13, | 
|  | 65 | }; | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 66 |  | 
|  | 67 | /* | 
|  | 68 | * StartTransfer expects a basic structure providing some information. | 
|  | 69 | */ | 
|  | 70 | struct StartTx | 
|  | 71 | { | 
|  | 72 | uint8_t cmd; | 
|  | 73 | uint32_t length; /* Maximum image length is 4GiB (little-endian) */ | 
|  | 74 | } __attribute__((packed)); | 
|  | 75 |  | 
| Patrick Venture | 79e131f | 2018-08-01 13:34:35 -0700 | [diff] [blame] | 76 | struct ChunkHdr | 
|  | 77 | { | 
|  | 78 | uint8_t cmd; | 
|  | 79 | uint32_t offset; /* 0-based write offset */ | 
|  | 80 | uint8_t data[]; | 
|  | 81 | } __attribute__((packed)); | 
|  | 82 |  | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 83 | class UpdateInterface | 
|  | 84 | { | 
|  | 85 | public: | 
|  | 86 | virtual ~UpdateInterface() = default; | 
|  | 87 |  | 
| Patrick Venture | 2c1205d | 2018-08-03 10:23:14 -0700 | [diff] [blame] | 88 | /** | 
|  | 89 | * Prepare to receive a BMC image and then a signature. | 
|  | 90 | * | 
|  | 91 | * @param[in] length - the size of the flash image. | 
|  | 92 | * @return true on success, false otherwise. | 
|  | 93 | */ | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 94 | virtual bool start(uint32_t length) = 0; | 
| Patrick Venture | 2c1205d | 2018-08-03 10:23:14 -0700 | [diff] [blame] | 95 |  | 
|  | 96 | /** | 
|  | 97 | * Attempt to write the bytes at the offset. | 
|  | 98 | * | 
|  | 99 | * @param[in] offset - the 0-based byte offset into the flash image. | 
|  | 100 | * @param[in] bytes - the bytes to write. | 
|  | 101 | * @return true on success, false otherwise. | 
|  | 102 | */ | 
| Patrick Venture | 79e131f | 2018-08-01 13:34:35 -0700 | [diff] [blame] | 103 | virtual bool flashData(uint32_t offset, | 
|  | 104 | const std::vector<uint8_t>& bytes) = 0; | 
| Patrick Venture | 2c1205d | 2018-08-03 10:23:14 -0700 | [diff] [blame] | 105 |  | 
|  | 106 | /** | 
|  | 107 | * Called to indicate the host is done sending the flash bytes. | 
|  | 108 | */ | 
|  | 109 | virtual bool flashFinish() = 0; | 
| Patrick Venture | 8d9f732 | 2018-08-03 10:39:13 -0700 | [diff] [blame] | 110 |  | 
|  | 111 | /** | 
|  | 112 | * Prepare to receive a BMC image signature. | 
|  | 113 | * | 
|  | 114 | * @param[in] length - length of signature in bytes. | 
|  | 115 | * @return true on success, false otherwise. | 
|  | 116 | */ | 
|  | 117 | virtual bool startHash(uint32_t length) = 0; | 
| Patrick Venture | cfe6687 | 2018-08-03 13:32:33 -0700 | [diff] [blame] | 118 |  | 
|  | 119 | /** | 
|  | 120 | * Attempt to write the bytes at the offset. | 
|  | 121 | * | 
|  | 122 | * @param[in] offset - the 0-based byte offset into the flash image. | 
|  | 123 | * @param[in] bytes - the bytes to write. | 
|  | 124 | * @return true on success, false otherwise. | 
|  | 125 | */ | 
|  | 126 | virtual bool hashData(uint32_t offset, | 
|  | 127 | const std::vector<uint8_t>& bytes) = 0; | 
| Patrick Venture | fbc7d19 | 2018-08-03 13:54:21 -0700 | [diff] [blame] | 128 |  | 
|  | 129 | /** | 
|  | 130 | * Called to indicate the host is done sending the hash bytes. | 
|  | 131 | */ | 
|  | 132 | virtual bool hashFinish() = 0; | 
| Patrick Venture | 1cb87d2 | 2018-08-03 18:22:09 -0700 | [diff] [blame] | 133 |  | 
|  | 134 | /** | 
|  | 135 | * Kick off the flash image verification process. | 
|  | 136 | * | 
|  | 137 | * @return true if it was started succesfully. | 
|  | 138 | */ | 
|  | 139 | virtual bool startDataVerification() = 0; | 
| Patrick Venture | 5c251ca | 2018-08-03 18:31:01 -0700 | [diff] [blame] | 140 |  | 
|  | 141 | /** | 
|  | 142 | * Attempt to abort everything. | 
|  | 143 | * | 
|  | 144 | * @return true if aborted, false if unable or failed. | 
|  | 145 | */ | 
|  | 146 | virtual bool abortUpdate() = 0; | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 147 | }; | 
|  | 148 |  | 
|  | 149 | class FlashUpdate : public UpdateInterface | 
|  | 150 | { | 
|  | 151 | public: | 
| Patrick Venture | 8ec019f | 2018-08-07 11:22:33 -0700 | [diff] [blame] | 152 | FlashUpdate(const std::string& stagingPath) : | 
|  | 153 | flashLength(0), flashFd(nullptr), tmpPath(stagingPath){}; | 
|  | 154 | ~FlashUpdate(); | 
|  | 155 |  | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 156 | FlashUpdate(const FlashUpdate&) = default; | 
|  | 157 | FlashUpdate& operator=(const FlashUpdate&) = default; | 
|  | 158 | FlashUpdate(FlashUpdate&&) = default; | 
|  | 159 | FlashUpdate& operator=(FlashUpdate&&) = default; | 
|  | 160 |  | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 161 | bool start(uint32_t length) override; | 
| Patrick Venture | 79e131f | 2018-08-01 13:34:35 -0700 | [diff] [blame] | 162 | bool flashData(uint32_t offset, const std::vector<uint8_t>& bytes) override; | 
| Patrick Venture | 2c1205d | 2018-08-03 10:23:14 -0700 | [diff] [blame] | 163 | bool flashFinish() override; | 
|  | 164 |  | 
| Patrick Venture | 8d9f732 | 2018-08-03 10:39:13 -0700 | [diff] [blame] | 165 | bool startHash(uint32_t length) override; | 
| Patrick Venture | cfe6687 | 2018-08-03 13:32:33 -0700 | [diff] [blame] | 166 | bool hashData(uint32_t offset, const std::vector<uint8_t>& bytes) override; | 
| Patrick Venture | fbc7d19 | 2018-08-03 13:54:21 -0700 | [diff] [blame] | 167 | bool hashFinish() override; | 
| Patrick Venture | 8d9f732 | 2018-08-03 10:39:13 -0700 | [diff] [blame] | 168 |  | 
| Patrick Venture | 1cb87d2 | 2018-08-03 18:22:09 -0700 | [diff] [blame] | 169 | bool startDataVerification() override; | 
| Patrick Venture | 5c251ca | 2018-08-03 18:31:01 -0700 | [diff] [blame] | 170 | bool abortUpdate() override; | 
| Patrick Venture | 1cb87d2 | 2018-08-03 18:22:09 -0700 | [diff] [blame] | 171 |  | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 172 | private: | 
|  | 173 | /** | 
| Patrick Venture | 8ec019f | 2018-08-07 11:22:33 -0700 | [diff] [blame] | 174 | * Tries to close out everything. | 
|  | 175 | */ | 
|  | 176 | void closeEverything(); | 
|  | 177 |  | 
|  | 178 | /** | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 179 | * Tries to close out and delete anything staged. | 
|  | 180 | */ | 
|  | 181 | void abortEverything(); | 
|  | 182 |  | 
|  | 183 | /** | 
|  | 184 | * Open all staged file handles you expect to use. | 
|  | 185 | * | 
|  | 186 | * @return false on failure. | 
|  | 187 | */ | 
|  | 188 | bool openEverything(); | 
| Patrick Venture | 8ec019f | 2018-08-07 11:22:33 -0700 | [diff] [blame] | 189 |  | 
|  | 190 | /* The length of the flash image in bytes. */ | 
|  | 191 | uint32_t flashLength; | 
|  | 192 |  | 
|  | 193 | /* The file handle to the flash staging file. */ | 
|  | 194 | std::FILE* flashFd; | 
|  | 195 |  | 
|  | 196 | /* Where the bytes are written before verification. */ | 
|  | 197 | const std::string tmpPath; | 
| Patrick Venture | 54c3b53 | 2018-08-01 11:45:49 -0700 | [diff] [blame] | 198 | }; |