diff options
Diffstat (limited to 'common/flash_log.c')
-rw-r--r-- | common/flash_log.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/common/flash_log.c b/common/flash_log.c index f5a138516a..c59511a3b5 100644 --- a/common/flash_log.c +++ b/common/flash_log.c @@ -106,8 +106,19 @@ static struct { /* Location where next entry is going to be added. */ static uint16_t log_write_cursor; -/* Timestamp of the next entry (when real time is not available). */ -static uint32_t log_stamp; +/* + * Base time in seconds, during init set to the time of the latest present log + * entry +1, expected be set by the host to current time. Log entries + * timestamps are set to this value plus uptime. + */ +static uint32_t log_tstamp_base; + +/* + * Keep track of the last used timestamp value to make sure there are no two + * entries with the same timestamp. + */ +test_mockable_static uint32_t last_used_timestamp; + /* Set to True after log has been initialized. */ static uint8_t log_inited; test_mockable_static uint8_t log_event_in_progress; @@ -263,6 +274,7 @@ static enum ec_error_list flash_log_add_event_core(uint8_t type, uint8_t size, size_t padded_entry_size; size_t entry_size; enum ec_error_list rv = EC_ERROR_INVAL; + uint32_t new_timestamp; if (size > MAX_FLASH_LOG_PAYLOAD_SIZE) return rv; @@ -293,7 +305,18 @@ static enum ec_error_list flash_log_add_event_core(uint8_t type, uint8_t size, entry_size = sizeof(e.r) + size; - e.r.timestamp = ++log_stamp; + new_timestamp = flash_log_get_tstamp(); + + /* + * Avoid rolling back or logging more than one entry with the same + * timestamp. + */ + if (last_used_timestamp >= new_timestamp) + last_used_timestamp += 1; + else + last_used_timestamp = new_timestamp; + + e.r.timestamp = last_used_timestamp; e.r.size = size; e.r.type = type; e.r.crc = 0; @@ -425,11 +448,14 @@ test_export_static void flash_log_init(void) r = log_offset_to_addr(read_cursor); while (entry_is_valid(r)) { - log_stamp = r->timestamp + 1; + last_used_timestamp = r->timestamp; read_cursor += FLASH_LOG_ENTRY_SIZE(r->size); r = log_offset_to_addr(read_cursor); } + /* Should be updated by the AP soon after booting. */ + log_tstamp_base = last_used_timestamp + 1; + log_write_cursor = read_cursor; log_inited = 1; @@ -462,6 +488,21 @@ test_export_static void flash_log_init(void) } DECLARE_HOOK(HOOK_INIT, flash_log_init, HOOK_PRIO_DEFAULT); +uint32_t flash_log_get_tstamp(void) +{ + return log_tstamp_base + get_time().val/1000000; +} + +enum ec_error_list flash_log_set_tstamp(uint32_t tstamp) +{ + if (tstamp <= last_used_timestamp) + return EC_ERROR_INVAL; + + log_tstamp_base = tstamp - get_time().val/1000000; + + return EC_SUCCESS; +} + #ifdef CONFIG_CMD_FLASH_LOG /* * Display Flash event log. @@ -499,10 +540,10 @@ static int command_flash_log(int argc, char **argv) sizeof(e))) > 0) { size_t i; - ccprintf("%08x:%02x", e.r.timestamp, e.r.type); + ccprintf("%10u:%02x", e.r.timestamp, e.r.type); for (i = 0; i < FLASH_LOG_PAYLOAD_SIZE(e.r.size); i++) { if (i && !(i % 16)) { - ccprintf("\n "); + ccprintf("\n "); cflush(); } ccprintf(" %02x", e.r.payload[i]); |