diff options
Diffstat (limited to 'src/soc/marvell/armada38x/bootblock_asm.S')
-rw-r--r-- | src/soc/marvell/armada38x/bootblock_asm.S | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/soc/marvell/armada38x/bootblock_asm.S b/src/soc/marvell/armada38x/bootblock_asm.S new file mode 100644 index 0000000000..640c4ed91e --- /dev/null +++ b/src/soc/marvell/armada38x/bootblock_asm.S @@ -0,0 +1,123 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/asm.h> + +.arm + /* + * Just in case the maskrom or the vendor basic firmware passes on a + * parameter when calling the bootblock, store it here for handling by C + * code. + */ + .section .bss, "aw" @nobits + .global maskrom_param + .align 4 +maskrom_param: + .word 0 + +ENTRY(_start) + /* + * Set the cpu to System mode with IRQ and FIQ disabled. Prefetch/Data + * aborts may happen early and crash before the abort handlers are + * installed, but at least the problem will show up near the code that + * causes it. + */ + msr cpsr_cxf, #0xdf + bl _thumb_start +ENDPROC(_start) + +.thumb +ENTRY(_thumb_start) + + /* Preserve the maskrom passed value, if any */ + mov r10, r0 + + /* Disable L2 Cache */ + ldr r1, =0x0 + ldr r0, =0xD0008100 + str r1, [r0] + + /* Disable windows that overlap with 0xF1000000 */ + /* By default, window #12 overlaps with 0xF1000000 */ + mov r1, #0 + ldr r0, =0xD00200B0 + str r1, [r0] + /* Set Registers Base address. */ + ldr r1, =0xf1000000 + ldr r0, =0xD0020080 + str r1, [r0] + /* Update SCU (peripheral) register Base address with + * correct INTER_REG_BASE + */ + ldr r2, = 0xC000 /* SCU offset = 0xC000 */ + add r1, r1, r2 /* r1 = INTER_REG_BASE + SCU_OFFSET */ + mcr p15, 4, r1, c15, c0, 0 /* Write SCU base register */ + + bl arm_init_caches + + /* + * From Cortex-A Series Programmer's Guide: + * Only CPU 0 performs initialization. Other CPUs go into WFI + * to do this, first work out which CPU this is + * this code typically is run before any other initialization step + */ + mrc p15, 0, r1, c0, c0, 5 @ Read Multiprocessor Affinity Register + and r1, r1, #0x3 @ Extract CPU ID bits + cmp r1, #0 + bne wait_for_interrupt @ If this is not core0, wait + + /* + * Initialize the stack to a known value. This is used to check for + * stack overflow later in the boot process. + */ + ldr r0, =_stack + ldr r1, =_estack + ldr r2, =0xdeadbeef +init_stack_loop: + str r2, [r0] + add r0, #4 + cmp r0, r1 + bne init_stack_loop + + ldr r0, =_bss + ldr r1, =_ebss + mov r2, #0x00000000 /* prepare zero to clear BSS */ +clbss_l: + str r2, [r0] + add r0, #4 + cmp r0, r1 + bne clbss_l + +call_bootblock: + + /* Restore parameter passed in by maskrom/vendor firmware. */ + ldr r0, =maskrom_param + str r10, [r0] + + /* Set stackpointer in internal RAM to call bootblock main() */ + ldr sp, =_estack + ldr r0,=0x00000000 + /* + * The current design of cpu_info places the struct at the top of the + * stack. Free enough space to accommodate for that, but make sure it's + * 8-byte aligned for ABI compliance. + */ + sub sp, sp, #16 + bl main + +wait_for_interrupt: + wfi + mov pc, lr @ back to my caller +ENDPROC(_thumb_start) |