blob: 4a13edbe8fd1bf5119f51e61bfe26a0b8c00906c [file] [log] [blame]
Patrick Venture3d1786b2018-08-01 11:19:24 -07001#pragma once
2
Patrick Venture3c086f22018-08-07 11:59:20 -07003#include <cstdio>
Patrick Venture8ec019f2018-08-07 11:22:33 -07004#include <string>
Patrick Venture79e131f2018-08-01 13:34:35 -07005#include <vector>
6
Patrick Venture54c3b532018-08-01 11:45:49 -07007#include "host-ipmid/ipmid-api.h"
8
9/* Clearer way to represent the subcommand size. */
10#define SUBCMD_SZ sizeof(uint8_t)
11
Patrick Venture3d1786b2018-08-01 11:19:24 -070012/*
Patrick Venturefdc65b22018-08-07 14:37:58 -070013 * These are the codes we return over IPMI when the host checks for the status
14 * of the asynchronous verification call.
15 */
16enum VerifyCheckResponse
17{
18 running = 0x00,
19 success = 0x01,
20 failed = 0x02,
21 other = 0x03,
22};
23
24/*
Patrick Venture3d1786b2018-08-01 11:19:24 -070025 * flashStartTransfer -- starts file upload.
26 * flashDataBlock -- adds data to image file.
27 * flashDataFinish -- closes the file.
28 *
29 * flashStartHash -- starts uploading hash.
30 * flashDataHash -- adds data to the hash.
31 * flashDataVerify -- triggers verification.
32 *
33 * flashAbort -- abort everything.
34 *
35 * flashVerifyCheck -- Check if the verification has completed.
36 *
37 * flashVersion -- Get the version of this OEM Handler.
38 *
39 * flashRequestRegion -- Request the physical address for decode (bridge)
40 * flashDataExtBlock -- Provide image data via a bridge
41 * flashHashExtData -- Provide hash data via a bridge
42 */
43enum FlashSubCmds
44{
45 /* Start a transfer. */
46 flashStartTransfer = 0,
47 /* Data block. */
48 flashDataBlock = 1,
49 /* Close file. */
50 flashDataFinish = 2,
51
52 /* Start a hash transfer. */
53 flashStartHash = 3,
54 /* Add data to the hash. */
55 flashHashData = 4,
56 /* Close out the hash file. */
57 flashHashFinish = 5,
58
59 /* Verify the flash image against the hast sent. */
60 flashDataVerify = 6,
61
62 /* Abort. */
63 flashAbort = 7,
64
65 /*
66 * Check if the verification is ready and was successful.
67 * If the response from the IPMI command is OK, check the
68 * response bytes to know if it's ready or still computing,
69 * or failed.
70 */
71 flashVerifyCheck = 8,
72
73 flashVersion = 9,
74 flashRequestRegion = 10,
75 flashDataExtBlock = 11,
76 flashHashExtData = 12,
77 flashMapRegionLpc = 13,
78};
Patrick Venture54c3b532018-08-01 11:45:49 -070079
80/*
81 * StartTransfer expects a basic structure providing some information.
82 */
83struct StartTx
84{
85 uint8_t cmd;
86 uint32_t length; /* Maximum image length is 4GiB (little-endian) */
87} __attribute__((packed));
88
Patrick Venture79e131f2018-08-01 13:34:35 -070089struct ChunkHdr
90{
91 uint8_t cmd;
92 uint32_t offset; /* 0-based write offset */
93 uint8_t data[];
94} __attribute__((packed));
95
Patrick Venture54c3b532018-08-01 11:45:49 -070096class UpdateInterface
97{
98 public:
99 virtual ~UpdateInterface() = default;
100
Patrick Venture2c1205d2018-08-03 10:23:14 -0700101 /**
102 * Prepare to receive a BMC image and then a signature.
103 *
104 * @param[in] length - the size of the flash image.
105 * @return true on success, false otherwise.
106 */
Patrick Venture54c3b532018-08-01 11:45:49 -0700107 virtual bool start(uint32_t length) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700108
109 /**
110 * Attempt to write the bytes at the offset.
111 *
112 * @param[in] offset - the 0-based byte offset into the flash image.
113 * @param[in] bytes - the bytes to write.
114 * @return true on success, false otherwise.
115 */
Patrick Venture79e131f2018-08-01 13:34:35 -0700116 virtual bool flashData(uint32_t offset,
117 const std::vector<uint8_t>& bytes) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700118
119 /**
120 * Called to indicate the host is done sending the flash bytes.
121 */
122 virtual bool flashFinish() = 0;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700123
124 /**
125 * Prepare to receive a BMC image signature.
126 *
127 * @param[in] length - length of signature in bytes.
128 * @return true on success, false otherwise.
129 */
130 virtual bool startHash(uint32_t length) = 0;
Patrick Venturecfe66872018-08-03 13:32:33 -0700131
132 /**
133 * Attempt to write the bytes at the offset.
134 *
135 * @param[in] offset - the 0-based byte offset into the flash image.
136 * @param[in] bytes - the bytes to write.
137 * @return true on success, false otherwise.
138 */
139 virtual bool hashData(uint32_t offset,
140 const std::vector<uint8_t>& bytes) = 0;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700141
142 /**
143 * Called to indicate the host is done sending the hash bytes.
144 */
145 virtual bool hashFinish() = 0;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700146
147 /**
148 * Kick off the flash image verification process.
149 *
150 * @return true if it was started succesfully.
151 */
152 virtual bool startDataVerification() = 0;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700153
154 /**
155 * Attempt to abort everything.
156 *
157 * @return true if aborted, false if unable or failed.
158 */
159 virtual bool abortUpdate() = 0;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700160
161 /**
162 * Check if the verification result is available and return.
163 *
164 * @return the verification response.
165 */
166 virtual VerifyCheckResponse checkVerify() = 0;
Patrick Venture54c3b532018-08-01 11:45:49 -0700167};
168
169class FlashUpdate : public UpdateInterface
170{
171 public:
Patrick Venturefdc65b22018-08-07 14:37:58 -0700172 FlashUpdate(const std::string& stagingPath, const std::string& verifyPath,
173 const std::string& hash = "") :
174 flashLength(0),
175 flashFd(nullptr), tmpPath(stagingPath), hashLength(0), hashFd(nullptr),
176 hashPath(hash), verifyPath(verifyPath){};
Patrick Venture8ec019f2018-08-07 11:22:33 -0700177 ~FlashUpdate();
178
Patrick Venture54c3b532018-08-01 11:45:49 -0700179 FlashUpdate(const FlashUpdate&) = default;
180 FlashUpdate& operator=(const FlashUpdate&) = default;
181 FlashUpdate(FlashUpdate&&) = default;
182 FlashUpdate& operator=(FlashUpdate&&) = default;
183
Patrick Venture54c3b532018-08-01 11:45:49 -0700184 bool start(uint32_t length) override;
Patrick Venture79e131f2018-08-01 13:34:35 -0700185 bool flashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700186 bool flashFinish() override;
187
Patrick Venture8d9f7322018-08-03 10:39:13 -0700188 bool startHash(uint32_t length) override;
Patrick Venturecfe66872018-08-03 13:32:33 -0700189 bool hashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700190 bool hashFinish() override;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700191
Patrick Venture1cb87d22018-08-03 18:22:09 -0700192 bool startDataVerification() override;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700193 bool abortUpdate() override;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700194 VerifyCheckResponse checkVerify() override;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700195
Patrick Venture54c3b532018-08-01 11:45:49 -0700196 private:
197 /**
Patrick Venture3c086f22018-08-07 11:59:20 -0700198 * Attempt to write the bytes at the offset.
199 *
200 * @param[in] fd - the file stream pointer.
201 * @param[in] offset - the 0-based byte offset into the flash image.
202 * @param[in] bytes - the bytes to write.
203 * @return true on success, false otherwise.
204 */
205 bool writeBlock(std::FILE* fd, uint32_t offset,
206 const std::vector<uint8_t>& bytes);
207
208 /**
Patrick Venture8ec019f2018-08-07 11:22:33 -0700209 * Tries to close out everything.
210 */
211 void closeEverything();
212
213 /**
Patrick Venture54c3b532018-08-01 11:45:49 -0700214 * Tries to close out and delete anything staged.
215 */
216 void abortEverything();
217
218 /**
219 * Open all staged file handles you expect to use.
220 *
221 * @return false on failure.
222 */
223 bool openEverything();
Patrick Venture8ec019f2018-08-07 11:22:33 -0700224
225 /* The length of the flash image in bytes. */
226 uint32_t flashLength;
227
228 /* The file handle to the flash staging file. */
229 std::FILE* flashFd;
230
231 /* Where the bytes are written before verification. */
232 const std::string tmpPath;
Patrick Venture6f17bd22018-08-07 13:24:17 -0700233
234 /* The length of the hash in bytes. */
235 uint32_t hashLength;
236
237 /* The file handle to the hash file. */
238 std::FILE* hashFd;
239
240 /* Where we write the hash bytes. Only required if your verification
241 * process uses a separate signature.
242 */
243 const std::string hashPath;
Patrick Venturefdc65b22018-08-07 14:37:58 -0700244
245 /* The path to read the status of the signature verification. */
246 const std::string verifyPath;
Patrick Venture54c3b532018-08-01 11:45:49 -0700247};