Home | History | Annotate | Download | only in t132
      1 /*
      2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <arch.h>
      8 #include <arch_helpers.h>
      9 #include <assert.h>
     10 #include <bl_common.h>
     11 #include <context_mgmt.h>
     12 #include <debug.h>
     13 #include <errno.h>
     14 #include <tegra_private.h>
     15 
     16 #define NS_SWITCH_AARCH32	1
     17 #define SCR_RW_BITPOS		__builtin_ctz(SCR_RW_BIT)
     18 
     19 /*******************************************************************************
     20  * Tegra132 SiP SMCs
     21  ******************************************************************************/
     22 #define TEGRA_SIP_AARCH_SWITCH			0x82000004
     23 
     24 /*******************************************************************************
     25  * SPSR settings for AARCH32/AARCH64 modes
     26  ******************************************************************************/
     27 #define SPSR32		SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, \
     28 			DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)
     29 #define SPSR64		SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)
     30 
     31 /*******************************************************************************
     32  * This function is responsible for handling all T132 SiP calls
     33  ******************************************************************************/
     34 int plat_sip_handler(uint32_t smc_fid,
     35 		     uint64_t x1,
     36 		     uint64_t x2,
     37 		     uint64_t x3,
     38 		     uint64_t x4,
     39 		     void *cookie,
     40 		     void *handle,
     41 		     uint64_t flags)
     42 {
     43 	switch (smc_fid) {
     44 
     45 	case TEGRA_SIP_AARCH_SWITCH:
     46 
     47 		/* clean up the high bits */
     48 		x1 = (uint32_t)x1;
     49 		x2 = (uint32_t)x2;
     50 
     51 		if (!x1 || x2 > NS_SWITCH_AARCH32) {
     52 			ERROR("%s: invalid parameters\n", __func__);
     53 			return -EINVAL;
     54 		}
     55 
     56 		/* x1 = ns entry point */
     57 		cm_set_elr_spsr_el3(NON_SECURE, x1,
     58 			(x2 == NS_SWITCH_AARCH32) ? SPSR32 : SPSR64);
     59 
     60 		/* switch NS world mode */
     61 		cm_write_scr_el3_bit(NON_SECURE, SCR_RW_BITPOS, !x2);
     62 
     63 		INFO("CPU switched to AARCH%s mode\n",
     64 			(x2 == NS_SWITCH_AARCH32) ? "32" : "64");
     65 		return 0;
     66 
     67 	default:
     68 		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
     69 		break;
     70 	}
     71 
     72 	return -ENOTSUP;
     73 }
     74