mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-11-29 06:31:28 +01:00
armv8: layerscape: Make U-Boot EL2 safe
When U-Boot boots from EL2, skip some lowlevel init code requiring EL3, including CCI-400/CCN-504, trust zone, GIC, etc. These initialization tasks are carried out before U-Boot runs. This applies to the RAM version image used for SPL boot if PPA is loaded first. Signed-off-by: York Sun <york.sun@nxp.com>
This commit is contained in:
parent
1f55a93802
commit
399e2bb60c
@ -244,6 +244,14 @@ u64 get_page_table_size(void)
|
|||||||
|
|
||||||
int arch_cpu_init(void)
|
int arch_cpu_init(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This function is called before U-Boot relocates itself to speed up
|
||||||
|
* on system running. It is not necessary to run if performance is not
|
||||||
|
* critical. Skip if MMU is already enabled by SPL or other means.
|
||||||
|
*/
|
||||||
|
if (get_sctlr() & CR_M)
|
||||||
|
return 0;
|
||||||
|
|
||||||
icache_enable();
|
icache_enable();
|
||||||
__asm_invalidate_dcache_all();
|
__asm_invalidate_dcache_all();
|
||||||
__asm_invalidate_tlb_all();
|
__asm_invalidate_tlb_all();
|
||||||
@ -530,7 +538,8 @@ int timer_init(void)
|
|||||||
unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
|
unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
|
||||||
|
|
||||||
/* Update with accurate clock frequency */
|
/* Update with accurate clock frequency */
|
||||||
asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
|
if (current_el() == 3)
|
||||||
|
asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_LSCH3
|
#ifdef CONFIG_FSL_LSCH3
|
||||||
|
|||||||
@ -73,6 +73,9 @@ ENDPROC(smp_kick_all_cpus)
|
|||||||
ENTRY(lowlevel_init)
|
ENTRY(lowlevel_init)
|
||||||
mov x29, lr /* Save LR */
|
mov x29, lr /* Save LR */
|
||||||
|
|
||||||
|
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||||
|
1:
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_LSCH3
|
#ifdef CONFIG_FSL_LSCH3
|
||||||
|
|
||||||
/* Set Wuo bit for RN-I 20 */
|
/* Set Wuo bit for RN-I 20 */
|
||||||
@ -193,6 +196,7 @@ ENTRY(lowlevel_init)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
100:
|
||||||
branch_if_master x0, x1, 2f
|
branch_if_master x0, x1, 2f
|
||||||
|
|
||||||
#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
|
#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
|
||||||
@ -201,6 +205,8 @@ ENTRY(lowlevel_init)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
2:
|
2:
|
||||||
|
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||||
|
1:
|
||||||
#ifdef CONFIG_FSL_TZPC_BP147
|
#ifdef CONFIG_FSL_TZPC_BP147
|
||||||
/* Set Non Secure access for all devices protected via TZPC */
|
/* Set Non Secure access for all devices protected via TZPC */
|
||||||
ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
|
ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
|
||||||
@ -266,8 +272,11 @@ ENTRY(lowlevel_init)
|
|||||||
isb
|
isb
|
||||||
dsb sy
|
dsb sy
|
||||||
#endif
|
#endif
|
||||||
|
100:
|
||||||
1:
|
1:
|
||||||
#ifdef CONFIG_ARCH_LS1046A
|
#ifdef CONFIG_ARCH_LS1046A
|
||||||
|
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||||
|
1:
|
||||||
/* Initialize the L2 RAM latency */
|
/* Initialize the L2 RAM latency */
|
||||||
mrs x1, S3_1_c11_c0_2
|
mrs x1, S3_1_c11_c0_2
|
||||||
mov x0, #0x1C7
|
mov x0, #0x1C7
|
||||||
@ -279,6 +288,7 @@ ENTRY(lowlevel_init)
|
|||||||
orr x1, x1, #0x80
|
orr x1, x1, #0x80
|
||||||
msr S3_1_c11_c0_2, x1
|
msr S3_1_c11_c0_2, x1
|
||||||
isb
|
isb
|
||||||
|
100:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
|
#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
|
||||||
@ -379,11 +389,14 @@ ENTRY(__asm_flush_l3_dcache)
|
|||||||
/*
|
/*
|
||||||
* Return status in x0
|
* Return status in x0
|
||||||
* success 0
|
* success 0
|
||||||
* tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
|
* timeout 1 for setting SFONLY, 2 for FAM, 3 for both
|
||||||
*/
|
*/
|
||||||
mov x29, lr
|
mov x29, lr
|
||||||
mov x8, #0
|
mov x8, #0
|
||||||
|
|
||||||
|
switch_el x0, 1f, 100f, 100f /* skip if not in EL3 */
|
||||||
|
|
||||||
|
1:
|
||||||
dsb sy
|
dsb sy
|
||||||
mov x0, #0x1 /* HNFPSTAT_SFONLY */
|
mov x0, #0x1 /* HNFPSTAT_SFONLY */
|
||||||
bl hnf_set_pstate
|
bl hnf_set_pstate
|
||||||
@ -401,6 +414,7 @@ ENTRY(__asm_flush_l3_dcache)
|
|||||||
bl hnf_pstate_poll
|
bl hnf_pstate_poll
|
||||||
cbz x0, 1f
|
cbz x0, 1f
|
||||||
add x8, x8, #0x2
|
add x8, x8, #0x2
|
||||||
|
100:
|
||||||
1:
|
1:
|
||||||
mov x0, x8
|
mov x0, x8
|
||||||
mov lr, x29
|
mov lr, x29
|
||||||
|
|||||||
@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
|
|
||||||
int ppa_init(void)
|
int ppa_init(void)
|
||||||
{
|
{
|
||||||
|
unsigned int el = current_el();
|
||||||
void *ppa_fit_addr;
|
void *ppa_fit_addr;
|
||||||
u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
|
u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
|
||||||
int ret;
|
int ret;
|
||||||
@ -45,6 +46,12 @@ int ppa_init(void)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Skip if running at lower exception level */
|
||||||
|
if (el < 3) {
|
||||||
|
debug("Skipping PPA init, running at EL%d\n", el);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
|
#ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
|
||||||
ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
|
ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
|
||||||
debug("%s: PPA image load from XIP\n", __func__);
|
debug("%s: PPA image load from XIP\n", __func__);
|
||||||
|
|||||||
@ -288,6 +288,10 @@ static void erratum_a008850_early(void)
|
|||||||
struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR;
|
struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR;
|
||||||
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||||
|
|
||||||
|
/* Skip if running at lower exception level */
|
||||||
|
if (current_el() < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
/* disables propagation of barrier transactions to DDRC from CCI400 */
|
/* disables propagation of barrier transactions to DDRC from CCI400 */
|
||||||
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
|
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
|
||||||
|
|
||||||
@ -304,6 +308,10 @@ void erratum_a008850_post(void)
|
|||||||
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
|
/* Skip if running at lower exception level */
|
||||||
|
if (current_el() < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
/* enable propagation of barrier transactions to DDRC from CCI400 */
|
/* enable propagation of barrier transactions to DDRC from CCI400 */
|
||||||
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
|
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
|
||||||
|
|
||||||
@ -455,8 +463,10 @@ void fsl_lsch2_early_init_f(void)
|
|||||||
* Enable snoop requests and DVM message requests for
|
* Enable snoop requests and DVM message requests for
|
||||||
* Slave insterface S4 (A53 core cluster)
|
* Slave insterface S4 (A53 core cluster)
|
||||||
*/
|
*/
|
||||||
out_le32(&cci->slave[4].snoop_ctrl,
|
if (current_el() == 3) {
|
||||||
CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
|
out_le32(&cci->slave[4].snoop_ctrl,
|
||||||
|
CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
|
||||||
|
}
|
||||||
|
|
||||||
/* Erratum */
|
/* Erratum */
|
||||||
erratum_a008850_early(); /* part 1 of 2 */
|
erratum_a008850_early(); /* part 1 of 2 */
|
||||||
|
|||||||
@ -224,7 +224,7 @@ __weak bool sec_firmware_is_valid(const void *sec_firmware_img)
|
|||||||
*/
|
*/
|
||||||
unsigned int sec_firmware_support_psci_version(void)
|
unsigned int sec_firmware_support_psci_version(void)
|
||||||
{
|
{
|
||||||
if (sec_firmware_addr & SEC_FIRMWARE_RUNNING)
|
if (current_el() == SEC_FIRMWARE_TARGET_EL)
|
||||||
return _sec_firmware_support_psci_version();
|
return _sec_firmware_support_psci_version();
|
||||||
|
|
||||||
return PSCI_INVALID_VER;
|
return PSCI_INVALID_VER;
|
||||||
|
|||||||
@ -91,9 +91,12 @@ save_boot_params_ret:
|
|||||||
* this bit should be set for A53/A57/A72.
|
* this bit should be set for A53/A57/A72.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_ARMV8_SET_SMPEN
|
#ifdef CONFIG_ARMV8_SET_SMPEN
|
||||||
|
switch_el x1, 3f, 1f, 1f
|
||||||
|
3:
|
||||||
mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */
|
mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */
|
||||||
orr x0, x0, #0x40
|
orr x0, x0, #0x40
|
||||||
msr S3_1_c15_c2_1, x0
|
msr S3_1_c15_c2_1, x0
|
||||||
|
1:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Apply ARM core specific erratas */
|
/* Apply ARM core specific erratas */
|
||||||
|
|||||||
@ -39,7 +39,10 @@ static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num)
|
|||||||
|
|
||||||
void enable_layerscape_ns_access(void)
|
void enable_layerscape_ns_access(void)
|
||||||
{
|
{
|
||||||
enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
|
#ifdef CONFIG_ARM64
|
||||||
|
if (current_el() == 3)
|
||||||
|
#endif
|
||||||
|
enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_pcie_ns_access(int pcie, u16 val)
|
void set_pcie_ns_access(int pcie, u16 val)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user