]> git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/microblaze/cpu/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[thirdparty/u-boot.git] / arch / microblaze / cpu / start.S
1 /*
2 * (C) Copyright 2007 Michal Simek
3 * (C) Copyright 2004 Atmark Techno, Inc.
4 *
5 * Michal SIMEK <monstr@monstr.eu>
6 * Yasushi SHOJI <yashi@atmark-techno.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11 #include <asm-offsets.h>
12 #include <config.h>
13
14 .text
15 .global _start
16 _start:
17 /*
18 * reserve registers:
19 * r10: Stores little/big endian offset for vectors
20 * r2: Stores imm opcode
21 * r3: Stores brai opcode
22 */
23
24 mts rmsr, r0 /* disable cache */
25 addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET
26 addi r1, r1, -4 /* Decrement SP to top of memory */
27
28 /* Find-out if u-boot is running on BIG/LITTLE endian platform
29 * There are some steps which is necessary to keep in mind:
30 * 1. Setup offset value to r6
31 * 2. Store word offset value to address 0x0
32 * 3. Load just byte from address 0x0
33 * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest
34 * value that's why is on address 0x0
35 * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
36 */
37 addik r6, r0, 0x2 /* BIG/LITTLE endian offset */
38 lwi r7, r0, 0x28
39 swi r6, r0, 0x28 /* used first unused MB vector */
40 lbui r10, r0, 0x28 /* used first unused MB vector */
41 swi r7, r0, 0x28
42
43 /* add opcode instruction for 32bit jump - 2 instruction imm & brai */
44 addi r2, r0, 0xb0000000 /* hex b000 opcode imm */
45 addi r3, r0, 0xb8080000 /* hew b808 opcode brai */
46
47 #ifdef CONFIG_SYS_RESET_ADDRESS
48 /* reset address */
49 swi r2, r0, 0x0 /* reset address - imm opcode */
50 swi r3, r0, 0x4 /* reset address - brai opcode */
51
52 addik r6, r0, CONFIG_SYS_RESET_ADDRESS
53 sw r6, r1, r0
54 lhu r7, r1, r10
55 rsubi r8, r10, 0x2
56 sh r7, r0, r8
57 rsubi r8, r10, 0x6
58 sh r6, r0, r8
59 #endif
60
61 #ifdef CONFIG_SYS_USR_EXCEP
62 /* user_vector_exception */
63 swi r2, r0, 0x8 /* user vector exception - imm opcode */
64 swi r3, r0, 0xC /* user vector exception - brai opcode */
65
66 addik r6, r0, _exception_handler
67 sw r6, r1, r0
68 /*
69 * BIG ENDIAN memory map for user exception
70 * 0x8: 0xB000XXXX
71 * 0xC: 0xB808XXXX
72 *
73 * then it is necessary to count address for storing the most significant
74 * 16bits from _exception_handler address and copy it to
75 * 0xa address. Big endian use offset in r10=0 that's why is it just
76 * 0xa address. The same is done for the least significant 16 bits
77 * for 0xe address.
78 *
79 * LITTLE ENDIAN memory map for user exception
80 * 0x8: 0xXXXX00B0
81 * 0xC: 0xXXXX08B8
82 *
83 * Offset is for little endian setup to 0x2. rsubi instruction decrease
84 * address value to ensure that points to proper place which is
85 * 0x8 for the most significant 16 bits and
86 * 0xC for the least significant 16 bits
87 */
88 lhu r7, r1, r10
89 rsubi r8, r10, 0xa
90 sh r7, r0, r8
91 rsubi r8, r10, 0xe
92 sh r6, r0, r8
93 #endif
94
95 /* interrupt_handler */
96 swi r2, r0, 0x10 /* interrupt - imm opcode */
97 swi r3, r0, 0x14 /* interrupt - brai opcode */
98
99 addik r6, r0, _interrupt_handler
100 sw r6, r1, r0
101 lhu r7, r1, r10
102 rsubi r8, r10, 0x12
103 sh r7, r0, r8
104 rsubi r8, r10, 0x16
105 sh r6, r0, r8
106
107 /* hardware exception */
108 swi r2, r0, 0x20 /* hardware exception - imm opcode */
109 swi r3, r0, 0x24 /* hardware exception - brai opcode */
110
111 addik r6, r0, _hw_exception_handler
112 sw r6, r1, r0
113 lhu r7, r1, r10
114 rsubi r8, r10, 0x22
115 sh r7, r0, r8
116 rsubi r8, r10, 0x26
117 sh r6, r0, r8
118
119 /* Flush cache before enable cache */
120 addik r5, r0, 0
121 addik r6, r0, XILINX_DCACHE_BYTE_SIZE
122 flush: bralid r15, flush_cache
123 nop
124
125 /* enable instruction and data cache */
126 mfs r12, rmsr
127 ori r12, r12, 0xa0
128 mts rmsr, r12
129
130 clear_bss:
131 /* clear BSS segments */
132 addi r5, r0, __bss_start
133 addi r4, r0, __bss_end
134 cmp r6, r5, r4
135 beqi r6, 3f
136 2:
137 swi r0, r5, 0 /* write zero to loc */
138 addi r5, r5, 4 /* increment to next loc */
139 cmp r6, r5, r4 /* check if we have reach the end */
140 bnei r6, 2b
141 3: /* jumping to board_init */
142 brai board_init_f
143 1: bri 1b
144
145 /*
146 * Read 16bit little endian
147 */
148 .text
149 .global in16
150 .ent in16
151 .align 2
152 in16: lhu r3, r0, r5
153 bslli r4, r3, 8
154 bsrli r3, r3, 8
155 andi r4, r4, 0xffff
156 or r3, r3, r4
157 rtsd r15, 8
158 sext16 r3, r3
159 .end in16
160
161 /*
162 * Write 16bit little endian
163 * first parameter(r5) - address, second(r6) - short value
164 */
165 .text
166 .global out16
167 .ent out16
168 .align 2
169 out16: bslli r3, r6, 8
170 bsrli r6, r6, 8
171 andi r3, r3, 0xffff
172 or r3, r3, r6
173 sh r3, r0, r5
174 rtsd r15, 8
175 or r0, r0, r0
176 .end out16