1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <string.h> 8 9 #include <arch_helpers.h> 10 #include <common/debug.h> 11 #include <lib/mmio.h> 12 13 #include <mce.h> 14 #include <tegra_def.h> 15 #include <tegra_private.h> 16 17 #define MISCREG_CPU_RESET_VECTOR 0x2000 18 #define MISCREG_AA64_RST_LOW 0x2004 19 #define MISCREG_AA64_RST_HIGH 0x2008 20 21 #define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658 22 #define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65C 23 24 #define CPU_RESET_MODE_AA64 1 25 26 extern void memcpy16(void *dest, const void *src, unsigned int length); 27 28 extern uint64_t tegra_bl31_phys_base; 29 extern uint64_t __tegra186_cpu_reset_handler_end; 30 31 /******************************************************************************* 32 * Setup secondary CPU vectors 33 ******************************************************************************/ 34 void plat_secondary_setup(void) 35 { 36 uint32_t addr_low, addr_high; 37 plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); 38 uint64_t cpu_reset_handler_base; 39 40 INFO("Setting up secondary CPU boot\n"); 41 42 if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) && 43 (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) { 44 45 /* 46 * The BL31 code resides in the TZSRAM which loses state 47 * when we enter System Suspend. Copy the wakeup trampoline 48 * code to TZDRAM to help us exit from System Suspend. 49 */ 50 cpu_reset_handler_base = params_from_bl2->tzdram_base; 51 memcpy16((void *)((uintptr_t)cpu_reset_handler_base), 52 (void *)(uintptr_t)tegra186_cpu_reset_handler, 53 (uintptr_t)&__tegra186_cpu_reset_handler_end - 54 (uintptr_t)tegra186_cpu_reset_handler); 55 56 } else { 57 cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint; 58 } 59 60 addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64; 61 addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff); 62 63 /* write lower 32 bits first, then the upper 11 bits */ 64 mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); 65 mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); 66 67 /* save reset vector to be used during SYSTEM_SUSPEND exit */ 68 mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0, 69 addr_low); 70 mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1, 71 addr_high); 72 73 /* update reset vector address to the CCPLEX */ 74 mce_update_reset_vector(); 75 } 76