blob: 02dd1cd56ca670d2c4202f568d880da5b4c312fd [file] [log] [blame]
Varun Wadekar7a269e22015-06-10 14:04:32 +05301/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar7a269e22015-06-10 14:04:32 +05305 */
6
Varun Wadekar7a269e22015-06-10 14:04:32 +05307#include <assert.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +05308#include <errno.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
10#include <arch.h>
11#include <arch_helpers.h>
12#include <common/bl_common.h>
13#include <common/debug.h>
14#include <lib/el3_runtime/context_mgmt.h>
15
Varun Wadekar7a269e22015-06-10 14:04:32 +053016#include <tegra_private.h>
17
Varun Wadekar0f3baa02015-07-16 11:36:33 +053018#define NS_SWITCH_AARCH32 1
19#define SCR_RW_BITPOS __builtin_ctz(SCR_RW_BIT)
20
21/*******************************************************************************
Varun Wadekarcbdace12015-09-03 14:32:44 +053022 * Tegra132 SiP SMCs
Varun Wadekar0f3baa02015-07-16 11:36:33 +053023 ******************************************************************************/
Varun Wadekar0f3baa02015-07-16 11:36:33 +053024#define TEGRA_SIP_AARCH_SWITCH 0x82000004
25
26/*******************************************************************************
27 * SPSR settings for AARCH32/AARCH64 modes
28 ******************************************************************************/
29#define SPSR32 SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, \
30 DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)
31#define SPSR64 SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)
Varun Wadekar7a269e22015-06-10 14:04:32 +053032
33/*******************************************************************************
Varun Wadekar923d04a2015-12-09 18:18:53 -080034 * This function is responsible for handling all T132 SiP calls
Varun Wadekar7a269e22015-06-10 14:04:32 +053035 ******************************************************************************/
Varun Wadekar923d04a2015-12-09 18:18:53 -080036int 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)
Varun Wadekar7a269e22015-06-10 14:04:32 +053044{
Varun Wadekar7a269e22015-06-10 14:04:32 +053045 switch (smc_fid) {
46
Varun Wadekar0f3baa02015-07-16 11:36:33 +053047 case TEGRA_SIP_AARCH_SWITCH:
48
49 /* clean up the high bits */
50 x1 = (uint32_t)x1;
51 x2 = (uint32_t)x2;
52
53 if (!x1 || x2 > NS_SWITCH_AARCH32) {
54 ERROR("%s: invalid parameters\n", __func__);
Varun Wadekar923d04a2015-12-09 18:18:53 -080055 return -EINVAL;
Varun Wadekar0f3baa02015-07-16 11:36:33 +053056 }
57
58 /* x1 = ns entry point */
59 cm_set_elr_spsr_el3(NON_SECURE, x1,
60 (x2 == NS_SWITCH_AARCH32) ? SPSR32 : SPSR64);
61
62 /* switch NS world mode */
63 cm_write_scr_el3_bit(NON_SECURE, SCR_RW_BITPOS, !x2);
64
65 INFO("CPU switched to AARCH%s mode\n",
66 (x2 == NS_SWITCH_AARCH32) ? "32" : "64");
Varun Wadekar923d04a2015-12-09 18:18:53 -080067 return 0;
Varun Wadekar7a269e22015-06-10 14:04:32 +053068
69 default:
70 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
71 break;
72 }
73
Varun Wadekar923d04a2015-12-09 18:18:53 -080074 return -ENOTSUP;
Varun Wadekar7a269e22015-06-10 14:04:32 +053075}