3c027ff9bb1c21eced03fa62e606d5c1f624ba70
[platform/kernel/u-boot.git] / cpu / microblaze / 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, CFG_INIT_SP_OFFSET
34         addi    r1, r1, -4      /* Decrement SP to top of memory */
35         /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/
36         addi    r6, r0, 0xb000  /* hex b000 opcode imm */
37         bslli   r6, r6, 16      /* shift */
38         swi     r6, r0, 0x0     /* reset address */
39         swi     r6, r0, 0x8     /* user vector exception */
40         swi     r6, r0, 0x10    /* interrupt */
41         swi     r6, r0, 0x20    /* hardware exception */
42
43         addi    r6, r0, 0xb808  /* hew b808 opcode brai*/
44         bslli   r6, r6, 16
45         swi     r6, r0, 0x4     /* reset address */
46         swi     r6, r0, 0xC     /* user vector exception */
47         swi     r6, r0, 0x14    /* interrupt */
48         swi     r6, r0, 0x24    /* hardware exception */
49
50 #ifdef CFG_RESET_ADDRESS
51         /* reset address */
52         addik   r6, r0, CFG_RESET_ADDRESS
53         sw      r6, r1, r0
54         lhu     r7, r1, r0
55         shi     r7, r0, 0x2
56         shi     r6, r0, 0x6
57 /*
58  * Copy U-Boot code to TEXT_BASE
59  * solve problem with sbrk_base
60  */
61 #if (CFG_RESET_ADDRESS != TEXT_BASE)
62         addi    r4, r0, __end
63         addi    r5, r0, __text_start
64         rsub    r4, r5, r4      /* size = __end - __text_start */
65         addi    r6, r0, CFG_RESET_ADDRESS       /* source address */
66         addi    r7, r0, 0       /* counter */
67 4:
68         lw      r8, r6, r7
69         sw      r8, r5, r7
70         addi    r7, r7, 0x4
71         cmp     r8, r4, r7
72         blti    r8, 4b
73 #endif
74 #endif
75
76 #ifdef CFG_USR_EXCEP
77         /* user_vector_exception */
78         addik   r6, r0, _exception_handler
79         sw      r6, r1, r0
80         lhu     r7, r1, r0
81         shi     r7, r0, 0xa
82         shi     r6, r0, 0xe
83 #endif
84
85 #ifdef CFG_INTC_0
86         /* interrupt_handler */
87         addik   r6, r0, _interrupt_handler
88         sw      r6, r1, r0
89         lhu     r7, r1, r0
90         shi     r7, r0, 0x12
91         shi     r6, r0, 0x16
92 #endif
93
94         /* hardware exception */
95         addik   r6, r0, _hw_exception_handler
96         sw      r6, r1, r0
97         lhu     r7, r1, r0
98         shi     r7, r0, 0x22
99         shi     r6, r0, 0x26
100
101         /* enable instruction and data cache */
102         mfs     r12, rmsr
103         ori     r12, r12, 0xa0
104         mts     rmsr, r12
105
106 clear_bss:
107         /* clear BSS segments */
108         addi    r5, r0, __bss_start
109         addi    r4, r0, __bss_end
110         cmp     r6, r5, r4
111         beqi    r6, 3f
112 2:
113         swi     r0, r5, 0 /* write zero to loc */
114         addi    r5, r5, 4 /* increment to next loc */
115         cmp     r6, r5, r4 /* check if we have reach the end */
116         bnei    r6, 2b
117 3:      /* jumping to board_init */
118         brai    board_init
119 1:      bri     1b
120
121 /*
122  * Read 16bit little endian
123  */
124         .text
125         .global in16
126         .ent    in16
127         .align  2
128 in16:   lhu     r3, r0, r5
129         bslli   r4, r3, 8
130         bsrli   r3, r3, 8
131         andi    r4, r4, 0xffff
132         or      r3, r3, r4
133         rtsd    r15, 8
134         sext16  r3, r3
135         .end    in16
136
137 /*
138  * Write 16bit little endian
139  * first parameter(r5) - address, second(r6) - short value
140  */
141         .text
142         .global out16
143         .ent    out16
144         .align  2
145 out16:  bslli   r3, r6, 8
146         bsrli   r6, r6, 8
147         andi    r3, r3, 0xffff
148         or      r3, r3, r6
149         sh      r3, r0, r5
150         rtsd    r15, 8
151         or      r0, r0, r0
152         .end    out16