123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #include <variant/core.h>
- #include <asm/regs.h>
- #include <asm/asmmacro.h>
- #include <asm/cacheasm.h>
- /*
- * RB-Data: RedBoot data/bss
- * P: Boot-Parameters
- * L: Kernel-Loader
- *
- * The Linux-Kernel image including the loader must be loaded
- * to a position so that the kernel and the boot parameters
- * can fit in the space before the load address.
- * ______________________________________________________
- * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
- * ^
- * ^ Load address
- * ______________________________________________________
- * |___Linux-Kernel___|_P_|_L_|___________________________|
- *
- * The loader copies the parameter to the position that will
- * be the end of the kernel and itself to the end of the
- * parameter list.
- */
- /* Make sure we have enough space for the 'uncompressor' */
- #define STACK_SIZE 32768
- #define HEAP_SIZE (131072*4)
- # a2: Parameter list
- # a3: Size of parameter list
- .section .start, "ax"
- .globl __start
- /* this must be the first byte of the loader! */
- __start:
- entry sp, 32 # we do not intend to return
- _call0 _start
- __start_a0:
- .align 4
- .section .text, "ax"
- .begin literal_prefix .text
- /* put literals in here! */
- .globl _start
- _start:
- /* 'reset' window registers */
- movi a4, 1
- wsr a4, ps
- rsync
- rsr a5, windowbase
- ssl a5
- sll a4, a4
- wsr a4, windowstart
- rsync
- movi a4, 0x00040000
- wsr a4, ps
- rsync
- /* copy the loader to its address
- * Note: The loader itself is a very small piece, so we assume we
- * don't partially overlap. We also assume (even more important)
- * that the kernel image is out of the way. Usually, when the
- * load address of this image is not at an arbitrary address,
- * but aligned to some 10K's we shouldn't overlap.
- */
- /* Note: The assembler cannot relax "addi a0, a0, ..." to an
- l32r, so we load to a4 first. */
- # addi a4, a0, __start - __start_a0
- # mov a0, a4
- movi a4, __start
- movi a5, __start_a0
- add a4, a0, a4
- sub a0, a4, a5
- movi a4, __start
- movi a5, __reloc_end
- # a0: address where this code has been loaded
- # a4: compiled address of __start
- # a5: compiled end address
- mov.n a7, a0
- mov.n a8, a4
- 1:
- l32i a10, a7, 0
- l32i a11, a7, 4
- s32i a10, a8, 0
- s32i a11, a8, 4
- l32i a10, a7, 8
- l32i a11, a7, 12
- s32i a10, a8, 8
- s32i a11, a8, 12
- addi a8, a8, 16
- addi a7, a7, 16
- blt a8, a5, 1b
- /* We have to flush and invalidate the caches here before we jump. */
- #if XCHAL_DCACHE_IS_WRITEBACK
- ___flush_dcache_all a5 a6
- #endif
- ___invalidate_icache_all a5 a6
- isync
- movi a11, _reloc
- jx a11
- .globl _reloc
- _reloc:
- /* RedBoot is now at the end of the memory, so we don't have
- * to copy the parameter list. Keep the code around; in case
- * we need it again. */
- #if 0
- # a0: load address
- # a2: start address of parameter list
- # a3: length of parameter list
- # a4: __start
- /* copy the parameter list out of the way */
- movi a6, _param_start
- add a3, a2, a3
- 2:
- l32i a8, a2, 0
- s32i a8, a6, 0
- addi a2, a2, 4
- addi a6, a6, 4
- blt a2, a3, 2b
- #endif
- /* clear BSS section */
- movi a6, __bss_start
- movi a7, __bss_end
- movi.n a5, 0
- 3:
- s32i a5, a6, 0
- addi a6, a6, 4
- blt a6, a7, 3b
- movi a5, -16
- movi a1, _stack + STACK_SIZE
- and a1, a1, a5
- /* Uncompress the kernel */
- # a0: load address
- # a2: boot parameter
- # a4: __start
- movi a3, __image_load
- sub a4, a3, a4
- add a8, a0, a4
- # a1 Stack
- # a8(a4) Load address of the image
- movi a6, _image_start
- movi a10, _image_end
- movi a7, 0x1000000
- sub a11, a10, a6
- movi a9, complen
- s32i a11, a9, 0
- movi a0, 0
- # a6 destination
- # a7 maximum size of destination
- # a8 source
- # a9 ptr to length
- .extern gunzip
- movi a4, gunzip
- beqz a4, 1f
- callx4 a4
- j 2f
- # a6 destination start
- # a7 maximum size of destination
- # a8 source start
- # a9 ptr to length
- # a10 destination end
- 1:
- l32i a9, a8, 0
- l32i a11, a8, 4
- s32i a9, a6, 0
- s32i a11, a6, 4
- l32i a9, a8, 8
- l32i a11, a8, 12
- s32i a9, a6, 8
- s32i a11, a6, 12
- addi a6, a6, 16
- addi a8, a8, 16
- blt a6, a10, 1b
- /* jump to the kernel */
- 2:
- #if XCHAL_DCACHE_IS_WRITEBACK
- ___flush_dcache_all a5 a6
- #endif
- ___invalidate_icache_all a5 a6
- isync
- # a2 Boot parameter list
- movi a0, _image_start
- jx a0
- .align 16
- .data
- .globl avail_ram
- avail_ram:
- .long _heap
- .globl end_avail
- end_avail:
- .long _heap + HEAP_SIZE
- .comm _stack, STACK_SIZE
- .comm _heap, HEAP_SIZE
- .globl end_avail
- .comm complen, 4
- .end literal_prefix
|