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 18start: 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 */ 631001: ldw r1, [r7+], #0 64 add r1, r1, r0 65 stw.w r1, [r7]+, #4 66 csub.a r7, r8 67 bub 1001b 68 69not_relocated: 70 /* 71 * Clear BSS region. 72 * r2 - BSS start 73 * r3 - BSS end 74 */ 75 mov r0, #0 761002: 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 */ 126wont_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 159LC0: .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 169print_string: 170#ifdef CONFIG_DEBUG_OCD 1712001: ldb.w r1, [r0]+, #1 172 csub.a r1, #0 173 bne 2002f 174 mov pc, lr 1752002: 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 1912001: nop8 192 b 2001b 193str_error: .asciz "\nError: Kernel address OVERWRITE\n" 194 .align 195 196 .ltorg 197 198 .align 4 199 .section ".stack", "aw", %nobits 200decompress_stack: .space 4096 201decompress_stack_end: 202