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