microblaze: Remove debug saving value
[platform/kernel/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 <asm-offsets.h>
28 #include <config.h>
29
30         .text
31         .global _start
32 _start:
33         mts     rmsr, r0        /* disable cache */
34         addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET
35         addi    r1, r1, -4      /* Decrement SP to top of memory */
36
37         /* Find-out if u-boot is running on BIG/LITTLE endian platform
38          * There are some steps which is necessary to keep in mind:
39          * 1. Setup offset value to r6
40          * 2. Store word offset value to address 0x0
41          * 3. Load just byte from address 0x0
42          * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest
43          *     value that's why is on address 0x0
44          * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
45          */
46         addik   r6, r0, 0x2 /* BIG/LITTLE endian offset */
47         swi     r6, r0, 0
48         lbui    r10, r0, 0
49
50         /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/
51         addi    r6, r0, 0xb0000000      /* hex b000 opcode imm */
52         swi     r6, r0, 0x0     /* reset address */
53         swi     r6, r0, 0x8     /* user vector exception */
54         swi     r6, r0, 0x10    /* interrupt */
55         swi     r6, r0, 0x20    /* hardware exception */
56
57         addi    r6, r0, 0xb8080000      /* hew b808 opcode brai*/
58         swi     r6, r0, 0x4     /* reset address */
59         swi     r6, r0, 0xC     /* user vector exception */
60         swi     r6, r0, 0x14    /* interrupt */
61         swi     r6, r0, 0x24    /* hardware exception */
62
63 #ifdef CONFIG_SYS_RESET_ADDRESS
64         /* reset address */
65         addik   r6, r0, CONFIG_SYS_RESET_ADDRESS
66         sw      r6, r1, r0
67         lhu     r7, r1, r0
68         shi     r7, r0, 0x2
69         shi     r6, r0, 0x6
70 /*
71  * Copy U-Boot code to CONFIG_SYS_TEXT_BASE
72  * solve problem with sbrk_base
73  */
74 #if (CONFIG_SYS_RESET_ADDRESS != CONFIG_SYS_TEXT_BASE)
75         addi    r4, r0, __end
76         addi    r5, r0, __text_start
77         rsub    r4, r5, r4      /* size = __end - __text_start */
78         addi    r6, r0, CONFIG_SYS_RESET_ADDRESS        /* source address */
79         addi    r7, r0, 0       /* counter */
80 4:
81         lw      r8, r6, r7
82         sw      r8, r5, r7
83         addi    r7, r7, 0x4
84         cmp     r8, r4, r7
85         blti    r8, 4b
86 #endif
87 #endif
88
89 #ifdef CONFIG_SYS_USR_EXCEP
90         /* user_vector_exception */
91         addik   r6, r0, _exception_handler
92         sw      r6, r1, r0
93         /*
94          * BIG ENDIAN memory map for user exception
95          * 0x8: 0xB000XXXX
96          * 0xC: 0xB808XXXX
97          *
98          * then it is necessary to count address for storing the most significant
99          * 16bits from _exception_handler address and copy it to
100          * 0xa address. Big endian use offset in r10=0 that's why is it just
101          * 0xa address. The same is done for the least significant 16 bits
102          * for 0xe address.
103          *
104          * LITTLE ENDIAN memory map for user exception
105          * 0x8: 0xXXXX00B0
106          * 0xC: 0xXXXX08B8
107          *
108          * Offset is for little endian setup to 0x2. rsubi instruction decrease
109          * address value to ensure that points to proper place which is
110          * 0x8 for the most significant 16 bits and
111          * 0xC for the least significant 16 bits
112          */
113         lhu     r7, r1, r10
114         rsubi   r8, r10, 0xa
115         sh      r7, r0, r8
116         rsubi   r8, r10, 0xe
117         sh      r6, r0, r8
118 #endif
119
120 #ifdef CONFIG_SYS_INTC_0
121         /* interrupt_handler */
122         addik   r6, r0, _interrupt_handler
123         sw      r6, r1, r0
124         lhu     r7, r1, r10
125         rsubi   r8, r10, 0x12
126         sh      r7, r0, r8
127         rsubi   r8, r10, 0x16
128         sh      r6, r0, r8
129 #endif
130
131         /* hardware exception */
132         addik   r6, r0, _hw_exception_handler
133         sw      r6, r1, r0
134         lhu     r7, r1, r10
135         rsubi   r8, r10, 0x22
136         sh      r7, r0, r8
137         rsubi   r8, r10, 0x26
138         sh      r6, r0, r8
139
140         /* enable instruction and data cache */
141         mfs     r12, rmsr
142         ori     r12, r12, 0xa0
143         mts     rmsr, r12
144
145 clear_bss:
146         /* clear BSS segments */
147         addi    r5, r0, __bss_start
148         addi    r4, r0, __bss_end
149         cmp     r6, r5, r4
150         beqi    r6, 3f
151 2:
152         swi     r0, r5, 0 /* write zero to loc */
153         addi    r5, r5, 4 /* increment to next loc */
154         cmp     r6, r5, r4 /* check if we have reach the end */
155         bnei    r6, 2b
156 3:      /* jumping to board_init */
157         brai    board_init
158 1:      bri     1b
159
160 /*
161  * Read 16bit little endian
162  */
163         .text
164         .global in16
165         .ent    in16
166         .align  2
167 in16:   lhu     r3, r0, r5
168         bslli   r4, r3, 8
169         bsrli   r3, r3, 8
170         andi    r4, r4, 0xffff
171         or      r3, r3, r4
172         rtsd    r15, 8
173         sext16  r3, r3
174         .end    in16
175
176 /*
177  * Write 16bit little endian
178  * first parameter(r5) - address, second(r6) - short value
179  */
180         .text
181         .global out16
182         .ent    out16
183         .align  2
184 out16:  bslli   r3, r6, 8
185         bsrli   r6, r6, 8
186         andi    r3, r3, 0xffff
187         or      r3, r3, r6
188         sh      r3, r0, r5
189         rtsd    r15, 8
190         or      r0, r0, r0
191         .end    out16