Files
tinyUSB/hw/mcu/broadcom/bcm2711/boot.s
2021-09-22 15:19:02 -07:00

173 lines
4.1 KiB
ArmAsm

.section ".text.boot" // Make sure the linker puts this at the start of the kernel image
.global _start // Execution starts here
_start:
// Check processor ID is zero (executing on main core), else hang
mrs x1, mpidr_el1
and x1, x1, #3
cbz x1, 2f
// We're not on the main core, so hang in an infinite wait loop
1: wfe
b 1b
2: // We're on the main core!
// Set stack to start below our code
ldr x1, =_start
mov sp, x1
adr x0, vectors // load VBAR_EL1 with virtual
// msr vbar_el3, x0 // vector table address
msr vbar_el1, x0 // vector table address
msr vbar_el2, x0 // vector table address
isb
// Clean the BSS section
ldr x1, =__bss_start // Start address
ldr w2, =__bss_size // Size of the section
3: cbz w2, 4f // Quit loop if zero
str xzr, [x1], #8
sub w2, w2, #1
cbnz w2, 3b // Loop if non-zero
// Jump to our main() routine in C (make sure it doesn't return)
4: bl main
// In case it does return, halt the master core too
b 1b
.macro ventry label
.align 7
b \label
.endm
.macro handle_invalid_entry type
irq_entry
mov x0, #\type
mrs x1, esr_el1
mrs x2, elr_el1
mrs x3, esr_el2
mrs x4, elr_el2
b err_hang
.endm
.macro irq_entry
sub sp, sp, #272
stp x0, x1, [sp, #16 * 0]
stp x2, x3, [sp, #16 * 1]
stp x4, x5, [sp, #16 * 2]
stp x6, x7, [sp, #16 * 3]
stp x8, x9, [sp, #16 * 4]
stp x10, x11, [sp, #16 * 5]
stp x12, x13, [sp, #16 * 6]
stp x14, x15, [sp, #16 * 7]
stp x16, x17, [sp, #16 * 8]
stp x18, x19, [sp, #16 * 9]
stp x20, x21, [sp, #16 * 10]
stp x22, x23, [sp, #16 * 11]
stp x24, x25, [sp, #16 * 12]
stp x26, x27, [sp, #16 * 13]
stp x28, x29, [sp, #16 * 14]
str x30, [sp, #16 * 15]
.endm
.macro irq_exit
ldp x0, x1, [sp, #16 * 0]
ldp x2, x3, [sp, #16 * 1]
ldp x4, x5, [sp, #16 * 2]
ldp x6, x7, [sp, #16 * 3]
ldp x8, x9, [sp, #16 * 4]
ldp x10, x11, [sp, #16 * 5]
ldp x12, x13, [sp, #16 * 6]
ldp x14, x15, [sp, #16 * 7]
ldp x16, x17, [sp, #16 * 8]
ldp x18, x19, [sp, #16 * 9]
ldp x20, x21, [sp, #16 * 10]
ldp x22, x23, [sp, #16 * 11]
ldp x24, x25, [sp, #16 * 12]
ldp x26, x27, [sp, #16 * 13]
ldp x28, x29, [sp, #16 * 14]
ldr x30, [sp, #16 * 15]
add sp, sp, #272
eret
.endm
/*
* Exception vectors.
*/
.align 11
.globl vectors
vectors:
ventry sync_invalid_el1t // Synchronous EL1t
ventry irq_invalid_el1t // IRQ EL1t
ventry fiq_invalid_el1t // FIQ EL1t
ventry error_invalid_el1t // Error EL1t
ventry sync_invalid_el1h // Synchronous EL1h
ventry el1_irq // IRQ EL1h
ventry fiq_invalid_el1h // FIQ EL1h
ventry error_invalid_el1h // Error EL1h
ventry sync_invalid_el0_64 // Synchronous 64-bit EL0
ventry irq_invalid_el0_64 // IRQ 64-bit EL0
ventry fiq_invalid_el0_64 // FIQ 64-bit EL0
ventry error_invalid_el0_64 // Error 64-bit EL0
ventry sync_invalid_el0_32 // Synchronous 32-bit EL0
ventry irq_invalid_el0_32 // IRQ 32-bit EL0
ventry fiq_invalid_el0_32 // FIQ 32-bit EL0
ventry error_invalid_el0_32 // Error 32-bit EL0
sync_invalid_el1t:
handle_invalid_entry 0
irq_invalid_el1t:
handle_invalid_entry 1
fiq_invalid_el1t:
handle_invalid_entry 2
error_invalid_el1t:
handle_invalid_entry 3
sync_invalid_el1h:
handle_invalid_entry 4
fiq_invalid_el1h:
handle_invalid_entry 5
error_invalid_el1h:
handle_invalid_entry 6
sync_invalid_el0_64:
handle_invalid_entry 7
irq_invalid_el0_64:
handle_invalid_entry 8
fiq_invalid_el0_64:
handle_invalid_entry 9
error_invalid_el0_64:
handle_invalid_entry 10
sync_invalid_el0_32:
handle_invalid_entry 11
irq_invalid_el0_32:
handle_invalid_entry 12
fiq_invalid_el0_32:
handle_invalid_entry 13
error_invalid_el0_32:
handle_invalid_entry 14
el1_irq:
irq_entry
bl handle_irq
irq_exit
.globl err_hang
err_hang: b err_hang