standalone.zig (1590B)
1 // Boot stub for standalone programs (directly on pi) 2 3 pub const standalone_asm = 4 \\ // Switch to Super mode and disable FIQ/IRQ 5 \\ mrs r0, cpsr 6 \\ and r0, r0, %[CLEAR_MODE_MASK] 7 \\ orr r0, r0, %[SUPER_MODE] 8 \\ orr r0, r0, %[CLEAR_MODE_IRQ_FIQ] 9 \\ msr cpsr, r0 10 \\ // Prefetch flush 11 \\ mov r0, #0 12 \\ mcr p15, 0, r0, c7, c5, 4 13 \\ // Clear BSS 14 \\ mov r0, #0 15 \\ ldr r1, bss_start 16 \\ ldr r2, bss_end 17 \\ subs r2, r2, r1 18 \\ beq L3 19 \\ L2: 20 \\ strb r0, [r1], #1 21 \\ subs r2, r2, #1 22 \\ bne L2 23 \\ L3: 24 \\ // Initialize SP 25 \\ ldr sp, stack_init 26 \\ and sp, sp, -16 27 \\ // Clear the frame pointer 28 \\ mov fp, #0 29 \\ // Boot 30 \\ bl %[kmain_fn:P] 31 \\ bl %[abort_fn:P] 32 \\ bss_start: .word __bss_start__ 33 \\ bss_end: .word __bss_end__ 34 \\ stack_init: .word 0x08000000 35 \\ 36 ; 37 38 pub const CLEAR_MODE_MASK: u32 = 0b11111; 39 pub const SUPER_MODE: u32 = 0b10011; 40 pub const CLEAR_MODE_IRQ_FIQ: u32 = (@as(u32, 1) << 7) | (@as(u32, 1) << 6); 41 42 pub fn make(comptime kmain: *const fn () callconv(.c) void, comptime abort: *const fn () callconv(.c) void) type { 43 return struct { 44 pub fn _start() linksection(".kmain") callconv(.naked) noreturn { 45 asm volatile (standalone_asm 46 : 47 : [CLEAR_MODE_MASK] "i" (CLEAR_MODE_MASK), 48 [SUPER_MODE] "i" (SUPER_MODE), 49 [CLEAR_MODE_IRQ_FIQ] "i" (CLEAR_MODE_IRQ_FIQ), 50 [kmain_fn] "X" (kmain), 51 [abort_fn] "X" (abort), 52 ); 53 } 54 }; 55 }