1e05e5de7SAlbert ARIBAUD/* 2e05e5de7SAlbert ARIBAUD * crt0 - C-runtime startup Code for ARM U-Boot 3e05e5de7SAlbert ARIBAUD * 4e05e5de7SAlbert ARIBAUD * Copyright (c) 2012 Albert ARIBAUD <albert.u.boot@aribaud.net> 5e05e5de7SAlbert ARIBAUD * 6e05e5de7SAlbert ARIBAUD * See file CREDITS for list of people who contributed to this 7e05e5de7SAlbert ARIBAUD * project. 8e05e5de7SAlbert ARIBAUD * 9e05e5de7SAlbert ARIBAUD * This program is free software; you can redistribute it and/or 10e05e5de7SAlbert ARIBAUD * modify it under the terms of the GNU General Public License as 11e05e5de7SAlbert ARIBAUD * published by the Free Software Foundation; either version 2 of 12e05e5de7SAlbert ARIBAUD * the License, or (at your option) any later version. 13e05e5de7SAlbert ARIBAUD * 14e05e5de7SAlbert ARIBAUD * This program is distributed in the hope that it will be useful, 15e05e5de7SAlbert ARIBAUD * but WITHOUT ANY WARRANTY; without even the implied warranty of 16e05e5de7SAlbert ARIBAUD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17e05e5de7SAlbert ARIBAUD * GNU General Public License for more details. 18e05e5de7SAlbert ARIBAUD * 19e05e5de7SAlbert ARIBAUD * You should have received a copy of the GNU General Public License 20e05e5de7SAlbert ARIBAUD * along with this program; if not, write to the Free Software 21e05e5de7SAlbert ARIBAUD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22e05e5de7SAlbert ARIBAUD * MA 02111-1307 USA 23e05e5de7SAlbert ARIBAUD */ 24e05e5de7SAlbert ARIBAUD 25e05e5de7SAlbert ARIBAUD#include <config.h> 26e05e5de7SAlbert ARIBAUD#include <asm-offsets.h> 279c5feab7SBenoît Thébaudeau#include <linux/linkage.h> 28e05e5de7SAlbert ARIBAUD 29e05e5de7SAlbert ARIBAUD/* 30e05e5de7SAlbert ARIBAUD * This file handles the target-independent stages of the U-Boot 31e05e5de7SAlbert ARIBAUD * start-up where a C runtime environment is needed. Its entry point 32e05e5de7SAlbert ARIBAUD * is _main and is branched into from the target's start.S file. 33e05e5de7SAlbert ARIBAUD * 34e05e5de7SAlbert ARIBAUD * _main execution sequence is: 35e05e5de7SAlbert ARIBAUD * 36e05e5de7SAlbert ARIBAUD * 1. Set up initial environment for calling board_init_f(). 37e05e5de7SAlbert ARIBAUD * This environment only provides a stack and a place to store 38e05e5de7SAlbert ARIBAUD * the GD ('global data') structure, both located in some readily 39e05e5de7SAlbert ARIBAUD * available RAM (SRAM, locked cache...). In this context, VARIABLE 40e05e5de7SAlbert ARIBAUD * global data, initialized or not (BSS), are UNAVAILABLE; only 41e05e5de7SAlbert ARIBAUD * CONSTANT initialized data are available. 42e05e5de7SAlbert ARIBAUD * 43e05e5de7SAlbert ARIBAUD * 2. Call board_init_f(). This function prepares the hardware for 44e05e5de7SAlbert ARIBAUD * execution from system RAM (DRAM, DDR...) As system RAM may not 45e05e5de7SAlbert ARIBAUD * be available yet, , board_init_f() must use the current GD to 46e05e5de7SAlbert ARIBAUD * store any data which must be passed on to later stages. These 47e05e5de7SAlbert ARIBAUD * data include the relocation destination, the future stack, and 48e05e5de7SAlbert ARIBAUD * the future GD location. 49e05e5de7SAlbert ARIBAUD * 50e05e5de7SAlbert ARIBAUD * (the following applies only to non-SPL builds) 51e05e5de7SAlbert ARIBAUD * 52e05e5de7SAlbert ARIBAUD * 3. Set up intermediate environment where the stack and GD are the 53e05e5de7SAlbert ARIBAUD * ones allocated by board_init_f() in system RAM, but BSS and 54e05e5de7SAlbert ARIBAUD * initialized non-const data are still not available. 55e05e5de7SAlbert ARIBAUD * 56e05e5de7SAlbert ARIBAUD * 4. Call relocate_code(). This function relocates U-Boot from its 57e05e5de7SAlbert ARIBAUD * current location into the relocation destination computed by 58e05e5de7SAlbert ARIBAUD * board_init_f(). 59e05e5de7SAlbert ARIBAUD * 60e05e5de7SAlbert ARIBAUD * 5. Set up final environment for calling board_init_r(). This 61e05e5de7SAlbert ARIBAUD * environment has BSS (initialized to 0), initialized non-const 62e05e5de7SAlbert ARIBAUD * data (initialized to their intended value), and stack in system 63e05e5de7SAlbert ARIBAUD * RAM. GD has retained values set by board_init_f(). Some CPUs 64e05e5de7SAlbert ARIBAUD * have some work left to do at this point regarding memory, so 65e05e5de7SAlbert ARIBAUD * call c_runtime_cpu_setup. 66e05e5de7SAlbert ARIBAUD * 67e05e5de7SAlbert ARIBAUD * 6. Branch to either nand_boot() or board_init_r(). 68e05e5de7SAlbert ARIBAUD */ 69e05e5de7SAlbert ARIBAUD 70e05e5de7SAlbert ARIBAUD/* 71e05e5de7SAlbert ARIBAUD * entry point of crt0 sequence 72e05e5de7SAlbert ARIBAUD */ 73e05e5de7SAlbert ARIBAUD 749c5feab7SBenoît ThébaudeauENTRY(_main) 75e05e5de7SAlbert ARIBAUD 76e05e5de7SAlbert ARIBAUD/* 77e05e5de7SAlbert ARIBAUD * Set up initial C runtime environment and call board_init_f(0). 78e05e5de7SAlbert ARIBAUD */ 79e05e5de7SAlbert ARIBAUD 80e05e5de7SAlbert ARIBAUD#if defined(CONFIG_NAND_SPL) 81e05e5de7SAlbert ARIBAUD /* deprecated, use instead CONFIG_SPL_BUILD */ 82e05e5de7SAlbert ARIBAUD ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) 83e05e5de7SAlbert ARIBAUD#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 84e05e5de7SAlbert ARIBAUD ldr sp, =(CONFIG_SPL_STACK) 85e05e5de7SAlbert ARIBAUD#else 86e05e5de7SAlbert ARIBAUD ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) 87e05e5de7SAlbert ARIBAUD#endif 88e05e5de7SAlbert ARIBAUD bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ 89e05e5de7SAlbert ARIBAUD sub sp, #GD_SIZE /* allocate one GD above SP */ 90e05e5de7SAlbert ARIBAUD bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ 91e05e5de7SAlbert ARIBAUD mov r8, sp /* GD is above SP */ 92e05e5de7SAlbert ARIBAUD mov r0, #0 93e05e5de7SAlbert ARIBAUD bl board_init_f 94e05e5de7SAlbert ARIBAUD 95e05e5de7SAlbert ARIBAUD#if ! defined(CONFIG_SPL_BUILD) 96e05e5de7SAlbert ARIBAUD 97e05e5de7SAlbert ARIBAUD/* 98e05e5de7SAlbert ARIBAUD * Set up intermediate environment (new sp and gd) and call 99*5c6db120SBenoît Thébaudeau * relocate_code(addr_moni). Trick here is that we'll return 100*5c6db120SBenoît Thébaudeau * 'here' but relocated. 101e05e5de7SAlbert ARIBAUD */ 102e05e5de7SAlbert ARIBAUD 103e05e5de7SAlbert ARIBAUD ldr sp, [r8, #GD_START_ADDR_SP] /* r8 = gd->start_addr_sp */ 104e05e5de7SAlbert ARIBAUD bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ 105e05e5de7SAlbert ARIBAUD ldr r8, [r8, #GD_BD] /* r8 = gd->bd */ 106e05e5de7SAlbert ARIBAUD sub r8, r8, #GD_SIZE /* new GD is below bd */ 107e05e5de7SAlbert ARIBAUD 108e05e5de7SAlbert ARIBAUD adr lr, here 109e05e5de7SAlbert ARIBAUD ldr r0, [r8, #GD_RELOC_OFF] /* lr = gd->start_addr_sp */ 110e05e5de7SAlbert ARIBAUD add lr, lr, r0 111*5c6db120SBenoît Thébaudeau ldr r0, [r8, #GD_RELOCADDR] /* r0 = gd->relocaddr */ 112e05e5de7SAlbert ARIBAUD b relocate_code 113e05e5de7SAlbert ARIBAUDhere: 114e05e5de7SAlbert ARIBAUD 115e05e5de7SAlbert ARIBAUD/* Set up final (full) environment */ 116e05e5de7SAlbert ARIBAUD 117e05e5de7SAlbert ARIBAUD bl c_runtime_cpu_setup /* we still call old routine here */ 118e05e5de7SAlbert ARIBAUD 119e05e5de7SAlbert ARIBAUD ldr r0, =__bss_start /* this is auto-relocated! */ 1203929fb0aSSimon Glass ldr r1, =__bss_end /* this is auto-relocated! */ 121e05e5de7SAlbert ARIBAUD 122e05e5de7SAlbert ARIBAUD mov r2, #0x00000000 /* prepare zero to clear BSS */ 123e05e5de7SAlbert ARIBAUD 124e05e5de7SAlbert ARIBAUDclbss_l:cmp r0, r1 /* while not at end of BSS */ 125e05e5de7SAlbert ARIBAUD strlo r2, [r0] /* clear 32-bit BSS word */ 126e05e5de7SAlbert ARIBAUD addlo r0, r0, #4 /* move to next */ 127e05e5de7SAlbert ARIBAUD blo clbss_l 128e05e5de7SAlbert ARIBAUD 129e05e5de7SAlbert ARIBAUD bl coloured_LED_init 130e05e5de7SAlbert ARIBAUD bl red_led_on 131e05e5de7SAlbert ARIBAUD 132e05e5de7SAlbert ARIBAUD#if defined(CONFIG_NAND_SPL) 133e05e5de7SAlbert ARIBAUD 134e05e5de7SAlbert ARIBAUD /* call _nand_boot() */ 135e05e5de7SAlbert ARIBAUD ldr pc, =nand_boot 136e05e5de7SAlbert ARIBAUD 137e05e5de7SAlbert ARIBAUD#else 138e05e5de7SAlbert ARIBAUD 139e05e5de7SAlbert ARIBAUD /* call board_init_r(gd_t *id, ulong dest_addr) */ 140e05e5de7SAlbert ARIBAUD mov r0, r8 /* gd_t */ 141e05e5de7SAlbert ARIBAUD ldr r1, [r8, #GD_RELOCADDR] /* dest_addr */ 142e05e5de7SAlbert ARIBAUD /* call board_init_r */ 143e05e5de7SAlbert ARIBAUD ldr pc, =board_init_r /* this is auto-relocated! */ 144e05e5de7SAlbert ARIBAUD 145e05e5de7SAlbert ARIBAUD#endif 146e05e5de7SAlbert ARIBAUD 147e05e5de7SAlbert ARIBAUD /* we should not return here. */ 148e05e5de7SAlbert ARIBAUD 149e05e5de7SAlbert ARIBAUD#endif 1509c5feab7SBenoît Thébaudeau 1519c5feab7SBenoît ThébaudeauENDPROC(_main) 152