]> git.sur5r.net Git - u-boot/blob - arch/nios2/cpu/start.S
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / arch / nios2 / cpu / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
4  * Scott McNutt <smcnutt@psyent.com>
5  */
6
7 #include <asm-offsets.h>
8 #include <config.h>
9 #include <version.h>
10
11 /*
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
20         /* RESTART */
21         .text
22         .global _start, _except_start, _except_end
23
24 _start:
25         wrctl   status, r0              /* Disable interrupts */
26         /*
27          * ICACHE INIT -- only the icache line at the reset address
28          * 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          */
33         ori     r4, r0, %lo(ICACHE_LINE_SIZE)
34         movhi   r5, %hi(ICACHE_SIZE_MAX)
35         ori     r5, r5, %lo(ICACHE_SIZE_MAX)
36 0:      initi   r5
37         sub     r5, r5, r4
38         bgt     r5, r0, 0b
39         br      _except_end     /* Skip the tramp */
40
41         /*
42          * EXCEPTION TRAMPOLINE -- the following gets copied
43          * 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:
51
52         /*
53          * INTERRUPTS -- for now, all interrupts masked and globally
54          * disabled.
55          */
56         wrctl   ienable, r0             /* All disabled */
57
58         /*
59          * DCACHE INIT -- if dcache not implemented, initd behaves as
60          * nop.
61          */
62         ori     r4, r0, %lo(DCACHE_LINE_SIZE_MIN)
63         movhi   r5, %hi(DCACHE_SIZE_MAX)
64         ori     r5, r5, %lo(DCACHE_SIZE_MAX)
65         mov     r6, r0
66 1:      initd   0(r6)
67         add     r6, r6, r4
68         bltu    r6, r5, 1b
69
70         /*
71          * RELOCATE CODE, DATA & COMMAND TABLE -- the following code
72          * 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 */
83         mov     sp, r5          /* initial stack below u-boot code */
84         beq     r4, r5, 3f
85
86         movhi   r6, %hi(CONFIG_SYS_MONITOR_LEN)
87         ori     r6, r6, %lo(CONFIG_SYS_MONITOR_LEN)
88         add     r6, r6, r5
89 2:      ldwio   r7, 0(r4)
90         addi    r4, r4, 4
91         stwio   r7, 0(r5)
92         addi    r5, r5, 4
93         bne     r5, r6, 2b
94 3:
95
96         /* JUMP TO RELOC ADDR */
97         movhi   r4, %hi(_reloc)
98         ori     r4, r4, %lo(_reloc)
99         jmp     r4
100 _reloc:
101
102         /* STACK INIT -- zero top two words for call back chain. */
103         addi    sp, sp, -8
104         stw     r0, 0(sp)
105         stw     r0, 4(sp)
106         mov     fp, sp
107
108 #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
115         /* Allocate and initialize reserved area, update SP */
116         mov     r4, sp
117         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)
124         callr   r2
125
126         /* Update frame-pointer */
127         mov     fp, sp
128
129         /* Call board_init_f -- never returns */
130         mov     r4, r0
131         movhi   r2, %hi(board_init_f@h)
132         ori     r2, r2, %lo(board_init_f@h)
133         callr   r2
134
135         /*
136          * NEVER RETURNS -- but branch to the _start just
137          * in case ;-)
138          */
139         br      _start
140
141         /*
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          *
150          * void relocate_code (ulong sp, gd_t *global_data,
151          *                      ulong reloc_addr)
152          *                      __attribute__ ((noreturn));
153          */
154         .text
155         .global relocate_code
156
157 relocate_code:
158         mov     sp, r4          /* Set the new sp */
159         mov     r4, r5
160
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
171 4:      stw     r0, 0(r5)
172         addi    r5, r5, 4
173         bne     r5, r6, 4b
174 5:
175
176         movhi   r8, %hi(board_init_r@h)
177         ori     r8, r8, %lo(board_init_r@h)
178         callr   r8
179         ret