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