aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2020-11-24 15:15:11 -0700
committerJosh Rahm <joshuarahm@gmail.com>2020-11-24 15:22:42 -0700
commitecbcb2509f4b811bce0a56e07de9737d14815251 (patch)
treef96492fb6db5d26c133dc3ab2993a9df3f224ea2
parent351ff7059a5bacb322664412a8c62ee4640b33bf (diff)
downloadstm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.tar.gz
stm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.tar.bz2
stm32l4-ecbcb2509f4b811bce0a56e07de9737d14815251.zip
Add better logging capabilities, including the ability to panic.
-rw-r--r--include/kern/init.h14
-rw-r--r--include/kern/log.h11
-rw-r--r--include/kern/panic.h6
-rw-r--r--src/kern/init.c60
-rw-r--r--src/kern/log.c20
-rw-r--r--src/kern/mem.c18
-rw-r--r--src/kern/panic.c36
-rw-r--r--test_harness/fake_env.c1
-rw-r--r--test_harness/test_harness.c12
9 files changed, 157 insertions, 21 deletions
diff --git a/include/kern/init.h b/include/kern/init.h
index 737b85f..0ebbeac 100644
--- a/include/kern/init.h
+++ b/include/kern/init.h
@@ -64,4 +64,18 @@
void(*init7_ptr)() = init7fn; \
static void init7fn
+typedef enum {
+ INIT_LEVEL_0,
+ INIT_LEVEL_1,
+ INIT_LEVEL_2,
+ INIT_LEVEL_3,
+ INIT_LEVEL_4,
+ INIT_LEVEL_5,
+ INIT_LEVEL_6,
+ INIT_LEVEL_7,
+ INIT_LEVEL_MAIN,
+} init_level_t;
+
+init_level_t get_system_init_level();
+
#endif /* INIT_H_ */
diff --git a/include/kern/log.h b/include/kern/log.h
index 5e49def..e1e4088 100644
--- a/include/kern/log.h
+++ b/include/kern/log.h
@@ -1,6 +1,8 @@
#ifndef LOG_H_
#define LOG_H_
+#include <stdarg.h>
+
/*
* Defines logging capabilities. This logging unit will enable logging on
* the systems main USART output.
@@ -9,4 +11,13 @@
/** Similar to fprintf, but with a stripped-down format-string DSL. */
void klogf(const char* fmt, ...);
+/** Like klogf, but with a va_list argument. */
+void kvlogf(const char* fmt, va_list args);
+
+/** Log the following message as an error. */
+void kerr_logf(const char* fmt, ...);
+
+/** Like klogf, but with a va_list argument. */
+void kerr_vlogf(const char* fmt, va_list args);
+
#endif
diff --git a/include/kern/panic.h b/include/kern/panic.h
new file mode 100644
index 0000000..aa064bf
--- /dev/null
+++ b/include/kern/panic.h
@@ -0,0 +1,6 @@
+#ifndef KERN_PANIC_H_
+#define KERN_PANIC_H_
+
+_Noreturn void panic(const char* fmt, ...);
+
+#endif
diff --git a/src/kern/init.c b/src/kern/init.c
index 8f2d7e8..8885c09 100644
--- a/src/kern/init.c
+++ b/src/kern/init.c
@@ -20,6 +20,22 @@ extern uint32_t BSS_END;
extern void (*INIT_ROUTINES_FLASH_START)();
extern void (*INIT_ROUTINES_FLASH_STOP)();
+extern uint32_t INIT_0_END;
+extern uint32_t INIT_1_END;
+extern uint32_t INIT_2_END;
+extern uint32_t INIT_3_END;
+extern uint32_t INIT_4_END;
+extern uint32_t INIT_5_END;
+extern uint32_t INIT_6_END;
+extern uint32_t INIT_7_END;
+
+static _no_init init_level_t initlevel;
+
+init_level_t get_system_init_level()
+{
+ return initlevel;
+}
+
init0()
{
/* Enable a higher clock speed. This is the first thing we do
@@ -58,18 +74,52 @@ init3()
SCB.vto_r = 0x08000000;
}
-/*
- * Runs before main. Initializes the data and bss segments by loading them
- * into memory.
- */
-_Noreturn void on_reset()
+void run_init_routines()
{
+ void* init_boundaries[] = {
+ &INIT_0_END,
+ &INIT_1_END,
+ &INIT_2_END,
+ &INIT_3_END,
+ &INIT_4_END,
+ &INIT_5_END,
+ &INIT_6_END,
+ &INIT_7_END,
+ };
+
void (**initfn)();
for (initfn = &INIT_ROUTINES_FLASH_START; initfn < &INIT_ROUTINES_FLASH_STOP;
++initfn) {
+ while (initfn == init_boundaries[initlevel] && initlevel < INIT_LEVEL_7) {
+ ++initlevel;
+
+ if (initlevel > 2) {
+ klogf("[init%d]\n", initlevel);
+ }
+ }
+
(*initfn)();
}
+ while (initlevel < INIT_LEVEL_7) {
+ ++initlevel;
+
+ klogf("[init%d]\n", initlevel);
+ }
+
+ klogf("Initialization Routines Complete. Onto main()\n");
+}
+
+/*
+ * Runs before main. Initializes the data and bss segments by loading them
+ * into memory.
+ */
+_Noreturn void on_reset()
+{
+ initlevel = INIT_LEVEL_0;
+
+ run_init_routines();
+
/* Jump to main. */
main();
diff --git a/src/kern/log.c b/src/kern/log.c
index ebc2cbe..c876759 100644
--- a/src/kern/log.c
+++ b/src/kern/log.c
@@ -26,7 +26,27 @@ void klogf(const char* fmt, ...)
va_list l;
va_start(l, fmt);
+ kvlogf(fmt, l);
+}
+
+void kvlogf(const char* fmt, va_list l)
+{
+ usart_vprintf(&USART2, fmt, l);
+}
+
+void kerr_vlogf(const char* fmt, va_list l)
+{
+ klogf("\x1b[01;31m[ERROR] ");
usart_vprintf(&USART2, fmt, l);
+ klogf("\x1b[00m");
+}
+
+void kerr_logf(const char* fmt, ...)
+{
+ va_list l;
+ va_start(l, fmt);
+
+ kerr_vlogf(fmt, l);
}
void setup_usart2(uint32_t baud_rate)
diff --git a/src/kern/mem.c b/src/kern/mem.c
index ac90f0d..eb4527e 100644
--- a/src/kern/mem.c
+++ b/src/kern/mem.c
@@ -1,7 +1,9 @@
#include "kern/mem.h"
#include "arch.h"
+
#include "kern/common.h"
+#include "kern/panic.h"
#ifdef ARCH_STM32L4
/* Provide a definition for memset() when not provided for the
@@ -146,22 +148,6 @@ static void coalesce(kalloc_node_t* cur)
last_freed->size = ((uint8_t*)next_used - (last_freed->mem)) / 4;
}
-#ifdef FOR_TESTING
-#include <assert.h>
-#include <stdio.h>
-void panic(const char* x)
-{
- fprintf(stderr, "%s\n", x);
- assert(0);
-}
-#else
-void panic(const char* x)
-{
- for (;;)
- ;
-}
-#endif
-
void kfree(void* mem)
{
/* Like normal free(), do nothing on free'ing NULL */
diff --git a/src/kern/panic.c b/src/kern/panic.c
new file mode 100644
index 0000000..8708456
--- /dev/null
+++ b/src/kern/panic.c
@@ -0,0 +1,36 @@
+#include "arch.h"
+#include "kern/panic.h"
+#include "kern/log.h"
+#include "kern/init.h"
+#include "arch/stm32l4xxx/peripherals/clock.h"
+#include "kern/gpio/sysled.h"
+#include "kern/gpio/gpio_manager.h"
+#include "kern/delay.h"
+
+#include <stdarg.h>
+
+#ifdef ARCH_STM32L4
+_Noreturn void panic(const char* fmt, ...)
+{
+
+ if (get_system_init_level() > INIT_LEVEL_2) {
+ va_list l;
+ va_start(l, fmt);
+
+ kerr_logf("** Kernel Panic! **\n");
+ kerr_vlogf(fmt, l);
+
+ set_system_clock_MHz(4); /* reduce power usage while we do nothing. */
+ for(;;);
+ } else {
+ set_system_clock_MHz(4); /* reduce power usage while we do nothing. */
+ gpio_reserved_pin_t pin3 = get_sysled();
+ for (;;) {
+ set_gpio_pin_high(pin3);
+ delay(100000);
+ set_gpio_pin_low(pin3);
+ delay(100000);
+ }
+ }
+}
+#endif
diff --git a/test_harness/fake_env.c b/test_harness/fake_env.c
index 7ac0d9b..fbe85ce 100644
--- a/test_harness/fake_env.c
+++ b/test_harness/fake_env.c
@@ -2,6 +2,7 @@
#include <assert.h>
#include <stdlib.h>
+#include <stdio.h>
struct fakeenv_memseg {
const char* name;
diff --git a/test_harness/test_harness.c b/test_harness/test_harness.c
index fda623f..2bd6194 100644
--- a/test_harness/test_harness.c
+++ b/test_harness/test_harness.c
@@ -7,6 +7,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <stdarg.h>
#include "fake_env.h"
@@ -117,6 +118,17 @@ static void nofork_reset()
memcpy(&__data_start, saved_data, saved_data_size);
}
+void panic(const char* fmt, ...)
+{
+ va_list l;
+ va_start(l, fmt);
+
+ fprintf(stderr, "Kernel panic detected.");
+ vfprintf(stderr, fmt, l);
+
+ ASSERT_TRUE(0);
+}
+
static int execute_test(test_t* test)
{
char fullname[512];