GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / unicore32 / boot / compressed / head.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * linux/arch/unicore32/boot/compressed/head.S
4  *
5  * Code specific to PKUnity SoC and UniCore ISA
6  *
7  * Copyright (C) 2001-2010 GUAN Xue-tao
8  */
9 #include <linux/linkage.h>
10 #include <mach/memory.h>
11
12 #define csub    cmpsub
13 #define cand    cmpand
14 #define nop8    nop; nop; nop; nop; nop; nop; nop; nop
15
16                 .section ".start", #alloc, #execinstr
17                 .text
18 start:
19                 .type   start,#function
20
21                 /* Initialize ASR, PRIV mode and INTR off */
22                 mov     r0, #0xD3
23                 mov.a   asr, r0
24
25                 adr     r0, LC0
26                 ldm     (r1, r2, r3, r5, r6, r7, r8), [r0]+
27                 ldw     sp, [r0+], #28
28                 sub.a   r0, r0, r1              @ calculate the delta offset
29
30                 /*
31                  * if delta is zero, we are running at the address
32                  * we were linked at.
33                  */
34                 beq     not_relocated
35
36                 /*
37                  * We're running at a different address.  We need to fix
38                  * up various pointers:
39                  *   r5 - zImage base address (_start)
40                  *   r7 - GOT start
41                  *   r8 - GOT end
42                  */
43                 add     r5, r5, r0
44                 add     r7, r7, r0
45                 add     r8, r8, r0
46
47                 /*
48                  * we need to fix up pointers into the BSS region.
49                  *   r2 - BSS start
50                  *   r3 - BSS end
51                  *   sp - stack pointer
52                  */
53                 add     r2, r2, r0
54                 add     r3, r3, r0
55                 add     sp, sp, r0
56
57                 /*
58                  * Relocate all entries in the GOT table.
59                  * This fixes up the C references.
60                  *   r7 - GOT start
61                  *   r8 - GOT end
62                  */
63 1001:           ldw     r1, [r7+], #0
64                 add     r1, r1, r0
65                 stw.w   r1, [r7]+, #4
66                 csub.a  r7, r8
67                 bub     1001b
68
69 not_relocated:
70                 /*
71                  * Clear BSS region.
72                  *   r2 - BSS start
73                  *   r3 - BSS end
74                  */
75                 mov     r0, #0
76 1002:           stw.w   r0, [r2]+, #4
77                 csub.a  r2, r3
78                 bub     1002b
79
80                 /*
81                  * Turn on the cache.
82                  */
83                 mov     r0, #0
84                 movc    p0.c5, r0, #28          @ cache invalidate all
85                 nop8
86                 movc    p0.c6, r0, #6           @ tlb invalidate all
87                 nop8
88
89                 mov     r0, #0x1c               @ en icache and wb dcache
90                 movc    p0.c1, r0, #0
91                 nop8
92
93                 /*
94                  * Set up some pointers, for starting decompressing.
95                  */
96
97                 mov     r1, sp                  @ malloc space above stack
98                 add     r2, sp, #0x10000        @ 64k max
99
100                 /*
101                  * Check to see if we will overwrite ourselves.
102                  *   r4 = final kernel address
103                  *   r5 = start of this image
104                  *   r6 = size of decompressed image
105                  *   r2 = end of malloc space (and therefore this image)
106                  * We basically want:
107                  *   r4 >= r2 -> OK
108                  *   r4 + image length <= r5 -> OK
109                  */
110                 ldw     r4, =KERNEL_IMAGE_START
111                 csub.a  r4, r2
112                 bea     wont_overwrite
113                 add     r0, r4, r6
114                 csub.a  r0, r5
115                 beb     wont_overwrite
116
117                 /*
118                  * If overwrite, just print error message
119                  */
120                 b       __error_overwrite
121
122                 /*
123                  * We're not in danger of overwriting ourselves.
124                  * Do this the simple way.
125                  */
126 wont_overwrite:
127                 /*
128                  * decompress_kernel:
129                  *   r0: output_start
130                  *   r1: free_mem_ptr_p
131                  *   r2: free_mem_ptr_end_p
132                  */
133                 mov     r0, r4
134                 b.l     decompress_kernel       @ C functions
135
136                 /*
137                  * Clean and flush the cache to maintain consistency.
138                  */
139                 mov     r0, #0
140                 movc    p0.c5, r0, #14          @ flush dcache
141                 nop8
142                 movc    p0.c5, r0, #20          @ icache invalidate all
143                 nop8
144
145                 /*
146                  * Turn off the Cache and MMU.
147                  */
148                 mov     r0, #0                  @ disable i/d cache and MMU
149                 movc    p0.c1, r0, #0
150                 nop8
151
152                 mov     r0, #0                  @ must be zero
153                 ldw     r4, =KERNEL_IMAGE_START
154                 mov     pc, r4                  @ call kernel
155
156
157                 .align  2
158                 .type   LC0, #object
159 LC0:            .word   LC0                     @ r1
160                 .word   __bss_start             @ r2
161                 .word   _end                    @ r3
162                 .word   _start                  @ r5
163                 .word   _image_size             @ r6
164                 .word   _got_start              @ r7
165                 .word   _got_end                @ r8
166                 .word   decompress_stack_end    @ sp
167                 .size   LC0, . - LC0
168
169 print_string:
170 #ifdef CONFIG_DEBUG_OCD
171 2001:           ldb.w   r1, [r0]+, #1
172                 csub.a  r1, #0
173                 bne     2002f
174                 mov     pc, lr
175 2002:
176                 movc    r2, p1.c0, #0
177                 cand.a  r2, #2
178                 bne     2002b
179                 movc    p1.c1, r1, #1
180                 csub.a  r1, #'\n'
181                 cmoveq  r1, #'\r'
182                 beq     2002b
183                 b       2001b
184 #else
185                 mov     pc, lr
186 #endif
187
188 __error_overwrite:
189                 adr     r0, str_error
190                 b.l     print_string
191 2001:           nop8
192                 b       2001b
193 str_error:      .asciz  "\nError: Kernel address OVERWRITE\n"
194                 .align
195
196                 .ltorg
197
198                 .align  4
199                 .section ".stack", "aw", %nobits
200 decompress_stack:       .space  4096
201 decompress_stack_end: