diff options
author | Jonathan Brandmeyer <jbrandmeyer@chromium.org> | 2018-07-16 15:02:22 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-26 04:07:41 -0700 |
commit | dda2f778befed39e449d96b471b94d489ed23d60 (patch) | |
tree | fc0db938c092a609fbf47e9758d8f0113e5b0cce /common/chipset.c | |
parent | 48113728b689870e6aeda6534d36eeffd3b738b3 (diff) | |
download | chrome-ec-dda2f778befed39e449d96b471b94d489ed23d60.tar.gz |
reset: Log the reason for AP resets.
Provides a new EC host command 'uptime info' which gathers up some
information which may be useful for debugging spurious resets on the AP
(was the EC reset recently? Why was the EC reset? If the EC reset the
AP, why did it do so?, etc.). Provide ectool support for the same.
Example results of `ectool uptimeinfo`:
```
localhost ~ # ectool uptimeinfo
EC uptime: 475.368 seconds
AP resets since EC boot: 2
Most recent AP reset causes:
315.903: reset: console command
363.507: reset: keyboard warm reboot
EC reset flags at last EC boot: reset-pin | sysjump
```
BRANCH=none
TEST=Perform some `apreset` commands from the EC console and observe
their side-effects via the `ectool uptimeinfo` command on the AP side.
Test sequences include no-resets through 5 resets, observing that the
ring buffer handling was correct.
BUG=b:110788201, b:79529789
Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
Change-Id: I0bf29d69de471c64f905ee8aa070b15b4f34f2ba
Reviewed-on: https://chromium-review.googlesource.com/1139028
Commit-Ready: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
Tested-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common/chipset.c')
-rw-r--r-- | common/chipset.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/common/chipset.c b/common/chipset.c index 7a2101624a..4342ba5fab 100644 --- a/common/chipset.c +++ b/common/chipset.c @@ -8,6 +8,11 @@ #include "chipset.h" #include "common.h" #include "console.h" +#include "ec_commands.h" +#include "host_command.h" +#include "system.h" +#include "task.h" +#include "timer.h" #include "util.h" /* Console output macros */ @@ -22,7 +27,7 @@ static int command_apreset(int argc, char **argv) { /* Force the chipset to reset */ ccprintf("Issuing AP reset...\n"); - chipset_reset(); + chipset_reset(CHIPSET_RESET_CONSOLE_CMD); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(apreset, command_apreset, @@ -31,10 +36,74 @@ DECLARE_CONSOLE_COMMAND(apreset, command_apreset, static int command_apshutdown(int argc, char **argv) { - chipset_force_shutdown(); + chipset_force_shutdown(CHIPSET_SHUTDOWN_CONSOLE_CMD); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(apshutdown, command_apshutdown, NULL, "Force AP shutdown"); + #endif + +#ifdef CONFIG_CMD_AP_RESET_LOG +static struct mutex reset_log_mutex; +static int next_reset_log; +static uint32_t ap_resets_since_ec_boot; +/* keep reset_logs size a power of 2 */ +static struct ap_reset_log_entry reset_logs[4]; + +void report_ap_reset(enum chipset_shutdown_reason reason) +{ + timestamp_t now = get_time(); + uint32_t now_ms = (uint32_t)(now.val / MSEC); + + mutex_lock(&reset_log_mutex); + reset_logs[next_reset_log].reset_cause = reason; + reset_logs[next_reset_log++].reset_time_ms = now_ms; + next_reset_log &= ARRAY_SIZE(reset_logs) - 1; + ap_resets_since_ec_boot++; + mutex_unlock(&reset_log_mutex); +} + +static int host_command_get_uptime_info(struct host_cmd_handler_args *args) +{ + /* + * In the current implementation, not all terms are preserved across a + * sysjump. Future implementations may preserve additional information. + * + * time_since_ec_boot_ms: preserved, but wraps at ~50 days + * ec_reset_flags: preserved, with 'sysjump' added + * ap_resets_since_ec_boot: Not preserved + * recent_ap_reset[*]: Not preserved + */ + struct ec_response_uptime_info *r = args->response; + timestamp_t now = get_time(); + uint32_t now_ms = (uint32_t)(now.val / MSEC); + size_t log_address = 0; + size_t i = 0; + + r->time_since_ec_boot_ms = now_ms; + r->ec_reset_flags = system_get_reset_flags(); + + memset(r->recent_ap_reset, 0, sizeof(r->recent_ap_reset)); + + mutex_lock(&reset_log_mutex); + r->ap_resets_since_ec_boot = ap_resets_since_ec_boot; + for (i = 0; + i != ARRAY_SIZE(reset_logs) && i != ARRAY_SIZE(r->recent_ap_reset); + ++i) { + log_address = (next_reset_log + i) & + (ARRAY_SIZE(reset_logs) - 1); + r->recent_ap_reset[i] = reset_logs[log_address]; + } + mutex_unlock(&reset_log_mutex); + + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_GET_UPTIME_INFO, + host_command_get_uptime_info, + EC_VER_MASK(0)); + +#endif /* !CONFIG_AP_RESET_LOG */ + |