Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a372326 authored by Pratik Patel's avatar Pratik Patel Committed by Matt Wagantall
Browse files

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: default avatarPratik Patel <pratikp@codeaurora.org>
parent 794b0bcc
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -386,6 +386,15 @@ config MSM_DCC
	  driver provides interface to configure DCC block and read back
	  captured data from DCC's internal SRAM.

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
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ obj-$(CONFIG_MSM_DDR_HEALTH) += ddr-health.o
obj-$(CONFIG_MSM_DCC) += dcc.o
obj-$(CONFIG_MSM_WATCHDOG_V2) += watchdog_v2.o
obj-$(CONFIG_MSM_COMMON_LOG) += common_log.o
obj-$(CONFIG_MSM_HVC) += hvc.o
obj-$(CONFIG_MSM_CPU_PWR_CTL) += cpu_pwr_ctl.o
obj-$(CONFIG_MSM_CACHE_M4M_ERP64) += cache_m4m_erp64.o
obj-$(CONFIG_SOC_BUS)  +=      socinfo.o

drivers/soc/qcom/hvc.c

0 → 100644
+102 −0
Original line number Diff line number Diff line
/* 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);

include/soc/qcom/hvc.h

0 → 100644
+58 −0
Original line number Diff line number Diff line
/* 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