1/* SPDX-License-Identifier: GPL-2.0 */ 2#include <asm/core.h> 3#include <asm/regs.h> 4#include <asm/asmmacro.h> 5#include <asm/cacheasm.h> 6 /* 7 * RB-Data: RedBoot data/bss 8 * P: Boot-Parameters 9 * L: Kernel-Loader 10 * 11 * The Linux-Kernel image including the loader must be loaded 12 * to a position so that the kernel and the boot parameters 13 * can fit in the space before the load address. 14 * ______________________________________________________ 15 * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______| 16 * ^ 17 * ^ Load address 18 * ______________________________________________________ 19 * |___Linux-Kernel___|_P_|_L_|___________________________| 20 * 21 * The loader copies the parameter to the position that will 22 * be the end of the kernel and itself to the end of the 23 * parameter list. 24 */ 25 26/* Make sure we have enough space for the 'uncompressor' */ 27 28#define STACK_SIZE 32768 29#define HEAP_SIZE (131072*4) 30 31 # a2: Parameter list 32 # a3: Size of parameter list 33 34 .section .start, "ax" 35 36 .globl __start 37 /* this must be the first byte of the loader! */ 38__start: 39 entry sp, 32 # we do not intend to return 40 _call0 _start 41__start_a0: 42 .align 4 43 44 .section .text, "ax" 45 .literal_position 46 .begin literal_prefix .text 47 48 /* put literals in here! */ 49 50 .globl _start 51_start: 52 53 /* 'reset' window registers */ 54 55 movi a4, 1 56 wsr a4, ps 57 rsync 58 59 rsr a5, windowbase 60 ssl a5 61 sll a4, a4 62 wsr a4, windowstart 63 rsync 64 65 movi a4, 0x00040000 66 wsr a4, ps 67 rsync 68 69 /* copy the loader to its address 70 * Note: The loader itself is a very small piece, so we assume we 71 * don't partially overlap. We also assume (even more important) 72 * that the kernel image is out of the way. Usually, when the 73 * load address of this image is not at an arbitrary address, 74 * but aligned to some 10K's we shouldn't overlap. 75 */ 76 77 /* Note: The assembler cannot relax "addi a0, a0, ..." to an 78 l32r, so we load to a4 first. */ 79 80 # addi a4, a0, __start - __start_a0 81 # mov a0, a4 82 83 movi a4, __start 84 movi a5, __start_a0 85 add a4, a0, a4 86 sub a0, a4, a5 87 88 movi a4, __start 89 movi a5, __reloc_end 90 91 # a0: address where this code has been loaded 92 # a4: compiled address of __start 93 # a5: compiled end address 94 95 mov.n a7, a0 96 mov.n a8, a4 97 981: 99 l32i a10, a7, 0 100 l32i a11, a7, 4 101 s32i a10, a8, 0 102 s32i a11, a8, 4 103 l32i a10, a7, 8 104 l32i a11, a7, 12 105 s32i a10, a8, 8 106 s32i a11, a8, 12 107 addi a8, a8, 16 108 addi a7, a7, 16 109 blt a8, a5, 1b 110 111 112 /* We have to flush and invalidate the caches here before we jump. */ 113 114#if XCHAL_DCACHE_IS_WRITEBACK 115 116 ___flush_dcache_all a5 a6 117 118#endif 119 120 ___invalidate_icache_all a5 a6 121 isync 122 123 movi a11, _reloc 124 jx a11 125 126 .globl _reloc 127_reloc: 128 129 /* RedBoot is now at the end of the memory, so we don't have 130 * to copy the parameter list. Keep the code around; in case 131 * we need it again. */ 132#if 0 133 # a0: load address 134 # a2: start address of parameter list 135 # a3: length of parameter list 136 # a4: __start 137 138 /* copy the parameter list out of the way */ 139 140 movi a6, _param_start 141 add a3, a2, a3 1422: 143 l32i a8, a2, 0 144 s32i a8, a6, 0 145 addi a2, a2, 4 146 addi a6, a6, 4 147 blt a2, a3, 2b 148#endif 149 150 /* clear BSS section */ 151 movi a6, __bss_start 152 movi a7, __bss_end 153 movi.n a5, 0 1543: 155 s32i a5, a6, 0 156 addi a6, a6, 4 157 blt a6, a7, 3b 158 159 movi a5, -16 160 movi a1, _stack + STACK_SIZE 161 and a1, a1, a5 162 163 /* Uncompress the kernel */ 164 165 # a0: load address 166 # a2: boot parameter 167 # a4: __start 168 169 movi a3, __image_load 170 sub a4, a3, a4 171 add a8, a0, a4 172 173 # a1 Stack 174 # a8(a4) Load address of the image 175 176 movi a6, _image_start 177 movi a10, _image_end 178 movi a7, 0x1000000 179 sub a11, a10, a6 180 movi a9, complen 181 s32i a11, a9, 0 182 183 movi a0, 0 184 185 # a6 destination 186 # a7 maximum size of destination 187 # a8 source 188 # a9 ptr to length 189 190 .extern gunzip 191 movi a4, gunzip 192 beqz a4, 1f 193 194 callx4 a4 195 196 j 2f 197 198 199 # a6 destination start 200 # a7 maximum size of destination 201 # a8 source start 202 # a9 ptr to length 203 # a10 destination end 204 2051: 206 l32i a9, a8, 0 207 l32i a11, a8, 4 208 s32i a9, a6, 0 209 s32i a11, a6, 4 210 l32i a9, a8, 8 211 l32i a11, a8, 12 212 s32i a9, a6, 8 213 s32i a11, a6, 12 214 addi a6, a6, 16 215 addi a8, a8, 16 216 blt a6, a10, 1b 217 218 219 /* jump to the kernel */ 2202: 221#if XCHAL_DCACHE_IS_WRITEBACK 222 223 ___flush_dcache_all a5 a6 224 225#endif 226 227 ___invalidate_icache_all a5 a6 228 229 isync 230 231 # a2 Boot parameter list 232 233 movi a0, _image_start 234 jx a0 235 236 .align 16 237 .data 238 .globl avail_ram 239avail_ram: 240 .long _heap 241 .globl end_avail 242end_avail: 243 .long _heap + HEAP_SIZE 244 245 .comm _stack, STACK_SIZE 246 .comm _heap, HEAP_SIZE 247 248 .globl end_avail 249 .comm complen, 4 250 251 .end literal_prefix 252