336 lines
9.4 KiB
ArmAsm
336 lines
9.4 KiB
ArmAsm
/*******************************************************************************
|
|
* DISCLAIMER
|
|
* This software is supplied by Renesas Electronics Corporation and is only
|
|
* intended for use with Renesas products. No other uses are authorized. This
|
|
* software is owned by Renesas Electronics Corporation and is protected under
|
|
* all applicable laws, including copyright laws.
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
|
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
|
|
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
|
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
|
|
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
|
|
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
|
|
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
|
|
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
* Renesas reserves the right, without notice, to make changes to this software
|
|
* and to discontinue the availability of this software. By using this software,
|
|
* you agree to the additional terms and conditions found by accessing the
|
|
* following link:
|
|
* http://www.renesas.com/disclaimer
|
|
* Copyright 2018-2023 Renesas Electronics Corporation All rights reserved.
|
|
*******************************************************************************/
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
* DESCRIPTION : Image load function
|
|
******************************************************************************/
|
|
/******************************************************************************
|
|
* @file loader_s4.S
|
|
* - Version : 0.06
|
|
* @brief
|
|
* .
|
|
*****************************************************************************/
|
|
/******************************************************************************
|
|
* History : DD.MM.YYYY Version Description
|
|
* : 02.02.2022 0.01 First Release
|
|
* : 27.06.2022 0.02 Remove unused definitions
|
|
* : 02.08.2022 0.03 Support WDT
|
|
* : 31.10.2022 0.04 License notation change.
|
|
* : 14.12.2022 0.05 Support MMU
|
|
* : 17.02.2023 0.06 Modified instruction and General purpose
|
|
* register to lower case.
|
|
*****************************************************************************/
|
|
|
|
#include "asm_macros.S"
|
|
|
|
/* SCTLR definitions */
|
|
#define SCTLR_M_BIT (1 << 0)
|
|
#define SCTLR_A_BIT (1 << 1)
|
|
#define SCTLR_SA_BIT (1 << 3)
|
|
#define SCTLR_I_BIT (1 << 12)
|
|
#define SCTLR_WXN_BIT (1 << 19)
|
|
#define SCTLR_EE_BIT (1 << 25)
|
|
#define SCTLR_RESET_VAL (SCTLR_SA_BIT)
|
|
#define SCTLR_MMU_ON (SCTLR_M_BIT)
|
|
#define SCTLR_OFF ~(SCTLR_M_BIT | SCTLR_I_BIT | SCTLR_A_BIT)
|
|
|
|
/* SCR definitions */
|
|
#define SCR_RES1_BITS ((1 << 4) | (1 << 5))
|
|
#define SCR_TWEDEL_SHIFT (30)
|
|
#define SCR_TWEDEL_MASK (0xf)
|
|
#define SCR_AMVOFFEN_BIT (1 << 35)
|
|
#define SCR_TWEDEn_BIT (1 << 29)
|
|
#define SCR_ECVEN_BIT (1 << 28)
|
|
#define SCR_FGTEN_BIT (1 << 27)
|
|
#define SCR_ATA_BIT (1 << 26)
|
|
#define SCR_FIEN_BIT (1 << 21)
|
|
#define SCR_EEL2_BIT (1 << 18)
|
|
#define SCR_API_BIT (1 << 17)
|
|
#define SCR_APK_BIT (1 << 16)
|
|
#define SCR_TERR_BIT (1 << 15)
|
|
#define SCR_TWE_BIT (1 << 13)
|
|
#define SCR_TWI_BIT (1 << 12)
|
|
#define SCR_ST_BIT (1 << 11)
|
|
#define SCR_RW_BIT (1 << 10)
|
|
#define SCR_SIF_BIT (1 << 9)
|
|
#define SCR_HCE_BIT (1 << 8)
|
|
#define SCR_SMD_BIT (1 << 7)
|
|
#define SCR_EA_BIT (1 << 3)
|
|
#define SCR_FIQ_BIT (1 << 2)
|
|
#define SCR_IRQ_BIT (1 << 1)
|
|
#define SCR_NS_BIT (1 << 0)
|
|
#define SCR_VALID_BIT_MASK (0x2f8f)
|
|
#define SCR_RESET_VAL SCR_RES1_BITS
|
|
|
|
/* CPSR/SPSR definitions */
|
|
#define DAIF_FIQ_BIT (1 << 0)
|
|
#define DAIF_IRQ_BIT (1 << 1)
|
|
#define DAIF_ABT_BIT (1 << 2)
|
|
#define DAIF_DBG_BIT (1 << 3)
|
|
#define SPSR_DAIF_SHIFT (6)
|
|
#define SPSR_DAIF_MASK (0xf)
|
|
|
|
#define SPSR_AIF_SHIFT (6)
|
|
#define SPSR_AIF_MASK (0x7)
|
|
|
|
#define SPSR_E_SHIFT (9)
|
|
#define SPSR_E_MASK (0x1)
|
|
#define SPSR_E_LITTLE (0x0)
|
|
#define SPSR_E_BIG (0x1)
|
|
|
|
#define SPSR_T_SHIFT (5)
|
|
#define SPSR_T_MASK (0x1)
|
|
#define SPSR_T_ARM (0x0)
|
|
#define SPSR_T_THUMB (0x1)
|
|
|
|
#define SPSR_M_SHIFT (4)
|
|
#define SPSR_M_MASK (0x1)
|
|
#define SPSR_M_AARCH64 (0x0)
|
|
#define SPSR_M_AARCH32 (0x1)
|
|
|
|
#define SPSR_EL_SHIFT (2)
|
|
#define SPSR_EL_WIDTH (2)
|
|
|
|
/* TCR definitions */
|
|
#define TCR_BIT31_RES1 (1 << 31)
|
|
#define TCR_BIT23_RES1 (1 << 23)
|
|
#define TCR_PS (0 << 16)
|
|
#define TCR_TG0 (0 << 14)
|
|
#define TCR_SH0 (3 << 12)
|
|
#define TCR_ORGN0 (3 << 10)
|
|
#define TCR_IRGN0 (3 << 8)
|
|
#define TCR_T0SZ (32 << 0)
|
|
|
|
#define TCR_VAL \
|
|
(TCR_BIT31_RES1 | TCR_BIT23_RES1 | TCR_PS | TCR_TG0 | TCR_SH0 | TCR_ORGN0 | TCR_IRGN0 | TCR_T0SZ)
|
|
|
|
/* MAIR definitions */
|
|
#define MAIR_ATTR0 (0x00 << 0) /* Device-nGnRnE memory */
|
|
#define MAIR_ATTR1 (0x4A << 8) /* Normal memory, Outer Non-cacheable, Inner Write-Through Non-transient */
|
|
#define MAIR_ATTR2 (0x44 << 16) /* Normal memory, Outer Non-cacheable, Inner Non-cacheable */
|
|
#define MAIR_ATTR3 (0x00 << 24)
|
|
#define MAIR_ATTR4 (0x00 << 32)
|
|
#define MAIR_ATTR5 (0x00 << 40)
|
|
#define MAIR_ATTR6 (0x00 << 48)
|
|
#define MAIR_ATTR7 (0x00 << 56)
|
|
|
|
#define MAIR_VAL \
|
|
(MAIR_ATTR7 | MAIR_ATTR6 | MAIR_ATTR5 | MAIR_ATTR4 | MAIR_ATTR3 | MAIR_ATTR2 | MAIR_ATTR1 | MAIR_ATTR0)
|
|
#define MAIR_INIT_VAL (0x44E048E000098AA4)
|
|
|
|
#define BIT_64Cx(nr) (1 << (nr))
|
|
#define SPSR_SSBS_BIT_AARCH64 BIT_64Cx(12)
|
|
#define SPSR_SSBS_BIT_AARCH32 BIT_64Cx(23)
|
|
|
|
#define DISABLE_ALL_EXCEPTIONS \
|
|
(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
|
|
|
|
#define DISABLE_INTERRUPTS (DAIF_FIQ_BIT | DAIF_IRQ_BIT)
|
|
#define MODE_RW_SHIFT (0x4)
|
|
#define MODE_SP_MASK (0x1)
|
|
#define MODE_SP_SHIFT (0x0)
|
|
#define MODE_EL_MASK (0x3)
|
|
#define MODE_EL_SHIFT (0x2)
|
|
#define MODE_EL3 (0x3)
|
|
|
|
#define MODE_RW_64 (0x0)
|
|
#define MODE_SP_ELX (0x1)
|
|
|
|
#define SPSR_64 (((MODE_RW_64 << MODE_RW_SHIFT) | \
|
|
((MODE_EL3 & MODE_EL_MASK) << MODE_EL_SHIFT) | \
|
|
((MODE_SP_ELX & MODE_SP_MASK) << MODE_SP_SHIFT) | \
|
|
((DISABLE_ALL_EXCEPTIONS & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)) & \
|
|
(~(SPSR_SSBS_BIT_AARCH64)))
|
|
|
|
|
|
.global Startup
|
|
|
|
/*****************************************************************************
|
|
* Reset Hander
|
|
*****************************************************************************/
|
|
Startup:
|
|
/* initialize registers*/
|
|
ldr x0, =0
|
|
ldr x1, =0
|
|
ldr x2, =0
|
|
ldr x3, =0
|
|
ldr x4, =0
|
|
ldr x5, =0
|
|
ldr x6, =0
|
|
ldr x7, =0
|
|
ldr x8, =0
|
|
ldr x9, =0
|
|
ldr x10, =0
|
|
ldr x11, =0
|
|
ldr x12, =0
|
|
ldr x13, =0
|
|
ldr x14, =0
|
|
ldr x15, =0
|
|
ldr x16, =0
|
|
ldr x17, =0
|
|
ldr x18, =0
|
|
ldr x19, =0
|
|
ldr x20, =0
|
|
ldr x21, =0
|
|
ldr x22, =0
|
|
ldr x23, =0
|
|
ldr x24, =0
|
|
ldr x25, =0
|
|
ldr x26, =0
|
|
ldr x27, =0
|
|
ldr x28, =0
|
|
ldr x29, =0
|
|
ldr x30, =0
|
|
|
|
ldr x0, =__STACKS_END__
|
|
|
|
mrs x1, sctlr_el3
|
|
mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
|
|
| SCTLR_SA_BIT | SCTLR_A_BIT))
|
|
orr x0, x0, x1
|
|
msr sctlr_el3, x0
|
|
isb
|
|
|
|
mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
|
|
mrs x0, sctlr_el3
|
|
orr x0, x0, x1
|
|
msr sctlr_el3, x0
|
|
isb
|
|
|
|
mrs x1, scr_el3
|
|
mov_imm x0, ((SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT | SCR_FIQ_BIT ) \
|
|
& ~(SCR_TWE_BIT | SCR_TWI_BIT | SCR_SMD_BIT))
|
|
orr x0, x0, x1
|
|
msr scr_el3, x0
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Set the exception vectors.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
adr x0, loader_exceptions
|
|
msr vbar_el3, x0
|
|
isb
|
|
|
|
msr daifclr, #(DAIF_ABT_BIT | DAIF_FIQ_BIT)
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Set the MMU table.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
ldr x0 ,=TCR_VAL
|
|
msr tcr_el3, x0
|
|
|
|
ldr x0, =MAIR_VAL
|
|
msr mair_el3, x0
|
|
|
|
ldr x0, =g_loader_level1_table
|
|
msr ttbr0_el3, x0
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Enable MMU.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
|
|
isb
|
|
tlbi alle3
|
|
isb
|
|
|
|
mrs x0, sctlr_el3
|
|
ldr x1 ,=SCTLR_MMU_ON
|
|
orr x0, x0, x1
|
|
msr sctlr_el3, x0
|
|
|
|
dsb sy
|
|
isb
|
|
tlbi alle3
|
|
isb
|
|
|
|
/* clear bss section */
|
|
mov x0, #0x0
|
|
ldr x1, =__BSS_START__
|
|
ldr x2, =__BSS_SIZE__
|
|
bss_loop:
|
|
subs x2, x2, #4
|
|
bcc bss_end
|
|
str w0, [x1, x2]
|
|
b bss_loop
|
|
bss_end:
|
|
|
|
/* copy data section */
|
|
ldr x0, =__DATA_COPY_START__
|
|
ldr x1, =__DATA_START__
|
|
ldr x2, =__DATA_SIZE__
|
|
data_loop:
|
|
subs x2, x2, #4
|
|
bcc data_end
|
|
ldr w3, [x0, x2]
|
|
str w3, [x1, x2]
|
|
b data_loop
|
|
data_end:
|
|
|
|
msr spsel, #0
|
|
|
|
ldr x0, =__STACKS_END__
|
|
mov sp, x0
|
|
|
|
bl loader_main
|
|
|
|
msr elr_el3, x0
|
|
|
|
mov x0, #SPSR_64
|
|
msr spsr_el3, x0
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Disable MMU.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
mrs x0, sctlr_el3
|
|
ldr x1 ,=SCTLR_OFF
|
|
and x0, x0, x1
|
|
msr sctlr_el3, x0
|
|
|
|
dsb sy
|
|
isb
|
|
tlbi alle3
|
|
ic iallu
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Set initial value.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
msr ttbr0_el3, xzr
|
|
|
|
ldr x0, =MAIR_INIT_VAL
|
|
msr mair_el3, x0
|
|
|
|
msr tcr_el3, xzr
|
|
|
|
msr vbar_el3, xzr
|
|
isb
|
|
|
|
eret
|
|
|
|
|
|
.end |