]>
Commit | Line | Data |
---|---|---|
e05e5de7 AA |
1 | /* |
2 | * crt0 - C-runtime startup Code for ARM U-Boot | |
3 | * | |
4 | * Copyright (c) 2012 Albert ARIBAUD <[email protected]> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
e05e5de7 AA |
7 | */ |
8 | ||
9 | #include <config.h> | |
10 | #include <asm-offsets.h> | |
9c5feab7 | 11 | #include <linux/linkage.h> |
e05e5de7 AA |
12 | |
13 | /* | |
14 | * This file handles the target-independent stages of the U-Boot | |
15 | * start-up where a C runtime environment is needed. Its entry point | |
16 | * is _main and is branched into from the target's start.S file. | |
17 | * | |
18 | * _main execution sequence is: | |
19 | * | |
20 | * 1. Set up initial environment for calling board_init_f(). | |
21 | * This environment only provides a stack and a place to store | |
22 | * the GD ('global data') structure, both located in some readily | |
23 | * available RAM (SRAM, locked cache...). In this context, VARIABLE | |
24 | * global data, initialized or not (BSS), are UNAVAILABLE; only | |
25 | * CONSTANT initialized data are available. | |
26 | * | |
27 | * 2. Call board_init_f(). This function prepares the hardware for | |
28 | * execution from system RAM (DRAM, DDR...) As system RAM may not | |
29 | * be available yet, , board_init_f() must use the current GD to | |
30 | * store any data which must be passed on to later stages. These | |
31 | * data include the relocation destination, the future stack, and | |
32 | * the future GD location. | |
33 | * | |
34 | * (the following applies only to non-SPL builds) | |
35 | * | |
36 | * 3. Set up intermediate environment where the stack and GD are the | |
37 | * ones allocated by board_init_f() in system RAM, but BSS and | |
38 | * initialized non-const data are still not available. | |
39 | * | |
40 | * 4. Call relocate_code(). This function relocates U-Boot from its | |
41 | * current location into the relocation destination computed by | |
42 | * board_init_f(). | |
43 | * | |
44 | * 5. Set up final environment for calling board_init_r(). This | |
45 | * environment has BSS (initialized to 0), initialized non-const | |
46 | * data (initialized to their intended value), and stack in system | |
47 | * RAM. GD has retained values set by board_init_f(). Some CPUs | |
48 | * have some work left to do at this point regarding memory, so | |
49 | * call c_runtime_cpu_setup. | |
50 | * | |
66f30bf9 | 51 | * 6. Branch to board_init_r(). |
e05e5de7 AA |
52 | */ |
53 | ||
e05e5de7 AA |
54 | /* |
55 | * entry point of crt0 sequence | |
56 | */ | |
57 | ||
9c5feab7 | 58 | ENTRY(_main) |
e05e5de7 AA |
59 | |
60 | /* | |
61 | * Set up initial C runtime environment and call board_init_f(0). | |
62 | */ | |
63 | ||
66f30bf9 | 64 | #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) |
e05e5de7 AA |
65 | ldr sp, =(CONFIG_SPL_STACK) |
66 | #else | |
67 | ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) | |
68 | #endif | |
69 | bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ | |
aae2aef9 | 70 | mov r2, sp |
6ba2bc8f | 71 | sub sp, sp, #GD_SIZE /* allocate one GD above SP */ |
e05e5de7 | 72 | bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ |
fe1378a9 | 73 | mov r9, sp /* GD is above SP */ |
aae2aef9 | 74 | mov r1, sp |
e05e5de7 | 75 | mov r0, #0 |
aae2aef9 SG |
76 | clr_gd: |
77 | cmp r1, r2 /* while not at end of GD */ | |
78 | strlo r0, [r1] /* clear 32-bit GD word */ | |
79 | addlo r1, r1, #4 /* move to next */ | |
80 | blo clr_gd | |
76a1e584 SG |
81 | #if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD) |
82 | sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN | |
83 | str sp, [r9, #GD_MALLOC_BASE] | |
84 | #endif | |
aae2aef9 | 85 | /* mov r0, #0 not needed due to above code */ |
e05e5de7 AA |
86 | bl board_init_f |
87 | ||
88 | #if ! defined(CONFIG_SPL_BUILD) | |
89 | ||
90 | /* | |
91 | * Set up intermediate environment (new sp and gd) and call | |
5c6db120 BT |
92 | * relocate_code(addr_moni). Trick here is that we'll return |
93 | * 'here' but relocated. | |
e05e5de7 AA |
94 | */ |
95 | ||
fe1378a9 | 96 | ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ |
e05e5de7 | 97 | bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ |
fe1378a9 JH |
98 | ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ |
99 | sub r9, r9, #GD_SIZE /* new GD is below bd */ | |
e05e5de7 AA |
100 | |
101 | adr lr, here | |
fe1378a9 | 102 | ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ |
e05e5de7 | 103 | add lr, lr, r0 |
fe1378a9 | 104 | ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ |
e05e5de7 AA |
105 | b relocate_code |
106 | here: | |
107 | ||
108 | /* Set up final (full) environment */ | |
109 | ||
110 | bl c_runtime_cpu_setup /* we still call old routine here */ | |
111 | ||
112 | ldr r0, =__bss_start /* this is auto-relocated! */ | |
3929fb0a | 113 | ldr r1, =__bss_end /* this is auto-relocated! */ |
e05e5de7 AA |
114 | |
115 | mov r2, #0x00000000 /* prepare zero to clear BSS */ | |
116 | ||
117 | clbss_l:cmp r0, r1 /* while not at end of BSS */ | |
118 | strlo r2, [r0] /* clear 32-bit BSS word */ | |
119 | addlo r0, r0, #4 /* move to next */ | |
120 | blo clbss_l | |
121 | ||
122 | bl coloured_LED_init | |
123 | bl red_led_on | |
124 | ||
e05e5de7 | 125 | /* call board_init_r(gd_t *id, ulong dest_addr) */ |
fe1378a9 JH |
126 | mov r0, r9 /* gd_t */ |
127 | ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */ | |
e05e5de7 AA |
128 | /* call board_init_r */ |
129 | ldr pc, =board_init_r /* this is auto-relocated! */ | |
130 | ||
e05e5de7 AA |
131 | /* we should not return here. */ |
132 | ||
133 | #endif | |
9c5feab7 BT |
134 | |
135 | ENDPROC(_main) |