blob: 9b0a36c8c870fa7528146febfd192c508c710104 [file] [log] [blame]
Varun Wadekar7a269e22015-06-10 14:04:32 +05301/*
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -08002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Varun Wadekar7a269e22015-06-10 14:04:32 +05303 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar7a269e22015-06-10 14:04:32 +05305 */
6
Varun Wadekar0f3baa02015-07-16 11:36:33 +05307#include <arch.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +05308#include <arch_helpers.h>
9#include <assert.h>
10#include <bl_common.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053011#include <debug.h>
12#include <errno.h>
13#include <memctrl.h>
14#include <runtime_svc.h>
15#include <tegra_private.h>
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -080016#include <tegra_platform.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053017
Varun Wadekar0f3baa02015-07-16 11:36:33 +053018/*******************************************************************************
Varun Wadekar923d04a2015-12-09 18:18:53 -080019 * Common Tegra SiP SMCs
Varun Wadekar0f3baa02015-07-16 11:36:33 +053020 ******************************************************************************/
Varun Wadekar7a269e22015-06-10 14:04:32 +053021#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
Varun Wadekardc799302015-12-28 16:36:42 -080022#define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005
23#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -080024#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2000007
Varun Wadekar7a269e22015-06-10 14:04:32 +053025
26/*******************************************************************************
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -080027 * Fake system suspend mode control var
28 ******************************************************************************/
29extern uint8_t tegra_fake_system_suspend;
30
31
32/*******************************************************************************
Varun Wadekar923d04a2015-12-09 18:18:53 -080033 * SoC specific SiP handler
34 ******************************************************************************/
35#pragma weak plat_sip_handler
36int plat_sip_handler(uint32_t smc_fid,
37 uint64_t x1,
38 uint64_t x2,
39 uint64_t x3,
40 uint64_t x4,
41 void *cookie,
42 void *handle,
43 uint64_t flags)
44{
45 return -ENOTSUP;
46}
47
48/*******************************************************************************
Wayne Lin2330edd2016-03-31 13:49:09 -070049 * This function is responsible for handling all SiP calls
Varun Wadekar7a269e22015-06-10 14:04:32 +053050 ******************************************************************************/
Varun Wadekar923d04a2015-12-09 18:18:53 -080051uint64_t tegra_sip_handler(uint32_t smc_fid,
Varun Wadekar7a269e22015-06-10 14:04:32 +053052 uint64_t x1,
53 uint64_t x2,
54 uint64_t x3,
55 uint64_t x4,
56 void *cookie,
57 void *handle,
58 uint64_t flags)
59{
Varun Wadekar7a269e22015-06-10 14:04:32 +053060 int err;
61
Varun Wadekar923d04a2015-12-09 18:18:53 -080062 /* Check if this is a SoC specific SiP */
63 err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
64 if (err == 0)
Varun Wadekar14f39572017-04-17 11:54:33 -070065 SMC_RET1(handle, (uint64_t)err);
Varun Wadekar923d04a2015-12-09 18:18:53 -080066
Varun Wadekar7a269e22015-06-10 14:04:32 +053067 switch (smc_fid) {
68
69 case TEGRA_SIP_NEW_VIDEOMEM_REGION:
70
Varun Wadekar0f3baa02015-07-16 11:36:33 +053071 /* clean up the high bits */
Varun Wadekar0f3baa02015-07-16 11:36:33 +053072 x2 = (uint32_t)x2;
73
Varun Wadekar7a269e22015-06-10 14:04:32 +053074 /*
75 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
76 * or falls outside of the valid DRAM range
77 */
78 err = bl31_check_ns_address(x1, x2);
79 if (err)
80 SMC_RET1(handle, err);
81
82 /*
83 * Check if Video Memory is aligned to 1MB.
84 */
85 if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
86 ERROR("Unaligned Video Memory base address!\n");
87 SMC_RET1(handle, -ENOTSUP);
88 }
89
90 /* new video memory carveout settings */
91 tegra_memctrl_videomem_setup(x1, x2);
92
93 SMC_RET1(handle, 0);
Varun Wadekar0f3baa02015-07-16 11:36:33 +053094 break;
Varun Wadekar7a269e22015-06-10 14:04:32 +053095
Varun Wadekardc799302015-12-28 16:36:42 -080096 /*
97 * The NS world registers the address of its handler to be
98 * used for processing the FIQ. This is normally used by the
99 * NS FIQ debugger driver to detect system hangs by programming
100 * a watchdog timer to fire a FIQ interrupt.
101 */
102 case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
103
104 if (!x1)
105 SMC_RET1(handle, SMC_UNK);
106
107 /*
108 * TODO: Check if x1 contains a valid DRAM address
109 */
110
111 /* store the NS world's entrypoint */
112 tegra_fiq_set_ns_entrypoint(x1);
113
114 SMC_RET1(handle, 0);
115 break;
116
117 /*
118 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
119 * CPU context when the FIQ interrupt was triggered. This allows the
120 * NS world to understand the CPU state when the watchdog interrupt
121 * triggered.
122 */
123 case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
124
125 /* retrieve context registers when FIQ triggered */
126 tegra_fiq_get_intr_context();
127
128 SMC_RET0(handle);
129 break;
130
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -0800131 case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
132 /*
133 * System suspend fake mode is set if we are on VDK and we make
134 * a debug SIP call. This mode ensures that we excercise debug
135 * path instead of the regular code path to suit the pre-silicon
136 * platform needs. These include replacing the call to WFI by
137 * a warm reset request.
138 */
139 if (tegra_platform_is_emulation() != 0U) {
140
141 tegra_fake_system_suspend = 1;
142 SMC_RET1(handle, 0);
143 }
144
145 /*
146 * We return to the external world as if this SIP is not
147 * implemented in case, we are not running on VDK.
148 */
149 break;
150
Varun Wadekar7a269e22015-06-10 14:04:32 +0530151 default:
152 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
153 break;
154 }
155
156 SMC_RET1(handle, SMC_UNK);
157}
158
159/* Define a runtime service descriptor for fast SMC calls */
160DECLARE_RT_SVC(
Varun Wadekar923d04a2015-12-09 18:18:53 -0800161 tegra_sip_fast,
Varun Wadekar7a269e22015-06-10 14:04:32 +0530162
163 OEN_SIP_START,
164 OEN_SIP_END,
165 SMC_TYPE_FAST,
166 NULL,
Varun Wadekar923d04a2015-12-09 18:18:53 -0800167 tegra_sip_handler
Varun Wadekar7a269e22015-06-10 14:04:32 +0530168);