m1n1/src/start.S
Hector Martin 3872b1a7da exception: implement el0_call to run code as EL0
This lets us test register access and other features from EL0.

No serious attempt at security is made, but at least EL0 runs off of a
separate stack and can return to EL2 at any time with `brk`; we can
easily implement a guard mode to break straight to EL2 on exception
later if needed.

Signed-off-by: Hector Martin <marcan@marcan.st>
2021-02-24 21:48:12 +09:00

181 lines
2.8 KiB
ArmAsm

/* SPDX-License-Identifier: MIT */
#define UART_BASE 0x235200000
#define UTRSTAT 0x010
#define UTXH 0x020
#define WDT_BASE 0x23d2b0000
#define WDT_COUNT 0x10
#define WDT_ALARM 0x14
#define WDT_CTL 0x1c
.extern _start_c
.extern _stack_bot
.extern _v_sp0_sync
.extern _v_sp0_irq
.extern _v_sp0_fiq
.extern _v_sp0_serr
.extern _reset_stack
.extern _cpu_reset_c
.section .init, "ax"
.globl _vectors_start
_vectors_start:
mov x9, '0'
b cpu_reset
.align 7
mov x9, '1'
b exc_unk
.align 7
mov x9, '2'
b exc_unk
.align 7
mov x9, '3'
b exc_unk
.align 7
b _v_sp0_sync
.align 7
b _v_sp0_irq
.align 7
b _v_sp0_fiq
.align 7
b _v_sp0_serr
.align 7
b _v_sp0_sync
b exc_unk
.align 7
b _v_sp0_irq
b exc_unk
.align 7
b _v_sp0_fiq
b exc_unk
.align 7
b _v_sp0_serr
b exc_unk
.align 7
mov x9, 'p'
b exc_unk
.align 7
mov x9, 'q'
b exc_unk
.align 7
mov x9, 'r'
b exc_unk
.align 7
mov x9, 's'
b exc_unk
.align 7
.globl _start
.type _start, @function
_start:
mov x19, x0
mov w0, 'm'
bl debug_putc
adrp x1, _stack_bot
mov sp, x1
mov w0, '1'
bl debug_putc
ldr x2, [sp, #-8]
mov w0, 'n'
bl debug_putc
adrp x0, _base
mov x20, x0
adrp x1, _rela_start
add x1, x1, :lo12:_rela_start
adrp x2, _rela_end
add x2, x2, :lo12:_rela_end
bl apply_rela
mov w0, '1'
bl debug_putc
mov w0, 0xd /* '\r', clang compat */
bl debug_putc
mov w0, '\n'
bl debug_putc
mov x0, x19
mov x1, x20
bl _start_c
b .
.globl exc_unk
.type exc_unk, @function
exc_unk:
mov w0, 0xd /* '\r', clang compat */
bl debug_putc
mov w0, '\n'
bl debug_putc
mov w0, '!'
bl debug_putc
mov w0, 'E'
bl debug_putc
mov w0, 'x'
bl debug_putc
mov w0, 'C'
bl debug_putc
mov w0, ':'
bl debug_putc
mov w0, w9
bl debug_putc
mov w0, '!'
bl debug_putc
mov w0, 0xd /* '\r', clang compat */
bl debug_putc
mov w0, '\n'
bl debug_putc
b reboot
.globl cpu_reset
.type cpu_reset, @function
cpu_reset:
mov w0, 'O'
bl debug_putc
adrp x1, _reset_stack
add x1, x1, :lo12:_reset_stack
ldr x1, [x1]
mov sp, x1
ldr x2, [sp, #-8]
mov w0, 'K'
bl debug_putc
mov x0, sp
bl _cpu_reset_c
b .
.globl debug_putc
.type debug_putc, @function
debug_putc:
ldr x1, =UART_BASE
1:
ldr w2, [x1, UTRSTAT]
tst w2, #2
beq 1b
str w0, [x1, UTXH]
ret
.globl reboot
.type reboot, @function
reboot:
ldr x1, =WDT_BASE
mov w0, #0x100000
str w0, [x1, #WDT_ALARM]
mov w0, #0
str w0, [x1, #WDT_COUNT]
mov w0, #4
str w0, [x1, #WDT_CTL]
b .
.pool