]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/microblaze/cpu/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.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