rt 0.19.1

A real-time operating system capable of full preemption
Documentation
// vim:ft=arm64asm

// Startup code for QEMU virt machine (Cortex-A53)

    .section .text.start, "ax", %progbits
    .global start
    .type start, %function
start:
    // Disable all interrupts (DAIF = Debug, Async, IRQ, FIQ).
    msr daifset, 0b1111

    // Set up the kernel stack (SP_EL1).
    // We start with SPSel=1 (using SP_EL1).
    adrp x0, __kernel_stack_end__
    add x0, x0, :lo12:__kernel_stack_end__
    mov sp, x0

    adrp x0, vector
    add x0, x0, :lo12:vector
    msr vbar_el1, x0
    isb

    bl init

    // Copy .data section from ROM to RAM.
    // Use callee-saved registers (x19/x20) for loop pointers since the
    // init_array loop calls functions that may clobber volatile registers.
    adrp x19, __copy_table__
    add x19, x19, :lo12:__copy_table__
    adrp x20, __copy_table_end__
    add x20, x20, :lo12:__copy_table_end__
    b 2f

0:  ldp x0, x1, [x19], 16   // x0 = dest, x1 = src
    ldr x2, [x19], 8        // x2 = size
    cbz x2, 2f              // skip if size is 0

1:  ldr x3, [x1], 8
    str x3, [x0], 8
    subs x2, x2, 8
    b.ne 1b

2:  cmp x19, x20
    b.ne 0b

    // Zero .bss section.
    adrp x19, __zero_table__
    add x19, x19, :lo12:__zero_table__
    adrp x20, __zero_table_end__
    add x20, x20, :lo12:__zero_table_end__
    b 2f

0:  ldp x0, x1, [x19], 16   // x0 = start, x1 = size
    cbz x1, 2f              // skip if size is 0

1:  str xzr, [x0], 8
    subs x1, x1, 8
    b.ne 1b

2:  cmp x19, x20
    b.ne 0b

    // Call C++ constructors / init_array.
    adrp x19, __init_array__
    add x19, x19, :lo12:__init_array__
    adrp x20, __init_array_end__
    add x20, x20, :lo12:__init_array_end__
    b 1f

0:  ldr x0, [x19], 8
    blr x0

1:  cmp x19, x20
    b.ne 0b

    b rt_start

    .size start, .-start