summaryrefslogtreecommitdiff
path: root/common/panic_output.c
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2013-12-04 17:15:12 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-12-05 22:30:58 +0000
commit1762de9d19d2671cc56e5a479055379a346030d3 (patch)
tree21f6ec886e9abcf9638c8a88767b8299d7eddfe7 /common/panic_output.c
parentb45f3b9f348c550a7389973d916b8b7cb6b25a88 (diff)
downloadchrome-ec-1762de9d19d2671cc56e5a479055379a346030d3.tar.gz
extract common core code
Move the non-core dependent code out of core/$(CORE) directory to common/ directory. Put all panic printing code in common/panic_output.c Put timer management code in common/timer.c Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=chrome-os-partner:23574 TEST=./util/make_all.sh use "crash divzero" and "panicinfo" on Link. Change-Id: Ia4e1ebc74cd53da55fe24f69e96f39f512b9336d Reviewed-on: https://chromium-review.googlesource.com/178871 Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Jeremy Thorpe <jeremyt@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common/panic_output.c')
-rw-r--r--common/panic_output.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/common/panic_output.c b/common/panic_output.c
new file mode 100644
index 0000000000..f77277ab33
--- /dev/null
+++ b/common/panic_output.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2013 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.
+ */
+
+#include "common.h"
+#include "console.h"
+#include "cpu.h"
+#include "host_command.h"
+#include "panic.h"
+#include "printf.h"
+#include "system.h"
+#include "task.h"
+#include "timer.h"
+#include "uart.h"
+#include "util.h"
+
+/* Panic data goes at the end of RAM. */
+static struct panic_data * const pdata_ptr = PANIC_DATA_PTR;
+
+/**
+ * Add a character directly to the UART buffer.
+ *
+ * @param context Context; ignored.
+ * @param c Character to write.
+ * @return 0 if the character was transmitted, 1 if it was dropped.
+ */
+static int panic_txchar(void *context, int c)
+{
+ if (c == '\n')
+ panic_txchar(context, '\r');
+
+ /* Wait for space in transmit FIFO */
+ while (!uart_tx_ready())
+ ;
+
+ /* Write the character directly to the transmit FIFO */
+ uart_write_char(c);
+
+ return 0;
+}
+
+void panic_puts(const char *outstr)
+{
+ /* Flush the output buffer */
+ uart_flush_output();
+
+ /* Put all characters in the output buffer */
+ while (*outstr)
+ panic_txchar(NULL, *outstr++);
+
+ /* Flush the transmit FIFO */
+ uart_tx_flush();
+}
+
+void panic_printf(const char *format, ...)
+{
+ va_list args;
+
+ /* Flush the output buffer */
+ uart_flush_output();
+
+ va_start(args, format);
+ vfnprintf(panic_txchar, NULL, format, args);
+ va_end(args);
+
+ /* Flush the transmit FIFO */
+ uart_tx_flush();
+}
+
+/**
+ * Display a message and reboot
+ */
+void panic_reboot(void)
+{
+ panic_puts("\n\nRebooting...\n");
+ system_reset(0);
+}
+
+#ifdef CONFIG_DEBUG_ASSERT_REBOOTS
+void panic_assert_fail(const char *msg, const char *func, const char *fname,
+ int linenum)
+{
+ panic_printf("\nASSERTION FAILURE '%s' in %s() at %s:%d\n",
+ msg, func, fname, linenum);
+
+ panic_reboot();
+}
+#endif
+
+void panic(const char *msg)
+{
+ panic_printf("\n** PANIC: %s\n", msg);
+ panic_reboot();
+}
+
+struct panic_data *panic_get_data(void)
+{
+ return pdata_ptr->magic == PANIC_DATA_MAGIC ? pdata_ptr : NULL;
+}
+
+/*****************************************************************************/
+/* Console commands */
+
+static int command_crash(int argc, char **argv)
+{
+ if (argc < 2)
+ return EC_ERROR_PARAM1;
+
+ if (!strcasecmp(argv[1], "divzero")) {
+ int a = 1, b = 0;
+
+ cflush();
+ ccprintf("%08x", a / b);
+ } else if (!strcasecmp(argv[1], "unaligned")) {
+ cflush();
+ ccprintf("%08x", *(int *)0xcdef);
+ } else {
+ return EC_ERROR_PARAM1;
+ }
+
+ /* Everything crashes, so shouldn't get back here */
+ return EC_ERROR_UNKNOWN;
+}
+DECLARE_CONSOLE_COMMAND(crash, command_crash,
+ "[divzero | unaligned]",
+ "Crash the system (for testing)",
+ NULL);
+
+static int command_panicinfo(int argc, char **argv)
+{
+ if (pdata_ptr->magic == PANIC_DATA_MAGIC) {
+ ccprintf("Saved panic data:%s\n",
+ (pdata_ptr->flags & PANIC_DATA_FLAG_OLD_CONSOLE ?
+ "" : " (NEW)"));
+
+ panic_data_print(pdata_ptr);
+
+ /* Data has now been printed */
+ pdata_ptr->flags |= PANIC_DATA_FLAG_OLD_CONSOLE;
+ } else {
+ ccprintf("No saved panic data available.\n");
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(panicinfo, command_panicinfo,
+ NULL,
+ "Print info from a previous panic",
+ NULL);
+
+/*****************************************************************************/
+/* Host commands */
+
+int host_command_panic_info(struct host_cmd_handler_args *args)
+{
+ if (pdata_ptr->magic == PANIC_DATA_MAGIC) {
+ ASSERT(pdata_ptr->struct_size <= args->response_max);
+ memcpy(args->response, pdata_ptr, pdata_ptr->struct_size);
+ args->response_size = pdata_ptr->struct_size;
+
+ /* Data has now been returned */
+ pdata_ptr->flags |= PANIC_DATA_FLAG_OLD_HOSTCMD;
+ }
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_GET_PANIC_INFO,
+ host_command_panic_info,
+ EC_VER_MASK(0));