1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 2367b8112SChris Zankel#include <variant/core.h> 3173d6681SChris Zankel#include <asm/regs.h> 4173d6681SChris Zankel#include <asm/asmmacro.h> 5173d6681SChris Zankel#include <asm/cacheasm.h> 64bedea94SChris Zankel /* 74bedea94SChris Zankel * RB-Data: RedBoot data/bss 84bedea94SChris Zankel * P: Boot-Parameters 94bedea94SChris Zankel * L: Kernel-Loader 104bedea94SChris Zankel * 114bedea94SChris Zankel * The Linux-Kernel image including the loader must be loaded 124bedea94SChris Zankel * to a position so that the kernel and the boot parameters 134bedea94SChris Zankel * can fit in the space before the load address. 144bedea94SChris Zankel * ______________________________________________________ 154bedea94SChris Zankel * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______| 164bedea94SChris Zankel * ^ 174bedea94SChris Zankel * ^ Load address 184bedea94SChris Zankel * ______________________________________________________ 194bedea94SChris Zankel * |___Linux-Kernel___|_P_|_L_|___________________________| 204bedea94SChris Zankel * 214bedea94SChris Zankel * The loader copies the parameter to the position that will 224bedea94SChris Zankel * be the end of the kernel and itself to the end of the 234bedea94SChris Zankel * parameter list. 244bedea94SChris Zankel */ 254bedea94SChris Zankel 264bedea94SChris Zankel/* Make sure we have enough space for the 'uncompressor' */ 274bedea94SChris Zankel 284bedea94SChris Zankel#define STACK_SIZE 32768 294bedea94SChris Zankel#define HEAP_SIZE (131072*4) 304bedea94SChris Zankel 314bedea94SChris Zankel # a2: Parameter list 324bedea94SChris Zankel # a3: Size of parameter list 334bedea94SChris Zankel 344bedea94SChris Zankel .section .start, "ax" 354bedea94SChris Zankel 364bedea94SChris Zankel .globl __start 374bedea94SChris Zankel /* this must be the first byte of the loader! */ 384bedea94SChris Zankel__start: 394bedea94SChris Zankel entry sp, 32 # we do not intend to return 404bedea94SChris Zankel _call0 _start 414bedea94SChris Zankel__start_a0: 424bedea94SChris Zankel .align 4 434bedea94SChris Zankel 444bedea94SChris Zankel .section .text, "ax" 45f8f02ca7SMax Filippov .literal_position 464bedea94SChris Zankel .begin literal_prefix .text 474bedea94SChris Zankel 484bedea94SChris Zankel /* put literals in here! */ 494bedea94SChris Zankel 504bedea94SChris Zankel .globl _start 514bedea94SChris Zankel_start: 524bedea94SChris Zankel 534bedea94SChris Zankel /* 'reset' window registers */ 544bedea94SChris Zankel 554bedea94SChris Zankel movi a4, 1 56bc5378fcSMax Filippov wsr a4, ps 574bedea94SChris Zankel rsync 584bedea94SChris Zankel 59bc5378fcSMax Filippov rsr a5, windowbase 604bedea94SChris Zankel ssl a5 614bedea94SChris Zankel sll a4, a4 62bc5378fcSMax Filippov wsr a4, windowstart 634bedea94SChris Zankel rsync 644bedea94SChris Zankel 654bedea94SChris Zankel movi a4, 0x00040000 66bc5378fcSMax Filippov wsr a4, ps 674bedea94SChris Zankel rsync 684bedea94SChris Zankel 694bedea94SChris Zankel /* copy the loader to its address 704bedea94SChris Zankel * Note: The loader itself is a very small piece, so we assume we 714bedea94SChris Zankel * don't partially overlap. We also assume (even more important) 724bedea94SChris Zankel * that the kernel image is out of the way. Usually, when the 734bedea94SChris Zankel * load address of this image is not at an arbitrary address, 744bedea94SChris Zankel * but aligned to some 10K's we shouldn't overlap. 754bedea94SChris Zankel */ 764bedea94SChris Zankel 774bedea94SChris Zankel /* Note: The assembler cannot relax "addi a0, a0, ..." to an 784bedea94SChris Zankel l32r, so we load to a4 first. */ 794bedea94SChris Zankel 80173d6681SChris Zankel # addi a4, a0, __start - __start_a0 81173d6681SChris Zankel # mov a0, a4 82173d6681SChris Zankel 83173d6681SChris Zankel movi a4, __start 84173d6681SChris Zankel movi a5, __start_a0 85173d6681SChris Zankel add a4, a0, a4 86173d6681SChris Zankel sub a0, a4, a5 87173d6681SChris Zankel 884bedea94SChris Zankel movi a4, __start 894bedea94SChris Zankel movi a5, __reloc_end 904bedea94SChris Zankel 914bedea94SChris Zankel # a0: address where this code has been loaded 924bedea94SChris Zankel # a4: compiled address of __start 934bedea94SChris Zankel # a5: compiled end address 944bedea94SChris Zankel 954bedea94SChris Zankel mov.n a7, a0 964bedea94SChris Zankel mov.n a8, a4 974bedea94SChris Zankel 984bedea94SChris Zankel1: 994bedea94SChris Zankel l32i a10, a7, 0 1004bedea94SChris Zankel l32i a11, a7, 4 1014bedea94SChris Zankel s32i a10, a8, 0 1024bedea94SChris Zankel s32i a11, a8, 4 1034bedea94SChris Zankel l32i a10, a7, 8 1044bedea94SChris Zankel l32i a11, a7, 12 1054bedea94SChris Zankel s32i a10, a8, 8 1064bedea94SChris Zankel s32i a11, a8, 12 1074bedea94SChris Zankel addi a8, a8, 16 1084bedea94SChris Zankel addi a7, a7, 16 1094bedea94SChris Zankel blt a8, a5, 1b 1104bedea94SChris Zankel 1114bedea94SChris Zankel 1124bedea94SChris Zankel /* We have to flush and invalidate the caches here before we jump. */ 1134bedea94SChris Zankel 1144bedea94SChris Zankel#if XCHAL_DCACHE_IS_WRITEBACK 115173d6681SChris Zankel 116173d6681SChris Zankel ___flush_dcache_all a5 a6 117173d6681SChris Zankel 1184bedea94SChris Zankel#endif 119173d6681SChris Zankel 120173d6681SChris Zankel ___invalidate_icache_all a5 a6 121173d6681SChris Zankel isync 1224bedea94SChris Zankel 1234bedea94SChris Zankel movi a11, _reloc 1244bedea94SChris Zankel jx a11 1254bedea94SChris Zankel 1264bedea94SChris Zankel .globl _reloc 1274bedea94SChris Zankel_reloc: 1284bedea94SChris Zankel 1294bedea94SChris Zankel /* RedBoot is now at the end of the memory, so we don't have 1304bedea94SChris Zankel * to copy the parameter list. Keep the code around; in case 1314bedea94SChris Zankel * we need it again. */ 1324bedea94SChris Zankel#if 0 1334bedea94SChris Zankel # a0: load address 1344bedea94SChris Zankel # a2: start address of parameter list 1354bedea94SChris Zankel # a3: length of parameter list 1364bedea94SChris Zankel # a4: __start 1374bedea94SChris Zankel 1384bedea94SChris Zankel /* copy the parameter list out of the way */ 1394bedea94SChris Zankel 1404bedea94SChris Zankel movi a6, _param_start 1414bedea94SChris Zankel add a3, a2, a3 1424bedea94SChris Zankel2: 1434bedea94SChris Zankel l32i a8, a2, 0 1444bedea94SChris Zankel s32i a8, a6, 0 1454bedea94SChris Zankel addi a2, a2, 4 1464bedea94SChris Zankel addi a6, a6, 4 1474bedea94SChris Zankel blt a2, a3, 2b 1484bedea94SChris Zankel#endif 1494bedea94SChris Zankel 1504bedea94SChris Zankel /* clear BSS section */ 1514bedea94SChris Zankel movi a6, __bss_start 1524bedea94SChris Zankel movi a7, __bss_end 1534bedea94SChris Zankel movi.n a5, 0 1544bedea94SChris Zankel3: 1554bedea94SChris Zankel s32i a5, a6, 0 1564bedea94SChris Zankel addi a6, a6, 4 1574bedea94SChris Zankel blt a6, a7, 3b 1584bedea94SChris Zankel 1594bedea94SChris Zankel movi a5, -16 1604bedea94SChris Zankel movi a1, _stack + STACK_SIZE 1614bedea94SChris Zankel and a1, a1, a5 1624bedea94SChris Zankel 1634bedea94SChris Zankel /* Uncompress the kernel */ 1644bedea94SChris Zankel 1654bedea94SChris Zankel # a0: load address 1664bedea94SChris Zankel # a2: boot parameter 1674bedea94SChris Zankel # a4: __start 1684bedea94SChris Zankel 1694bedea94SChris Zankel movi a3, __image_load 1704bedea94SChris Zankel sub a4, a3, a4 1714bedea94SChris Zankel add a8, a0, a4 1724bedea94SChris Zankel 1734bedea94SChris Zankel # a1 Stack 1744bedea94SChris Zankel # a8(a4) Load address of the image 1754bedea94SChris Zankel 1764bedea94SChris Zankel movi a6, _image_start 1774bedea94SChris Zankel movi a10, _image_end 1784bedea94SChris Zankel movi a7, 0x1000000 1794bedea94SChris Zankel sub a11, a10, a6 1804bedea94SChris Zankel movi a9, complen 1814bedea94SChris Zankel s32i a11, a9, 0 1824bedea94SChris Zankel 1834bedea94SChris Zankel movi a0, 0 1844bedea94SChris Zankel 1854bedea94SChris Zankel # a6 destination 1864bedea94SChris Zankel # a7 maximum size of destination 1874bedea94SChris Zankel # a8 source 1884bedea94SChris Zankel # a9 ptr to length 1894bedea94SChris Zankel 1904bedea94SChris Zankel .extern gunzip 1914bedea94SChris Zankel movi a4, gunzip 1924bedea94SChris Zankel beqz a4, 1f 1934bedea94SChris Zankel 1944bedea94SChris Zankel callx4 a4 1954bedea94SChris Zankel 1964bedea94SChris Zankel j 2f 1974bedea94SChris Zankel 1984bedea94SChris Zankel 1994bedea94SChris Zankel # a6 destination start 2004bedea94SChris Zankel # a7 maximum size of destination 2014bedea94SChris Zankel # a8 source start 2024bedea94SChris Zankel # a9 ptr to length 2034bedea94SChris Zankel # a10 destination end 2044bedea94SChris Zankel 2054bedea94SChris Zankel1: 2064bedea94SChris Zankel l32i a9, a8, 0 2074bedea94SChris Zankel l32i a11, a8, 4 2084bedea94SChris Zankel s32i a9, a6, 0 2094bedea94SChris Zankel s32i a11, a6, 4 2104bedea94SChris Zankel l32i a9, a8, 8 2114bedea94SChris Zankel l32i a11, a8, 12 2124bedea94SChris Zankel s32i a9, a6, 8 2134bedea94SChris Zankel s32i a11, a6, 12 2144bedea94SChris Zankel addi a6, a6, 16 2154bedea94SChris Zankel addi a8, a8, 16 2164bedea94SChris Zankel blt a6, a10, 1b 2174bedea94SChris Zankel 2184bedea94SChris Zankel 2194bedea94SChris Zankel /* jump to the kernel */ 2204bedea94SChris Zankel2: 2214bedea94SChris Zankel#if XCHAL_DCACHE_IS_WRITEBACK 222173d6681SChris Zankel 223173d6681SChris Zankel ___flush_dcache_all a5 a6 224173d6681SChris Zankel 2254bedea94SChris Zankel#endif 226173d6681SChris Zankel 227173d6681SChris Zankel ___invalidate_icache_all a5 a6 228173d6681SChris Zankel 229173d6681SChris Zankel isync 2304bedea94SChris Zankel 2314bedea94SChris Zankel # a2 Boot parameter list 2324bedea94SChris Zankel 2334bedea94SChris Zankel movi a0, _image_start 2344bedea94SChris Zankel jx a0 2354bedea94SChris Zankel 2364bedea94SChris Zankel .align 16 2374bedea94SChris Zankel .data 2384bedea94SChris Zankel .globl avail_ram 2394bedea94SChris Zankelavail_ram: 2404bedea94SChris Zankel .long _heap 2414bedea94SChris Zankel .globl end_avail 2424bedea94SChris Zankelend_avail: 2434bedea94SChris Zankel .long _heap + HEAP_SIZE 2444bedea94SChris Zankel 2454bedea94SChris Zankel .comm _stack, STACK_SIZE 2464bedea94SChris Zankel .comm _heap, HEAP_SIZE 2474bedea94SChris Zankel 2484bedea94SChris Zankel .globl end_avail 2494bedea94SChris Zankel .comm complen, 4 2504bedea94SChris Zankel 2514bedea94SChris Zankel .end literal_prefix 252