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>
This commit is contained in:
Pratik Patel 2014-09-01 10:04:34 -07:00 committed by David Keitel
parent 240d67c2b0
commit ebce13ea36
4 changed files with 170 additions and 0 deletions

View file

@ -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

View file

@ -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

102
drivers/soc/qcom/hvc.c Normal file
View file

@ -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);

58
include/soc/qcom/hvc.h Normal file
View file

@ -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