summaryrefslogtreecommitdiff
path: root/boot/bootloader.h
diff options
context:
space:
mode:
Diffstat (limited to 'boot/bootloader.h')
-rw-r--r--boot/bootloader.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/boot/bootloader.h b/boot/bootloader.h
new file mode 100644
index 0000000..e5c013d
--- /dev/null
+++ b/boot/bootloader.h
@@ -0,0 +1,55 @@
+#include "../src/bootinfo.h"
+
+/* to be provider by the bootloader including this header */
+_Noreturn void bootloader(struct systemid *boot);
+
+__asm__(
+".text \n"
+".extern __bss_start \n"
+".extern __bss_end \n"
+".global __start \n"
+".type __start, @function \n"
+"__start: \n"
+
+/* zero any bss section */
+" mov #0, r0 \n"
+" mov.l 1f, r1 \n"
+" mov.l 2f, r2 \n"
+"0: cmp/hi r1, r2 \n"
+" bf 0f \n"
+" bra 0b \n"
+" mov.l r0, @-r2 \n"
+
+/* cannibalize code before this for stack space, and pass control to C */
+"0: mov.l 3f, r15 \n"
+" mov.l 4f, r4 \n"
+" bra bootloader \n"
+" nop \n"
+
+".align 2 \n"
+"1: .long __bss_start \n"
+"2: .long __bss_end \n"
+"3: .long __start \n"
+"4: .long 0x06002000 \n"
+);
+
+/* helper to jump to the specified code with the specified stack */
+static inline _Noreturn void jump(const void *code, long *stack)
+{
+ __asm__ __volatile__(
+ " jmp @%0\n"
+ " mov %1, r15\n"
+ : : "r"(code), "r"(stack)
+ );
+ __builtin_unreachable();
+}
+
+/* helper to abort by repeatedly executing an illegal instruction */
+static inline _Noreturn void fail(void)
+{
+ __asm__ __volatile__(
+ "0: bra 0b\n"
+ " .word 0xfffd\n"
+ );
+ __builtin_unreachable();
+}