summaryrefslogtreecommitdiff
path: root/purgatory
diff options
context:
space:
mode:
Diffstat (limited to 'purgatory')
-rw-r--r--purgatory/Makefile1
-rw-r--r--purgatory/arch/arm64/Makefile18
-rw-r--r--purgatory/arch/arm64/entry.S54
-rw-r--r--purgatory/arch/arm64/purgatory-arm64.c35
4 files changed, 108 insertions, 0 deletions
diff --git a/purgatory/Makefile b/purgatory/Makefile
index 1945702..0c85da6 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -18,6 +18,7 @@ dist += purgatory/Makefile $(PURGATORY_SRCS) \
include $(srcdir)/purgatory/arch/alpha/Makefile
include $(srcdir)/purgatory/arch/arm/Makefile
+include $(srcdir)/purgatory/arch/arm64/Makefile
include $(srcdir)/purgatory/arch/i386/Makefile
include $(srcdir)/purgatory/arch/ia64/Makefile
include $(srcdir)/purgatory/arch/mips/Makefile
diff --git a/purgatory/arch/arm64/Makefile b/purgatory/arch/arm64/Makefile
new file mode 100644
index 0000000..4749715
--- /dev/null
+++ b/purgatory/arch/arm64/Makefile
@@ -0,0 +1,18 @@
+
+arm64_PURGATORY_EXTRA_CFLAGS = \
+ -mcmodel=large \
+ -Wl,-Map=purgatory/purgatory.map \
+ -fno-stack-protector \
+ -Wundef \
+ -Werror-implicit-function-declaration \
+ -Wdeclaration-after-statement \
+ -Werror=implicit-int \
+ -Werror=strict-prototypes
+
+arm64_PURGATORY_SRCS += \
+ purgatory/arch/arm64/entry.S \
+ purgatory/arch/arm64/purgatory-arm64.c
+
+dist += \
+ $(arm64_PURGATORY_SRCS) \
+ purgatory/arch/arm64/Makefile
diff --git a/purgatory/arch/arm64/entry.S b/purgatory/arch/arm64/entry.S
new file mode 100644
index 0000000..140e91d
--- /dev/null
+++ b/purgatory/arch/arm64/entry.S
@@ -0,0 +1,54 @@
+/*
+ * ARM64 purgatory.
+ */
+
+.macro debug_brk
+ mov x0, #0x18; /* angel_SWIreason_ReportException */
+ mov x1, #0x20000;
+ add x1, x1, #0x20; /* ADP_Stopped_BreakPoint */
+ hlt #0xf000 /* A64 semihosting */
+.endm
+
+.macro size, sym:req
+ .size \sym, . - \sym
+.endm
+
+.text
+
+.globl purgatory_start
+purgatory_start:
+
+ adr x19, .Lstack
+ mov sp, x19
+
+ bl purgatory
+
+1: debug_brk
+ b 1b
+
+size purgatory_start
+
+.align 4
+ .rept 256
+ .quad 0
+ .endr
+.Lstack:
+
+.data
+
+.align 3
+
+.globl arm64_sink
+arm64_sink:
+ .quad 0
+size arm64_sink
+
+.globl arm64_kernel_entry
+arm64_kernel_entry:
+ .quad 0
+size arm64_kernel_entry
+
+.globl arm64_dtb_addr
+arm64_dtb_addr:
+ .quad 0
+size arm64_dtb_addr
diff --git a/purgatory/arch/arm64/purgatory-arm64.c b/purgatory/arch/arm64/purgatory-arm64.c
new file mode 100644
index 0000000..25960c3
--- /dev/null
+++ b/purgatory/arch/arm64/purgatory-arm64.c
@@ -0,0 +1,35 @@
+/*
+ * ARM64 purgatory.
+ */
+
+#include <stdint.h>
+#include <purgatory.h>
+
+/* Symbols set by kexec. */
+
+extern uint32_t *arm64_sink;
+extern void (*arm64_kernel_entry)(uint64_t);
+extern uint64_t arm64_dtb_addr;
+
+void putchar(int ch)
+{
+ if (!arm64_sink)
+ return;
+
+ *arm64_sink = ch;
+
+ if (ch == '\n')
+ *arm64_sink = '\r';
+}
+
+void setup_arch(void)
+{
+ printf("purgatory: kernel_entry: %lx\n",
+ (unsigned long)arm64_kernel_entry);
+ printf("purgatory: dtb: %lx\n", arm64_dtb_addr);
+}
+
+void post_verification_setup_arch(void)
+{
+ arm64_kernel_entry(arm64_dtb_addr);
+}