Path: blob/master/arch/xtensa/boot/boot-redboot/bootstrap.S
26439 views
/* SPDX-License-Identifier: GPL-2.0 */1#include <asm/core.h>2#include <asm/regs.h>3#include <asm/asmmacro.h>4#include <asm/cacheasm.h>5#include <asm/processor.h>6/*7* RB-Data: RedBoot data/bss8* P: Boot-Parameters9* L: Kernel-Loader10*11* The Linux-Kernel image including the loader must be loaded12* to a position so that the kernel and the boot parameters13* can fit in the space before the load address.14* ______________________________________________________15* |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|16* ^17* ^ Load address18* ______________________________________________________19* |___Linux-Kernel___|_P_|_L_|___________________________|20*21* The loader copies the parameter to the position that will22* be the end of the kernel and itself to the end of the23* parameter list.24*/2526/* Make sure we have enough space for the 'uncompressor' */2728#define STACK_SIZE 3276829#define HEAP_SIZE (131072*4)3031# a2: Parameter list32# a3: Size of parameter list3334.section .start, "ax"3536.globl __start37/* this must be the first byte of the loader! */38__start:39abi_entry(32) # we do not intend to return40_call0 _start41__start_a0:42.align 44344.section .text, "ax"45.literal_position46.begin literal_prefix .text4748/* put literals in here! */4950.globl _start51_start:5253/* 'reset' window registers */5455movi a4, 156wsr a4, ps57rsync58#if XCHAL_HAVE_WINDOWED59rsr a5, windowbase60ssl a561sll a4, a462wsr a4, windowstart63rsync64#endif65movi a4, KERNEL_PS_WOE_MASK66wsr a4, ps67rsync6869KABI_C0 mov abi_saved0, abi_arg07071/* copy the loader to its address72* Note: The loader itself is a very small piece, so we assume we73* don't partially overlap. We also assume (even more important)74* that the kernel image is out of the way. Usually, when the75* load address of this image is not at an arbitrary address,76* but aligned to some 10K's we shouldn't overlap.77*/7879/* Note: The assembler cannot relax "addi a0, a0, ..." to an80l32r, so we load to a4 first. */8182# addi a4, a0, __start - __start_a083# mov a0, a48485movi a4, __start86movi a5, __start_a087add a4, a0, a488sub a0, a4, a58990movi a4, __start91movi a5, __reloc_end9293# a0: address where this code has been loaded94# a4: compiled address of __start95# a5: compiled end address9697mov.n a7, a098mov.n a8, a4991001:101l32i a10, a7, 0102l32i a11, a7, 4103s32i a10, a8, 0104s32i a11, a8, 4105l32i a10, a7, 8106l32i a11, a7, 12107s32i a10, a8, 8108s32i a11, a8, 12109addi a8, a8, 16110addi a7, a7, 16111blt a8, a5, 1b112113114/* We have to flush and invalidate the caches here before we jump. */115116#if XCHAL_DCACHE_IS_WRITEBACK117118___flush_dcache_all a5 a6119120#endif121122___invalidate_icache_all a5 a6123isync124125movi a11, _reloc126jx a11127128.globl _reloc129_reloc:130131/* RedBoot is now at the end of the memory, so we don't have132* to copy the parameter list. Keep the code around; in case133* we need it again. */134#if 0135# a0: load address136# a2: start address of parameter list137# a3: length of parameter list138# a4: __start139140/* copy the parameter list out of the way */141142movi a6, _param_start143add a3, a2, a31442:145l32i a8, a2, 0146s32i a8, a6, 0147addi a2, a2, 4148addi a6, a6, 4149blt a2, a3, 2b150#endif151152/* clear BSS section */153movi a6, __bss_start154movi a7, __bss_end155movi.n a5, 01563:157s32i a5, a6, 0158addi a6, a6, 4159blt a6, a7, 3b160161movi a5, -16162movi a1, _stack + STACK_SIZE163and a1, a1, a5164165/* Uncompress the kernel */166167# a0: load address168# a2: boot parameter169# a4: __start170171movi a3, __image_load172sub a4, a3, a4173add abi_arg2, a0, a4174175# a1 Stack176# a8(a4) Load address of the image177178movi abi_arg0, _image_start179movi abi_arg4, _image_end180movi abi_arg1, 0x1000000181sub abi_tmp0, abi_arg4, abi_arg0182movi abi_arg3, complen183s32i abi_tmp0, abi_arg3, 0184185movi a0, 0186187# abi_arg0 destination188# abi_arg1 maximum size of destination189# abi_arg2 source190# abi_arg3 ptr to length191192.extern gunzip193movi abi_tmp0, gunzip194beqz abi_tmp0, 1f195196abi_callx abi_tmp0197198j 2f199200201# abi_arg0 destination start202# abi_arg1 maximum size of destination203# abi_arg2 source start204# abi_arg3 ptr to length205# abi_arg4 destination end2062071:208l32i abi_tmp0, abi_arg2, 0209l32i abi_tmp1, abi_arg2, 4210s32i abi_tmp0, abi_arg0, 0211s32i abi_tmp1, abi_arg0, 4212l32i abi_tmp0, abi_arg2, 8213l32i abi_tmp1, abi_arg2, 12214s32i abi_tmp0, abi_arg0, 8215s32i abi_tmp1, abi_arg0, 12216addi abi_arg0, abi_arg0, 16217addi abi_arg2, abi_arg2, 16218blt abi_arg0, abi_arg4, 1b219220221/* jump to the kernel */2222:223#if XCHAL_DCACHE_IS_WRITEBACK224225___flush_dcache_all a5 a6226227#endif228229___invalidate_icache_all a5 a6230231isync232233# a2 Boot parameter list234235KABI_C0 mov abi_arg0, abi_saved0236movi a0, _image_start237jx a0238239.align 16240.data241.globl avail_ram242avail_ram:243.long _heap244.globl end_avail245end_avail:246.long _heap + HEAP_SIZE247248.comm _stack, STACK_SIZE249.comm _heap, HEAP_SIZE250251.globl end_avail252.comm complen, 4253254.end literal_prefix255256257