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