Home | History | Annotate | Download | only in aarch64
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 #include <arch.h>
      7 #include <asm_macros.S>
      8 #include <assert_macros.S>
      9 #include <cpu_macros.S>
     10 #include <cortex_a53.h>
     11 #include <cortex_a57.h>
     12 #include <platform_def.h>
     13 #include <tegra_def.h>
     14 
     15 #define MIDR_PN_CORTEX_A57		0xD07
     16 
     17 /*******************************************************************************
     18  * Implementation defined ACTLR_EL3 bit definitions
     19  ******************************************************************************/
     20 #define ACTLR_EL3_L2ACTLR_BIT		(1 << 6)
     21 #define ACTLR_EL3_L2ECTLR_BIT		(1 << 5)
     22 #define ACTLR_EL3_L2CTLR_BIT		(1 << 4)
     23 #define ACTLR_EL3_CPUECTLR_BIT		(1 << 1)
     24 #define ACTLR_EL3_CPUACTLR_BIT		(1 << 0)
     25 #define ACTLR_EL3_ENABLE_ALL_ACCESS	(ACTLR_EL3_L2ACTLR_BIT | \
     26 					 ACTLR_EL3_L2ECTLR_BIT | \
     27 					 ACTLR_EL3_L2CTLR_BIT | \
     28 					 ACTLR_EL3_CPUECTLR_BIT | \
     29 					 ACTLR_EL3_CPUACTLR_BIT)
     30 
     31 	/* Global functions */
     32 	.globl	plat_is_my_cpu_primary
     33 	.globl	plat_my_core_pos
     34 	.globl	plat_get_my_entrypoint
     35 	.globl	plat_secondary_cold_boot_setup
     36 	.globl	platform_mem_init
     37 	.globl	plat_crash_console_init
     38 	.globl	plat_crash_console_putc
     39 	.globl	tegra_secure_entrypoint
     40 	.globl	plat_reset_handler
     41 
     42 	/* Global variables */
     43 	.globl	tegra_sec_entry_point
     44 	.globl	ns_image_entrypoint
     45 	.globl	tegra_bl31_phys_base
     46 	.globl	tegra_console_base
     47 	.globl	tegra_enable_l2_ecc_parity_prot
     48 
     49 	/* ---------------------
     50 	 * Common CPU init code
     51 	 * ---------------------
     52 	 */
     53 .macro	cpu_init_common
     54 
     55 	/* ------------------------------------------------
     56 	 * We enable procesor retention, L2/CPUECTLR NS
     57 	 * access and ECC/Parity protection for A57 CPUs
     58 	 * ------------------------------------------------
     59 	 */
     60 	mrs	x0, midr_el1
     61 	mov	x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
     62 	and	x0, x0, x1
     63 	lsr	x0, x0, #MIDR_PN_SHIFT
     64 	cmp	x0, #MIDR_PN_CORTEX_A57
     65 	b.ne	1f
     66 
     67 	/* ---------------------------
     68 	 * Enable processor retention
     69 	 * ---------------------------
     70 	 */
     71 	mrs	x0, CORTEX_A57_L2ECTLR_EL1
     72 	mov	x1, #RETENTION_ENTRY_TICKS_512
     73 	bic	x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK
     74 	orr	x0, x0, x1
     75 	msr	CORTEX_A57_L2ECTLR_EL1, x0
     76 	isb
     77 
     78 	mrs	x0, CORTEX_A57_ECTLR_EL1
     79 	mov	x1, #RETENTION_ENTRY_TICKS_512
     80 	bic	x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK
     81 	orr	x0, x0, x1
     82 	msr	CORTEX_A57_ECTLR_EL1, x0
     83 	isb
     84 
     85 	/* -------------------------------------------------------
     86 	 * Enable L2 and CPU ECTLR RW access from non-secure world
     87 	 * -------------------------------------------------------
     88 	 */
     89 	mov	x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
     90 	msr	actlr_el3, x0
     91 	msr	actlr_el2, x0
     92 	isb
     93 
     94 	/* -------------------------------------------------------
     95 	 * Enable L2 ECC and Parity Protection
     96 	 * -------------------------------------------------------
     97 	 */
     98 	adr	x0, tegra_enable_l2_ecc_parity_prot
     99 	ldr	x0, [x0]
    100 	cbz	x0, 1f
    101 	mrs	x0, CORTEX_A57_L2CTLR_EL1
    102 	and	x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
    103 	cbnz	x1, 1f
    104 	orr	x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
    105 	msr	CORTEX_A57_L2CTLR_EL1, x0
    106 	isb
    107 
    108 	/* --------------------------------
    109 	 * Enable the cycle count register
    110 	 * --------------------------------
    111 	 */
    112 1:	mrs	x0, pmcr_el0
    113 	ubfx	x0, x0, #11, #5		// read PMCR.N field
    114 	mov	x1, #1
    115 	lsl	x0, x1, x0
    116 	sub	x0, x0, #1		// mask of event counters
    117 	orr	x0, x0, #0x80000000	// disable overflow intrs
    118 	msr	pmintenclr_el1, x0
    119 	msr	pmuserenr_el0, x1	// enable user mode access
    120 
    121 	/* ----------------------------------------------------------------
    122 	 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
    123 	 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
    124 	 * registers from EL0.
    125 	 * ----------------------------------------------------------------
    126 	 */
    127 	mrs	x0, cntkctl_el1
    128 	orr	x0, x0, #EL0VCTEN_BIT
    129 	msr	cntkctl_el1, x0
    130 .endm
    131 
    132 	/* -----------------------------------------------------
    133 	 * unsigned int plat_is_my_cpu_primary(void);
    134 	 *
    135 	 * This function checks if this is the Primary CPU
    136 	 * -----------------------------------------------------
    137 	 */
    138 func plat_is_my_cpu_primary
    139 	mrs	x0, mpidr_el1
    140 	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
    141 	cmp	x0, #TEGRA_PRIMARY_CPU
    142 	cset	x0, eq
    143 	ret
    144 endfunc plat_is_my_cpu_primary
    145 
    146 	/* -----------------------------------------------------
    147 	 * unsigned int plat_my_core_pos(void);
    148 	 *
    149 	 * result: CorePos = CoreId + (ClusterId << 2)
    150 	 * -----------------------------------------------------
    151 	 */
    152 func plat_my_core_pos
    153 	mrs	x0, mpidr_el1
    154 	and	x1, x0, #MPIDR_CPU_MASK
    155 	and	x0, x0, #MPIDR_CLUSTER_MASK
    156 	add	x0, x1, x0, LSR #6
    157 	ret
    158 endfunc plat_my_core_pos
    159 
    160 	/* -----------------------------------------------------
    161 	 * unsigned long plat_get_my_entrypoint (void);
    162 	 *
    163 	 * Main job of this routine is to distinguish between
    164 	 * a cold and warm boot. If the tegra_sec_entry_point for
    165 	 * this CPU is present, then it's a warm boot.
    166 	 *
    167 	 * -----------------------------------------------------
    168 	 */
    169 func plat_get_my_entrypoint
    170 	adr	x1, tegra_sec_entry_point
    171 	ldr	x0, [x1]
    172 	ret
    173 endfunc plat_get_my_entrypoint
    174 
    175 	/* -----------------------------------------------------
    176 	 * int platform_get_core_pos(int mpidr);
    177 	 *
    178 	 * With this function: CorePos = (ClusterId * 4) +
    179 	 *                                CoreId
    180 	 * -----------------------------------------------------
    181 	 */
    182 func platform_get_core_pos
    183 	and	x1, x0, #MPIDR_CPU_MASK
    184 	and	x0, x0, #MPIDR_CLUSTER_MASK
    185 	add	x0, x1, x0, LSR #6
    186 	ret
    187 endfunc platform_get_core_pos
    188 
    189 	/* -----------------------------------------------------
    190 	 * void plat_secondary_cold_boot_setup (void);
    191 	 *
    192 	 * This function performs any platform specific actions
    193 	 * needed for a secondary cpu after a cold reset. Right
    194 	 * now this is a stub function.
    195 	 * -----------------------------------------------------
    196 	 */
    197 func plat_secondary_cold_boot_setup
    198 	mov	x0, #0
    199 	ret
    200 endfunc plat_secondary_cold_boot_setup
    201 
    202 	/* --------------------------------------------------------
    203 	 * void platform_mem_init (void);
    204 	 *
    205 	 * Any memory init, relocation to be done before the
    206 	 * platform boots. Called very early in the boot process.
    207 	 * --------------------------------------------------------
    208 	 */
    209 func platform_mem_init
    210 	mov	x0, #0
    211 	ret
    212 endfunc platform_mem_init
    213 
    214 	/* ---------------------------------------------
    215 	 * int plat_crash_console_init(void)
    216 	 * Function to initialize the crash console
    217 	 * without a C Runtime to print crash report.
    218 	 * Clobber list : x0 - x4
    219 	 * ---------------------------------------------
    220 	 */
    221 func plat_crash_console_init
    222 	mov	x0, #0
    223 	adr	x1, tegra_console_base
    224 	ldr	x1, [x1]
    225 	cbz	x1, 1f
    226 	mov	w0, #1
    227 1:	ret
    228 endfunc plat_crash_console_init
    229 
    230 	/* ---------------------------------------------
    231 	 * int plat_crash_console_putc(void)
    232 	 * Function to print a character on the crash
    233 	 * console without a C Runtime.
    234 	 * Clobber list : x1, x2
    235 	 * ---------------------------------------------
    236 	 */
    237 func plat_crash_console_putc
    238 	adr	x1, tegra_console_base
    239 	ldr	x1, [x1]
    240 	b	console_core_putc
    241 endfunc plat_crash_console_putc
    242 
    243 	/* ---------------------------------------------------
    244 	 * Function to handle a platform reset and store
    245 	 * input parameters passed by BL2.
    246 	 * ---------------------------------------------------
    247 	 */
    248 func plat_reset_handler
    249 
    250 	/* ----------------------------------------------------
    251 	 * Verify if we are running from BL31_BASE address
    252 	 * ----------------------------------------------------
    253 	 */
    254 	adr	x18, bl31_entrypoint
    255 	mov	x17, #BL31_BASE
    256 	cmp	x18, x17
    257 	b.eq	1f
    258 
    259 	/* ----------------------------------------------------
    260 	 * Copy the entire BL31 code to BL31_BASE if we are not
    261 	 * running from it already
    262 	 * ----------------------------------------------------
    263 	 */
    264 	mov	x0, x17
    265 	mov	x1, x18
    266 	mov	x2, #BL31_SIZE
    267 _loop16:
    268 	cmp	x2, #16
    269 	b.lo	_loop1
    270 	ldp	x3, x4, [x1], #16
    271 	stp	x3, x4, [x0], #16
    272 	sub	x2, x2, #16
    273 	b	_loop16
    274 	/* copy byte per byte */
    275 _loop1:
    276 	cbz	x2, _end
    277 	ldrb	w3, [x1], #1
    278 	strb	w3, [x0], #1
    279 	subs	x2, x2, #1
    280 	b.ne	_loop1
    281 
    282 	/* ----------------------------------------------------
    283 	 * Jump to BL31_BASE and start execution again
    284 	 * ----------------------------------------------------
    285 	 */
    286 _end:	mov	x0, x20
    287 	mov	x1, x21
    288 	br	x17
    289 1:
    290 
    291 	/* -----------------------------------
    292 	 * derive and save the phys_base addr
    293 	 * -----------------------------------
    294 	 */
    295 	adr	x17, tegra_bl31_phys_base
    296 	ldr	x18, [x17]
    297 	cbnz	x18, 1f
    298 	adr	x18, bl31_entrypoint
    299 	str	x18, [x17]
    300 
    301 1:	cpu_init_common
    302 
    303 	ret
    304 endfunc plat_reset_handler
    305 
    306 	/* ----------------------------------------
    307 	 * Secure entrypoint function for CPU boot
    308 	 * ----------------------------------------
    309 	 */
    310 func tegra_secure_entrypoint _align=6
    311 
    312 #if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
    313 
    314 	/* -------------------------------------------------------
    315 	 * Invalidate BTB along with I$ to remove any stale
    316 	 * entries from the branch predictor array.
    317 	 * -------------------------------------------------------
    318 	 */
    319 	mrs	x0, CORTEX_A57_CPUACTLR_EL1
    320 	orr	x0, x0, #1
    321 	msr	CORTEX_A57_CPUACTLR_EL1, x0	/* invalidate BTB and I$ together */
    322 	dsb	sy
    323 	isb
    324 	ic	iallu			/* actual invalidate */
    325 	dsb	sy
    326 	isb
    327 
    328 	mrs	x0, CORTEX_A57_CPUACTLR_EL1
    329 	bic	x0, x0, #1
    330 	msr	CORTEX_A57_CPUACTLR_EL1, X0	/* restore original CPUACTLR_EL1 */
    331 	dsb	sy
    332 	isb
    333 
    334 	.rept	7
    335 	nop				/* wait */
    336 	.endr
    337 
    338 	/* -----------------------------------------------
    339 	 * Extract OSLK bit and check if it is '1'. This
    340 	 * bit remains '0' for A53 on warm-resets. If '1',
    341 	 * turn off regional clock gating and request warm
    342 	 * reset.
    343 	 * -----------------------------------------------
    344 	 */
    345 	mrs	x0, oslsr_el1
    346 	and	x0, x0, #2
    347 	mrs	x1, mpidr_el1
    348 	bics	xzr, x0, x1, lsr #7	/* 0 = slow cluster or warm reset */
    349 	b.eq	restore_oslock
    350 	mov	x0, xzr
    351 	msr	oslar_el1, x0		/* os lock stays 0 across warm reset */
    352 	mov	x3, #3
    353 	movz	x4, #0x8000, lsl #48
    354 	msr	CORTEX_A57_CPUACTLR_EL1, x4	/* turn off RCG */
    355 	isb
    356 	msr	rmr_el3, x3		/* request warm reset */
    357 	isb
    358 	dsb	sy
    359 1:	wfi
    360 	b	1b
    361 
    362 	/* --------------------------------------------------
    363 	 * These nops are here so that speculative execution
    364 	 * won't harm us before we are done with warm reset.
    365 	 * --------------------------------------------------
    366 	 */
    367 	.rept	65
    368 	nop
    369 	.endr
    370 
    371 	/* --------------------------------------------------
    372 	 * Do not insert instructions here
    373 	 * --------------------------------------------------
    374 	 */
    375 #endif
    376 
    377 	/* --------------------------------------------------
    378 	 * Restore OS Lock bit
    379 	 * --------------------------------------------------
    380 	 */
    381 restore_oslock:
    382 	mov	x0, #1
    383 	msr	oslar_el1, x0
    384 
    385 	cpu_init_common
    386 
    387 	/* ---------------------------------------------------------------------
    388 	 * The initial state of the Architectural feature trap register
    389 	 * (CPTR_EL3) is unknown and it must be set to a known state. All
    390 	 * feature traps are disabled. Some bits in this register are marked as
    391 	 * Reserved and should not be modified.
    392 	 *
    393 	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
    394 	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
    395 	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
    396 	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
    397 	 *  access to trace functionality is not supported, this bit is RES0.
    398 	 * CPTR_EL3.TFP: This causes instructions that access the registers
    399 	 *  associated with Floating Point and Advanced SIMD execution to trap
    400 	 *  to EL3 when executed from any exception level, unless trapped to EL1
    401 	 *  or EL2.
    402 	 * ---------------------------------------------------------------------
    403 	 */
    404 	mrs	x1, cptr_el3
    405 	bic	w1, w1, #TCPAC_BIT
    406 	bic	w1, w1, #TTA_BIT
    407 	bic	w1, w1, #TFP_BIT
    408 	msr	cptr_el3, x1
    409 
    410 	/* --------------------------------------------------
    411 	 * Get secure world's entry point and jump to it
    412 	 * --------------------------------------------------
    413 	 */
    414 	bl	plat_get_my_entrypoint
    415 	br	x0
    416 endfunc tegra_secure_entrypoint
    417 
    418 	.data
    419 	.align 3
    420 
    421 	/* --------------------------------------------------
    422 	 * CPU Secure entry point - resume from suspend
    423 	 * --------------------------------------------------
    424 	 */
    425 tegra_sec_entry_point:
    426 	.quad	0
    427 
    428 	/* --------------------------------------------------
    429 	 * NS world's cold boot entry point
    430 	 * --------------------------------------------------
    431 	 */
    432 ns_image_entrypoint:
    433 	.quad	0
    434 
    435 	/* --------------------------------------------------
    436 	 * BL31's physical base address
    437 	 * --------------------------------------------------
    438 	 */
    439 tegra_bl31_phys_base:
    440 	.quad	0
    441 
    442 	/* --------------------------------------------------
    443 	 * UART controller base for console init
    444 	 * --------------------------------------------------
    445 	 */
    446 tegra_console_base:
    447 	.quad	0
    448 
    449 	/* --------------------------------------------------
    450 	 * Enable L2 ECC and Parity Protection
    451 	 * --------------------------------------------------
    452 	 */
    453 tegra_enable_l2_ecc_parity_prot:
    454 	.quad	0
    455