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