mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
soc: qcom: Migrate SCM calls in qtee_shmbridge
Adding APIs to create, delete, and enable shmbridge. Migrating SCM calls in qtee_shmbridge to use the new APIs. Change-Id: I038e7950d11cbf6bb38a8824a576f2d92f879454 Signed-off-by: Siddharth Gupta <sidgup@codeaurora.org> Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
parent
49ec350a86
commit
b6e110d2d0
5 changed files with 131 additions and 63 deletions
|
|
@ -1137,6 +1137,69 @@ int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following shmbridge functions should be called before the SCM driver
|
||||
* has been initialized. If not, there could be errors that might cause the
|
||||
* system to crash.
|
||||
*/
|
||||
int __qcom_scm_enable_shm_bridge(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_MP,
|
||||
.cmd = QCOM_SCM_MEMP_SHM_BRIDGE_ENABLE,
|
||||
.owner = ARM_SMCCC_OWNER_SIP
|
||||
};
|
||||
|
||||
ret = qcom_scm_call(dev, &desc);
|
||||
|
||||
return ret ? : desc.res[0];
|
||||
}
|
||||
|
||||
int __qcom_scm_delete_shm_bridge(struct device *dev, u64 handle)
|
||||
{
|
||||
int ret;
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_MP,
|
||||
.cmd = QCOM_SCM_MEMP_SHM_BRIDGE_DELETE,
|
||||
.owner = ARM_SMCCC_OWNER_SIP
|
||||
};
|
||||
|
||||
desc.args[0] = handle;
|
||||
desc.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL);
|
||||
|
||||
ret = qcom_scm_call(dev, &desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||
u64 ns_vmids, u64 *handle)
|
||||
{
|
||||
int ret;
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_MP,
|
||||
.cmd = QCOM_SCM_MEMP_SHM_BRDIGE_CREATE,
|
||||
.owner = ARM_SMCCC_OWNER_SIP
|
||||
};
|
||||
|
||||
desc.args[0] = pfn_and_ns_perm_flags;
|
||||
desc.args[1] = ipfn_and_s_perm_flags;
|
||||
desc.args[2] = size_and_flags;
|
||||
desc.args[3] = ns_vmids;
|
||||
|
||||
desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
|
||||
QCOM_SCM_VAL, QCOM_SCM_VAL);
|
||||
|
||||
ret = qcom_scm_call(dev, &desc);
|
||||
|
||||
if (handle)
|
||||
*handle = desc.res[1];
|
||||
|
||||
return ret ? : desc.res[0];
|
||||
}
|
||||
|
||||
int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id, int cb_num,
|
||||
int operation)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -504,6 +504,28 @@ int qcom_scm_kgsl_set_smmu_aperture(unsigned int num_context_bank)
|
|||
}
|
||||
EXPORT_SYMBOL(qcom_scm_kgsl_set_smmu_aperture);
|
||||
|
||||
int qcom_scm_enable_shm_bridge(void)
|
||||
{
|
||||
return __qcom_scm_enable_shm_bridge(__scm ? __scm->dev : NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_enable_shm_bridge);
|
||||
|
||||
int qcom_scm_delete_shm_bridge(u64 handle)
|
||||
{
|
||||
return __qcom_scm_delete_shm_bridge(__scm ? __scm->dev : NULL, handle);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_delete_shm_bridge);
|
||||
|
||||
int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags, u64 ns_vmids,
|
||||
u64 *handle)
|
||||
{
|
||||
return __qcom_scm_create_shm_bridge(__scm ? __scm->dev : NULL,
|
||||
pfn_and_ns_perm_flags, ipfn_and_s_perm_flags,
|
||||
size_and_flags, ns_vmids, handle);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_create_shm_bridge);
|
||||
|
||||
int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation)
|
||||
{
|
||||
return __qcom_scm_smmu_prepare_atos_id(__scm->dev, dev_id, cb_num,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ extern void __qcom_scm_mmu_sync(struct device *dev, bool sync);
|
|||
#define QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT 0x13
|
||||
#define QCOM_SCM_MP_ASSIGN 0x16
|
||||
#define QCOM_SCM_MP_CP_SMMU_APERTURE_ID 0x1b
|
||||
#define QCOM_SCM_MEMP_SHM_BRIDGE_ENABLE 0x1c
|
||||
#define QCOM_SCM_MEMP_SHM_BRIDGE_DELETE 0x1d
|
||||
#define QCOM_SCM_MEMP_SHM_BRDIGE_CREATE 0x1e
|
||||
#define QCOM_SCM_MP_SMMU_PREPARE_ATOS_ID 0x21
|
||||
extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
|
||||
u32 spare);
|
||||
|
|
@ -96,6 +99,11 @@ extern int __qcom_scm_assign_mem(struct device *dev,
|
|||
phys_addr_t dest, size_t dest_sz);
|
||||
extern int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev,
|
||||
unsigned int num_context_bank);
|
||||
extern int __qcom_scm_enable_shm_bridge(struct device *dev);
|
||||
extern int __qcom_scm_delete_shm_bridge(struct device *dev, u64 handle);
|
||||
extern int __qcom_scm_create_shm_bridge(struct device *dev,
|
||||
u64 pfn_and_ns_perm_flags, u64 ipfn_and_s_perm_flags,
|
||||
u64 size_and_flags, u64 ns_vmids, u64 *handle);
|
||||
extern int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id,
|
||||
int cb_num, int operation);
|
||||
#define QCOM_SCM_IOMMU_TLBINVAL_FLAG 0x00000001
|
||||
|
|
|
|||
|
|
@ -11,48 +11,13 @@
|
|||
#include <linux/genalloc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <soc/qcom/scm.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <soc/qcom/qseecomi.h>
|
||||
#include <linux/qtee_shmbridge.h>
|
||||
|
||||
#include "qtee_shmbridge_internal.h"
|
||||
|
||||
#define DEFAULT_BRIDGE_SIZE SZ_4M /*4M*/
|
||||
/*
|
||||
* tz_enable_shm_bridge
|
||||
* smc_id: 0x02000C1C
|
||||
*/
|
||||
#define TZ_SVC_MEMORY_PROTECTION 12
|
||||
|
||||
#define TZ_SHM_BRIDGE_ENABLE \
|
||||
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1C)
|
||||
|
||||
#define TZ_SHM_BRIDGE_ENABLE_PARAM_ID \
|
||||
TZ_SYSCALL_CREATE_PARAM_ID_0
|
||||
|
||||
/*
|
||||
* tz_create_shm_bridge
|
||||
* smc_id: 0x02000C1E
|
||||
*/
|
||||
|
||||
#define TZ_SHM_BRIDGE_CREATE \
|
||||
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1E)
|
||||
|
||||
#define TZ_SHM_BRIDGE_CREATE_PARAM_ID \
|
||||
TZ_SYSCALL_CREATE_PARAM_ID_4( \
|
||||
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
|
||||
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
|
||||
|
||||
/**
|
||||
* tz_delete_shm_bridge
|
||||
* smc_id: 0x02000C1D
|
||||
*/
|
||||
#define TZ_SHM_BRIDGE_DELETE \
|
||||
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1D)
|
||||
|
||||
#define TZ_SHM_BRIDGE_DELETE_PARAM_ID \
|
||||
TZ_SYSCALL_CREATE_PARAM_ID_1( \
|
||||
TZ_SYSCALL_PARAM_TYPE_VAL)
|
||||
|
||||
#define MAXSHMVMS 4
|
||||
#define PERM_BITS 3
|
||||
|
|
@ -118,7 +83,6 @@ static bool qtee_shmbridge_enabled;
|
|||
static int32_t qtee_shmbridge_enable(bool enable)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
struct scm_desc desc = {0};
|
||||
|
||||
qtee_shmbridge_enabled = false;
|
||||
if (!enable) {
|
||||
|
|
@ -126,14 +90,14 @@ static int32_t qtee_shmbridge_enable(bool enable)
|
|||
return ret;
|
||||
}
|
||||
|
||||
desc.arginfo = TZ_SHM_BRIDGE_ENABLE_PARAM_ID;
|
||||
ret = scm_call2(TZ_SHM_BRIDGE_ENABLE, &desc);
|
||||
if (ret || desc.ret[0]) {
|
||||
pr_err("Failed to enable shmbridge, rsp = %lld, ret = %d\n",
|
||||
desc.ret[0], ret);
|
||||
if (ret == -EIO || desc.ret[0] == SHMBRIDGE_E_NOT_SUPPORTED)
|
||||
ret = qcom_scm_enable_shm_bridge();
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to enable shmbridge, ret = %d\n", ret);
|
||||
|
||||
if (ret == -EIO || ret == SHMBRIDGE_E_NOT_SUPPORTED)
|
||||
pr_warn("shmbridge is not supported by this target\n");
|
||||
return ret | desc.ret[0];
|
||||
return ret;
|
||||
}
|
||||
qtee_shmbridge_enabled = true;
|
||||
pr_warn("shmbridge is enabled\n");
|
||||
|
|
@ -210,9 +174,11 @@ int32_t qtee_shmbridge_register(
|
|||
|
||||
{
|
||||
int32_t ret = 0;
|
||||
uint64_t pfn_and_ns_perm_flags = 0;
|
||||
uint64_t ipfn_and_s_perm_flags = 0;
|
||||
uint64_t size_and_flags = 0;
|
||||
uint64_t ns_perms = 0;
|
||||
uint64_t ns_vmids = 0;
|
||||
struct scm_desc desc = {0};
|
||||
int i = 0;
|
||||
|
||||
if (!qtee_shmbridge_enabled)
|
||||
|
|
@ -234,23 +200,23 @@ int32_t qtee_shmbridge_register(
|
|||
ns_vmids = UPDATE_NS_VMIDS(ns_vmids, ns_vmid_list[i]);
|
||||
}
|
||||
|
||||
desc.arginfo = TZ_SHM_BRIDGE_CREATE_PARAM_ID;
|
||||
desc.args[0] = UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms);
|
||||
desc.args[1] = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm);
|
||||
desc.args[2] = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num);
|
||||
desc.args[3] = ns_vmids;
|
||||
pfn_and_ns_perm_flags = UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms);
|
||||
ipfn_and_s_perm_flags = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm);
|
||||
size_and_flags = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num);
|
||||
|
||||
pr_debug("%s: arginfo %x, desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n",
|
||||
__func__, desc.arginfo, desc.args[0],
|
||||
desc.args[1], desc.args[2], desc.args[3]);
|
||||
ret = scm_call2(TZ_SHM_BRIDGE_CREATE, &desc);
|
||||
if (ret || desc.ret[0]) {
|
||||
pr_err("create shmbridge failed, ret = %d, status = %llx\n",
|
||||
ret, desc.ret[0]);
|
||||
pr_debug("%s: desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n",
|
||||
__func__, pfn_and_ns_perm_flags, ipfn_and_s_perm_flags,
|
||||
size_and_flags, ns_vmids);
|
||||
|
||||
ret = qcom_scm_create_shm_bridge(pfn_and_ns_perm_flags,
|
||||
ipfn_and_s_perm_flags, size_and_flags, ns_vmids,
|
||||
handle);
|
||||
|
||||
if (ret) {
|
||||
pr_err("create shmbridge failed, ret = %d\n", ret);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
*handle = desc.ret[1];
|
||||
|
||||
ret = qtee_shmbridge_list_add_nolock(paddr, *handle);
|
||||
exit:
|
||||
|
|
@ -263,15 +229,14 @@ EXPORT_SYMBOL(qtee_shmbridge_register);
|
|||
int32_t qtee_shmbridge_deregister(uint64_t handle)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
struct scm_desc desc = {0};
|
||||
|
||||
if (!qtee_shmbridge_enabled)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&bridge_list_head.lock);
|
||||
desc.arginfo = TZ_SHM_BRIDGE_DELETE_PARAM_ID;
|
||||
desc.args[0] = handle;
|
||||
ret = scm_call2(TZ_SHM_BRIDGE_DELETE, &desc);
|
||||
|
||||
ret = qcom_scm_delete_shm_bridge(handle);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to del bridge %lld, ret = %d\n", handle, ret);
|
||||
goto exit;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ extern int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation);
|
|||
extern bool qcom_scm_hdcp_available(void);
|
||||
extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
|
||||
u32 *resp);
|
||||
extern int qcom_scm_enable_shm_bridge(void);
|
||||
extern int qcom_scm_delete_shm_bridge(u64 handle);
|
||||
extern int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||
u64 ns_vmids, u64 *handle);
|
||||
extern int qcom_scm_smmu_change_pgtbl_format(u64 dev_id, int cbndx);
|
||||
extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
|
||||
extern int qcom_scm_ice_restore_cfg(void);
|
||||
|
|
@ -139,6 +144,11 @@ static inline int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num,
|
|||
static inline bool qcom_scm_hdcp_available(void) { return false; }
|
||||
static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
|
||||
u32 *resp) { return -ENODEV; }
|
||||
static inline int qcom_scm_enable_shm_bridge(void) { return -ENODEV; }
|
||||
static inline int qcom_scm_delete_shm_bridge(u64 handle) { return -ENODEV; }
|
||||
static inline int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
|
||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||
u64 ns_vmids, u64 *handle) { return -ENODEV; }
|
||||
static inline int qcom_scm_smmu_change_pgtbl_format(u64 dev_id, int cbndx)
|
||||
{ return -ENODEV; }
|
||||
static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
|
||||
|
|
|
|||
Loading…
Reference in a new issue