1/* 2 * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8#include <arch.h> 9#include <asm_macros.S> 10#include <common/bl_common.h> 11#include <memctrl_v2.h> 12#include <plat/common/common_def.h> 13#include <tegra_def.h> 14 15#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7 16#define TEGRA186_STATE_SYSTEM_RESUME 0x600D 17#define TEGRA186_MC_CTX_SIZE 0x93 18 19 .globl tegra186_cpu_reset_handler 20 21/* CPU reset handler routine */ 22func tegra186_cpu_reset_handler _align=4 23 /* check if we are exiting system suspend state */ 24 adr x0, __tegra186_system_suspend_state 25 ldr x1, [x0] 26 mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND 27 lsl x2, x2, #16 28 add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND 29 cmp x1, x2 30 bne boot_cpu 31 32 /* set system resume state */ 33 mov x1, #TEGRA186_STATE_SYSTEM_RESUME 34 lsl x1, x1, #16 35 mov x2, #TEGRA186_STATE_SYSTEM_RESUME 36 add x1, x1, x2 37 str x1, [x0] 38 dsb sy 39 40 /* prepare to relocate to TZSRAM */ 41 mov x0, #BL31_BASE 42 adr x1, __tegra186_cpu_reset_handler_end 43 adr x2, __tegra186_cpu_reset_handler_data 44 ldr x2, [x2, #8] 45 46 /* memcpy16 */ 47m_loop16: 48 cmp x2, #16 49 b.lt m_loop1 50 ldp x3, x4, [x1], #16 51 stp x3, x4, [x0], #16 52 sub x2, x2, #16 53 b m_loop16 54 /* copy byte per byte */ 55m_loop1: 56 cbz x2, boot_cpu 57 ldrb w3, [x1], #1 58 strb w3, [x0], #1 59 subs x2, x2, #1 60 b.ne m_loop1 61 62boot_cpu: 63 adr x0, __tegra186_cpu_reset_handler_data 64 ldr x0, [x0] 65 br x0 66endfunc tegra186_cpu_reset_handler 67 68 /* 69 * Tegra186 reset data (offset 0x0 - 0x430) 70 * 71 * 0x000: secure world's entrypoint 72 * 0x008: BL31 size (RO + RW) 73 * 0x00C: MC context start 74 * 0x42C: MC context end 75 */ 76 77 .align 4 78 .type __tegra186_cpu_reset_handler_data, %object 79 .globl __tegra186_cpu_reset_handler_data 80__tegra186_cpu_reset_handler_data: 81 .quad tegra_secure_entrypoint 82 .quad __BL31_END__ - BL31_BASE 83 84 .globl __tegra186_system_suspend_state 85__tegra186_system_suspend_state: 86 .quad 0 87 88 .align 4 89 .globl __tegra186_mc_context 90__tegra186_mc_context: 91 .rept TEGRA186_MC_CTX_SIZE 92 .quad 0 93 .endr 94 .size __tegra186_cpu_reset_handler_data, \ 95 . - __tegra186_cpu_reset_handler_data 96 97 .align 4 98 .globl __tegra186_cpu_reset_handler_end 99__tegra186_cpu_reset_handler_end: 100 101 .globl tegra186_get_cpu_reset_handler_size 102 .globl tegra186_get_cpu_reset_handler_base 103 .globl tegra186_get_mc_ctx_offset 104 .globl tegra186_set_system_suspend_entry 105 106/* return size of the CPU reset handler */ 107func tegra186_get_cpu_reset_handler_size 108 adr x0, __tegra186_cpu_reset_handler_end 109 adr x1, tegra186_cpu_reset_handler 110 sub x0, x0, x1 111 ret 112endfunc tegra186_get_cpu_reset_handler_size 113 114/* return the start address of the CPU reset handler */ 115func tegra186_get_cpu_reset_handler_base 116 adr x0, tegra186_cpu_reset_handler 117 ret 118endfunc tegra186_get_cpu_reset_handler_base 119 120/* return the size of the MC context */ 121func tegra186_get_mc_ctx_offset 122 adr x0, __tegra186_mc_context 123 adr x1, tegra186_cpu_reset_handler 124 sub x0, x0, x1 125 ret 126endfunc tegra186_get_mc_ctx_offset 127 128/* set system suspend state before SC7 entry */ 129func tegra186_set_system_suspend_entry 130 mov x0, #TEGRA_MC_BASE 131 mov x3, #MC_SECURITY_CFG3_0 132 ldr w1, [x0, x3] 133 lsl x1, x1, #32 134 mov x3, #MC_SECURITY_CFG0_0 135 ldr w2, [x0, x3] 136 orr x3, x1, x2 /* TZDRAM base */ 137 adr x0, __tegra186_system_suspend_state 138 adr x1, tegra186_cpu_reset_handler 139 sub x2, x0, x1 /* offset in TZDRAM */ 140 mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND 141 lsl x0, x0, #16 142 add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND 143 str x0, [x3, x2] /* set value in TZDRAM */ 144 dsb sy 145 ret 146endfunc tegra186_set_system_suspend_entry 147