MCPcopy Create free account
hub / github.com/coreboot/coreboot / ec_flash_write

Function ec_flash_write

src/security/vboot/ec_sync.c:242–317  ·  view source on GitHub ↗

* Send an image to the EC in burst-sized chunks. */

Source from the content-addressed store, hash-verified

240 * Send an image to the EC in burst-sized chunks.
241 */
242static vb2_error_t ec_flash_write(void *image, uint32_t region_offset,
243 int image_size)
244{
245 struct ec_response_get_protocol_info resp_proto;
246 struct ec_response_flash_info resp_flash;
247 ssize_t pdata_max_size;
248 ssize_t burst;
249 uint8_t *file_buf;
250 struct ec_params_flash_write *params;
251 uint32_t end, off;
252
253 /*
254 * Get EC's protocol information, so that we can figure out how much
255 * data can be sent in one message.
256 */
257 if (google_chromeec_get_protocol_info(&resp_proto)) {
258 printk(BIOS_ERR, "Failed to get EC protocol information; "
259 "skipping flash write\n");
260 return VB2_ERROR_UNKNOWN;
261 }
262
263 /*
264 * Determine burst size. This must be a multiple of the write block
265 * size, and must also fit into the host parameter buffer.
266 */
267 if (google_chromeec_flash_info(&resp_flash)) {
268 printk(BIOS_ERR, "Failed to get EC flash information; "
269 "skipping flash write\n");
270 return VB2_ERROR_UNKNOWN;
271 }
272
273 /* Limit the potential buffer stack allocation to 1K */
274 pdata_max_size = MIN(1024, resp_proto.max_request_packet_size -
275 sizeof(struct ec_host_request));
276
277 /* Round burst to a multiple of the flash write block size */
278 burst = pdata_max_size - sizeof(*params);
279 burst = (burst / resp_flash.write_block_size) *
280 resp_flash.write_block_size;
281
282 /* Buffer too small */
283 if (burst <= 0) {
284 printk(BIOS_ERR, "Flash write buffer too small! skipping "
285 "flash write\n");
286 return VB2_ERROR_UNKNOWN;
287 }
288
289 /* Allocate buffer on the stack */
290 params = alloca(burst + sizeof(*params));
291
292 /* Fill up the buffer */
293 end = region_offset + image_size;
294 file_buf = image;
295 for (off = region_offset; off < end; off += burst) {
296 uint32_t todo = MIN(end - off, burst);
297 uint32_t xfer_size = todo + sizeof(*params);
298
299 params->offset = off;

Callers 1

ec_update_imageFunction · 0.85

Calls 5

printkFunction · 0.50
memcpyFunction · 0.50

Tested by

no test coverage detected