mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-11-03 01:41:44 +01:00 
			
		
		
		
	The branch_if_master macro jumps to a label if the CPU is the "master" core, which we define as having all affinity levels set to 0. To check for this condition, we need to mask off some bits from the MPIDR register, then compare the remaining register value against zero. The implementation of this was slighly broken (it preserved the upper RES0 bits), overly complicated and hard to understand, especially since it lacked comments. The same was true for the very similar branch_if_slave macro. Use a much shorter assembly sequence for those checks, use the same masking for both macros (just negate the final branch), and put some comments on them, to make it clear what the code does. This allows to drop the second temporary register for branch_if_master, so we adjust all call sites as well. Also use the opportunity to remove a misleading comment: the macro works fine on SoCs with multiple clusters. Judging by the commit message, the original problem with the Juno SoC stems from the fact that the master CPU *can* be configured to be from cluster 1, so the assumption that the master CPU has all affinity values set to 0 does not hold there. But this is already mentioned above in a comment, so remove the extra comment. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0+ */
 | 
						|
/*
 | 
						|
 * arch/arm/cpu/armv8/rcar_gen3/lowlevel_init.S
 | 
						|
 *	This file is lowlevel initialize routine.
 | 
						|
 *
 | 
						|
 * (C) Copyright 2015 Renesas Electronics Corporation
 | 
						|
 *
 | 
						|
 * This file is based on the arch/arm/cpu/armv8/start.S
 | 
						|
 *
 | 
						|
 * (C) Copyright 2013
 | 
						|
 * David Feng <fenghua@phytium.com.cn>
 | 
						|
 */
 | 
						|
 | 
						|
#include <asm-offsets.h>
 | 
						|
#include <config.h>
 | 
						|
#include <linux/linkage.h>
 | 
						|
#include <asm/macro.h>
 | 
						|
 | 
						|
.align 8
 | 
						|
.globl	rcar_atf_boot_args
 | 
						|
rcar_atf_boot_args:
 | 
						|
	.dword 0
 | 
						|
	.dword 0
 | 
						|
	.dword 0
 | 
						|
	.dword 0
 | 
						|
 | 
						|
ENTRY(save_boot_params)
 | 
						|
	adr	x8, rcar_atf_boot_args
 | 
						|
	stp	x0, x1, [x8], #16
 | 
						|
	stp	x2, x3, [x8], #16
 | 
						|
	b	save_boot_params_ret
 | 
						|
ENDPROC(save_boot_params)
 | 
						|
 | 
						|
.pushsection .text.s_init, "ax"
 | 
						|
WEAK(s_init)
 | 
						|
	ret
 | 
						|
ENDPROC(s_init)
 | 
						|
.popsection
 | 
						|
 | 
						|
ENTRY(lowlevel_init)
 | 
						|
	mov	x29, lr			/* Save LR */
 | 
						|
 | 
						|
#ifndef CONFIG_ARMV8_MULTIENTRY
 | 
						|
	/*
 | 
						|
	 * For single-entry systems the lowlevel init is very simple.
 | 
						|
	 */
 | 
						|
	ldr	x0, =GICD_BASE
 | 
						|
	bl	gic_init_secure
 | 
						|
 | 
						|
#else /* CONFIG_ARMV8_MULTIENTRY is set */
 | 
						|
 | 
						|
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
 | 
						|
	branch_if_slave x0, 1f
 | 
						|
	ldr	x0, =GICD_BASE
 | 
						|
	bl	gic_init_secure
 | 
						|
1:
 | 
						|
#if defined(CONFIG_GICV3)
 | 
						|
	ldr	x0, =GICR_BASE
 | 
						|
	bl	gic_init_secure_percpu
 | 
						|
#elif defined(CONFIG_GICV2)
 | 
						|
	ldr	x0, =GICD_BASE
 | 
						|
	ldr	x1, =GICC_BASE
 | 
						|
	bl	gic_init_secure_percpu
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
	branch_if_master x0, 2f
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Slave should wait for master clearing spin table.
 | 
						|
	 * This sync prevent salves observing incorrect
 | 
						|
	 * value of spin table and jumping to wrong place.
 | 
						|
	 */
 | 
						|
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
 | 
						|
#ifdef CONFIG_GICV2
 | 
						|
	ldr	x0, =GICC_BASE
 | 
						|
#endif
 | 
						|
	bl	gic_wait_for_interrupt
 | 
						|
#endif
 | 
						|
 | 
						|
	/*
 | 
						|
	 * All slaves will enter EL2 and optionally EL1.
 | 
						|
	 */
 | 
						|
	adr	x4, lowlevel_in_el2
 | 
						|
	ldr	x5, =ES_TO_AARCH64
 | 
						|
	bl	armv8_switch_to_el2
 | 
						|
 | 
						|
lowlevel_in_el2:
 | 
						|
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
 | 
						|
	adr	x4, lowlevel_in_el1
 | 
						|
	ldr	x5, =ES_TO_AARCH64
 | 
						|
	bl	armv8_switch_to_el1
 | 
						|
 | 
						|
lowlevel_in_el1:
 | 
						|
#endif
 | 
						|
#endif /* CONFIG_ARMV8_MULTIENTRY */
 | 
						|
 | 
						|
	bl      s_init
 | 
						|
 | 
						|
2:
 | 
						|
	mov	lr, x29			/* Restore LR */
 | 
						|
	ret
 | 
						|
ENDPROC(lowlevel_init)
 |