linux/arch/xtensa/boot/boot-redboot/bootstrap.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#include <asm/core.h>
   3#include <asm/regs.h>
   4#include <asm/asmmacro.h>
   5#include <asm/cacheasm.h>
   6#include <asm/processor.h>
   7        /*
   8         * RB-Data: RedBoot data/bss
   9         * P:       Boot-Parameters
  10         * L:       Kernel-Loader
  11         *
  12         * The Linux-Kernel image including the loader must be loaded
  13         * to a position so that the kernel and the boot parameters
  14         * can fit in the space before the load address.
  15         *  ______________________________________________________
  16         * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
  17         *                          ^
  18         *                          ^ Load address
  19         *  ______________________________________________________
  20         * |___Linux-Kernel___|_P_|_L_|___________________________|
  21         *
  22         * The loader copies the parameter to the position that will
  23         * be the end of the kernel and itself to the end of the
  24         * parameter list.
  25         */
  26
  27/* Make sure we have enough space for the 'uncompressor' */
  28
  29#define STACK_SIZE 32768
  30#define HEAP_SIZE (131072*4)
  31
  32        # a2: Parameter list
  33        # a3: Size of parameter list
  34
  35        .section .start, "ax"
  36
  37        .globl __start
  38        /* this must be the first byte of the loader! */
  39__start:
  40        abi_entry(32)           # we do not intend to return
  41        _call0  _start
  42__start_a0:
  43        .align 4
  44
  45        .section .text, "ax"
  46        .literal_position
  47        .begin literal_prefix .text
  48
  49        /* put literals in here! */
  50
  51        .globl _start
  52_start:
  53
  54        /* 'reset' window registers */
  55
  56        movi    a4, 1
  57        wsr     a4, ps
  58        rsync
  59#if XCHAL_HAVE_WINDOWED
  60        rsr     a5, windowbase
  61        ssl     a5
  62        sll     a4, a4
  63        wsr     a4, windowstart
  64        rsync
  65#endif
  66        movi    a4, KERNEL_PS_WOE_MASK
  67        wsr     a4, ps
  68        rsync
  69
  70KABI_C0 mov     abi_saved0, abi_arg0
  71
  72        /* copy the loader to its address
  73         * Note: The loader itself is a very small piece, so we assume we
  74         *       don't partially overlap. We also assume (even more important)
  75         *       that the kernel image is out of the way. Usually, when the
  76         *       load address of this image is not at an arbitrary address,
  77         *       but aligned to some 10K's we shouldn't overlap.
  78         */
  79
  80        /* Note: The assembler cannot relax "addi a0, a0, ..." to an
  81           l32r, so we load to a4 first. */
  82
  83        # addi  a4, a0, __start - __start_a0
  84        # mov   a0, a4
  85
  86        movi    a4, __start
  87        movi    a5, __start_a0
  88        add     a4, a0, a4
  89        sub     a0, a4, a5
  90
  91        movi    a4, __start
  92        movi    a5, __reloc_end
  93
  94        # a0: address where this code has been loaded
  95        # a4: compiled address of __start
  96        # a5: compiled end address
  97
  98        mov.n   a7, a0
  99        mov.n   a8, a4
 100
 1011:
 102        l32i    a10, a7, 0
 103        l32i    a11, a7, 4
 104        s32i    a10, a8, 0
 105        s32i    a11, a8, 4
 106        l32i    a10, a7, 8
 107        l32i    a11, a7, 12
 108        s32i    a10, a8, 8
 109        s32i    a11, a8, 12
 110        addi    a8, a8, 16
 111        addi    a7, a7, 16
 112        blt     a8, a5, 1b
 113
 114
 115        /* We have to flush and invalidate the caches here before we jump. */
 116
 117#if XCHAL_DCACHE_IS_WRITEBACK
 118
 119        ___flush_dcache_all a5 a6
 120
 121#endif
 122
 123        ___invalidate_icache_all a5 a6
 124        isync
 125
 126        movi    a11, _reloc
 127        jx      a11
 128
 129        .globl _reloc
 130_reloc:
 131
 132        /* RedBoot is now at the end of the memory, so we don't have
 133         * to copy the parameter list. Keep the code around; in case
 134         * we need it again. */
 135#if 0
 136        # a0: load address
 137        # a2: start address of parameter list
 138        # a3: length of parameter list
 139        # a4: __start
 140
 141        /* copy the parameter list out of the way */
 142
 143        movi    a6, _param_start
 144        add     a3, a2, a3
 1452:
 146        l32i    a8, a2, 0
 147        s32i    a8, a6, 0
 148        addi    a2, a2, 4
 149        addi    a6, a6, 4
 150        blt     a2, a3, 2b
 151#endif
 152
 153        /* clear BSS section */
 154        movi    a6, __bss_start
 155        movi    a7, __bss_end
 156        movi.n  a5, 0
 1573:
 158        s32i    a5, a6, 0
 159        addi    a6, a6, 4
 160        blt     a6, a7, 3b
 161
 162        movi    a5, -16
 163        movi    a1, _stack + STACK_SIZE
 164        and     a1, a1, a5
 165
 166        /* Uncompress the kernel */
 167
 168        # a0: load address
 169        # a2: boot parameter
 170        # a4: __start
 171
 172        movi    a3, __image_load
 173        sub     a4, a3, a4
 174        add     abi_arg2, a0, a4
 175
 176        # a1  Stack
 177        # a8(a4)  Load address of the image
 178
 179        movi    abi_arg0, _image_start
 180        movi    abi_arg4, _image_end
 181        movi    abi_arg1, 0x1000000
 182        sub     abi_tmp0, abi_arg4, abi_arg0
 183        movi    abi_arg3, complen
 184        s32i    abi_tmp0, abi_arg3, 0
 185
 186        movi    a0, 0
 187
 188        # abi_arg0 destination
 189        # abi_arg1 maximum size of destination
 190        # abi_arg2 source
 191        # abi_arg3 ptr to length
 192
 193        .extern gunzip
 194        movi    abi_tmp0, gunzip
 195        beqz    abi_tmp0, 1f
 196
 197        abi_callx       abi_tmp0
 198
 199        j       2f
 200
 201
 202        # abi_arg0 destination start
 203        # abi_arg1 maximum size of destination
 204        # abi_arg2 source start
 205        # abi_arg3 ptr to length
 206        # abi_arg4 destination end
 207
 2081:
 209        l32i    abi_tmp0, abi_arg2, 0
 210        l32i    abi_tmp1, abi_arg2, 4
 211        s32i    abi_tmp0, abi_arg0, 0
 212        s32i    abi_tmp1, abi_arg0, 4
 213        l32i    abi_tmp0, abi_arg2, 8
 214        l32i    abi_tmp1, abi_arg2, 12
 215        s32i    abi_tmp0, abi_arg0, 8
 216        s32i    abi_tmp1, abi_arg0, 12
 217        addi    abi_arg0, abi_arg0, 16
 218        addi    abi_arg2, abi_arg2, 16
 219        blt     abi_arg0, abi_arg4, 1b
 220
 221
 222        /* jump to the kernel */
 2232:
 224#if XCHAL_DCACHE_IS_WRITEBACK
 225
 226        ___flush_dcache_all a5 a6
 227
 228#endif
 229
 230        ___invalidate_icache_all a5 a6
 231
 232        isync
 233
 234        # a2  Boot parameter list
 235
 236KABI_C0 mov     abi_arg0, abi_saved0
 237        movi    a0, _image_start
 238        jx      a0
 239
 240        .align 16
 241        .data
 242        .globl avail_ram
 243avail_ram:
 244        .long   _heap
 245        .globl end_avail
 246end_avail:
 247        .long   _heap + HEAP_SIZE
 248
 249        .comm _stack, STACK_SIZE
 250        .comm _heap, HEAP_SIZE
 251
 252        .globl end_avail
 253        .comm complen, 4
 254
 255        .end    literal_prefix
 256