common fw: Add a 'panic' handler
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: Ice3f338abfe3d361da875c3233b8a052bd6aa2c2
diff --git a/firmware/ice40-riscv/common/utils.c b/firmware/ice40-riscv/common/utils.c
index 67b292f..1ac111b 100644
--- a/firmware/ice40-riscv/common/utils.c
+++ b/firmware/ice40-riscv/common/utils.c
@@ -5,9 +5,15 @@
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
+#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
+#include "console.h"
+#include "led.h"
+#include "mini-printf.h"
+#include "misc.h"
+
char *
hexstr(void *d, int n, bool space)
{
@@ -29,3 +35,47 @@
return buf;
}
+
+
+void
+_panic(const char *file, int lineno, const char *fmt, ...)
+{
+ char buf[256];
+ va_list va;
+ int l;
+
+ /* Fast hard red blinking led */
+ led_state(true);
+ led_color(255, 0, 8);
+ led_breathe(false, 0, 0);
+ led_blink(true, 75, 75);
+
+ /* Prepare buffer */
+ l = mini_snprintf(buf, 255, "PANIC @ %s:%d = ", file, lineno);
+
+ va_start(va, fmt);
+ l += mini_vsnprintf(buf+l, 255-l, fmt, va);
+ va_end(va);
+
+ buf[l] = '\n';
+ buf[l+1] = '\0';
+
+ /* Print once */
+ puts(buf);
+
+ /* Loop waiting for commands */
+ while (1) {
+ int cmd = getchar_nowait();
+
+ switch (cmd) {
+ case 'b':
+ /* Reboot */
+ reboot(2);
+ break;
+ case ' ':
+ /* Print error again */
+ puts(buf);
+ break;
+ }
+ }
+}
diff --git a/firmware/ice40-riscv/common/utils.h b/firmware/ice40-riscv/common/utils.h
index fc898f8..03359ae 100644
--- a/firmware/ice40-riscv/common/utils.h
+++ b/firmware/ice40-riscv/common/utils.h
@@ -10,3 +10,6 @@
#include <stdbool.h>
char *hexstr(void *d, int n, bool space);
+
+void _panic(const char *file, int lineno, const char *fmt, ...);
+#define panic(fmt, ...) _panic(__FILE__, __LINE__, fmt, ##__VA_ARGS__)