blob: f5ad184e8d0bd53bf579f1e6ab0a874c8d3659b5 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
wdenk5c952cf2004-10-10 21:27:30 +00002/*
3 * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
4 * Scott McNutt <smcnutt@psyent.com>
wdenk5c952cf2004-10-10 21:27:30 +00005 */
6
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +02007#include <asm-offsets.h>
wdenk5c952cf2004-10-10 21:27:30 +00008#include <config.h>
9#include <version.h>
10
Thomas Chou55e2b4d2015-10-09 20:09:17 +080011/*
12 * icache and dcache configuration used only for start.S.
13 * the values are chosen so that it will work for all configuration.
14 */
15#define ICACHE_LINE_SIZE 32 /* fixed 32 */
16#define ICACHE_SIZE_MAX 0x10000 /* 64k max */
17#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */
18#define DCACHE_SIZE_MAX 0x10000 /* 64k max */
19
Thomas Chou4a572fa2015-10-06 10:12:59 +080020 /* RESTART */
wdenk5c952cf2004-10-10 21:27:30 +000021 .text
Thomas Choub8112092015-10-06 14:09:19 +080022 .global _start, _except_start, _except_end
wdenk5c952cf2004-10-10 21:27:30 +000023
24_start:
Thomas Choufd2712d2010-04-20 11:01:11 +080025 wrctl status, r0 /* Disable interrupts */
Thomas Chou4a572fa2015-10-06 10:12:59 +080026 /*
27 * ICACHE INIT -- only the icache line at the reset address
wdenk5c952cf2004-10-10 21:27:30 +000028 * is invalidated at reset. So the init must stay within
29 * the cache line size (8 words). If GERMS is used, we'll
30 * just be invalidating the cache a second time. If cache
31 * is not implemented initi behaves as nop.
32 */
Thomas Chou55e2b4d2015-10-09 20:09:17 +080033 ori r4, r0, %lo(ICACHE_LINE_SIZE)
34 movhi r5, %hi(ICACHE_SIZE_MAX)
35 ori r5, r5, %lo(ICACHE_SIZE_MAX)
Thomas Choufd2712d2010-04-20 11:01:11 +0800360: initi r5
37 sub r5, r5, r4
38 bgt r5, r0, 0b
wdenk0c1c117c2005-03-30 23:28:18 +000039 br _except_end /* Skip the tramp */
40
Thomas Chou4a572fa2015-10-06 10:12:59 +080041 /*
42 * EXCEPTION TRAMPOLINE -- the following gets copied
wdenk0c1c117c2005-03-30 23:28:18 +000043 * to the exception address (below), but is otherwise at the
44 * default exception vector offset (0x0020).
45 */
46_except_start:
47 movhi et, %hi(_exception)
48 ori et, et, %lo(_exception)
49 jmp et
50_except_end:
wdenk5c952cf2004-10-10 21:27:30 +000051
Thomas Chou4a572fa2015-10-06 10:12:59 +080052 /*
53 * INTERRUPTS -- for now, all interrupts masked and globally
wdenk5c952cf2004-10-10 21:27:30 +000054 * disabled.
55 */
wdenk5c952cf2004-10-10 21:27:30 +000056 wrctl ienable, r0 /* All disabled */
57
Thomas Chou4a572fa2015-10-06 10:12:59 +080058 /*
59 * DCACHE INIT -- if dcache not implemented, initd behaves as
wdenk5c952cf2004-10-10 21:27:30 +000060 * nop.
61 */
Thomas Chou55e2b4d2015-10-09 20:09:17 +080062 ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
63 movhi r5, %hi(DCACHE_SIZE_MAX)
64 ori r5, r5, %lo(DCACHE_SIZE_MAX)
wdenk5c952cf2004-10-10 21:27:30 +000065 mov r6, r0
661: initd 0(r6)
67 add r6, r6, r4
68 bltu r6, r5, 1b
69
Thomas Chou4a572fa2015-10-06 10:12:59 +080070 /*
71 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
wdenk5c952cf2004-10-10 21:27:30 +000072 * assumes code, data and the command table are all
73 * contiguous. This lets us relocate everything as a single
74 * block. Make sure the linker script matches this ;-)
75 */
76 nextpc r4
77_cur: movhi r5, %hi(_cur - _start)
78 ori r5, r5, %lo(_cur - _start)
79 sub r4, r4, r5 /* r4 <- cur _start */
80 mov r8, r4
81 movhi r5, %hi(_start)
82 ori r5, r5, %lo(_start) /* r5 <- linked _start */
Thomas Chou65af9f62015-11-03 13:47:02 +080083 mov sp, r5 /* initial stack below u-boot code */
wdenk5c952cf2004-10-10 21:27:30 +000084 beq r4, r5, 3f
85
Thomas Choue9002982015-09-04 16:39:16 +080086 movhi r6, %hi(CONFIG_SYS_MONITOR_LEN)
87 ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
88 add r6, r6, r5
wdenk5c952cf2004-10-10 21:27:30 +0000892: ldwio r7, 0(r4)
90 addi r4, r4, 4
91 stwio r7, 0(r5)
92 addi r5, r5, 4
93 bne r5, r6, 2b
943:
95
wdenk5c952cf2004-10-10 21:27:30 +000096 /* JUMP TO RELOC ADDR */
97 movhi r4, %hi(_reloc)
98 ori r4, r4, %lo(_reloc)
99 jmp r4
100_reloc:
101
Thomas Chou4a572fa2015-10-06 10:12:59 +0800102 /* STACK INIT -- zero top two words for call back chain. */
wdenk5c952cf2004-10-10 21:27:30 +0000103 addi sp, sp, -8
104 stw r0, 0(sp)
105 stw r0, 4(sp)
106 mov fp, sp
107
Thomas Choue4f348b2015-12-30 20:29:18 +0800108#ifdef CONFIG_DEBUG_UART
109 /* Set up the debug UART */
110 movhi r2, %hi(debug_uart_init@h)
111 ori r2, r2, %lo(debug_uart_init@h)
112 callr r2
113#endif
114
Albert ARIBAUDecc30662015-11-25 17:56:32 +0100115 /* Allocate and initialize reserved area, update SP */
Thomas Chou3e468e62015-09-09 15:09:43 +0800116 mov r4, sp
Albert ARIBAUDecc30662015-11-25 17:56:32 +0100117 movhi r2, %hi(board_init_f_alloc_reserve@h)
118 ori r2, r2, %lo(board_init_f_alloc_reserve@h)
119 callr r2
120 mov sp, r2
121 mov r4, sp
122 movhi r2, %hi(board_init_f_init_reserve@h)
123 ori r2, r2, %lo(board_init_f_init_reserve@h)
Thomas Chou3e468e62015-09-09 15:09:43 +0800124 callr r2
125
Albert ARIBAUDecc30662015-11-25 17:56:32 +0100126 /* Update frame-pointer */
Thomas Chou3e468e62015-09-09 15:09:43 +0800127 mov fp, sp
128
Thomas Chou4a572fa2015-10-06 10:12:59 +0800129 /* Call board_init_f -- never returns */
Thomas Chou5ff10aa2014-08-22 11:36:47 +0800130 mov r4, r0
131 movhi r2, %hi(board_init_f@h)
132 ori r2, r2, %lo(board_init_f@h)
133 callr r2
wdenk5c952cf2004-10-10 21:27:30 +0000134
Thomas Chou4a572fa2015-10-06 10:12:59 +0800135 /*
136 * NEVER RETURNS -- but branch to the _start just
wdenk5c952cf2004-10-10 21:27:30 +0000137 * in case ;-)
138 */
139 br _start
140
Thomas Chou4a572fa2015-10-06 10:12:59 +0800141 /*
142 * relocate_code -- Nios2 handles the relocation above. But
143 * the generic board code monkeys with the heap, stack, etc.
144 * (it makes some assumptions that may not be appropriate
145 * for Nios). Nevertheless, we capitulate here.
146 *
147 * We'll call the board_init_r from here since this isn't
148 * supposed to return.
149 *
Simon Glass94133872019-12-28 10:44:45 -0700150 * void relocate_code(ulong sp, gd_t *global_data,
Thomas Chou4a572fa2015-10-06 10:12:59 +0800151 * ulong reloc_addr)
152 * __attribute__ ((noreturn));
153 */
Thomas Chou5ff10aa2014-08-22 11:36:47 +0800154 .text
155 .global relocate_code
156
157relocate_code:
158 mov sp, r4 /* Set the new sp */
159 mov r4, r5
Thomas Chou4192b8c2015-09-07 08:57:14 +0800160
161 /*
162 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
163 * and between __bss_start and __bss_end.
164 */
165 movhi r5, %hi(__bss_start)
166 ori r5, r5, %lo(__bss_start)
167 movhi r6, %hi(__bss_end)
168 ori r6, r6, %lo(__bss_end)
169 beq r5, r6, 5f
170
Thomas Chou9208d7e2015-11-03 13:52:15 +08001714: stw r0, 0(r5)
Thomas Chou4192b8c2015-09-07 08:57:14 +0800172 addi r5, r5, 4
173 bne r5, r6, 4b
1745:
175
Thomas Chou5ff10aa2014-08-22 11:36:47 +0800176 movhi r8, %hi(board_init_r@h)
177 ori r8, r8, %lo(board_init_r@h)
178 callr r8
179 ret