• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <arch_helpers.h>
10 #include <common/debug.h>
11 #include <denver.h>
12 #include <lib/mmio.h>
13 #include <lib/psci/psci.h>
14 #include <plat/common/platform.h>
15 
16 #include <pmc.h>
17 #include <tegra_def.h>
18 
19 #define SB_CSR				0x0
20 #define  SB_CSR_NS_RST_VEC_WR_DIS	(1 << 1)
21 
22 /* AARCH64 CPU reset vector */
23 #define SB_AA64_RESET_LOW		0x30	/* width = 31:0 */
24 #define SB_AA64_RESET_HI		0x34	/* width = 11:0 */
25 
26 /* AARCH32 CPU reset vector */
27 #define EVP_CPU_RESET_VECTOR		0x100
28 
29 extern void tegra_secure_entrypoint(void);
30 
31 /*
32  * For T132, CPUs reset to AARCH32, so the reset vector is first
33  * armv8_trampoline which does a warm reset to AARCH64 and starts
34  * execution at the address in SB_AA64_RESET_LOW/SB_AA64_RESET_HI.
35  */
36 __aligned(8) const uint32_t armv8_trampoline[] = {
37 	0xE3A00003,		/* mov	r0, #3 */
38 	0xEE0C0F50,		/* mcr	p15, 0, r0, c12, c0, 2 */
39 	0xEAFFFFFE,		/* b	. */
40 };
41 
42 /*******************************************************************************
43  * Setup secondary CPU vectors
44  ******************************************************************************/
plat_secondary_setup(void)45 void plat_secondary_setup(void)
46 {
47 	uint32_t val;
48 	uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint;
49 
50 	/*
51 	 * For T132, CPUs reset to AARCH32, so the reset vector is first
52 	 * armv8_trampoline, which does a warm reset to AARCH64 and starts
53 	 * execution at the address in SCRATCH34/SCRATCH35.
54 	 */
55 	INFO("Setting up T132 CPU boot\n");
56 
57 	/* initial AARCH32 reset address */
58 	tegra_pmc_write_32(PMC_SECURE_SCRATCH22,
59 		(unsigned long)&armv8_trampoline);
60 
61 	/* set AARCH32 exception vector (read to flush) */
62 	mmio_write_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR,
63 		(unsigned long)&armv8_trampoline);
64 	val = mmio_read_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR);
65 
66 	/* setup secondary CPU vector */
67 	mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_LOW,
68 			(reset_addr & 0xFFFFFFFF) | 1);
69 	val = reset_addr >> 32;
70 	mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_HI, val & 0x7FF);
71 
72 	/* configure PMC */
73 	tegra_pmc_cpu_setup(reset_addr);
74 	tegra_pmc_lock_cpu_vectors();
75 }
76