]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/nios2/cpu/start.S
Merge branch 'master' of git://git.denx.de/u-boot-x86
[people/ms/u-boot.git] / arch / nios2 / cpu / start.S
CommitLineData
5c952cf0
WD
1/*
2 * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
3 * Scott McNutt <smcnutt@psyent.com>
4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
5c952cf0
WD
6 */
7
25ddd1fb 8#include <asm-offsets.h>
5c952cf0
WD
9#include <config.h>
10#include <version.h>
11
55e2b4d4
TC
12/*
13 * icache and dcache configuration used only for start.S.
14 * the values are chosen so that it will work for all configuration.
15 */
16#define ICACHE_LINE_SIZE 32 /* fixed 32 */
17#define ICACHE_SIZE_MAX 0x10000 /* 64k max */
18#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */
19#define DCACHE_SIZE_MAX 0x10000 /* 64k max */
20
4a572fa8 21 /* RESTART */
5c952cf0 22 .text
b8112091 23 .global _start, _except_start, _except_end
5c952cf0
WD
24
25_start:
fd2712d0 26 wrctl status, r0 /* Disable interrupts */
4a572fa8
TC
27 /*
28 * ICACHE INIT -- only the icache line at the reset address
5c952cf0
WD
29 * is invalidated at reset. So the init must stay within
30 * the cache line size (8 words). If GERMS is used, we'll
31 * just be invalidating the cache a second time. If cache
32 * is not implemented initi behaves as nop.
33 */
55e2b4d4
TC
34 ori r4, r0, %lo(ICACHE_LINE_SIZE)
35 movhi r5, %hi(ICACHE_SIZE_MAX)
36 ori r5, r5, %lo(ICACHE_SIZE_MAX)
fd2712d0
TC
370: initi r5
38 sub r5, r5, r4
39 bgt r5, r0, 0b
0c1c117c
WD
40 br _except_end /* Skip the tramp */
41
4a572fa8
TC
42 /*
43 * EXCEPTION TRAMPOLINE -- the following gets copied
0c1c117c
WD
44 * to the exception address (below), but is otherwise at the
45 * default exception vector offset (0x0020).
46 */
47_except_start:
48 movhi et, %hi(_exception)
49 ori et, et, %lo(_exception)
50 jmp et
51_except_end:
5c952cf0 52
4a572fa8
TC
53 /*
54 * INTERRUPTS -- for now, all interrupts masked and globally
5c952cf0
WD
55 * disabled.
56 */
5c952cf0
WD
57 wrctl ienable, r0 /* All disabled */
58
4a572fa8
TC
59 /*
60 * DCACHE INIT -- if dcache not implemented, initd behaves as
5c952cf0
WD
61 * nop.
62 */
55e2b4d4
TC
63 ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
64 movhi r5, %hi(DCACHE_SIZE_MAX)
65 ori r5, r5, %lo(DCACHE_SIZE_MAX)
5c952cf0
WD
66 mov r6, r0
671: initd 0(r6)
68 add r6, r6, r4
69 bltu r6, r5, 1b
70
4a572fa8
TC
71 /*
72 * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
5c952cf0
WD
73 * assumes code, data and the command table are all
74 * contiguous. This lets us relocate everything as a single
75 * block. Make sure the linker script matches this ;-)
76 */
77 nextpc r4
78_cur: movhi r5, %hi(_cur - _start)
79 ori r5, r5, %lo(_cur - _start)
80 sub r4, r4, r5 /* r4 <- cur _start */
81 mov r8, r4
82 movhi r5, %hi(_start)
83 ori r5, r5, %lo(_start) /* r5 <- linked _start */
65af9f69 84 mov sp, r5 /* initial stack below u-boot code */
5c952cf0
WD
85 beq r4, r5, 3f
86
e900298e
TC
87 movhi r6, %hi(CONFIG_SYS_MONITOR_LEN)
88 ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
89 add r6, r6, r5
5c952cf0
WD
902: ldwio r7, 0(r4)
91 addi r4, r4, 4
92 stwio r7, 0(r5)
93 addi r5, r5, 4
94 bne r5, r6, 2b
953:
96
5c952cf0
WD
97 /* JUMP TO RELOC ADDR */
98 movhi r4, %hi(_reloc)
99 ori r4, r4, %lo(_reloc)
100 jmp r4
101_reloc:
102
4a572fa8 103 /* STACK INIT -- zero top two words for call back chain. */
5c952cf0
WD
104 addi sp, sp, -8
105 stw r0, 0(sp)
106 stw r0, 4(sp)
107 mov fp, sp
108
ecc30663 109 /* Allocate and initialize reserved area, update SP */
3e468e68 110 mov r4, sp
ecc30663
AA
111 movhi r2, %hi(board_init_f_alloc_reserve@h)
112 ori r2, r2, %lo(board_init_f_alloc_reserve@h)
3e468e68 113 callr r2
3e468e68 114 mov sp, r2
ecc30663
AA
115 mov r4, sp
116 movhi r2, %hi(board_init_f_init_reserve@h)
117 ori r2, r2, %lo(board_init_f_init_reserve@h)
118 callr r2
119
120 /* Update frame-pointer */
3e468e68
TC
121 mov fp, sp
122
4a572fa8 123 /* Call board_init_f -- never returns */
5ff10aa7
TC
124 mov r4, r0
125 movhi r2, %hi(board_init_f@h)
126 ori r2, r2, %lo(board_init_f@h)
127 callr r2
5c952cf0 128
4a572fa8
TC
129 /*
130 * NEVER RETURNS -- but branch to the _start just
5c952cf0
WD
131 * in case ;-)
132 */
133 br _start
134
4a572fa8
TC
135 /*
136 * relocate_code -- Nios2 handles the relocation above. But
137 * the generic board code monkeys with the heap, stack, etc.
138 * (it makes some assumptions that may not be appropriate
139 * for Nios). Nevertheless, we capitulate here.
140 *
141 * We'll call the board_init_r from here since this isn't
142 * supposed to return.
143 *
144 * void relocate_code (ulong sp, gd_t *global_data,
145 * ulong reloc_addr)
146 * __attribute__ ((noreturn));
147 */
5ff10aa7
TC
148 .text
149 .global relocate_code
150
151relocate_code:
152 mov sp, r4 /* Set the new sp */
153 mov r4, r5
4192b8c3
TC
154
155 /*
156 * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent
157 * and between __bss_start and __bss_end.
158 */
159 movhi r5, %hi(__bss_start)
160 ori r5, r5, %lo(__bss_start)
161 movhi r6, %hi(__bss_end)
162 ori r6, r6, %lo(__bss_end)
163 beq r5, r6, 5f
164
9208d7eb 1654: stw r0, 0(r5)
4192b8c3
TC
166 addi r5, r5, 4
167 bne r5, r6, 4b
1685:
169
5ff10aa7
TC
170 movhi r8, %hi(board_init_r@h)
171 ori r8, r8, %lo(board_init_r@h)
172 callr r8
173 ret