From 6e853562c94698916c7f582df064a154b154f3d6 Mon Sep 17 00:00:00 2001 From: Wei-Han Chen Date: Thu, 16 Aug 2018 15:29:48 +0800 Subject: usb_update: add extra command "UPDATE_EXTRA_CMD_CONSOLE_READ_*" Similar to corressponding host commands, we can read uart console buffer by following ways: A. Read from the beginning of buffer to the end of buffer: # 1. set snapshot before reading UPDATE_EXTRA_CMD_CONSOLE_READ_INIT while (true) { # 2. read 64 bytes back UPDATE_EXTRA_CMD_CONSOLE_READ_NEXT CONSOLE_READ_NEXT # 3. if (2) returns an empty string, break, otherwise, continue. } B. Mimic `dmesg -w` (keep reading new messages) while (true) { # 1. set snapshot before reading UPDATE_EXTRA_CMD_CONSOLE_READ_INIT while (true) { # 2. read 64 bytes back UPDATE_EXTRA_CMD_CONSOLE_READ_NEXT CONSOLE_READ_RECENT # 3. if (2) returns an empty string, break, otherwise, continue. } } Add argument `-l` to usb_updater2, which will perform (B). Note that the update interface will be occupied while `usb_updater2 -l` is still running, so you can't use other updater command at the same time. BRANCH=none BUG=b:112877237 TEST=test on whiskers Signed-off-by: Wei-Han Chen Change-Id: I8d2010f84602ca6b84034a0cabe42ae7441614e0 Reviewed-on: https://chromium-review.googlesource.com/1177293 Commit-Ready: Wei-Han Chen Tested-by: Wei-Han Chen Reviewed-by: Nicolas Boichat --- extra/usb_updater/usb_updater2.c | 78 +++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 16 deletions(-) (limited to 'extra/usb_updater/usb_updater2.c') diff --git a/extra/usb_updater/usb_updater2.c b/extra/usb_updater/usb_updater2.c index e31770b40e..c625b628f4 100644 --- a/extra/usb_updater/usb_updater2.c +++ b/extra/usb_updater/usb_updater2.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,7 @@ static struct first_response_pdu targ; static uint16_t protocol_version; static uint16_t header_type; static char *progname; -static char *short_opts = "bd:efg:hjnp:rsS:tuw"; +static char *short_opts = "bd:efg:hjlnp:rsS:tuw"; static const struct option long_opts[] = { /* name hasarg *flag val */ {"binvers", 1, NULL, 'b'}, @@ -82,6 +83,7 @@ static const struct option long_opts[] = { {"tp_debug", 1, NULL, 'g'}, {"help", 0, NULL, 'h'}, {"jump_to_rw", 0, NULL, 'j'}, + {"follow_log", 0, NULL, 'l'}, {"no_reset", 0, NULL, 'n'}, {"tp_update", 1, NULL, 'p'}, {"reboot", 0, NULL, 'r'}, @@ -113,11 +115,12 @@ static void usage(int errs) " -b,--binvers Report versions of image's " "RW and RO, do not update\n" " -d,--device VID:PID USB device (default %04x:%04x)\n" + " -e,--entropy Add entropy to device secret\n" " -f,--fwver Report running firmware versions.\n" " -g,--tp_debug Touchpad debug command\n" " -h,--help Show this message\n" - " -e,--entropy Add entropy to device secret\n" " -j,--jump_to_rw Tell EC to jump to RW\n" + " -l,--follow_log Get console log\n" " -p,--tp_update file Update touchpad FW\n" " -r,--reboot Tell EC to reboot\n" " -s,--stay_in_ro Tell EC to stay in RO\n" @@ -305,9 +308,9 @@ static void do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen, } static void xfer(struct usb_endpoint *uep, void *outbuf, - size_t outlen, void *inbuf, size_t inlen) + size_t outlen, void *inbuf, size_t inlen, int allow_less) { - do_xfer(uep, outbuf, outlen, inbuf, inlen, 0, NULL); + do_xfer(uep, outbuf, outlen, inbuf, inlen, allow_less, NULL); } /* Return 0 on error, since it's never gonna be EP 0 */ @@ -495,14 +498,14 @@ static int transfer_block(struct usb_endpoint *uep, int r; /* First send the header. */ - xfer(uep, ufh, sizeof(*ufh), NULL, 0); + xfer(uep, ufh, sizeof(*ufh), NULL, 0, 0); /* Now send the block, chunk by chunk. */ for (transfer_size = 0; transfer_size < payload_size;) { int chunk_size; chunk_size = MIN(uep->chunk_len, payload_size - transfer_size); - xfer(uep, transfer_data_ptr, chunk_size, NULL, 0); + xfer(uep, transfer_data_ptr, chunk_size, NULL, 0, 0); transfer_data_ptr += chunk_size; transfer_size += chunk_size; } @@ -843,7 +846,8 @@ static void setup_connection(struct transfer_descriptor *td) */ static int ext_cmd_over_usb(struct usb_endpoint *uep, uint16_t subcommand, void *cmd_body, size_t body_size, - void *resp, size_t *resp_size) + void *resp, size_t *resp_size, + int allow_less) { struct update_frame_header *ufh; uint16_t *frame_ptr; @@ -868,7 +872,8 @@ static int ext_cmd_over_usb(struct usb_endpoint *uep, uint16_t subcommand, if (body_size) memcpy(frame_ptr + 1, cmd_body, body_size); - xfer(uep, ufh, usb_msg_size, resp, resp_size ? *resp_size : 0); + xfer(uep, ufh, usb_msg_size, resp, resp_size ? *resp_size : 0, + allow_less); free(ufh); return 0; @@ -886,7 +891,7 @@ static void send_done(struct usb_endpoint *uep) /* Send stop request, ignoring reply. */ out = htobe32(UPDATE_DONE); - xfer(uep, &out, sizeof(out), &out, 1); + xfer(uep, &out, sizeof(out), &out, 1, 0); } static void send_subcommand(struct transfer_descriptor *td, uint16_t subcommand, @@ -897,7 +902,7 @@ static void send_subcommand(struct transfer_descriptor *td, uint16_t subcommand, ext_cmd_over_usb(&td->uep, subcommand, cmd_body, body_size, - response, &response_size); + response, &response_size, 0); printf("sent command %x, resp %x\n", subcommand, response[0]); } @@ -965,7 +970,7 @@ static void generate_reset_request(struct transfer_descriptor *td) subcommand = UPDATE_EXTRA_CMD_IMMEDIATE_RESET; ext_cmd_over_usb(&td->uep, subcommand, command_body, command_body_size, - &response, &response_size); + &response, &response_size, 0); printf("reboot not triggered\n"); } @@ -995,6 +1000,42 @@ static void get_random(uint8_t *data, int len) fclose(fp); } +static void read_console(struct transfer_descriptor *td) +{ + uint8_t payload[] = { 0x1 }; + uint8_t response[64]; + size_t response_size = 64; + struct timespec sleep_duration = { /* 100 ms */ + .tv_sec = 0, + .tv_nsec = 100l * 1000l * 1000l, + }; + + send_done(&td->uep); + + printf("\n"); + while (1) { + response_size = 1; + ext_cmd_over_usb(&td->uep, + UPDATE_EXTRA_CMD_CONSOLE_READ_INIT, + NULL, 0, + response, &response_size, 0); + + while (1) { + response_size = 64; + ext_cmd_over_usb(&td->uep, + UPDATE_EXTRA_CMD_CONSOLE_READ_NEXT, + payload, sizeof(payload), + response, &response_size, 1); + if (response[0] == 0) + break; + /* make sure it's null-terminated. */ + response[response_size - 1] = 0; + printf((const char *)response); + } + nanosleep(&sleep_duration, NULL); + } +} + int main(int argc, char *argv[]) { struct transfer_descriptor td; @@ -1038,6 +1079,11 @@ int main(int argc, char *argv[]) errorcnt++; } break; + case 'e': + get_random(extra_command_data, 32); + extra_command_data_len = 32; + extra_command = UPDATE_EXTRA_CMD_INJECT_ENTROPY; + break; case 'f': show_fw_ver = 1; break; @@ -1053,14 +1099,12 @@ int main(int argc, char *argv[]) case 'h': usage(errorcnt); break; - case 'e': - get_random(extra_command_data, 32); - extra_command_data_len = 32; - extra_command = UPDATE_EXTRA_CMD_INJECT_ENTROPY; - break; case 'j': extra_command = UPDATE_EXTRA_CMD_JUMP_TO_RW; break; + case 'l': + extra_command = UPDATE_EXTRA_CMD_CONSOLE_READ_INIT; + break; case 'n': no_reset_request = 1; break; @@ -1161,6 +1205,8 @@ int main(int argc, char *argv[]) if (transferred_sections && !no_reset_request) generate_reset_request(&td); } + } else if (extra_command == UPDATE_EXTRA_CMD_CONSOLE_READ_INIT) { + read_console(&td); } else if (extra_command > -1) { send_subcommand(&td, extra_command, extra_command_data, extra_command_data_len, -- cgit v1.2.1