#include <link.h>
#include <led.h>
#include <uart.h>
+#include <panic.h>
/* Initialize just enough to be able to handle a fault. */
__attribute__ ((noinline, used)) static void
asm ("b kentry");
}
+/* TODO write proper exception handlers, this is just a test */
+__attribute__ ((noreturn)) static void
+fault_handler (void)
+{
+ panic ("Fault");
+}
+
__attribute__ ((section (".vector_table"), used))
static unsigned long const vector_table[] = {
- (unsigned long) &_sram_end,
- (unsigned long) reset_handler,
+ [0] = (unsigned long) &_sram_end,
+ [1] = (unsigned long) reset_handler,
+ [3] = (unsigned long) fault_handler, /* ??? */
+ [6] = (unsigned long) fault_handler,
};
{
unsigned int line;
- /* Test UART and LED ---------------------------------------------------- */
+ for (line = 0; line < sizeof text / sizeof *text; ++line)
+ kputs_busytc (text[line]);
+
+ /* Trigger a fault to test kernel panic */
+ asm ("udf #0");
+
+ kputs_busytc ("Unreachable");
while (1)
- {
- for (line = 0; line < sizeof text / sizeof *text; ++line)
- {
- kputs_busytc (text[line]);
- led_toggle ();
- }
- }
+ asm ("wfi");
}
--- /dev/null
+#include <panic.h>
+#include <led.h>
+#include <uart.h>
+
+void
+panic (const char *msg)
+{
+ asm ("cpsid f");
+
+ led_on ();
+ kputs_busytc ("\r\n\nKernel panic: ");
+ kputs_busytc (msg);
+ kputs_busytc ("\r\n\nStop.");
+
+ while (1)
+ asm ("wfi");
+}
{
/* GPIOCEN: IO port C clock enable */
*RCC_AHB1ENR |= (1u << 2); /* 1: IO port C clock enabled */
+
+ /* Default to LED being turned off */
+ *GPIOC_ODR |= (1u << 13);
+
/* MODERy[1:0]: Port x configuration bits (y = 0..15) */
*GPIOC_MODER &= ~(0b11u << 26); /* Clear PC13 bits */
*GPIOC_MODER |= (1u << 26); /* 01: General purpose output mode */
--- /dev/null
+#ifndef _PANIC_H_
+#define _PANIC_H_
+
+__attribute__ ((noreturn)) void panic (const char *msg);
+
+#endif /* _PANIC_H_ */