diff options
Diffstat (limited to 'purgatory')
-rw-r--r-- | purgatory/Makefile | 1 | ||||
-rw-r--r-- | purgatory/arch/arm64/Makefile | 18 | ||||
-rw-r--r-- | purgatory/arch/arm64/entry.S | 54 | ||||
-rw-r--r-- | purgatory/arch/arm64/purgatory-arm64.c | 35 |
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); +} |