diff options
| author | Pratik Patel <pratikp@codeaurora.org> | 2014-09-01 10:04:34 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:12:06 -0700 |
| commit | ebce13ea36f54efcb366c562deb0c1bd3d81e688 (patch) | |
| tree | 8e98747fb7e83a7d154d47d531e4b8b7f00dbab0 | |
| parent | 240d67c2b05d5e3e0e358d7c607b531b65eb8b51 (diff) | |
soc: qcom: hvc: add hypervisor call support
Add API support for calling into the hypervisor. This will allow
various drivers to avail hypervisor services.
Change-Id: I0a0e8f8fe13a550ad20c5421b712e207933c82f3
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
[pdaly@codeaurora.org Resolve minor conflicts]
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
| -rw-r--r-- | drivers/soc/qcom/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/soc/qcom/Makefile | 1 | ||||
| -rw-r--r-- | drivers/soc/qcom/hvc.c | 102 | ||||
| -rw-r--r-- | include/soc/qcom/hvc.h | 58 |
4 files changed, 170 insertions, 0 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 6991305fc4ab..640ad813b88c 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -179,6 +179,15 @@ config QCOM_SMEM The driver provides an interface to items in a heap shared among all processors in a Qualcomm platform. +config MSM_HVC + bool "MSM Hypervisor Call Support" + help + This enables the Hypervisor Call module. It provides apis to call + into the hypervisor thereby allowing access to services exposed by + the hypervisor. It is primarily intended to be used for Silicon + Partner/Manufacturer function identifier subrange but supports other + service call subranges as well. + config MSM_IPC_ROUTER_SMD_XPRT depends on MSM_SMD depends on IPC_ROUTER diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 30bff4c3f6b3..ea2556d8861a 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_sleepstate.o obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_spinlock_test.o obj-$(CONFIG_MSM_QMI_INTERFACE) += qmi_interface.o obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd.o +obj-$(CONFIG_MSM_HVC) += hvc.o ifdef CONFIG_DEBUG_FS obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o endif diff --git a/drivers/soc/qcom/hvc.c b/drivers/soc/qcom/hvc.c new file mode 100644 index 000000000000..0421326aa1cd --- /dev/null +++ b/drivers/soc/qcom/hvc.c @@ -0,0 +1,102 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/io.h> +#include <linux/export.h> +#include <linux/err.h> + +#include <asm/compiler.h> + +#include <soc/qcom/hvc.h> + +#define HVC_RET_SUCCESS 0 +#define HVC_RET_ERROR -1 +#define HVC_RET_EFUNCNOSUPPORT -2 +#define HVC_RET_EINVALARCH -3 +#define HVC_RET_EMEMMAP -4 +#define HVC_RET_EMEMUNMAP -5 +#define HVC_RET_EMEMPERM -6 + +static int hvc_to_linux_errno(int errno) +{ + switch (errno) { + case HVC_RET_SUCCESS: + return 0; + case HVC_RET_ERROR: + return -EIO; + case HVC_RET_EFUNCNOSUPPORT: + return -EOPNOTSUPP; + case HVC_RET_EINVALARCH: + case HVC_RET_EMEMMAP: + case HVC_RET_EMEMUNMAP: + return -EINVAL; + case HVC_RET_EMEMPERM: + return -EPERM; + }; + + return -EINVAL; +} + +#ifdef CONFIG_ARM64 +static int __hvc(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, + u64 x6, u64 x7, u64 *ret1, u64 *ret2, u64 *ret3) +{ + register u64 r0 asm("x0") = x0; + register u64 r1 asm("x1") = x1; + register u64 r2 asm("x2") = x2; + register u64 r3 asm("x3") = x3; + register u64 r4 asm("x4") = x4; + register u64 r5 asm("x5") = x5; + register u64 r6 asm("x6") = x6; + register u64 r7 asm("x7") = x7; + + asm volatile( + __asmeq("%0", "x0") + __asmeq("%1", "x1") + __asmeq("%2", "x2") + __asmeq("%3", "x3") + __asmeq("%4", "x4") + __asmeq("%5", "x5") + __asmeq("%6", "x6") + __asmeq("%7", "x7") + "hvc #0\n" + : "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3) + : "r" (r4), "r" (r5), "r" (r6), "r" (r7)); + + *ret1 = r1; + *ret2 = r2; + *ret3 = r3; + + return r0; +} +#else +static int __hvc(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5, + u64 x6, u64 *ret1, u64 *ret2, u64 *ret3) +{ + return 0; +} +#endif + +int hvc(u64 func_id, struct hvc_desc *desc) +{ + int ret; + + if (!desc) + return -EINVAL; + + ret = __hvc(func_id, desc->arg[0], desc->arg[1], desc->arg[2], + desc->arg[3], desc->arg[4], desc->arg[5], 0, + &desc->ret[0], &desc->ret[1], &desc->ret[2]); + + return hvc_to_linux_errno(ret); +} +EXPORT_SYMBOL(hvc); diff --git a/include/soc/qcom/hvc.h b/include/soc/qcom/hvc.h new file mode 100644 index 000000000000..435729b13490 --- /dev/null +++ b/include/soc/qcom/hvc.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MSM_HVC_H +#define __MSM_HVC_H + +#ifdef CONFIG_ARM64 +#define HVC_FN_ARM_BASE 0xC0000000 +#define HVC_FN_CPU_BASE 0xC1000000 +#define HVC_FN_SIP_BASE 0xC2000000 +#define HVC_FN_OEM_BASE 0xC3000000 +#define HVC_FN_APP_BASE 0xF0000000 +#define HVC_FN_OS_BASE 0xF2000000 +#else +#define HVC_FN_ARM_BASE 0x80000000 +#define HVC_FN_CPU_BASE 0x81000000 +#define HVC_FN_SIP_BASE 0x82000000 +#define HVC_FN_OEM_BASE 0x83000000 +#define HVC_FN_APP_BASE 0xB0000000 +#define HVC_FN_OS_BASE 0xB2000000 +#endif + +#define HVC_FN_ARM(n) (HVC_FN_ARM_BASE + (n)) +#define HVC_FN_CPU(n) (HVC_FN_CPU_BASE + (n)) +#define HVC_FN_SIP(n) (HVC_FN_SIP_BASE + (n)) +#define HVC_FN_OEM(n) (HVC_FN_OEM_BASE + (n)) +#define HVC_FN_APP(n) (HVC_FN_APP_BASE + (n)) +#define HVC_FN_OS(n) (HVC_FN_OS_BASE + (n)) + +#define HVC_MAX_ARGS 6 +#define HVC_MAX_RETS 3 +#define HVC_MAX_EXTRA_ARGS 4 + +struct hvc_desc { + u64 arg[HVC_MAX_ARGS]; + u64 ret[HVC_MAX_RETS]; +}; + +struct hvc_extra_args { + u64 arg[HVC_MAX_EXTRA_ARGS]; +}; + +#ifdef CONFIG_MSM_HVC +extern int hvc(u64 func_id, struct hvc_desc *desc); +#else +static inline int hvc(u64 func_id, struct hvc_desc *desc) { return 0; } +#endif + +#endif |
