137535Sdes/*-
237535Sdes * SPDX-License-Identifier: BSD-2-Clause
337535Sdes *
437535Sdes * Copyright (c) 2018 Andrew Turner
537535Sdes *
637535Sdes * This software was developed by SRI International and the University of
737535Sdes * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
837535Sdes * ("CTSRD"), as part of the DARPA CRASH research programme.
937535Sdes *
1037535Sdes * Redistribution and use in source and binary forms, with or without
1137535Sdes * modification, are permitted provided that the following conditions
1237535Sdes * are met:
1337535Sdes * 1. Redistributions of source code must retain the above copyright
1437535Sdes *    notice, this list of conditions and the following disclaimer.
1537535Sdes * 2. Redistributions in binary form must reproduce the above copyright
1637535Sdes *    notice, this list of conditions and the following disclaimer in the
1737535Sdes *    documentation and/or other materials provided with the distribution.
1837535Sdes *
1937535Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2037535Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2137535Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2237535Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2337535Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2437535Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2537535Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2637535Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2737535Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2840939Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2937535Sdes * SUCH DAMAGE.
3037535Sdes */
3137608Sdes
3237608Sdes#ifndef	_PSCI_SMCCC_H_
3337608Sdes#define	_PSCI_SMCCC_H_
3437608Sdes
3537608Sdes#define	SMCCC_VERSION_MAJOR(ver)	(((ver) >> 16) & 0x7fff)
3637608Sdes#define	SMCCC_VERSION_MINOR(ver)	((ver) & 0xffff)
3737608Sdes
3837608Sdes#define	SMCCC_FUNC_ID(type, call_conv, range, func)	\
3937608Sdes	(((type) << 31) |				\
4037608Sdes	 ((call_conv) << 30) |				\
4137608Sdes	 (((range) & 0x3f) << 24) |				\
4237608Sdes	 ((func) & 0xffff))
4337608Sdes
4437608Sdes#define	SMCCC_YIELDING_CALL	0
4537608Sdes#define	SMCCC_FAST_CALL		1
4637608Sdes
4737608Sdes#define	SMCCC_32BIT_CALL	0
4837608Sdes#define	SMCCC_64BIT_CALL	1
4937608Sdes
5037608Sdes#define	SMCCC_ARM_ARCH_CALLS		0
5137608Sdes#define	SMCCC_CPU_SERVICE_CALLS		1
5237608Sdes#define	SMCCC_SIP_SERVICE_CALLS		2
5337608Sdes#define	SMCCC_OEM_SERVICE_CALLS		3
5437608Sdes#define	SMCCC_STD_SECURE_SERVICE_CALLS	4
5537608Sdes#define	SMCCC_STD_HYP_SERVICE_CALLS	5
5637608Sdes#define	SMCCC_VENDOR_HYP_SERVICE_CALLS	6
5737608Sdes
5837608Sdesstruct arm_smccc_res {
5937608Sdes	register_t a0;
6037608Sdes	register_t a1;
6137608Sdes	register_t a2;
6237608Sdes	register_t a3;
6337535Sdes};
6437535Sdes
6537535Sdes/*
6637535Sdes * Arm Architecture Calls.
6737535Sdes * These are documented in the document ARM DEN 0070A.
6837535Sdes */
6937535Sdes#define	SMCCC_VERSION							\
7037535Sdes    SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 0)
7137535Sdes#define	SMCCC_ARCH_FEATURES						\
7237535Sdes    SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 1)
7337608Sdes#define	SMCCC_ARCH_WORKAROUND_1						\
7437535Sdes    SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 0x8000)
7537535Sdes#define	SMCCC_ARCH_WORKAROUND_2						\
7637535Sdes    SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 0x7fff)
7737535Sdes
7837535Sdes/* The return values from ARM DEN 0070A. */
7937535Sdes#define	SMCCC_RET_SUCCESS		0
8040939Sdes#define	SMCCC_RET_NOT_SUPPORTED		-1
8137535Sdes#define	SMCCC_RET_NOT_REQUIRED		-2
8237535Sdes
8337535Sdesvoid smccc_init(void);
8437535Sdesuint32_t smccc_get_version(void);
8537535Sdesint32_t smccc_arch_features(uint32_t);
8637535Sdesint smccc_arch_workaround_1(void);
8737535Sdesint smccc_arch_workaround_2(int);
8837535Sdes
8937535Sdesint arm_smccc_smc(register_t, register_t, register_t, register_t, register_t,
9037535Sdes    register_t, register_t, register_t, struct arm_smccc_res *res);
9137535Sdesint arm_smccc_hvc(register_t, register_t, register_t, register_t, register_t,
9237535Sdes    register_t, register_t, register_t, struct arm_smccc_res *res);
9337535Sdes
9437535Sdesstruct arm_smccc_1_2_regs {
9537535Sdes	register_t a0;
9637535Sdes	register_t a1;
9737535Sdes	register_t a2;
9837535Sdes	register_t a3;
9937535Sdes	register_t a4;
10037535Sdes	register_t a5;
10137535Sdes	register_t a6;
10237535Sdes	register_t a7;
10337535Sdes	register_t a8;
10437535Sdes	register_t a9;
10537535Sdes	register_t a10;
10637608Sdes	register_t a11;
10737608Sdes	register_t a12;
10837608Sdes	register_t a13;
10937608Sdes	register_t a14;
11037608Sdes	register_t a15;
11137608Sdes	register_t a16;
11237608Sdes	register_t a17;
11337608Sdes};
11437608Sdes
11537608Sdesint arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
11637608Sdes    struct arm_smccc_1_2_regs *res);
11737608Sdesint arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
11837608Sdes    struct arm_smccc_1_2_regs *res);
11937608Sdes#endif /* _PSCI_SMCCC_H_ */
12037608Sdes