1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of Google or the names of contributors or
18 * licensors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * This software is provided "AS IS," without a warranty of any kind.
22 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
23 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
24 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
25 * GOOGLE INC AND ITS LICENSORS SHALL NOT BE LIABLE
26 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
27 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
28 * GOOGLE OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
29 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
30 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
31 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
32 * EVEN IF GOOGLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 */
34
35 #include <assert.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <inttypes.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include <sys/ioctl.h>
45 #include <sys/stat.h>
46 #include <sys/types.h>
47
48 #include <linux/ioctl.h>
49 #include <linux/types.h>
50
51 #include "flashchips.h"
52 #include "flash.h"
53 #include "fmap.h"
54 #include "cros_ec_commands.h"
55 #include "programmer.h"
56 #include "spi.h"
57
58 static bool g_cros_ec_detected = false;
59 static int g_cros_ec_fd; /* File descriptor for kernel device */
60
61 struct cros_ec_priv {
62 enum ec_current_image current_image;
63 struct ec_response_flash_region_info *region;
64
65 /*
66 * Some CrOS ECs support page write mode for their flash memory. This
67 * represents the ideal size of a data payload to write to flash.
68 */
69 unsigned int ideal_write_size;
70 } cros_ec_dev_priv = {
71 .current_image = EC_IMAGE_UNKNOWN,
72 .region = NULL,
73 .ideal_write_size = 0,
74 };
75
76
77 /* For region larger use async version for FLASH_ERASE */
78 #define FLASH_SMALL_REGION_THRESHOLD (16 * 1024)
79
80 /* 1 if we want the flashrom to call erase_and_write_flash() again. */
81 static int need_2nd_pass = 0;
82
83 /* true if cros_ec encounters spi_access denied during erasure. */
84 static bool spi_acc_issue = false;
85
86 /* 1 if EC firmware has RWSIG enabled. */
87 static int rwsig_enabled = 0;
88
89 /* The range of each firmware copy from the image file to update.
90 * But re-define the .flags as the valid flag to indicate the firmware is
91 * new or not (if flags = 1).
92 */
93 static struct fmap_area fwcopy[4]; // [0] is not used.
94
95 /* The names of enum lpc_current_image to match in FMAP area names. */
96 static const char *sections[] = {
97 "UNKNOWN SECTION", // EC_IMAGE_UNKNOWN -- never matches
98 "EC_RO",
99 "EC_RW",
100 };
101
102 static struct ec_response_flash_region_info regions[EC_FLASH_REGION_COUNT];
103
104 /*
105 * Delay after reboot before EC can respond to host command.
106 * This value should be large enough for EC to initialize, but no larger than
107 * CONFIG_RWSIG_JUMP_TIMEOUT. This way for EC using RWSIG task, we will be
108 * able to abort RWSIG jump and stay in RO.
109 */
110 #define EC_INIT_DELAY 800000
111
112 /*
113 * Delay after a cold reboot which allows RWSIG enabled EC to jump to EC_RW.
114 */
115 #define EC_RWSIG_JUMP_TO_RW_DELAY 3000000
116
117 /* Given the range not able to update, mark the corresponding
118 * firmware as old.
119 */
cros_ec_invalidate_copy(unsigned int addr,unsigned int len)120 static void cros_ec_invalidate_copy(unsigned int addr, unsigned int len)
121 {
122 for (unsigned int i = EC_IMAGE_RO; i < ARRAY_SIZE(fwcopy); i++) {
123 struct fmap_area *fw = &fwcopy[i];
124 if ((addr >= fw->offset && (addr < fw->offset + fw->size)) ||
125 (fw->offset >= addr && (fw->offset < addr + len))) {
126 msg_pdbg(" OLD[%s]", sections[i]);
127 fw->flags = 0; // mark as old
128 }
129 }
130 }
131
132 /* ugly singleton to work around cros layering violations in action_descriptor.c */
programming_ec(void)133 bool programming_ec(void)
134 {
135 /* Programmer is EC so toggle ec-alias path detection on. */
136 return g_cros_ec_detected;
137 }
138
139 /*
140 * @version: Command version number (often 0)
141 * @command: Command to send (EC_CMD_...)
142 * @outsize: Outgoing length in bytes
143 * @insize: Max number of bytes to accept from EC
144 * @result: EC's response to the command (separate from communication failure)
145 * @data: Where to put the incoming data from EC and outgoing data to EC
146 */
147 struct cros_ec_command_v2 {
148 uint32_t version;
149 uint32_t command;
150 uint32_t outsize;
151 uint32_t insize;
152 uint32_t result;
153 uint8_t data[0];
154 };
155
156 #define CROS_EC_DEV_IOC_V2 0xEC
157 #define CROS_EC_DEV_IOCXCMD_V2 _IOWR(CROS_EC_DEV_IOC_V2, 0, \
158 struct cros_ec_command_v2)
159
160 #define CROS_EC_DEV_RETRY 3
161 #define CROS_EC_COMMAND_RETRIES 50
162
163 /*
164 * ec device interface v2
165 * (used with upstream kernel as well as with Chrome OS v4.4 and later)
166 */
167
command_wait_for_response_v2(int cros_ec_fd)168 static int command_wait_for_response_v2(int cros_ec_fd)
169 {
170 uint8_t s_cmd_buf[sizeof(struct cros_ec_command_v2) +
171 sizeof(struct ec_response_get_comms_status)];
172 struct cros_ec_command_v2 *s_cmd = (struct cros_ec_command_v2 *)s_cmd_buf;
173 struct ec_response_get_comms_status *status = (struct ec_response_get_comms_status *)s_cmd->data;
174 int ret;
175
176 s_cmd->version = 0;
177 s_cmd->command = EC_CMD_GET_COMMS_STATUS;
178 s_cmd->outsize = 0;
179 s_cmd->insize = sizeof(*status);
180
181 /*
182 * FIXME: magic delay until we fix the underlying problem (probably in
183 * the kernel driver)
184 */
185 usleep(10 * 1000);
186 for (int i = 1; i <= CROS_EC_COMMAND_RETRIES; i++) {
187 ret = ioctl(cros_ec_fd, CROS_EC_DEV_IOCXCMD_V2, s_cmd_buf);
188 if (ret < 0) {
189 msg_perr("%s(): CrOS EC command failed: %d, errno=%d\n",
190 __func__, ret, errno);
191 ret = -EC_RES_ERROR;
192 break;
193 }
194 if (s_cmd->result) {
195 msg_perr("%s(): CrOS EC command failed: result=%d\n",
196 __func__, s_cmd->result);
197 ret = -s_cmd->result;
198 break;
199 }
200
201 if (!(status->flags & EC_COMMS_STATUS_PROCESSING)) {
202 ret = -EC_RES_SUCCESS;
203 break;
204 }
205
206 usleep(1000);
207 }
208
209 return ret;
210 }
211
__cros_ec_command_dev_v2(int cros_ec_fd,int command,int version,const void * outdata,int outsize,void * indata,int insize)212 static int __cros_ec_command_dev_v2(int cros_ec_fd, int command, int version,
213 const void *outdata, int outsize,
214 void *indata, int insize)
215 {
216 const size_t size = sizeof(struct cros_ec_command_v2) + max(outsize, insize);
217
218 assert(outsize == 0 || outdata != NULL);
219 assert(insize == 0 || indata != NULL);
220
221 struct cros_ec_command_v2 *s_cmd = malloc(size);
222 if (s_cmd == NULL)
223 return -EC_RES_ERROR;
224
225 s_cmd->command = command;
226 s_cmd->version = version;
227 s_cmd->result = 0xff;
228 s_cmd->outsize = outsize;
229 s_cmd->insize = insize;
230 memcpy(s_cmd->data, outdata, outsize);
231
232 int ret = ioctl(cros_ec_fd, CROS_EC_DEV_IOCXCMD_V2, s_cmd, size);
233 if (ret < 0 && errno == EAGAIN) {
234 ret = command_wait_for_response_v2(cros_ec_fd);
235 s_cmd->result = 0;
236 }
237 if (ret < 0) {
238 msg_perr("%s(): Command 0x%04x failed: %d, errno=%d\n",
239 __func__, command, ret, errno);
240 free(s_cmd);
241 return -EC_RES_ERROR;
242 }
243 if (s_cmd->result) {
244 msg_pdbg("%s(): Command 0x%04x returned result: %d\n",
245 __func__, command, s_cmd->result);
246 ret = -s_cmd->result;
247 free(s_cmd);
248 return ret;
249 }
250
251 memcpy(indata, s_cmd->data, min(ret, insize));
252 free(s_cmd);
253 return min(ret, insize);
254 }
255
256 /*
257 * cros_ec_command - Issue command to CROS_EC device with retry
258 *
259 * @command: command code
260 * @outdata: data to send to EC
261 * @outsize: number of bytes in outbound payload
262 * @indata: (unallocated) buffer to store data received from EC
263 * @insize: number of bytes in inbound payload
264 *
265 * This uses the kernel Chrome OS EC driver to communicate with the EC.
266 *
267 * The outdata and indata buffers contain payload data (if any); command
268 * and response codes as well as checksum data are handled transparently by
269 * this function.
270 *
271 * Returns >=0 for success, or negative if other error.
272 */
cros_ec_command(int command,int version,const void * outdata,int outsize,void * indata,int insize)273 static int cros_ec_command(int command, int version,
274 const void *outdata, int outsize,
275 void *indata, int insize)
276 {
277 int ret = EC_RES_ERROR;
278 int attempt;
279
280 for (attempt = 0; attempt < CROS_EC_DEV_RETRY; attempt++) {
281 ret = __cros_ec_command_dev_v2(g_cros_ec_fd, command, version, outdata,
282 outsize, indata, insize);
283 if (ret >= 0)
284 return ret;
285 }
286
287 return ret;
288 }
289
cros_ec_get_current_image(void)290 static int cros_ec_get_current_image(void)
291 {
292 struct ec_response_get_version resp;
293
294 int rc = cros_ec_command(EC_CMD_GET_VERSION,
295 0, NULL, 0, &resp, sizeof(resp));
296 if (rc < 0) {
297 msg_perr("CROS_EC cannot get the running copy: rc=%d\n", rc);
298 return rc;
299 }
300 if (resp.current_image == EC_IMAGE_UNKNOWN) {
301 msg_perr("CROS_EC gets unknown running copy\n");
302 return -1;
303 }
304
305 return resp.current_image;
306 }
307
308
cros_ec_get_region_info(enum ec_flash_region region,struct ec_response_flash_region_info * info)309 static int cros_ec_get_region_info(enum ec_flash_region region,
310 struct ec_response_flash_region_info *info)
311 {
312 struct ec_params_flash_region_info req = { .region = region };
313 struct ec_response_flash_region_info resp;
314
315 int rc = cros_ec_command(EC_CMD_FLASH_REGION_INFO,
316 EC_VER_FLASH_REGION_INFO, &req, sizeof(req),
317 &resp, sizeof(resp));
318 if (rc < 0) {
319 msg_perr("Cannot get the WP_RO region info: %d\n", rc);
320 return rc;
321 }
322
323 info->offset = resp.offset;
324 info->size = resp.size;
325 return 0;
326 }
327
328 /**
329 * Check if a feature is supported by EC.
330 *
331 * @param feature feature code
332 * @return < 0 if error, 0 not supported, > 0 supported
333 *
334 * NOTE: Once it successfully runs, the feature bits are cached. So, if you
335 * want to query a feature that can be different per copy, you need to
336 * cache features per image copy.
337 */
ec_check_features(int feature)338 static int ec_check_features(int feature)
339 {
340 static struct ec_response_get_features r;
341 int rc = 0;
342
343 if (feature < 0 || feature >= (int)sizeof(r.flags) * 8)
344 return -1;
345
346 /* We don't cache return code. We retry regardless the return code. */
347 if (r.flags[0] == 0)
348 rc = cros_ec_command(EC_CMD_GET_FEATURES,
349 0, NULL, 0, &r, sizeof(r));
350
351 if (rc < 0)
352 return rc;
353
354 return !!(r.flags[feature / 32] & (1 << (feature % 32)));
355 }
356
357 /**
358 * Disable EC rwsig jump.
359 *
360 * @return 0 if success, <0 if error
361 */
ec_rwsig_abort()362 static int ec_rwsig_abort()
363 {
364 struct ec_params_rwsig_action p = { .action = RWSIG_ACTION_ABORT };
365 return cros_ec_command(EC_CMD_RWSIG_ACTION,
366 0, &p, sizeof(p), NULL, 0);
367 }
368
369 /**
370 * Get the versions of the command supported by the EC.
371 *
372 * @param cmd Command
373 * @param pmask Destination for version mask; will be set to 0 on
374 * error.
375 * @return 0 if success, <0 if error
376 */
ec_get_cmd_versions(int cmd,uint32_t * pmask)377 static int ec_get_cmd_versions(int cmd, uint32_t *pmask)
378 {
379 struct ec_params_get_cmd_versions pver = { .cmd = cmd };
380 struct ec_response_get_cmd_versions rver;
381
382 *pmask = 0;
383
384 int rc = cros_ec_command(EC_CMD_GET_CMD_VERSIONS, 0,
385 &pver, sizeof(pver), &rver, sizeof(rver));
386 if (rc < 0)
387 return rc;
388
389 *pmask = rver.version_mask;
390 return rc;
391 }
392
393 /* Perform a cold reboot.
394 *
395 * @param flags flags to pass to EC_CMD_REBOOT_EC.
396 * @return 0 for success, < 0 for command failure.
397 */
cros_ec_cold_reboot(int flags)398 static int cros_ec_cold_reboot(int flags)
399 {
400 struct ec_params_reboot_ec p = { .cmd = EC_REBOOT_COLD, .flags = flags };
401 return cros_ec_command(EC_CMD_REBOOT_EC, 0, &p, sizeof(p),
402 NULL, 0);
403 }
404
405 /* Asks EC to jump to a firmware copy. If target is EC_IMAGE_UNKNOWN,
406 * then this functions picks a NEW firmware copy and jumps to it. Note that
407 * RO is preferred, then A, finally B.
408 *
409 * Returns 0 for success.
410 */
cros_ec_jump_copy(enum ec_current_image target)411 static int cros_ec_jump_copy(enum ec_current_image target)
412 {
413 /* Since the EC may return EC_RES_SUCCESS twice if the EC doesn't
414 * jump to different firmware copy. The second EC_RES_SUCCESS would
415 * set the OBF=1 and the next command cannot be executed.
416 * Thus, we call EC to jump only if the target is different.
417 */
418 const enum ec_current_image current_image = cros_ec_get_current_image();
419 if (current_image < 0)
420 return 1;
421 if (current_image == target)
422 return 0;
423
424 struct ec_params_reboot_ec p = {0};
425
426 /* Translate target --> EC reboot command parameter */
427 switch (target) {
428 case EC_IMAGE_RO:
429 /*
430 * Do a cold reset instead of JUMP_RO so board enabling
431 * EC_FLASH_PROTECT_ALL_NOW at runtime can clear the WP flag.
432 * This is true for EC enabling RWSIG, where
433 * EC_FLASH_PROTECT_ALL_NOW is applied before jumping into RW.
434 */
435 if (rwsig_enabled)
436 p.cmd = EC_REBOOT_COLD;
437 else
438 p.cmd = EC_REBOOT_JUMP_RO;
439 break;
440 case EC_IMAGE_RW:
441 p.cmd = EC_REBOOT_JUMP_RW;
442 break;
443 default:
444 /*
445 * If target is unspecified, set EC reboot command to use
446 * a new image. Also set "target" so that it may be used
447 * to update the priv->current_image if jump is successful.
448 */
449 if (fwcopy[EC_IMAGE_RO].flags) {
450 p.cmd = EC_REBOOT_JUMP_RO;
451 target = EC_IMAGE_RO;
452 } else if (fwcopy[EC_IMAGE_RW].flags) {
453 p.cmd = EC_REBOOT_JUMP_RW;
454 target = EC_IMAGE_RW;
455 } else {
456 return 1;
457 }
458 break;
459 }
460
461 if (p.cmd == EC_REBOOT_COLD)
462 msg_pdbg("Doing a cold reboot instead of JUMP_RO/RW.\n");
463 else
464 msg_pdbg("CROS_EC is jumping to [%s]\n", sections[target]);
465
466 if (current_image == p.cmd) {
467 msg_pdbg("CROS_EC is already in [%s]\n", sections[target]);
468 cros_ec_dev_priv.current_image = target;
469 return 0;
470 }
471
472 int rc = cros_ec_command(EC_CMD_REBOOT_EC,
473 0, &p, sizeof(p), NULL, 0);
474 if (rc < 0) {
475 msg_perr("CROS_EC cannot jump/reboot to [%s]:%d\n",
476 sections[target], rc);
477 return rc;
478 }
479
480 /* Sleep until EC can respond to host command, but just before
481 * CONFIG_RWSIG_JUMP_TIMEOUT if EC is using RWSIG task. */
482 usleep(EC_INIT_DELAY);
483
484 /* Abort RWSIG jump for EC that use it. Normal EC will ignore it. */
485 if (target == EC_IMAGE_RO && rwsig_enabled) {
486 msg_pdbg("Aborting RWSIG jump.\n");
487 ec_rwsig_abort();
488 }
489
490 msg_pdbg("CROS_EC jumped/rebooted to [%s]\n", sections[target]);
491 cros_ec_dev_priv.current_image = target;
492
493 return EC_RES_SUCCESS;
494 }
495
cros_ec_restore_wp(void * data)496 static int cros_ec_restore_wp(void *data)
497 {
498 msg_pdbg("Restoring EC soft WP.\n");
499
500 struct flashctx *flash = data;
501
502 struct flashrom_wp_cfg *cfg = NULL;
503 if (flashrom_wp_cfg_new(&cfg) != FLASHROM_WP_OK)
504 return 1;
505 flashrom_wp_set_mode(cfg, FLASHROM_WP_MODE_HARDWARE);
506
507 enum flashrom_wp_result ret = flashrom_wp_write_cfg(flash, cfg);
508 flashrom_wp_cfg_release(cfg);
509
510 return (ret != FLASHROM_WP_OK);
511 }
512
cros_ec_wp_is_enabled(void)513 static int cros_ec_wp_is_enabled(void)
514 {
515 struct ec_params_flash_protect p = {0};
516 struct ec_response_flash_protect r;
517
518 int rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
519 EC_VER_FLASH_PROTECT, &p, sizeof(p), &r, sizeof(r));
520 if (rc < 0) {
521 msg_perr("FAILED: Cannot get the write protection status: %d\n",
522 rc);
523 return -1;
524 } else if (rc < (int)sizeof(r)) {
525 msg_perr("FAILED: Too little data returned (expected:%zd, "
526 "actual:%d)\n", sizeof(r), rc);
527 return -1;
528 }
529
530 if (r.flags & (EC_FLASH_PROTECT_RO_NOW | EC_FLASH_PROTECT_ALL_NOW))
531 return 1;
532
533 return 0;
534 }
535
536 /*
537 * If HW WP is disabled we may still need to disable write protection
538 * that is active on the EC. Otherwise the EC can reject erase/write
539 * commands.
540 *
541 * Failure is OK since HW WP might be enabled or the EC needs to be
542 * rebooted for the change to take effect. We can still update RW
543 * portions.
544 *
545 * If disabled here, EC WP will be restored at the end so that
546 * "--wp-enable" does not need to be run later. This greatly
547 * simplifies logic for developers and scripts.
548 */
disable_soft_wp_if_needed(struct flashctx * flash)549 static int disable_soft_wp_if_needed(struct flashctx *flash)
550 {
551 const int wp_status = cros_ec_wp_is_enabled();
552 if (wp_status < 0) {
553 return 1;
554 } else if (wp_status == 1) {
555 msg_pdbg("Attempting to disable EC soft WP.\n");
556
557 struct flashrom_wp_cfg *cfg = NULL;
558 enum flashrom_wp_result ret = flashrom_wp_cfg_new(&cfg);
559
560 if (ret == FLASHROM_WP_OK) {
561 flashrom_wp_set_mode(cfg, FLASHROM_WP_MODE_DISABLED);
562
563 ret = flashrom_wp_write_cfg(flash, cfg);
564 flashrom_wp_cfg_release(cfg);
565 }
566
567 if (ret == FLASHROM_WP_OK) {
568 msg_pdbg("EC soft WP disabled successfully.\n");
569 if (register_shutdown(cros_ec_restore_wp, flash))
570 return 1;
571 } else {
572 msg_pdbg("Failed. Hardware WP might in effect or EC "
573 "needs to be rebooted first.\n");
574 }
575 } else {
576 msg_pdbg("EC soft WP is already disabled.\n");
577 }
578 return 0;
579 }
580
parse_fmap(const uint8_t * const image,uint32_t flash_size)581 static void parse_fmap(const uint8_t *const image, uint32_t flash_size)
582 {
583 // Parse the fmap in the image file and cache the firmware ranges.
584 struct fmap *fmap = NULL;
585 if (fmap_read_from_buffer(&fmap, image, flash_size)) {
586 return;
587 }
588
589 // Lookup RO/A/B sections in FMAP.
590 for (unsigned int i = 0; i < fmap->nareas; i++) {
591 const struct fmap_area *fa = &fmap->areas[i];
592
593 for (unsigned int j = EC_IMAGE_RO; j < ARRAY_SIZE(sections); j++) {
594 /* skip fmap sections unrelated to cros_ec sections. */
595 if (strcmp(sections[j], (const char *) fa->name))
596 continue;
597
598 msg_pdbg("Found '%s' in image.\n", fa->name);
599 fwcopy[j] = *fa;
600 fwcopy[j].flags = 1; // mark as new
601 }
602 }
603 free(fmap);
604 }
605
606 /**
607 * iff layout region is one of the supported cros_ec
608 * sections then modify the region_type bit-feild.
609 * 00 - no RO or RW.
610 * 01 - RO found.
611 * 10 - RW found.
612 * 11 - RO+RW found.
613 */
parse_layout(const struct flashrom_layout * const layout)614 static enum ec_current_image parse_layout(const struct flashrom_layout *const layout)
615 {
616 enum ec_current_image region_type = EC_IMAGE_UNKNOWN; /* no RO or RW found yet. */
617 const struct romentry *entry = NULL;
618
619 while ((entry = layout_next_included(layout, entry))) {
620 const struct flash_region *region = &entry->region;
621 if (!strcmp("WP_RO", (const char *) region->name))
622 region_type |= EC_IMAGE_RO;
623 if (!strcmp(sections[EC_IMAGE_RW], (const char *) region->name))
624 region_type |= EC_IMAGE_RW;
625 }
626 /* iff neither RO or RW was found in the layout then assume a full image of both. */
627 return region_type == EC_IMAGE_UNKNOWN ? (EC_IMAGE_RO | EC_IMAGE_RW) : region_type;
628 }
629
630 /*
631 * Prepare EC for update:
632 * - Disable soft WP if needed.
633 * - Parse flashmap.
634 * - Jump to RO firmware.
635 */
cros_ec_prepare(struct flashctx * flash,const uint8_t * const image,uint32_t flash_size)636 int cros_ec_prepare(struct flashctx *flash, const uint8_t *const image, uint32_t flash_size)
637 {
638 if (!programming_ec())
639 return 0;
640
641 if (ec_check_features(EC_FEATURE_RWSIG) > 0) {
642 rwsig_enabled = 1;
643 msg_pdbg("EC has RWSIG enabled.\n");
644 }
645
646 if (disable_soft_wp_if_needed(flash))
647 return 1;
648
649 parse_fmap(image, flash_size);
650 /* check layout to determine what sysjumps we are required to do. */
651 const struct flashrom_layout *const layout = get_layout(flash);
652 const enum ec_current_image region_typ = parse_layout(layout);
653
654 if (ec_check_features(EC_FEATURE_EXEC_IN_RAM) <= 0) {
655 /* Warning: before update, we jump the EC to RO copy. If you
656 * want to change this behavior, please also check the
657 * cros_ec_finish().
658 */
659 msg_pwarn("EXEC_IN_RAM unsupported..");
660
661 if (!(region_typ & EC_IMAGE_RO) && cros_ec_get_current_image() == EC_IMAGE_RO) {
662 msg_pwarn(" image contains RW and already in RO, skipping jump.\n");
663 return 0;
664 }
665 if (!(region_typ & EC_IMAGE_RW) && cros_ec_get_current_image() == EC_IMAGE_RW) {
666 msg_pwarn(" image contains RO and already in RW, skipping jump.\n");
667 return 0;
668 }
669
670 msg_pwarn(" unconditional jump to RO.\n");
671 return cros_ec_jump_copy(EC_IMAGE_RO);
672 }
673 msg_pwarn("EXEC_IN_RAM supported - skip jumping to RO\n");
674
675 return 0;
676 }
677
678
679 /* Returns >0 if we need 2nd pass of erase_and_write_flash().
680 * <0 if we cannot jump to any firmware copy.
681 * ==0 if no more pass is needed.
682 *
683 * This function also jumps to new-updated firmware copy before return >0.
684 */
cros_ec_need_2nd_pass(void)685 int cros_ec_need_2nd_pass(void)
686 {
687 if (!programming_ec())
688 return 0;
689
690 if (!need_2nd_pass)
691 return 0;
692
693 if (ec_check_features(EC_FEATURE_EXEC_IN_RAM) > 0)
694 /* EC_RES_ACCESS_DENIED is returned when the block is either
695 * protected or unsafe. Thus, theoretically, we shouldn't reach
696 * here because everywhere is safe for EXEC_IN_RAM chips and
697 * WP is disabled before erase/write cycle starts.
698 * We can still let the 2nd pass run (and it will probably
699 * fail again).
700 */
701 return 1;
702
703 if (cros_ec_jump_copy(EC_IMAGE_UNKNOWN))
704 return -1;
705
706 return 1;
707 }
708
cros_ec_erasure_failed(void)709 bool cros_ec_erasure_failed(void)
710 {
711 return spi_acc_issue;
712 }
713
714 /**
715 * Returns 0 for success.
716 * Try latest firmware: B > A > RO
717 */
cros_ec_finish(void)718 int cros_ec_finish(void)
719 {
720 if (!programming_ec())
721 return 0;
722
723 /*
724 * Check that the EC had jumped to RO at cros_ec_prepare() so that
725 * the fwcopy[RO].flags is old (0) and A/B are new otherwise return.
726 */
727 if (cros_ec_get_current_image() != EC_IMAGE_RO)
728 return 0;
729
730 /* For EC with RWSIG enabled. We need a cold reboot to enable
731 * EC_FLASH_PROTECT_ALL_NOW and make sure RWSIG check is performed.
732 */
733 if (rwsig_enabled) {
734 msg_pdbg("RWSIG enabled: doing a cold reboot to enable WP.\n");
735 int rc = cros_ec_cold_reboot(0);
736 usleep(EC_RWSIG_JUMP_TO_RW_DELAY);
737 return rc;
738 }
739
740 return 0;
741 }
742
cros_ec_read(struct flashctx * flash,uint8_t * readarr,unsigned int blockaddr,unsigned int readcnt)743 static int cros_ec_read(struct flashctx *flash, uint8_t *readarr,
744 unsigned int blockaddr, unsigned int readcnt)
745 {
746 int rc = 0;
747 struct ec_params_flash_read p;
748 const int maxlen = flash->mst->opaque.max_data_read;
749 uint8_t buf[maxlen];
750 unsigned offset = 0, count;
751
752 while (offset < readcnt) {
753 count = min(maxlen, readcnt - offset);
754 p.offset = blockaddr + offset;
755 p.size = count;
756 rc = cros_ec_command(EC_CMD_FLASH_READ,
757 0, &p, sizeof(p), buf, count);
758 if (rc < 0) {
759 msg_perr("CROS_EC: Flash read error at offset 0x%x\n",
760 blockaddr + offset);
761 return rc;
762 } else {
763 rc = EC_RES_SUCCESS;
764 }
765
766 memcpy(readarr + offset, buf, count);
767 offset += count;
768 }
769
770 return rc;
771 }
772
773 /*
774 * returns 0 to indicate area does not overlap current EC image
775 * returns 1 to indicate area overlaps current EC image or error
776 *
777 * We can't get rid of this. The ECs should know what region is safe to erase
778 * or write. We should let them decide (and return EC_RES_ACCESS_DENIED).
779 * Not all existing EC firmware can do so.
780 */
in_current_image(unsigned int addr,unsigned int len)781 static int in_current_image(unsigned int addr, unsigned int len)
782 {
783 const enum ec_current_image image = cros_ec_dev_priv.current_image;
784 const uint32_t region_offset = cros_ec_dev_priv.region[image].offset;
785 const uint32_t region_size = cros_ec_dev_priv.region[image].size;
786
787 if ((addr + len - 1 < region_offset) ||
788 (addr > region_offset + region_size - 1)) {
789 return 0;
790 }
791 return 1;
792 }
793
794
cros_ec_block_erase(struct flashctx * flash,unsigned int blockaddr,unsigned int len)795 int cros_ec_block_erase(struct flashctx *flash, unsigned int blockaddr,
796 unsigned int len)
797 {
798 spi_acc_issue = false; /* reset SPI access workaround singleton */
799
800 if (ec_check_features(EC_FEATURE_EXEC_IN_RAM) <= 0 &&
801 in_current_image(blockaddr, len)) {
802 cros_ec_invalidate_copy(blockaddr, len);
803 need_2nd_pass = 1;
804 spi_acc_issue = true;
805 return 0; /* ignore SPI access denied, check spi_acc_issue. */
806 }
807
808 struct ec_params_flash_erase_v1 erase;
809 erase.params.offset = blockaddr;
810 erase.params.size = len;
811 uint32_t mask;
812 int rc = ec_get_cmd_versions(EC_CMD_FLASH_ERASE, &mask);
813 if (rc < 0) {
814 msg_perr("Cannot determine erase command version\n");
815 return 0;
816 }
817 int cmd_version = 31 - __builtin_clz(mask);
818
819 if (cmd_version == 0) {
820 rc = cros_ec_command(EC_CMD_FLASH_ERASE, 0,
821 &erase.params,
822 sizeof(struct ec_params_flash_erase), NULL, 0);
823 if (rc == -EC_RES_ACCESS_DENIED) {
824 // this is active image.
825 cros_ec_invalidate_copy(blockaddr, len);
826 need_2nd_pass = 1;
827 spi_acc_issue = true;
828 return 0; /* ignore SPI access denied, check spi_acc_issue. */
829 }
830 if (rc < 0) {
831 msg_perr("CROS_EC: Flash erase error at address 0x%x, rc=%d\n",
832 blockaddr, rc);
833 return rc;
834 }
835 goto end_flash_erase;
836 }
837
838 if (len >= FLASH_SMALL_REGION_THRESHOLD) {
839 erase.cmd = FLASH_ERASE_SECTOR_ASYNC;
840 } else {
841 erase.cmd = FLASH_ERASE_SECTOR;
842 }
843 rc = cros_ec_command(EC_CMD_FLASH_ERASE, cmd_version,
844 &erase, sizeof(erase), NULL, 0);
845 switch (rc) {
846 case 0:
847 break;
848 case -EC_RES_ACCESS_DENIED:
849 // this is active image.
850 cros_ec_invalidate_copy(blockaddr, len);
851 need_2nd_pass = 1;
852 spi_acc_issue = true;
853 return 0; /* ignore SPI access denied, check spi_acc_issue. */
854 case -EC_RES_BUSY:
855 msg_perr("CROS_EC: Flash erase command "
856 " already in progress\n");
857 return rc;
858 default:
859 return rc;
860 }
861 if (len < FLASH_SMALL_REGION_THRESHOLD)
862 goto end_flash_erase;
863
864 /* Wait for the erase command to complete */
865 rc = -EC_RES_BUSY;
866
867 /* wait up to 10s to erase a flash sector */
868 #define CROS_EC_ERASE_ASYNC_TIMEOUT 10000000
869 /* wait .5 second between queries. */
870 #define CROS_EC_ERASE_ASYNC_WAIT 500000
871
872 int timeout = 0;
873 while (rc < 0 && timeout < CROS_EC_ERASE_ASYNC_TIMEOUT) {
874 usleep(CROS_EC_ERASE_ASYNC_WAIT);
875 timeout += CROS_EC_ERASE_ASYNC_WAIT;
876 erase.cmd = FLASH_ERASE_GET_RESULT;
877 rc = cros_ec_command(EC_CMD_FLASH_ERASE, cmd_version,
878 &erase, sizeof(erase), NULL, 0);
879 }
880 if (rc < 0) {
881 msg_perr("CROS_EC: Flash erase error at address 0x%x, rc=%d\n",
882 blockaddr, rc);
883 return rc;
884 }
885
886 end_flash_erase:
887 if (rc > 0) {
888 /*
889 * Can happen if the command with retried with
890 * EC_CMD_GET_COMMS_STATUS
891 */
892 rc = -EC_RES_SUCCESS;
893 }
894 return rc;
895 }
896
897
cros_ec_write(struct flashctx * flash,const uint8_t * buf,unsigned int addr,unsigned int nbytes)898 static int cros_ec_write(struct flashctx *flash, const uint8_t *buf, unsigned int addr,
899 unsigned int nbytes)
900 {
901 int rc = 0;
902 unsigned int written = 0, real_write_size;
903 struct ec_params_flash_write p;
904
905 /*
906 * For b:35542013, to workaround the undersized
907 * outdata buffer issue in kernel.
908 * chunk size should exclude the packet header ec_params_flash_write.
909 */
910 real_write_size = min(flash->mst->opaque.max_data_write - sizeof(p),
911 cros_ec_dev_priv.ideal_write_size);
912 assert(real_write_size > 0);
913
914 uint8_t *packet = malloc(sizeof(p) + real_write_size);
915 if (!packet)
916 return -1;
917
918 for (unsigned int i = 0; i < nbytes; i += written) {
919 written = min(nbytes - i, real_write_size);
920 p.offset = addr + i;
921 p.size = written;
922
923 if (ec_check_features(EC_FEATURE_EXEC_IN_RAM) <= 0 &&
924 in_current_image(p.offset, p.size)) {
925 need_2nd_pass = 1;
926 cros_ec_invalidate_copy(addr, nbytes);
927 free(packet);
928 return 0; /* SPI access denied is ignored. */
929 }
930
931 memcpy(packet, &p, sizeof(p));
932 memcpy(packet + sizeof(p), &buf[i], written);
933 rc = cros_ec_command(EC_CMD_FLASH_WRITE,
934 0, packet, sizeof(p) + p.size, NULL, 0);
935 if (rc == -EC_RES_ACCESS_DENIED) {
936 need_2nd_pass = 1; /* this is a active image. */
937 cros_ec_invalidate_copy(addr, nbytes);
938 free(packet);
939 return 0; /* SPI access denied is ignored. */
940 }
941
942 if (rc < 0) break;
943 rc = EC_RES_SUCCESS;
944 }
945
946 free(packet);
947 return rc;
948 }
949
cros_ec_probe_size(struct flashctx * flash)950 static int cros_ec_probe_size(struct flashctx *flash)
951 {
952 int rc = cros_ec_get_current_image();
953 if (rc < 0) {
954 msg_perr("%s(): Failed to probe (no current image): %d\n",
955 __func__, rc);
956 return 0;
957 }
958 cros_ec_dev_priv.current_image = rc;
959 cros_ec_dev_priv.region = ®ions[0];
960
961 uint32_t mask;
962 rc = ec_get_cmd_versions(EC_CMD_FLASH_INFO, &mask);
963 if (rc < 0) {
964 msg_perr("Cannot determine write command version\n");
965 return 0;
966 }
967 int cmd_version = 31 - __builtin_clz(mask);
968
969 struct block_eraser *eraser = &flash->chip->block_erasers[0];
970 flash->chip->page_size = flash->mst->opaque.max_data_read;
971
972 if (cmd_version < 2) {
973 struct ec_response_flash_info_1 info;
974 /* Request general information about flash (v1 or below). */
975 rc = cros_ec_command(EC_CMD_FLASH_INFO, cmd_version,
976 NULL, 0, &info,
977 (cmd_version > 0 ? sizeof(info) :
978 sizeof(struct ec_response_flash_info)));
979 if (rc < 0) {
980 msg_perr("%s(): FLASH_INFO v%d returns %d.\n", __func__,
981 cmd_version, rc);
982 return 0;
983 }
984 if (cmd_version == 0) {
985 cros_ec_dev_priv.ideal_write_size =
986 EC_FLASH_WRITE_VER0_SIZE;
987 } else {
988 cros_ec_dev_priv.ideal_write_size = info.write_ideal_size;
989 if (info.flags & EC_FLASH_INFO_ERASE_TO_0)
990 flash->chip->feature_bits |=
991 FEATURE_ERASED_ZERO;
992 }
993 flash->chip->total_size = info.flash_size / 1024;
994
995 eraser->eraseblocks[0].size = info.erase_block_size;
996 eraser->eraseblocks[0].count = info.flash_size /
997 eraser->eraseblocks[0].size;
998 } else {
999 struct ec_response_flash_info_2 info_2;
1000 struct ec_params_flash_info_2 params_2;
1001 struct ec_response_flash_info_2 *info_2_p = &info_2;
1002 int size_info_v2 = sizeof(info_2), i;
1003
1004 params_2.num_banks_desc = 0;
1005 /*
1006 * Call FLASH_INFO twice, second time with all banks
1007 * information.
1008 */
1009 for (i = 0; i < 2; i++) {
1010 rc = cros_ec_command(EC_CMD_FLASH_INFO,
1011 cmd_version, ¶ms_2,
1012 sizeof(params_2),
1013 info_2_p, size_info_v2);
1014 if (rc < 0) {
1015 msg_perr("%s(): FLASH_INFO(%d) v%d returns %d.\n",
1016 __func__,
1017 params_2.num_banks_desc,
1018 cmd_version, rc);
1019 if (info_2_p != &info_2)
1020 free(info_2_p);
1021 return 0;
1022 } else if (i > 0) {
1023 break;
1024 }
1025 params_2.num_banks_desc = info_2_p->num_banks_total;
1026 size_info_v2 += info_2_p->num_banks_total *
1027 sizeof(struct ec_flash_bank);
1028
1029 info_2_p = malloc(size_info_v2);
1030 if (!info_2_p) {
1031 msg_perr("%s(): malloc of %d banks failed\n",
1032 __func__, params_2.num_banks_desc);
1033 return 0;
1034 }
1035 }
1036 flash->chip->total_size = info_2_p->flash_size / 1024;
1037 for (i = 0; i < info_2_p->num_banks_desc; i++) {
1038 /* Allow overriding the erase block size in case EC is incorrect */
1039 eraser->eraseblocks[i].size =
1040 (unsigned) 1 << info_2_p->banks[i].erase_size_exp;
1041 eraser->eraseblocks[i].count =
1042 info_2_p->banks[i].count <<
1043 (info_2_p->banks[i].size_exp -
1044 info_2_p->banks[i].erase_size_exp);
1045 }
1046 cros_ec_dev_priv.ideal_write_size = info_2_p->write_ideal_size;
1047 #if 0
1048 /*
1049 * TODO(b/38506987)Comment out, as some firmware were not
1050 * setting this flag properly.
1051 */
1052 if (info_2_p->flags & EC_FLASH_INFO_ERASE_TO_0)
1053 flash->chip->feature_bits |= FEATURE_ERASED_ZERO;
1054 #endif
1055 free(info_2_p);
1056 }
1057 eraser->block_erase = CROS_EC_BLOCK_ERASE;
1058 /*
1059 * Some STM32 variants erase bits to 0. For now, assume that this
1060 * applies to STM32L parts.
1061 *
1062 * FIXME: This info will eventually be exposed via some EC command.
1063 * See chrome-os-partner:20973.
1064 */
1065 struct ec_response_get_chip_info chip_info;
1066 rc = cros_ec_command(EC_CMD_GET_CHIP_INFO,
1067 0, NULL, 0, &chip_info, sizeof(chip_info));
1068 if (rc < 0) {
1069 msg_perr("%s(): CHIP_INFO returned %d.\n", __func__, rc);
1070 return 0;
1071 }
1072 if (!strncmp(chip_info.name, "stm32l1", 7))
1073 flash->chip->feature_bits |= FEATURE_ERASED_ZERO;
1074
1075
1076
1077 struct ec_response_flash_spi_info spi_info;
1078 rc = cros_ec_command(EC_CMD_FLASH_SPI_INFO,
1079 0, NULL, 0, &spi_info, sizeof(spi_info));
1080 if (rc < 0) {
1081 static char chip_vendor[32];
1082 static char chip_name[32];
1083
1084 memcpy(chip_vendor, chip_info.vendor, sizeof(chip_vendor));
1085 memcpy(chip_name, chip_info.name, sizeof(chip_name));
1086 flash->chip->vendor = chip_vendor;
1087 flash->chip->name = chip_name;
1088 flash->chip->tested = TEST_OK_PREWB;
1089 } else {
1090 const struct flashchip *f;
1091 uint32_t mfg = spi_info.jedec[0];
1092 uint32_t model = (spi_info.jedec[1] << 8) | spi_info.jedec[2];
1093
1094 for (f = flashchips; f && f->name; f++) {
1095 if (f->bustype != BUS_SPI)
1096 continue;
1097 if ((f->manufacture_id == mfg) &&
1098 f->model_id == model) {
1099 flash->chip->vendor = f->vendor;
1100 flash->chip->name = f->name;
1101 flash->chip->tested = f->tested;
1102 break;
1103 }
1104 }
1105 }
1106
1107 /* FIXME: EC_IMAGE_* is ordered differently from EC_FLASH_REGION_*,
1108 * so we need to be careful about using these enums as array indices */
1109 rc = cros_ec_get_region_info(EC_FLASH_REGION_RO,
1110 &cros_ec_dev_priv.region[EC_IMAGE_RO]);
1111 if (rc) {
1112 msg_perr("%s(): Failed to probe (cannot find RO region): %d\n",
1113 __func__, rc);
1114 return 0;
1115 }
1116
1117 rc = cros_ec_get_region_info(EC_FLASH_REGION_RW,
1118 &cros_ec_dev_priv.region[EC_IMAGE_RW]);
1119 if (rc) {
1120 msg_perr("%s(): Failed to probe (cannot find RW region): %d\n",
1121 __func__, rc);
1122 return 0;
1123 }
1124
1125 return 1;
1126 };
1127
1128 /* perform basic "hello" test to see if we can talk to the EC */
cros_ec_test(void)1129 static int cros_ec_test(void)
1130 {
1131 struct ec_params_hello request;
1132 struct ec_response_hello response;
1133
1134 /* Say hello to EC. */
1135 request.in_data = 0xf0e0d0c0; /* Expect EC will add on 0x01020304. */
1136 msg_pdbg("%s: sending HELLO request with 0x%08x\n",
1137 __func__, request.in_data);
1138 int rc = cros_ec_command(EC_CMD_HELLO, 0, &request,
1139 sizeof(request), &response, sizeof(response));
1140 msg_pdbg("%s: response: 0x%08x\n", __func__, response.out_data);
1141
1142 if (rc < 0 || response.out_data != 0xf1e2d3c4) {
1143 msg_pdbg("response.out_data is not 0xf1e2d3c4.\n"
1144 "rc=%d, request=0x%x response=0x%x\n",
1145 rc, request.in_data, response.out_data);
1146 return 1;
1147 }
1148
1149 return 0;
1150 }
1151
cros_ec_set_max_size(struct opaque_master * op)1152 static void cros_ec_set_max_size(struct opaque_master *op)
1153 {
1154 struct ec_response_get_protocol_info info;
1155
1156 msg_pdbg("%s: sending protoinfo command\n", __func__);
1157 int rc = cros_ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0,
1158 &info, sizeof(info));
1159 msg_pdbg("%s: rc:%d\n", __func__, rc);
1160
1161 /*
1162 * Use V3 large size only if v2 protocol is not supported.
1163 * When v2 is supported, we may be using a kernel without v3 support,
1164 * leading to sending larger commands the kernel can support.
1165 */
1166 if (rc == sizeof(info) && ((info.protocol_versions & (1<<2)) == 0)) {
1167
1168 op->max_data_write = info.max_request_packet_size -
1169 sizeof(struct ec_host_request);
1170 op->max_data_read = info.max_response_packet_size -
1171 sizeof(struct ec_host_response);
1172 /*
1173 * Due to a bug in NPCX SPI code (chromium:725580),
1174 * The EC may responds 163 when it meant 160; it should not
1175 * have included header and footer.
1176 */
1177 op->max_data_read &= ~3;
1178 msg_pdbg("%s: max_write:%d max_read:%d\n", __func__,
1179 op->max_data_write, op->max_data_read);
1180 }
1181 }
1182
cros_ec_wp_read_cfg(struct flashrom_wp_cfg * cfg,struct flashctx * flash)1183 static enum flashrom_wp_result cros_ec_wp_read_cfg(struct flashrom_wp_cfg *cfg, struct flashctx *flash)
1184 {
1185 struct ec_params_flash_protect p;
1186 struct ec_response_flash_protect r;
1187
1188 memset(&p, 0, sizeof(p));
1189 int rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
1190 EC_VER_FLASH_PROTECT, &p, sizeof(p), &r, sizeof(r));
1191
1192 if (rc < (int)sizeof(r)) {
1193 msg_perr("FAILED: Too little data returned (expected:%zd, "
1194 "actual:%d)\n", sizeof(r), rc);
1195 return FLASHROM_WP_ERR_READ_FAILED;
1196 }
1197
1198 if (r.flags & EC_FLASH_PROTECT_RO_AT_BOOT) {
1199 struct ec_response_flash_region_info info;
1200
1201 rc = cros_ec_get_region_info(EC_FLASH_REGION_WP_RO, &info);
1202 if (rc < 0) {
1203 msg_perr("FAILED: Cannot get the WP_RO region info: "
1204 "%d\n", rc);
1205 return FLASHROM_WP_ERR_READ_FAILED;
1206 }
1207
1208 cfg->range.start = info.offset;
1209 cfg->range.len = info.size;
1210 cfg->mode = FLASHROM_WP_MODE_HARDWARE;
1211 } else {
1212 cfg->range.start = 0;
1213 cfg->range.len = 0;
1214 cfg->mode = FLASHROM_WP_MODE_DISABLED;
1215 }
1216
1217 /*
1218 * If neither RO_NOW or ALL_NOW is set, it means write protect is
1219 * NOT active now.
1220 */
1221 if (!(r.flags & (EC_FLASH_PROTECT_RO_NOW | EC_FLASH_PROTECT_ALL_NOW))) {
1222 cfg->range.start = 0;
1223 cfg->range.len = 0;
1224 }
1225
1226 return FLASHROM_WP_OK;
1227 }
1228
cros_ec_wp_write_cfg(struct flashctx * flash,const struct flashrom_wp_cfg * cfg)1229 static enum flashrom_wp_result cros_ec_wp_write_cfg(struct flashctx *flash, const struct flashrom_wp_cfg *cfg)
1230 {
1231 bool enable = cfg->mode == FLASHROM_WP_MODE_HARDWARE;
1232
1233 struct ec_params_flash_protect p;
1234 struct ec_response_flash_protect r;
1235 const int ro_at_boot_flag = EC_FLASH_PROTECT_RO_AT_BOOT;
1236 const int ro_now_flag = EC_FLASH_PROTECT_RO_NOW;
1237 int need_an_ec_cold_reset = 0;
1238 int rc;
1239
1240 /* Try to set RO_AT_BOOT and RO_NOW first */
1241 memset(&p, 0, sizeof(p));
1242 p.mask = (ro_at_boot_flag | ro_now_flag);
1243 p.flags = enable ? (ro_at_boot_flag | ro_now_flag) : 0;
1244 rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
1245 EC_VER_FLASH_PROTECT, &p, sizeof(p), &r, sizeof(r));
1246 if (rc < 0) {
1247 msg_perr("FAILED: Cannot set the RO_AT_BOOT and RO_NOW: %d\n",
1248 rc);
1249 return FLASHROM_WP_ERR_WRITE_FAILED;
1250 }
1251
1252 /* Read back */
1253 memset(&p, 0, sizeof(p));
1254 rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
1255 EC_VER_FLASH_PROTECT, &p, sizeof(p), &r, sizeof(r));
1256 if (rc < 0) {
1257 msg_perr("FAILED: Cannot get RO_AT_BOOT and RO_NOW: %d\n",
1258 rc);
1259 return FLASHROM_WP_ERR_WRITE_FAILED;
1260 }
1261
1262 if (!enable) {
1263 /* The disable case is easier to check. */
1264 if (r.flags & ro_at_boot_flag) {
1265 msg_perr("FAILED: RO_AT_BOOT is not clear.\n");
1266 return FLASHROM_WP_ERR_WRITE_FAILED;
1267 } else if (r.flags & ro_now_flag) {
1268 msg_perr("FAILED: RO_NOW is asserted unexpectedly.\n");
1269 need_an_ec_cold_reset = 1;
1270 goto exit;
1271 }
1272
1273 msg_pdbg("INFO: RO_AT_BOOT is clear.\n");
1274 return FLASHROM_WP_OK;
1275 }
1276
1277 /* Check if RO_AT_BOOT is set. If not, fail in anyway. */
1278 if (r.flags & ro_at_boot_flag) {
1279 msg_pdbg("INFO: RO_AT_BOOT has been set.\n");
1280 } else {
1281 msg_perr("FAILED: RO_AT_BOOT is not set.\n");
1282 return FLASHROM_WP_ERR_WRITE_FAILED;
1283 }
1284
1285 /* Then, we check if the protection has been activated. */
1286 if (r.flags & ro_now_flag) {
1287 /* Good, RO_NOW is set. */
1288 msg_pdbg("INFO: RO_NOW is set. WP is active now.\n");
1289 } else if (r.writable_flags & EC_FLASH_PROTECT_ALL_NOW) {
1290 msg_pdbg("WARN: RO_NOW is not set. Trying ALL_NOW.\n");
1291
1292 memset(&p, 0, sizeof(p));
1293 p.mask = EC_FLASH_PROTECT_ALL_NOW;
1294 p.flags = EC_FLASH_PROTECT_ALL_NOW;
1295 rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
1296 EC_VER_FLASH_PROTECT,
1297 &p, sizeof(p), &r, sizeof(r));
1298 if (rc < 0) {
1299 msg_perr("FAILED: Cannot set ALL_NOW: %d\n", rc);
1300 return FLASHROM_WP_ERR_WRITE_FAILED;
1301 }
1302
1303 /* Read back */
1304 memset(&p, 0, sizeof(p));
1305 rc = cros_ec_command(EC_CMD_FLASH_PROTECT,
1306 EC_VER_FLASH_PROTECT,
1307 &p, sizeof(p), &r, sizeof(r));
1308 if (rc < 0) {
1309 msg_perr("FAILED:Cannot get ALL_NOW: %d\n", rc);
1310 return FLASHROM_WP_ERR_WRITE_FAILED;
1311 }
1312
1313 if (!(r.flags & EC_FLASH_PROTECT_ALL_NOW)) {
1314 msg_perr("FAILED: ALL_NOW is not set.\n");
1315 need_an_ec_cold_reset = 1;
1316 goto exit;
1317 }
1318
1319 msg_pdbg("INFO: ALL_NOW has been set. WP is active now.\n");
1320
1321 /*
1322 * Our goal is to protect the RO ASAP. The entire protection
1323 * is just a workaround for platform not supporting RO_NOW.
1324 * It has side-effect that the RW is also protected and leads
1325 * the RW update failed. So, we arrange an EC code reset to
1326 * unlock RW ASAP.
1327 */
1328 rc = cros_ec_cold_reboot(EC_REBOOT_FLAG_ON_AP_SHUTDOWN);
1329 if (rc < 0) {
1330 msg_perr("WARN: Cannot arrange a cold reset at next "
1331 "shutdown to unlock entire protect.\n");
1332 msg_perr(" But you can do it manually.\n");
1333 } else {
1334 msg_pdbg("INFO: A cold reset is arranged at next "
1335 "shutdown.\n");
1336 }
1337
1338 } else {
1339 msg_perr("FAILED: RO_NOW is not set.\n");
1340 msg_perr("FAILED: The PROTECT_RO_AT_BOOT is set, but cannot "
1341 "make write protection active now.\n");
1342 need_an_ec_cold_reset = 1;
1343 }
1344
1345 exit:
1346 if (need_an_ec_cold_reset) {
1347 msg_perr("FAILED: You may need a reboot to take effect of "
1348 "PROTECT_RO_AT_BOOT.\n");
1349 return FLASHROM_WP_ERR_WRITE_FAILED;
1350 }
1351
1352 return FLASHROM_WP_OK;
1353 }
1354
cros_ec_wp_get_available_ranges(struct flashrom_wp_ranges ** list,struct flashctx * flash)1355 static enum flashrom_wp_result cros_ec_wp_get_available_ranges(struct flashrom_wp_ranges **list, struct flashctx *flash)
1356 {
1357 /* Allocate output buffer */
1358 *list = calloc(1, sizeof(struct flashrom_wp_ranges));
1359 if (!*list)
1360 return FLASHROM_WP_ERR_OTHER;
1361
1362 (*list)->ranges = calloc(2, sizeof(struct wp_range));
1363 if (!(*list)->ranges) {
1364 free(*list);
1365 return FLASHROM_WP_ERR_OTHER;
1366 }
1367
1368 /* Read the size of the EC's only protection region */
1369 struct ec_response_flash_region_info info;
1370 if (cros_ec_get_region_info(EC_FLASH_REGION_WP_RO, &info) < 0)
1371 return FLASHROM_WP_ERR_OTHER;
1372
1373 /* WP disabled */
1374 (*list)->ranges[0].start = 0;
1375 (*list)->ranges[0].len = 0;
1376
1377 /* WP enabled */
1378 (*list)->ranges[1].start = info.offset;
1379 (*list)->ranges[1].len = info.size;
1380
1381 (*list)->count = 2;
1382
1383 return FLASHROM_WP_OK;
1384 }
1385
1386 static struct opaque_master opaque_master_cros_ec_dev = {
1387 .max_data_read = 128,
1388 .max_data_write = 128,
1389 .probe = cros_ec_probe_size,
1390 .read = cros_ec_read,
1391 .write = cros_ec_write,
1392 .erase = cros_ec_block_erase,
1393 .wp_read_cfg = cros_ec_wp_read_cfg,
1394 .wp_write_cfg = cros_ec_wp_write_cfg,
1395 .wp_get_ranges = cros_ec_wp_get_available_ranges,
1396 .data = NULL
1397 };
1398
cros_ec_dev_shutdown(void * data)1399 static int cros_ec_dev_shutdown(void *data)
1400 {
1401 close(g_cros_ec_fd);
1402 return 0;
1403 }
1404
cros_ec_init(const struct programmer_cfg * cfg)1405 static int cros_ec_init(const struct programmer_cfg *cfg)
1406 {
1407 const char *dev_path = "/dev/cros_ec";
1408 msg_pdbg("%s: probing for CROS_EC at %s\n", __func__, dev_path);
1409 g_cros_ec_fd = open(dev_path, O_RDWR);
1410 if (g_cros_ec_fd < 0)
1411 return g_cros_ec_fd;
1412
1413 if (cros_ec_test())
1414 return 1;
1415
1416 cros_ec_set_max_size(&opaque_master_cros_ec_dev);
1417
1418 msg_pdbg("CROS_EC detected at %s\n", dev_path);
1419 register_opaque_master(&opaque_master_cros_ec_dev, NULL);
1420 register_shutdown(cros_ec_dev_shutdown, NULL);
1421 g_cros_ec_detected = true;
1422
1423 return 0;
1424 }
1425
1426 const struct programmer_entry programmer_cros_ec = {
1427 .name = "ec",
1428 .type = OTHER,
1429 .devs.note = "Google EC.\n",
1430 .init = cros_ec_init,
1431 };
1432