]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/microblaze/cpu/start.S
Rename TEXT_BASE into CONFIG_SYS_TEXT_BASE
[people/ms/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 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27 #include <config.h>
28
29 .text
30 .global _start
31 _start:
32 mts rmsr, r0 /* disable cache */
33 addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET
34 addi r1, r1, -4 /* Decrement SP to top of memory */
35
36 /* Find-out if u-boot is running on BIG/LITTLE endian platform
37 * There are some steps which is necessary to keep in mind:
38 * 1. Setup offset value to r6
39 * 2. Store word offset value to address 0x0
40 * 3. Load just byte from address 0x0
41 * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest
42 * value that's why is on address 0x0
43 * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
44 */
45 addik r6, r0, 0x2 /* BIG/LITTLE endian offset */
46 swi r6, r0, 0
47 lbui r10, r0, 0
48 swi r6, r0, 0x40
49 swi r10, r0, 0x50
50
51 /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/
52 addi r6, r0, 0xb0000000 /* hex b000 opcode imm */
53 swi r6, r0, 0x0 /* reset address */
54 swi r6, r0, 0x8 /* user vector exception */
55 swi r6, r0, 0x10 /* interrupt */
56 swi r6, r0, 0x20 /* hardware exception */
57
58 addi r6, r0, 0xb8080000 /* hew b808 opcode brai*/
59 swi r6, r0, 0x4 /* reset address */
60 swi r6, r0, 0xC /* user vector exception */
61 swi r6, r0, 0x14 /* interrupt */
62 swi r6, r0, 0x24 /* hardware exception */
63
64 #ifdef CONFIG_SYS_RESET_ADDRESS
65 /* reset address */
66 addik r6, r0, CONFIG_SYS_RESET_ADDRESS
67 sw r6, r1, r0
68 lhu r7, r1, r0
69 shi r7, r0, 0x2
70 shi r6, r0, 0x6
71 /*
72 * Copy U-Boot code to CONFIG_SYS_TEXT_BASE
73 * solve problem with sbrk_base
74 */
75 #if (CONFIG_SYS_RESET_ADDRESS != CONFIG_SYS_TEXT_BASE)
76 addi r4, r0, __end
77 addi r5, r0, __text_start
78 rsub r4, r5, r4 /* size = __end - __text_start */
79 addi r6, r0, CONFIG_SYS_RESET_ADDRESS /* source address */
80 addi r7, r0, 0 /* counter */
81 4:
82 lw r8, r6, r7
83 sw r8, r5, r7
84 addi r7, r7, 0x4
85 cmp r8, r4, r7
86 blti r8, 4b
87 #endif
88 #endif
89
90 #ifdef CONFIG_SYS_USR_EXCEP
91 /* user_vector_exception */
92 addik r6, r0, _exception_handler
93 sw r6, r1, r0
94 /*
95 * BIG ENDIAN memory map for user exception
96 * 0x8: 0xB000XXXX
97 * 0xC: 0xB808XXXX
98 *
99 * then it is necessary to count address for storing the most significant
100 * 16bits from _exception_handler address and copy it to
101 * 0xa address. Big endian use offset in r10=0 that's why is it just
102 * 0xa address. The same is done for the least significant 16 bits
103 * for 0xe address.
104 *
105 * LITTLE ENDIAN memory map for user exception
106 * 0x8: 0xXXXX00B0
107 * 0xC: 0xXXXX08B8
108 *
109 * Offset is for little endian setup to 0x2. rsubi instruction decrease
110 * address value to ensure that points to proper place which is
111 * 0x8 for the most significant 16 bits and
112 * 0xC for the least significant 16 bits
113 */
114 lhu r7, r1, r10
115 rsubi r8, r10, 0xa
116 sh r7, r0, r8
117 rsubi r8, r10, 0xe
118 sh r6, r0, r8
119 #endif
120
121 #ifdef CONFIG_SYS_INTC_0
122 /* interrupt_handler */
123 addik r6, r0, _interrupt_handler
124 sw r6, r1, r0
125 lhu r7, r1, r10
126 rsubi r8, r10, 0x12
127 sh r7, r0, r8
128 rsubi r8, r10, 0x16
129 sh r6, r0, r8
130 #endif
131
132 /* hardware exception */
133 addik r6, r0, _hw_exception_handler
134 sw r6, r1, r0
135 lhu r7, r1, r10
136 rsubi r8, r10, 0x22
137 sh r7, r0, r8
138 rsubi r8, r10, 0x26
139 sh r6, r0, r8
140
141 /* enable instruction and data cache */
142 mfs r12, rmsr
143 ori r12, r12, 0xa0
144 mts rmsr, r12
145
146 clear_bss:
147 /* clear BSS segments */
148 addi r5, r0, __bss_start
149 addi r4, r0, __bss_end
150 cmp r6, r5, r4
151 beqi r6, 3f
152 2:
153 swi r0, r5, 0 /* write zero to loc */
154 addi r5, r5, 4 /* increment to next loc */
155 cmp r6, r5, r4 /* check if we have reach the end */
156 bnei r6, 2b
157 3: /* jumping to board_init */
158 brai board_init
159 1: bri 1b
160
161 /*
162 * Read 16bit little endian
163 */
164 .text
165 .global in16
166 .ent in16
167 .align 2
168 in16: lhu r3, r0, r5
169 bslli r4, r3, 8
170 bsrli r3, r3, 8
171 andi r4, r4, 0xffff
172 or r3, r3, r4
173 rtsd r15, 8
174 sext16 r3, r3
175 .end in16
176
177 /*
178 * Write 16bit little endian
179 * first parameter(r5) - address, second(r6) - short value
180 */
181 .text
182 .global out16
183 .ent out16
184 .align 2
185 out16: bslli r3, r6, 8
186 bsrli r6, r6, 8
187 andi r3, r3, 0xffff
188 or r3, r3, r6
189 sh r3, r0, r5
190 rtsd r15, 8
191 or r0, r0, r0
192 .end out16