hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 *  crt0 - C-runtime startup Code for ARM U-Boot
 *
 *  Copyright (c) 2012  Albert ARIBAUD <albert.u.boot@aribaud.net>
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
#include <config.h>
#include <asm-offsets.h>
#include <linux/linkage.h>
#ifdef CONFIG_CPU_V7M
#include <asm/armv7m.h>
#endif
 
/*
 * This file handles the target-independent stages of the U-Boot
 * start-up where a C runtime environment is needed. Its entry point
 * is _main and is branched into from the target's start.S file.
 *
 * _main execution sequence is:
 *
 * 1. Set up initial environment for calling board_init_f().
 *    This environment only provides a stack and a place to store
 *    the GD ('global data') structure, both located in some readily
 *    available RAM (SRAM, locked cache...). In this context, VARIABLE
 *    global data, initialized or not (BSS), are UNAVAILABLE; only
 *    CONSTANT initialized data are available. GD should be zeroed
 *    before board_init_f() is called.
 *
 * 2. Call board_init_f(). This function prepares the hardware for
 *    execution from system RAM (DRAM, DDR...) As system RAM may not
 *    be available yet, , board_init_f() must use the current GD to
 *    store any data which must be passed on to later stages. These
 *    data include the relocation destination, the future stack, and
 *    the future GD location.
 *
 * 3. Set up intermediate environment where the stack and GD are the
 *    ones allocated by board_init_f() in system RAM, but BSS and
 *    initialized non-const data are still not available.
 *
 * 4a.For U-Boot proper (not SPL), call relocate_code(). This function
 *    relocates U-Boot from its current location into the relocation
 *    destination computed by board_init_f().
 *
 * 4b.For SPL, board_init_f() just returns (to crt0). There is no
 *    code relocation in SPL.
 *
 * 5. Set up final environment for calling board_init_r(). This
 *    environment has BSS (initialized to 0), initialized non-const
 *    data (initialized to their intended value), and stack in system
 *    RAM (for SPL moving the stack and GD into RAM is optional - see
 *    CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
 *
 * 6. For U-Boot proper (not SPL), some CPUs have some work left to do
 *    at this point regarding memory, so call c_runtime_cpu_setup.
 *
 * 7. Branch to board_init_r().
 *
 * For more information see 'Board Initialisation Flow in README.
 */
 
/*
 * entry point of crt0 sequence
 */
 
ENTRY(_main)
 
/*
 * Set up initial C runtime environment and call board_init_f(0).
 */
 
#if defined(CONFIG_TPL_BUILD) && defined(CONFIG_TPL_NEEDS_SEPARATE_STACK)
   ldr    r0, =(CONFIG_TPL_STACK)
#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
   ldr    r0, =(CONFIG_SPL_STACK)
#else
   ldr    r0, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
   bic    r0, r0, #7    /* 8-byte alignment for ABI compliance */
   mov    sp, r0
   bl    board_init_f_alloc_reserve
   mov    sp, r0
   /* set up gd here, outside any C code */
   mov    r9, r0
   bl    board_init_f_init_reserve
   bl    board_init_f_boot_flags
 
   bl    board_init_f
 
#if ! defined(CONFIG_SPL_BUILD)
 
/*
 * Set up intermediate environment (new sp and gd) and call
 * relocate_code(addr_moni). Trick here is that we'll return
 * 'here' but relocated.
 */
 
   ldr    r0, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp */
   bic    r0, r0, #7    /* 8-byte alignment for ABI compliance */
   mov    sp, r0
   ldr    r9, [r9, #GD_BD]        /* r9 = gd->bd */
   sub    r9, r9, #GD_SIZE        /* new GD is below bd */
 
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
   adr    lr, here
   ldr    r0, [r9, #GD_RELOC_OFF]        /* r0 = gd->reloc_off */
   add    lr, lr, r0
#if defined(CONFIG_CPU_V7M)
   orr    lr, #1                /* As required by Thumb-only */
#endif
   ldr    r0, [r9, #GD_RELOCADDR]        /* r0 = gd->relocaddr */
   b    relocate_code
#endif
here:
 
/*
 * The "relocate_vectors" is in section: .text.relocate_vectors, if we don't
 * compile "bl    relocate_vectors", there seems something wrong about sections
 * layout(U-Boot code section is quite large, I don't find root cause now),
 * so let's just skip it.
 */
#ifdef CONFIG_SKIP_RELOCATE_UBOOT
   b    c_runtime
#endif
 
/*
 * now relocate vectors
 */
   bl    relocate_vectors
 
c_runtime:
/* Set up final (full) environment */
 
   bl    c_runtime_cpu_setup    /* we still call old routine here */
#endif
#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FRAMEWORK) && !defined(CONFIG_TPL_BUILD))
# ifdef CONFIG_SPL_BUILD
   /* Use a DRAM stack for the rest of SPL, if requested */
   bl    spl_relocate_stack_gd
   cmp    r0, #0
   movne    sp, r0
   movne    r9, r0
# endif
   ldr    r0, =__bss_start    /* this is auto-relocated! */
 
#ifdef CONFIG_USE_ARCH_MEMSET
   ldr    r3, =__bss_end        /* this is auto-relocated! */
   mov    r1, #0x00000000        /* prepare zero to clear BSS */
 
   subs    r2, r3, r0        /* r2 = memset len */
   bl    memset
#else
   ldr    r1, =__bss_end        /* this is auto-relocated! */
   mov    r2, #0x00000000        /* prepare zero to clear BSS */
 
clbss_l:cmp    r0, r1            /* while not at end of BSS */
#if defined(CONFIG_CPU_V7M)
   itt    lo
#endif
   strlo    r2, [r0]        /* clear 32-bit BSS word */
   addlo    r0, r0, #4        /* move to next */
   blo    clbss_l
#endif
 
#if ! defined(CONFIG_SPL_BUILD)
   bl coloured_LED_init
   bl red_led_on
#endif
   /* call board_init_r(gd_t *id, ulong dest_addr) */
   mov     r0, r9                  /* gd_t */
   ldr    r1, [r9, #GD_RELOCADDR]    /* dest_addr */
   /* call board_init_r */
#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
   ldr    lr, =board_init_r    /* this is auto-relocated! */
   bx    lr
#else
   ldr    pc, =board_init_r    /* this is auto-relocated! */
#endif
   /* we should not return here. */
#endif
 
ENDPROC(_main)