From 6244dfa30c03811409e726931b6bffe98c58f29e Mon Sep 17 00:00:00 2001 From: Brian Granaghan Date: Thu, 31 Mar 2022 01:31:52 +0000 Subject: gsctool: Support flog on H1D3C. BUG=b:219038720 TEST=gsctool -aL Change-Id: I1c0b417e61dcb6460345c2fcf8d43952ebbf65d3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3573469 Commit-Queue: Brian Granaghan Tested-by: Brian Granaghan Reviewed-by: Andrey Pronin Reviewed-by: Mary Ruthven --- extra/usb_updater/dauntless_event.h | 24 +++++++++ extra/usb_updater/gsctool.c | 103 ++++++++++++++++++++++++++++-------- 2 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 extra/usb_updater/dauntless_event.h (limited to 'extra') diff --git a/extra/usb_updater/dauntless_event.h b/extra/usb_updater/dauntless_event.h new file mode 100644 index 0000000000..fc87d4d0bc --- /dev/null +++ b/extra/usb_updater/dauntless_event.h @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef __EXTRA_USB_UPDATER_DAUNTLESS_EVENT_H +#define __EXTRA_USB_UPDATER_DAUNTLESS_EVENT_H + +#include + +typedef struct { + uint64_t time; + uint32_t size; + uint32_t event_type; + uint8_t payload[0]; +} dt_event_t; + +union dt_entry_u { + uint8_t raw[256]; + dt_event_t evt; +}; + + +#endif // __EXTRA_USB_UPDATER_DAUNTLESS_EVENT_H diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index 70696ff2b3..f170c1d73a 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -27,6 +27,7 @@ #include "ap_ro_integrity_check.h" #include "ccd_config.h" #include "compile_time_macros.h" +#include "dauntless_event.h" #include "flash_log.h" #include "generated_version.h" #include "gsctool.h" @@ -2778,6 +2779,69 @@ static int process_tpm_mode(struct transfer_descriptor *td, return rv; } +#define MAX_PAYLOAD_SIZE 256 +struct parsed_flog_entry { + bool end_of_list; + char payload[MAX_PAYLOAD_SIZE]; + size_t payload_size; + uint64_t raw_timestamp; + time_t timestamp; + uint32_t event_type; +}; + +static int pop_flog_dt(struct transfer_descriptor *td, + struct parsed_flog_entry *parsed_entry) +{ + union dt_entry_u entry; + size_t resp_size = sizeof(entry); + int rv = send_vendor_command(td, VENDOR_CC_POP_LOG_ENTRY_MS, + &parsed_entry->raw_timestamp, + sizeof(parsed_entry->raw_timestamp), + &entry, &resp_size); + if (rv) + return rv; + if (resp_size == 0) { + parsed_entry->end_of_list = true; + return 0; + } + parsed_entry->event_type = entry.evt.event_type; + parsed_entry->payload_size = MIN(entry.evt.size - + sizeof(entry.evt.event_type), + MAX_PAYLOAD_SIZE); + memcpy(parsed_entry->payload, entry.evt.payload, + parsed_entry->payload_size); + parsed_entry->raw_timestamp = entry.evt.time; + parsed_entry->timestamp = parsed_entry->raw_timestamp / 1000; + return rv; + +} + +static int pop_flog(struct transfer_descriptor *td, + struct parsed_flog_entry *parsed_entry) +{ + union entry_u entry; + size_t resp_size = sizeof(entry); + uint32_t ts = (uint32_t) parsed_entry->raw_timestamp; + int rv = send_vendor_command(td, VENDOR_CC_POP_LOG_ENTRY, + &ts, sizeof(ts), + &entry, &resp_size); + if (rv) + return rv; + if (resp_size == 0) { + parsed_entry->end_of_list = true; + return 0; + } + parsed_entry->event_type = entry.r.type; + parsed_entry->payload_size = MIN(FLASH_LOG_PAYLOAD_SIZE(entry.r.size), + MAX_PAYLOAD_SIZE); + memcpy(parsed_entry->payload, entry.r.payload, + parsed_entry->payload_size); + parsed_entry->raw_timestamp = entry.r.timestamp; + parsed_entry->timestamp = entry.r.timestamp; + return rv; + +} + /* * Retrieve from H1 flash log entries which are newer than the passed in * timestamp. @@ -2785,8 +2849,8 @@ static int process_tpm_mode(struct transfer_descriptor *td, * On error retry a few times just in case flash log is locked by a concurrent * access. */ -static int process_get_flog(struct transfer_descriptor *td, uint32_t prev_stamp, - bool show_machine_output) +static int process_get_flog(struct transfer_descriptor *td, uint64_t prev_stamp, + bool show_machine_output, bool is_dauntless) { int rv; const int max_retries = 3; @@ -2794,17 +2858,16 @@ static int process_get_flog(struct transfer_descriptor *td, uint32_t prev_stamp, bool time_zone_reported = false; while (retries--) { - union entry_u entry; - size_t resp_size; + struct parsed_flog_entry entry = {0}; + entry.raw_timestamp = prev_stamp; size_t i; struct tm loc_time; - time_t entry_epoch; char date_str[25]; - - resp_size = sizeof(entry); - rv = send_vendor_command(td, VENDOR_CC_POP_LOG_ENTRY, - &prev_stamp, sizeof(prev_stamp), - &entry, &resp_size); + if (is_dauntless) { + rv = pop_flog_dt(td, &entry); + } else { + rv = pop_flog(td, &entry); + } if (rv) { /* @@ -2816,16 +2879,14 @@ static int process_get_flog(struct transfer_descriptor *td, uint32_t prev_stamp, continue; } - if (resp_size == 0) - /* No more entries. */ + if (entry.end_of_list) return 0; - memcpy(&prev_stamp, &entry.r.timestamp, sizeof(prev_stamp)); + prev_stamp = entry.raw_timestamp; if (show_machine_output) { - printf("%10u:%02x", prev_stamp, entry.r.type); + printf("%10"PRIu64":%02x", prev_stamp, entry.event_type); } else { - entry_epoch = prev_stamp; - localtime_r(&entry_epoch, &loc_time); + localtime_r(&entry.timestamp, &loc_time); if (!time_zone_reported) { strftime(date_str, sizeof(date_str), "%Z", @@ -2837,10 +2898,10 @@ static int process_get_flog(struct transfer_descriptor *td, uint32_t prev_stamp, /* Date format is MMM DD YY HH:mm:ss */ strftime(date_str, sizeof(date_str), "%b %d %y %T", &loc_time); - printf("%s : %02x", date_str, entry.r.type); + printf("%s : %02x", date_str, entry.event_type); } - for (i = 0; i < FLASH_LOG_PAYLOAD_SIZE(entry.r.size); i++) - printf(" %02x", entry.r.payload[i]); + for (i = 0; i < entry.payload_size; i++) + printf(" %02x", entry.payload[i]); printf("\n"); retries = max_retries; } @@ -3416,8 +3477,8 @@ int main(int argc, char *argv[]) if (get_boot_mode) exit(process_get_boot_mode(&td)); - if (get_flog) - process_get_flog(&td, prev_log_entry, show_machine_output); + if (get_flog) + process_get_flog(&td, prev_log_entry, show_machine_output, is_dauntless); if (erase_ap_ro_hash) process_erase_ap_ro_hash(&td); -- cgit v1.2.1