diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2017-06-01 22:07:04 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2018-03-13 23:50:20 +0000 |
commit | 4c3282fe24b10423d28b80682dd1be22e1d881d0 (patch) | |
tree | 6d84a5164cc4538e322009e8e8d66857626e1f66 | |
parent | 0215f0cf8513f7294d02da35b9d3134d10b9dcdd (diff) | |
download | chrome-ec-4c3282fe24b10423d28b80682dd1be22e1d881d0.tar.gz |
Cr50: usb_updater: add commands to get/set board id
This patch enhances the Cr50 usb_updater to allow to get and set Board
ID value saved in the Cr50's INFO1 space using the earlier introduced
dedicated vendor commands.
Getting or Setting the board ID does not require establishing a
connection with the Cr50, the new option is --board_id/-i. When
specified without a parameter, the new option will cause the Board ID
to be read. When specified with a parameter, the board ID value will
be set. The parameter includes one or two values in a single string,
the values separated by a colon.
The first value is a 4 byte board ID, and the second value is the
flags field. The default flags field is set to 0xff00.
BRANCH=cr50
BUG=b:35587387,b:35587053
TEST=verified that it is possible to get and set the board ID value
using usb_updater, both over USB and TPM.
verified that it is not possible to set a new board ID value is
the INFO1 space has been already programmed.
verified that it is not possible to set a board ID value which
would not allow the currently running image to start (even
though there is no run time check yet).
Original Change-Id: Ief175d8b2ef3177db13fa86f831914088d9447b0
Original Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original Reviewed-on: https://chromium-review.googlesource.com/525096
Original Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Change-Id: I7bf66fe6c3ad3515d82444ba1ab956aca866acda
Reviewed-on: https://chromium-review.googlesource.com/958717
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Marco Chen <marcochen@chromium.org>
Commit-Queue: Marco Chen <marcochen@chromium.org>
-rw-r--r-- | extra/usb_updater/usb_updater.c | 134 |
1 files changed, 131 insertions, 3 deletions
diff --git a/extra/usb_updater/usb_updater.c b/extra/usb_updater/usb_updater.c index 340fc791be..1758bfab28 100644 --- a/extra/usb_updater/usb_updater.c +++ b/extra/usb_updater/usb_updater.c @@ -230,7 +230,7 @@ struct transfer_descriptor { static uint32_t protocol_version; static char *progname; -static char *short_opts = "bcd:fhpsu"; +static char *short_opts = "bcd:fhipsu"; static const struct option long_opts[] = { /* name hasarg *flag val */ {"binvers", 0, NULL, 'b'}, @@ -239,6 +239,7 @@ static const struct option long_opts[] = { {"fwver", 0, NULL, 'f'}, {"help", 0, NULL, 'h'}, {"post_reset", 0, NULL, 'p'}, + {"board_id", 2, NULL, 'i'}, {"systemdev", 0, NULL, 's'}, {"upstart", 0, NULL, 'u'}, {}, @@ -364,6 +365,8 @@ static void usage(int errs) " -d,--device VID:PID USB device (default %04x:%04x)\n" " -f,--fwver Report running firmware versions.\n" " -h,--help Show this message\n" + " -i,--board_id [ID[:FLAGS]]\n" + " Get or set Info1 board ID fields\n" " -p,--post_reset Request post reset after transfer\n" " -s,--systemdev Use /dev/tpm0 (-d is ignored)\n" " -u,--upstart " @@ -1238,6 +1241,112 @@ static int show_headers_versions(const void *image) return 0; } +struct board_id { + uint32_t type; /* Board type */ + uint32_t type_inv; /* Board type (inverted) */ + uint32_t flags; /* Flags */ +}; + +enum board_id_action { + bid_none, + bid_get, + bid_set +}; + +/* + * The default flag value will allow to run images built for any hardware + * generation of a particular board ID. + */ +#define DEFAULT_BOARD_ID_FLAG 0xff00 +static int parse_bid(const char *opt, + struct board_id *bid, + enum board_id_action *bid_action) +{ + char *e; + + if (!opt) { + *bid_action = bid_get; + return 1; + } + + bid->type = (uint32_t)strtoul(opt, &e, 0); + *bid_action = bid_set; /* Ignored by caller on errors. */ + + if (!e || !*e) { + bid->flags = DEFAULT_BOARD_ID_FLAG; + return 1; + } + + if (*e == ':') { + bid->flags = (uint32_t)strtoul(e + 1, &e, 0); + if (!e || !*e) + return 1; + } + + return 0; +} + +static void process_bid(struct transfer_descriptor *td, + enum board_id_action bid_action, + struct board_id *bid) +{ + size_t response_size; + + if (bid_action == bid_get) { + struct board_id bid; + + response_size = sizeof(bid); + send_vendor_command(td, VENDOR_CC_GET_BOARD_ID, + &bid, sizeof(bid), + &bid, &response_size); + + if (response_size == sizeof(bid)) { + printf("Board ID space: %08x:%08x:%08x\n", + be32toh(bid.type), be32toh(bid.type_inv), + be32toh(bid.flags)); + return; + + } + fprintf(stderr, "Error reading board ID: response size %zd," + " first byte %#02x\n", response_size, + response_size ? *(uint8_t *)&bid : -1); + exit(update_error); + } + + if (bid_action == bid_set) { + /* Sending just two fields: type and flags. */ + uint32_t command_body[2]; + uint8_t response; + + command_body[0] = htobe32(bid->type); + command_body[1] = htobe32(bid->flags); + + response_size = sizeof(command_body); + send_vendor_command(td, VENDOR_CC_SET_BOARD_ID, + command_body, sizeof(command_body), + command_body, &response_size); + + /* + * Speculative assignment: the response is expected to be one + * byte in size and be placed in the first byte of the buffer. + */ + response = *((uint8_t *)command_body); + + if (response_size == 1) { + if (!response) + return; /* Success! */ + + fprintf(stderr, "Error %d while setting board id\n", + response); + } else { + fprintf(stderr, "Unexpected response size %zd" + " while setting board id\n", + response_size); + } + exit(update_error); + } +} + int main(int argc, char *argv[]) { struct transfer_descriptor td; @@ -1251,6 +1360,8 @@ int main(int argc, char *argv[]) int binary_vers = 0; int show_fw_ver = 0; int corrupt_inactive_rw = 0; + struct board_id bid; + enum board_id_action bid_action; progname = strrchr(argv[0], '/'); if (progname) @@ -1262,6 +1373,7 @@ int main(int argc, char *argv[]) memset(&td, 0, sizeof(td)); td.ep_type = usb_xfer; + bid_action = bid_none; errorcnt = 0; opterr = 0; /* quiet, you */ while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) { @@ -1271,7 +1383,8 @@ int main(int argc, char *argv[]) break; case 'd': if (!parse_vidpid(optarg, &vid, &pid)) { - printf("Invalid argument: \"%s\"\n", optarg); + printf("Invalid device argument: \"%s\"\n", + optarg); errorcnt++; } break; @@ -1284,6 +1397,18 @@ int main(int argc, char *argv[]) case 'h': usage(errorcnt); break; + case 'i': + if (!optarg && argv[optind] && argv[optind][0] != '-') { + /* optional argument present. */ + optarg = argv[optind]; + optind++; + } + if (!parse_bid(optarg, &bid, &bid_action)) { + printf("Invalid board id argument: \"%s\"\n", + optarg); + errorcnt++; + } + break; case 's': td.ep_type = dev_xfer; break; @@ -1316,7 +1441,7 @@ int main(int argc, char *argv[]) if (errorcnt) usage(errorcnt); - if (!show_fw_ver && !corrupt_inactive_rw) { + if (!show_fw_ver && !corrupt_inactive_rw && (bid_action == bid_none)) { if (optind >= argc) { fprintf(stderr, "\nERROR: Missing required <binary image>\n\n"); @@ -1351,6 +1476,9 @@ int main(int argc, char *argv[]) } } + if (bid_action != bid_none) + process_bid(&td, bid_action, &bid); + if (corrupt_inactive_rw) invalidate_inactive_rw(&td); |