mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 18:35:42 +01:00 
			
		
		
		
	armv8: Initialize CNTFRQ if at highest exception level
CNTFRQ_EL0 is only writable from the highest supported exception level on the platform. For Armv8-A, this is typically EL3, but technically EL2 and EL3 are optional so it may need to be initialized at EL2 or EL1. For Armv8-R, the highest exception level is always EL2. This patch moves the initialization outside of the switch_el block and uses a new macro branch_if_not_highest_el which dynamically detects whether it is at the highest supported exception level. Linux's docs state that CNTFRQ_EL0 should be initialized by the bootloader. If not set, the the U-Boot prompt countdown hangs. Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
This commit is contained in:
		| @@ -127,10 +127,6 @@ pie_fixup_done: | |||||||
| 	orr	x0, x0, #0xf			/* SCR_EL3.NS|IRQ|FIQ|EA */ | 	orr	x0, x0, #0xf			/* SCR_EL3.NS|IRQ|FIQ|EA */ | ||||||
| 	msr	scr_el3, x0 | 	msr	scr_el3, x0 | ||||||
| 	msr	cptr_el3, xzr			/* Enable FP/SIMD */ | 	msr	cptr_el3, xzr			/* Enable FP/SIMD */ | ||||||
| #ifdef COUNTER_FREQUENCY |  | ||||||
| 	ldr	x0, =COUNTER_FREQUENCY |  | ||||||
| 	msr	cntfrq_el0, x0			/* Initialize CNTFRQ */ |  | ||||||
| #endif |  | ||||||
| 	b	0f | 	b	0f | ||||||
| 2:	mrs	x1, hcr_el2 | 2:	mrs	x1, hcr_el2 | ||||||
| 	tbnz	x1, #34, 1f			/* HCR_EL2.E2H */ | 	tbnz	x1, #34, 1f			/* HCR_EL2.E2H */ | ||||||
| @@ -142,7 +138,14 @@ pie_fixup_done: | |||||||
| 	mov	x0, #3 << 20 | 	mov	x0, #3 << 20 | ||||||
| 	msr	cpacr_el1, x0			/* Enable FP/SIMD */ | 	msr	cpacr_el1, x0			/* Enable FP/SIMD */ | ||||||
| 0: | 0: | ||||||
| 	isb |  | ||||||
|  | #ifdef COUNTER_FREQUENCY | ||||||
|  | 	branch_if_not_highest_el x0, 4f | ||||||
|  | 	ldr	x0, =COUNTER_FREQUENCY | ||||||
|  | 	msr	cntfrq_el0, x0			/* Initialize CNTFRQ */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 4:	isb | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Enable SMPEN bit for coherency. | 	 * Enable SMPEN bit for coherency. | ||||||
|   | |||||||
| @@ -77,6 +77,24 @@ lr	.req	x30 | |||||||
| 	b.eq	\el1_label | 	b.eq	\el1_label | ||||||
| .endm | .endm | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Branch if we are not in the highest exception level | ||||||
|  |  */ | ||||||
|  | .macro	branch_if_not_highest_el, xreg, label | ||||||
|  | 	switch_el \xreg, 3f, 2f, 1f | ||||||
|  |  | ||||||
|  | 2:	mrs	\xreg, ID_AA64PFR0_EL1 | ||||||
|  | 	and	\xreg, \xreg, #(ID_AA64PFR0_EL1_EL3) | ||||||
|  | 	cbnz	\xreg, \label | ||||||
|  | 	b	3f | ||||||
|  |  | ||||||
|  | 1:	mrs	\xreg, ID_AA64PFR0_EL1 | ||||||
|  | 	and	\xreg, \xreg, #(ID_AA64PFR0_EL1_EL3 | ID_AA64PFR0_EL1_EL2) | ||||||
|  | 	cbnz	\xreg, \label | ||||||
|  |  | ||||||
|  | 3: | ||||||
|  | .endm | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Branch if current processor is a Cortex-A57 core. |  * Branch if current processor is a Cortex-A57 core. | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -79,6 +79,12 @@ | |||||||
| #define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are AArch32         */ | #define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are AArch32         */ | ||||||
| #define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call disabled         */ | #define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call disabled         */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * ID_AA64PFR0_EL1 bits definitions | ||||||
|  |  */ | ||||||
|  | #define ID_AA64PFR0_EL1_EL3	(0xF << 12) /* EL3 implemented                */ | ||||||
|  | #define ID_AA64PFR0_EL1_EL2	(0xF << 8)  /* EL2 implemented                */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * CPACR_EL1 bits definitions |  * CPACR_EL1 bits definitions | ||||||
|  */ |  */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user