1/* SPDX-License-Identifier: GPL-2.0 */ 2#include <variant/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 .begin literal_prefix .text 46 47 /* put literals in here! */ 48 49 .globl _start 50_start: 51 52 /* 'reset' window registers */ 53 54 movi a4, 1 55 wsr a4, ps 56 rsync 57 58 rsr a5, windowbase 59 ssl a5 60 sll a4, a4 61 wsr a4, windowstart 62 rsync 63 64 movi a4, 0x00040000 65 wsr a4, ps 66 rsync 67 68 /* copy the loader to its address 69 * Note: The loader itself is a very small piece, so we assume we 70 * don't partially overlap. We also assume (even more important) 71 * that the kernel image is out of the way. Usually, when the 72 * load address of this image is not at an arbitrary address, 73 * but aligned to some 10K's we shouldn't overlap. 74 */ 75 76 /* Note: The assembler cannot relax "addi a0, a0, ..." to an 77 l32r, so we load to a4 first. */ 78 79 # addi a4, a0, __start - __start_a0 80 # mov a0, a4 81 82 movi a4, __start 83 movi a5, __start_a0 84 add a4, a0, a4 85 sub a0, a4, a5 86 87 movi a4, __start 88 movi a5, __reloc_end 89 90 # a0: address where this code has been loaded 91 # a4: compiled address of __start 92 # a5: compiled end address 93 94 mov.n a7, a0 95 mov.n a8, a4 96 971: 98 l32i a10, a7, 0 99 l32i a11, a7, 4 100 s32i a10, a8, 0 101 s32i a11, a8, 4 102 l32i a10, a7, 8 103 l32i a11, a7, 12 104 s32i a10, a8, 8 105 s32i a11, a8, 12 106 addi a8, a8, 16 107 addi a7, a7, 16 108 blt a8, a5, 1b 109 110 111 /* We have to flush and invalidate the caches here before we jump. */ 112 113#if XCHAL_DCACHE_IS_WRITEBACK 114 115 ___flush_dcache_all a5 a6 116 117#endif 118 119 ___invalidate_icache_all a5 a6 120 isync 121 122 movi a11, _reloc 123 jx a11 124 125 .globl _reloc 126_reloc: 127 128 /* RedBoot is now at the end of the memory, so we don't have 129 * to copy the parameter list. Keep the code around; in case 130 * we need it again. */ 131#if 0 132 # a0: load address 133 # a2: start address of parameter list 134 # a3: length of parameter list 135 # a4: __start 136 137 /* copy the parameter list out of the way */ 138 139 movi a6, _param_start 140 add a3, a2, a3 1412: 142 l32i a8, a2, 0 143 s32i a8, a6, 0 144 addi a2, a2, 4 145 addi a6, a6, 4 146 blt a2, a3, 2b 147#endif 148 149 /* clear BSS section */ 150 movi a6, __bss_start 151 movi a7, __bss_end 152 movi.n a5, 0 1533: 154 s32i a5, a6, 0 155 addi a6, a6, 4 156 blt a6, a7, 3b 157 158 movi a5, -16 159 movi a1, _stack + STACK_SIZE 160 and a1, a1, a5 161 162 /* Uncompress the kernel */ 163 164 # a0: load address 165 # a2: boot parameter 166 # a4: __start 167 168 movi a3, __image_load 169 sub a4, a3, a4 170 add a8, a0, a4 171 172 # a1 Stack 173 # a8(a4) Load address of the image 174 175 movi a6, _image_start 176 movi a10, _image_end 177 movi a7, 0x1000000 178 sub a11, a10, a6 179 movi a9, complen 180 s32i a11, a9, 0 181 182 movi a0, 0 183 184 # a6 destination 185 # a7 maximum size of destination 186 # a8 source 187 # a9 ptr to length 188 189 .extern gunzip 190 movi a4, gunzip 191 beqz a4, 1f 192 193 callx4 a4 194 195 j 2f 196 197 198 # a6 destination start 199 # a7 maximum size of destination 200 # a8 source start 201 # a9 ptr to length 202 # a10 destination end 203 2041: 205 l32i a9, a8, 0 206 l32i a11, a8, 4 207 s32i a9, a6, 0 208 s32i a11, a6, 4 209 l32i a9, a8, 8 210 l32i a11, a8, 12 211 s32i a9, a6, 8 212 s32i a11, a6, 12 213 addi a6, a6, 16 214 addi a8, a8, 16 215 blt a6, a10, 1b 216 217 218 /* jump to the kernel */ 2192: 220#if XCHAL_DCACHE_IS_WRITEBACK 221 222 ___flush_dcache_all a5 a6 223 224#endif 225 226 ___invalidate_icache_all a5 a6 227 228 isync 229 230 # a2 Boot parameter list 231 232 movi a0, _image_start 233 jx a0 234 235 .align 16 236 .data 237 .globl avail_ram 238avail_ram: 239 .long _heap 240 .globl end_avail 241end_avail: 242 .long _heap + HEAP_SIZE 243 244 .comm _stack, STACK_SIZE 245 .comm _heap, HEAP_SIZE 246 247 .globl end_avail 248 .comm complen, 4 249 250 .end literal_prefix 251