• 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 #include <errno.h>
9 
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 
16 #include <tegra_private.h>
17 
18 #define NS_SWITCH_AARCH32	1
19 #define SCR_RW_BITPOS		__builtin_ctz(SCR_RW_BIT)
20 
21 /*******************************************************************************
22  * Tegra132 SiP SMCs
23  ******************************************************************************/
24 #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)
32 
33 /*******************************************************************************
34  * This function is responsible for handling all T132 SiP calls
35  ******************************************************************************/
plat_sip_handler(uint32_t smc_fid,uint64_t x1,uint64_t x2,uint64_t x3,uint64_t x4,const void * cookie,void * handle,uint64_t flags)36 int plat_sip_handler(uint32_t smc_fid,
37 		     uint64_t x1,
38 		     uint64_t x2,
39 		     uint64_t x3,
40 		     uint64_t x4,
41 		     const void *cookie,
42 		     void *handle,
43 		     uint64_t flags)
44 {
45 	switch (smc_fid) {
46 
47 	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__);
55 			return -EINVAL;
56 		}
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");
67 		return 0;
68 
69 	default:
70 		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
71 		break;
72 	}
73 
74 	return -ENOTSUP;
75 }
76