blob: 2d7dcaa63190d7ace8544165fcad014347216b9c [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/*
13 * flashStartTransfer -- starts file upload.
14 * flashDataBlock -- adds data to image file.
15 * flashDataFinish -- closes the file.
16 *
17 * flashStartHash -- starts uploading hash.
18 * flashDataHash -- adds data to the hash.
19 * flashDataVerify -- triggers verification.
20 *
21 * flashAbort -- abort everything.
22 *
23 * flashVerifyCheck -- Check if the verification has completed.
24 *
25 * flashVersion -- Get the version of this OEM Handler.
26 *
27 * flashRequestRegion -- Request the physical address for decode (bridge)
28 * flashDataExtBlock -- Provide image data via a bridge
29 * flashHashExtData -- Provide hash data via a bridge
30 */
31enum FlashSubCmds
32{
33 /* Start a transfer. */
34 flashStartTransfer = 0,
35 /* Data block. */
36 flashDataBlock = 1,
37 /* Close file. */
38 flashDataFinish = 2,
39
40 /* Start a hash transfer. */
41 flashStartHash = 3,
42 /* Add data to the hash. */
43 flashHashData = 4,
44 /* Close out the hash file. */
45 flashHashFinish = 5,
46
47 /* Verify the flash image against the hast sent. */
48 flashDataVerify = 6,
49
50 /* Abort. */
51 flashAbort = 7,
52
53 /*
54 * Check if the verification is ready and was successful.
55 * If the response from the IPMI command is OK, check the
56 * response bytes to know if it's ready or still computing,
57 * or failed.
58 */
59 flashVerifyCheck = 8,
60
61 flashVersion = 9,
62 flashRequestRegion = 10,
63 flashDataExtBlock = 11,
64 flashHashExtData = 12,
65 flashMapRegionLpc = 13,
66};
Patrick Venture54c3b532018-08-01 11:45:49 -070067
68/*
69 * StartTransfer expects a basic structure providing some information.
70 */
71struct StartTx
72{
73 uint8_t cmd;
74 uint32_t length; /* Maximum image length is 4GiB (little-endian) */
75} __attribute__((packed));
76
Patrick Venture79e131f2018-08-01 13:34:35 -070077struct ChunkHdr
78{
79 uint8_t cmd;
80 uint32_t offset; /* 0-based write offset */
81 uint8_t data[];
82} __attribute__((packed));
83
Patrick Venture54c3b532018-08-01 11:45:49 -070084class UpdateInterface
85{
86 public:
87 virtual ~UpdateInterface() = default;
88
Patrick Venture2c1205d2018-08-03 10:23:14 -070089 /**
90 * Prepare to receive a BMC image and then a signature.
91 *
92 * @param[in] length - the size of the flash image.
93 * @return true on success, false otherwise.
94 */
Patrick Venture54c3b532018-08-01 11:45:49 -070095 virtual bool start(uint32_t length) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -070096
97 /**
98 * Attempt to write the bytes at the offset.
99 *
100 * @param[in] offset - the 0-based byte offset into the flash image.
101 * @param[in] bytes - the bytes to write.
102 * @return true on success, false otherwise.
103 */
Patrick Venture79e131f2018-08-01 13:34:35 -0700104 virtual bool flashData(uint32_t offset,
105 const std::vector<uint8_t>& bytes) = 0;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700106
107 /**
108 * Called to indicate the host is done sending the flash bytes.
109 */
110 virtual bool flashFinish() = 0;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700111
112 /**
113 * Prepare to receive a BMC image signature.
114 *
115 * @param[in] length - length of signature in bytes.
116 * @return true on success, false otherwise.
117 */
118 virtual bool startHash(uint32_t length) = 0;
Patrick Venturecfe66872018-08-03 13:32:33 -0700119
120 /**
121 * Attempt to write the bytes at the offset.
122 *
123 * @param[in] offset - the 0-based byte offset into the flash image.
124 * @param[in] bytes - the bytes to write.
125 * @return true on success, false otherwise.
126 */
127 virtual bool hashData(uint32_t offset,
128 const std::vector<uint8_t>& bytes) = 0;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700129
130 /**
131 * Called to indicate the host is done sending the hash bytes.
132 */
133 virtual bool hashFinish() = 0;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700134
135 /**
136 * Kick off the flash image verification process.
137 *
138 * @return true if it was started succesfully.
139 */
140 virtual bool startDataVerification() = 0;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700141
142 /**
143 * Attempt to abort everything.
144 *
145 * @return true if aborted, false if unable or failed.
146 */
147 virtual bool abortUpdate() = 0;
Patrick Venture54c3b532018-08-01 11:45:49 -0700148};
149
150class FlashUpdate : public UpdateInterface
151{
152 public:
Patrick Venture6f17bd22018-08-07 13:24:17 -0700153 FlashUpdate(const std::string& stagingPath, const std::string& hash = "") :
154 flashLength(0), flashFd(nullptr), tmpPath(stagingPath), hashLength(0),
155 hashFd(nullptr), hashPath(hash){};
Patrick Venture8ec019f2018-08-07 11:22:33 -0700156 ~FlashUpdate();
157
Patrick Venture54c3b532018-08-01 11:45:49 -0700158 FlashUpdate(const FlashUpdate&) = default;
159 FlashUpdate& operator=(const FlashUpdate&) = default;
160 FlashUpdate(FlashUpdate&&) = default;
161 FlashUpdate& operator=(FlashUpdate&&) = default;
162
Patrick Venture54c3b532018-08-01 11:45:49 -0700163 bool start(uint32_t length) override;
Patrick Venture79e131f2018-08-01 13:34:35 -0700164 bool flashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venture2c1205d2018-08-03 10:23:14 -0700165 bool flashFinish() override;
166
Patrick Venture8d9f7322018-08-03 10:39:13 -0700167 bool startHash(uint32_t length) override;
Patrick Venturecfe66872018-08-03 13:32:33 -0700168 bool hashData(uint32_t offset, const std::vector<uint8_t>& bytes) override;
Patrick Venturefbc7d192018-08-03 13:54:21 -0700169 bool hashFinish() override;
Patrick Venture8d9f7322018-08-03 10:39:13 -0700170
Patrick Venture1cb87d22018-08-03 18:22:09 -0700171 bool startDataVerification() override;
Patrick Venture5c251ca2018-08-03 18:31:01 -0700172 bool abortUpdate() override;
Patrick Venture1cb87d22018-08-03 18:22:09 -0700173
Patrick Venture54c3b532018-08-01 11:45:49 -0700174 private:
175 /**
Patrick Venture3c086f22018-08-07 11:59:20 -0700176 * Attempt to write the bytes at the offset.
177 *
178 * @param[in] fd - the file stream pointer.
179 * @param[in] offset - the 0-based byte offset into the flash image.
180 * @param[in] bytes - the bytes to write.
181 * @return true on success, false otherwise.
182 */
183 bool writeBlock(std::FILE* fd, uint32_t offset,
184 const std::vector<uint8_t>& bytes);
185
186 /**
Patrick Venture8ec019f2018-08-07 11:22:33 -0700187 * Tries to close out everything.
188 */
189 void closeEverything();
190
191 /**
Patrick Venture54c3b532018-08-01 11:45:49 -0700192 * Tries to close out and delete anything staged.
193 */
194 void abortEverything();
195
196 /**
197 * Open all staged file handles you expect to use.
198 *
199 * @return false on failure.
200 */
201 bool openEverything();
Patrick Venture8ec019f2018-08-07 11:22:33 -0700202
203 /* The length of the flash image in bytes. */
204 uint32_t flashLength;
205
206 /* The file handle to the flash staging file. */
207 std::FILE* flashFd;
208
209 /* Where the bytes are written before verification. */
210 const std::string tmpPath;
Patrick Venture6f17bd22018-08-07 13:24:17 -0700211
212 /* The length of the hash in bytes. */
213 uint32_t hashLength;
214
215 /* The file handle to the hash file. */
216 std::FILE* hashFd;
217
218 /* Where we write the hash bytes. Only required if your verification
219 * process uses a separate signature.
220 */
221 const std::string hashPath;
Patrick Venture54c3b532018-08-01 11:45:49 -0700222};