aboutsummaryrefslogtreecommitdiffstats
path: root/src/generic/armcm_boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/generic/armcm_boot.c')
-rw-r--r--src/generic/armcm_boot.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/generic/armcm_boot.c b/src/generic/armcm_boot.c
new file mode 100644
index 00000000..c559c1c1
--- /dev/null
+++ b/src/generic/armcm_boot.c
@@ -0,0 +1,73 @@
+// ARM Cortex-M vector table and initial bootup handling
+//
+// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "armcm_boot.h" // DECL_ARMCM_IRQ
+#include "board/internal.h" // SystemInit
+
+// Symbols created by armcm_boot.lds.S linker script
+extern uint32_t _data_start, _data_end, _data_flash;
+extern uint32_t _bss_start, _bss_end, _stack_start;
+
+
+/****************************************************************
+ * Basic interrupt handlers
+ ****************************************************************/
+
+// Initial code entry point - invoked by the processor after a reset
+void
+ResetHandler(void)
+{
+ // Copy global variables from flash to ram
+ uint32_t count = (&_data_end - &_data_start) * 4;
+ __builtin_memcpy(&_data_start, &_data_flash, count);
+
+ // Clear the bss segment
+ __builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
+
+ barrier();
+
+ // Initializing the C library isn't needed...
+ //__libc_init_array();
+
+ // Initialize the machine
+ SystemInit();
+
+ // Run the main code
+ extern int main(void);
+ main();
+
+ // The main() call should not return
+ for (;;)
+ ;
+}
+DECL_ARMCM_IRQ(ResetHandler, -15);
+
+// Code called for any undefined interrupts
+void
+DefaultHandler(void)
+{
+ for (;;)
+ ;
+}
+
+
+/****************************************************************
+ * Dynamic memory range
+ ****************************************************************/
+
+// Return the start of memory available for dynamic allocations
+void *
+dynmem_start(void)
+{
+ return &_bss_end;
+}
+
+// Return the end of memory available for dynamic allocations
+void *
+dynmem_end(void)
+{
+ return &_stack_start;
+}