sdk-hwV1.3/lichee/melis-v3.0/source/ekernel/arch/riscv/compressed/head.S

336 lines
7.8 KiB
ArmAsm
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
*
* Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
* the the People's Republic of China and other countries.
* All Allwinner Technology Co.,Ltd. trademarks are used with permission.
*
* DISCLAIMER
* THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
* IF YOU NEED TO INTEGRATE THIRD PARTYS TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
* IN ALLWINNERSSDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
* ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
* ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
* COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
* YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTYS TECHNOLOGY.
*
*
* THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
* PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
* THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
* OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <compiler.h>
#define HEAP_SIZE (0x10000)
.section ".start", "ax", @progbits
.align
.type start, %function
.option norvc
start:
j 1f
.word _magic_sig #
.word _magic_comp
.word _magic_start # zImage
.word _magic_end # zImage
.word input_data_end - 4 # decompress image size
.word 0x04030201 #
1:
# mask all interrupts
csrw mie, 0
csrw mip, 0
# Enable thead extens
li t0, (1 << 22) | (1 << 15)
csrs mxstatus, t0
rdtime s8
/*
* t0 = pc
* t4 = Image
* if t0 < t4 :
* t0 = LC0[8] = _end - restart + =
* t0 = t0 + pc =
* if t4 < t0 :()
* t4 |= 0x1
* else :
* bl cache_on
* else :
* bl cache_on
*/
#ifdef CONFIG_KERNEL_COMPRESS_ELF
la t4, zelfaddr
bnez t4, 1f
la t0, LC0
lw s0, 0 * 4(t0) # LC0
lw t4, 7 * 4(t0) # .L_user_stack_end
sub t0, t0, s0 # calculate the delta offset
add t4, t4, t0
li t0, HEAP_SIZE
add t4, t4, t0 #
#else
la t4, zreladdr
#endif
1:
auipc t0, 0
bgeu t0, t4, 1f
la t1, LC0
lw t2, 8 * 4(t1)
auipc t0, 0
add t0, t0, t2
bltu t4, t0, 2f
1:
jal cache_on
j restart
2:
ori t4, t4, 1 # remember we skipped cache_on
restart:
la t0, LC0
lw s0, 0 * 4(t0) # LC0
lw s1, 1 * 4(t0) # __bss_start
lw s2, 2 * 4(t0) # _end
lw s3, 3 * 4(t0) # _edata
lw s4, 4 * 4(t0) # input+data_end - 4
lw s5, 5 * 4(t0) # _got_start
lw s6, 6 * 4(t0) # _got_end
lw sp, 7 * 4(t0) # .L_user_stack_end
/*
* r0 -= r1 ,
* r6 += r0 _edata, _edata
* r10 += r0
*/
sub t0, t0, s0 # calculate the delta offset
add s3, s3, t0 # _edata
add s4, s4, t0 # inflated kernel size location
/*
* t1
*/
lbu t1, 0(s4)
lbu t2, 1(s4)
slli t2, t2, 8
or t1, t1, t2
lbu t2, 2(s4)
slli t2, t2, 16
or t1, t1, t2
lbu t2, 3(s4)
slli t2, t2, 24
or t1, t1, t2
/*
* sp += r0
* s4 = sp + HEAP_SIZE (C)
*/
add sp, sp, t0
li t5, HEAP_SIZE
add s4, sp, t5
/*
* .
* t4 =
* t1 =
* s4 = , bss/stack/malloc
* 不发生自覆盖的条件: 16KMMU
* t4 >= s4 -> OK
* t4 + t1 <= PC -> OK
*/
# addi s4, s4, 0x4000
bgeu t4, s4, wont_overwrite
add s4, t4, t1
auipc t1, 0
bgeu t1, s4, wont_overwrite
/*
* .
* s3 = _edata (text+data+bss,)
* s4 =
* Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap.
*/
/*
*
* 256B
* s4 = ALIGN_UP(s4, 0xff)
*/
# la t5, ((reloc_code_end - restart + 256) & ~255)
la t5, reloc_code_end
la t3, restart
sub t5, t5, t3
addi t5, t5, 256
li t3, ~0xff
and t5, t5, t3
add s4, s4, t5
andi s4, s4, ~0xff
/*
* 32B
*/
la t1, restart
andi t1, t1, ~0x1f
/*
*
* NOTE:
* t1 restart
* s3
*/
sub t2, s3, t1 # size to copy
addi t2, t2, 0x1f # rounded up to a multiple
andi t2, t2, ~0x1f # ... of 32 bytes
add t3, t2, t1 # src t3
add t2, t2, s4 # dst t2
/*
* byte, t3 <= t1
*
*/
1: lw a0, 0 * 4(t3)
lw a0, 1 * 4(t3)
lw a0, 2 * 4(t3)
lw a0, 3 * 4(t3)
addi t3, t3, 4 * 4
sw a0, 0 * 4(t2)
sw a0, 1 * 4(t2)
sw a0, 2 * 4(t2)
sw a0, 3 * 4(t2)
addi t2, t2, 4 * 4
bgeu t3, t1, 1b
/* 保留重定位代码的偏移 */
sub t6, t2, t3
/* cache_clean_flush may use the stack, so relocate it */
add sp, sp, t6
jal cache_clean_flush
la t1, restart
add t1, t1, t6
jr t1
wont_overwrite:
/*
* t0 = delta()
* s0 = LC0
* s1 = BSS start
* s2 = BSS end
* s3 = _edata
* s4 = input+data_end - 4
* t4 =
* s5 = _got_start
* s6 = _got_end
* sp = .L_user_stack_end
*/
beqz t0, not_relocated
/* 重定位 GOT */
add s5, s5, t0
add s6, s6, t0
/* 重定位 BSS */
add s1, s1, t0
add s2, s2, t0
not_relocated:
1: sw t0, 0(s1)
addi s1, s1, 4
bltu s1, s2, 1b
/*
* cache_on, t4=1
* cache
*/
andi t0, t4, 0x1
beqz t0, 2f
li t5, 1
sub t4, t4, t5
jal cache_on
2:
/*
* C
* a0 =
*/
mv x3, t4
mv a0, t4
mv a1 , sp # free_mem_start
li t5, HEAP_SIZE
add a2, sp, t5 # free_mem_end
mv a3, x0 # architecture ID
jal decompress_kernel
jal cache_clean_flush
#ifdef CONFIG_KERNEL_COMPRESS_ELF
mv a0, x3
jal load_elf_image
mv a0, x3
jal elf_get_entry_addr
mv x3, a0
jal cache_clean_flush
#endif
jal cache_off
mv a0, s8
jr x3 # __enter_kernel
.align 5
.type LC0, %object
LC0:
.word LC0 # s0
.word __bss_start # s1
.word _end # s2
.word _edata # s3
.word input_data_end - 4 # s4 (inflated size location)
.word _got_start # s5
.word _got_end # s6
.word .L_user_stack_end # sp
.word _end - restart # s7
.size LC0, . - LC0
.align 5
cache_on:
li t0, 0x11ff
csrw mhcr, t0
li t0, 0x638000
csrw mxstatus, t0
li t0, 0x11ff
csrw mhint, t0
fence
sync
ret
cache_off:
li t0, 0x3
csrc mhcr, x0
fence
sync
ret
cache_clean_flush:
dcache.call
icache.iall
fence
sync
ret
reloc_code_end:
.align 6
.section ".stack", "aw", %nobits
.L_user_stack: .space 4096
.L_user_stack_end: