18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#include <asm/core.h> 38c2ecf20Sopenharmony_ci#include <asm/regs.h> 48c2ecf20Sopenharmony_ci#include <asm/asmmacro.h> 58c2ecf20Sopenharmony_ci#include <asm/cacheasm.h> 68c2ecf20Sopenharmony_ci /* 78c2ecf20Sopenharmony_ci * RB-Data: RedBoot data/bss 88c2ecf20Sopenharmony_ci * P: Boot-Parameters 98c2ecf20Sopenharmony_ci * L: Kernel-Loader 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The Linux-Kernel image including the loader must be loaded 128c2ecf20Sopenharmony_ci * to a position so that the kernel and the boot parameters 138c2ecf20Sopenharmony_ci * can fit in the space before the load address. 148c2ecf20Sopenharmony_ci * ______________________________________________________ 158c2ecf20Sopenharmony_ci * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______| 168c2ecf20Sopenharmony_ci * ^ 178c2ecf20Sopenharmony_ci * ^ Load address 188c2ecf20Sopenharmony_ci * ______________________________________________________ 198c2ecf20Sopenharmony_ci * |___Linux-Kernel___|_P_|_L_|___________________________| 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * The loader copies the parameter to the position that will 228c2ecf20Sopenharmony_ci * be the end of the kernel and itself to the end of the 238c2ecf20Sopenharmony_ci * parameter list. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* Make sure we have enough space for the 'uncompressor' */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define STACK_SIZE 32768 298c2ecf20Sopenharmony_ci#define HEAP_SIZE (131072*4) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci # a2: Parameter list 328c2ecf20Sopenharmony_ci # a3: Size of parameter list 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci .section .start, "ax" 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci .globl __start 378c2ecf20Sopenharmony_ci /* this must be the first byte of the loader! */ 388c2ecf20Sopenharmony_ci__start: 398c2ecf20Sopenharmony_ci entry sp, 32 # we do not intend to return 408c2ecf20Sopenharmony_ci _call0 _start 418c2ecf20Sopenharmony_ci__start_a0: 428c2ecf20Sopenharmony_ci .align 4 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci .section .text, "ax" 458c2ecf20Sopenharmony_ci .literal_position 468c2ecf20Sopenharmony_ci .begin literal_prefix .text 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* put literals in here! */ 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci .globl _start 518c2ecf20Sopenharmony_ci_start: 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* 'reset' window registers */ 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci movi a4, 1 568c2ecf20Sopenharmony_ci wsr a4, ps 578c2ecf20Sopenharmony_ci rsync 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci rsr a5, windowbase 608c2ecf20Sopenharmony_ci ssl a5 618c2ecf20Sopenharmony_ci sll a4, a4 628c2ecf20Sopenharmony_ci wsr a4, windowstart 638c2ecf20Sopenharmony_ci rsync 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci movi a4, 0x00040000 668c2ecf20Sopenharmony_ci wsr a4, ps 678c2ecf20Sopenharmony_ci rsync 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /* copy the loader to its address 708c2ecf20Sopenharmony_ci * Note: The loader itself is a very small piece, so we assume we 718c2ecf20Sopenharmony_ci * don't partially overlap. We also assume (even more important) 728c2ecf20Sopenharmony_ci * that the kernel image is out of the way. Usually, when the 738c2ecf20Sopenharmony_ci * load address of this image is not at an arbitrary address, 748c2ecf20Sopenharmony_ci * but aligned to some 10K's we shouldn't overlap. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci /* Note: The assembler cannot relax "addi a0, a0, ..." to an 788c2ecf20Sopenharmony_ci l32r, so we load to a4 first. */ 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci # addi a4, a0, __start - __start_a0 818c2ecf20Sopenharmony_ci # mov a0, a4 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci movi a4, __start 848c2ecf20Sopenharmony_ci movi a5, __start_a0 858c2ecf20Sopenharmony_ci add a4, a0, a4 868c2ecf20Sopenharmony_ci sub a0, a4, a5 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci movi a4, __start 898c2ecf20Sopenharmony_ci movi a5, __reloc_end 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci # a0: address where this code has been loaded 928c2ecf20Sopenharmony_ci # a4: compiled address of __start 938c2ecf20Sopenharmony_ci # a5: compiled end address 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci mov.n a7, a0 968c2ecf20Sopenharmony_ci mov.n a8, a4 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci1: 998c2ecf20Sopenharmony_ci l32i a10, a7, 0 1008c2ecf20Sopenharmony_ci l32i a11, a7, 4 1018c2ecf20Sopenharmony_ci s32i a10, a8, 0 1028c2ecf20Sopenharmony_ci s32i a11, a8, 4 1038c2ecf20Sopenharmony_ci l32i a10, a7, 8 1048c2ecf20Sopenharmony_ci l32i a11, a7, 12 1058c2ecf20Sopenharmony_ci s32i a10, a8, 8 1068c2ecf20Sopenharmony_ci s32i a11, a8, 12 1078c2ecf20Sopenharmony_ci addi a8, a8, 16 1088c2ecf20Sopenharmony_ci addi a7, a7, 16 1098c2ecf20Sopenharmony_ci blt a8, a5, 1b 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci /* We have to flush and invalidate the caches here before we jump. */ 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#if XCHAL_DCACHE_IS_WRITEBACK 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci ___flush_dcache_all a5 a6 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#endif 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci ___invalidate_icache_all a5 a6 1218c2ecf20Sopenharmony_ci isync 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci movi a11, _reloc 1248c2ecf20Sopenharmony_ci jx a11 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci .globl _reloc 1278c2ecf20Sopenharmony_ci_reloc: 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci /* RedBoot is now at the end of the memory, so we don't have 1308c2ecf20Sopenharmony_ci * to copy the parameter list. Keep the code around; in case 1318c2ecf20Sopenharmony_ci * we need it again. */ 1328c2ecf20Sopenharmony_ci#if 0 1338c2ecf20Sopenharmony_ci # a0: load address 1348c2ecf20Sopenharmony_ci # a2: start address of parameter list 1358c2ecf20Sopenharmony_ci # a3: length of parameter list 1368c2ecf20Sopenharmony_ci # a4: __start 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* copy the parameter list out of the way */ 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci movi a6, _param_start 1418c2ecf20Sopenharmony_ci add a3, a2, a3 1428c2ecf20Sopenharmony_ci2: 1438c2ecf20Sopenharmony_ci l32i a8, a2, 0 1448c2ecf20Sopenharmony_ci s32i a8, a6, 0 1458c2ecf20Sopenharmony_ci addi a2, a2, 4 1468c2ecf20Sopenharmony_ci addi a6, a6, 4 1478c2ecf20Sopenharmony_ci blt a2, a3, 2b 1488c2ecf20Sopenharmony_ci#endif 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci /* clear BSS section */ 1518c2ecf20Sopenharmony_ci movi a6, __bss_start 1528c2ecf20Sopenharmony_ci movi a7, __bss_end 1538c2ecf20Sopenharmony_ci movi.n a5, 0 1548c2ecf20Sopenharmony_ci3: 1558c2ecf20Sopenharmony_ci s32i a5, a6, 0 1568c2ecf20Sopenharmony_ci addi a6, a6, 4 1578c2ecf20Sopenharmony_ci blt a6, a7, 3b 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci movi a5, -16 1608c2ecf20Sopenharmony_ci movi a1, _stack + STACK_SIZE 1618c2ecf20Sopenharmony_ci and a1, a1, a5 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci /* Uncompress the kernel */ 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci # a0: load address 1668c2ecf20Sopenharmony_ci # a2: boot parameter 1678c2ecf20Sopenharmony_ci # a4: __start 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci movi a3, __image_load 1708c2ecf20Sopenharmony_ci sub a4, a3, a4 1718c2ecf20Sopenharmony_ci add a8, a0, a4 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci # a1 Stack 1748c2ecf20Sopenharmony_ci # a8(a4) Load address of the image 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci movi a6, _image_start 1778c2ecf20Sopenharmony_ci movi a10, _image_end 1788c2ecf20Sopenharmony_ci movi a7, 0x1000000 1798c2ecf20Sopenharmony_ci sub a11, a10, a6 1808c2ecf20Sopenharmony_ci movi a9, complen 1818c2ecf20Sopenharmony_ci s32i a11, a9, 0 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci movi a0, 0 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci # a6 destination 1868c2ecf20Sopenharmony_ci # a7 maximum size of destination 1878c2ecf20Sopenharmony_ci # a8 source 1888c2ecf20Sopenharmony_ci # a9 ptr to length 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci .extern gunzip 1918c2ecf20Sopenharmony_ci movi a4, gunzip 1928c2ecf20Sopenharmony_ci beqz a4, 1f 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci callx4 a4 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci j 2f 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci # a6 destination start 2008c2ecf20Sopenharmony_ci # a7 maximum size of destination 2018c2ecf20Sopenharmony_ci # a8 source start 2028c2ecf20Sopenharmony_ci # a9 ptr to length 2038c2ecf20Sopenharmony_ci # a10 destination end 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci1: 2068c2ecf20Sopenharmony_ci l32i a9, a8, 0 2078c2ecf20Sopenharmony_ci l32i a11, a8, 4 2088c2ecf20Sopenharmony_ci s32i a9, a6, 0 2098c2ecf20Sopenharmony_ci s32i a11, a6, 4 2108c2ecf20Sopenharmony_ci l32i a9, a8, 8 2118c2ecf20Sopenharmony_ci l32i a11, a8, 12 2128c2ecf20Sopenharmony_ci s32i a9, a6, 8 2138c2ecf20Sopenharmony_ci s32i a11, a6, 12 2148c2ecf20Sopenharmony_ci addi a6, a6, 16 2158c2ecf20Sopenharmony_ci addi a8, a8, 16 2168c2ecf20Sopenharmony_ci blt a6, a10, 1b 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci /* jump to the kernel */ 2208c2ecf20Sopenharmony_ci2: 2218c2ecf20Sopenharmony_ci#if XCHAL_DCACHE_IS_WRITEBACK 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci ___flush_dcache_all a5 a6 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci#endif 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci ___invalidate_icache_all a5 a6 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci isync 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci # a2 Boot parameter list 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci movi a0, _image_start 2348c2ecf20Sopenharmony_ci jx a0 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci .align 16 2378c2ecf20Sopenharmony_ci .data 2388c2ecf20Sopenharmony_ci .globl avail_ram 2398c2ecf20Sopenharmony_ciavail_ram: 2408c2ecf20Sopenharmony_ci .long _heap 2418c2ecf20Sopenharmony_ci .globl end_avail 2428c2ecf20Sopenharmony_ciend_avail: 2438c2ecf20Sopenharmony_ci .long _heap + HEAP_SIZE 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci .comm _stack, STACK_SIZE 2468c2ecf20Sopenharmony_ci .comm _heap, HEAP_SIZE 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci .globl end_avail 2498c2ecf20Sopenharmony_ci .comm complen, 4 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci .end literal_prefix 252