소스 검색

Merge 986fef5bf884643f52c68d95c59f10373b06fe83 on remote branch

Change-Id: Ic3fff7f991116ed3c44d213faa723db504703e3d
Linux Build Service Account 2 년 전
부모
커밋
b4ad3daaac
55개의 변경된 파일5444개의 추가작업 그리고 1296개의 파일을 삭제
  1. 52 4
      Android.bp
  2. 3 4
      Android.mk
  3. 30 14
      BUILD.bazel
  4. 9 5
      Kbuild
  5. 2 0
      config/sec-kernel_defconfig.conf
  6. 1 1
      config/sec-kernel_defconfig_qseecom.conf
  7. 6 0
      config/sec-kernel_defconfig_qseecom_compat.h
  8. 2 1
      crypto-qti/compat_qcedev.c
  9. 1 0
      crypto-qti/fips_status.h
  10. 4 2
      crypto-qti/qce.h
  11. 48 28
      crypto-qti/qce50.c
  12. 24 11
      crypto-qti/qcedev.c
  13. 3 2
      crypto-qti/qcedevi.h
  14. 1 0
      crypto-qti/qcom_crypto_device.h
  15. 4 3
      crypto-qti/qcrypto.c
  16. 1 0
      crypto-qti/qcrypto.h
  17. 123 0
      hdcp/hdcp1.h
  18. 27 0
      hdcp/hdcp1_ops.h
  19. 303 0
      hdcp/hdcp2p2.h
  20. 316 0
      hdcp/hdcp_main.c
  21. 108 0
      hdcp/hdcp_main.h
  22. 685 989
      hdcp/hdcp_qseecom.c
  23. 326 0
      hdcp/hdcp_qseecom.h
  24. 1090 0
      hdcp/hdcp_smcinvoke.c
  25. 62 0
      hdcp/hdcp_smcinvoke.h
  26. 15 11
      include/linux/smcinvoke.h
  27. 1 1
      include/linux/smcinvoke_object.h
  28. 48 0
      include/smci/interface/IAppClient.h
  29. 143 0
      include/smci/interface/IAppController.h
  30. 105 0
      include/smci/interface/IAppLoader.h
  31. 48 0
      include/smci/interface/IOpener.h
  32. 20 0
      include/smci/uid/CAppClient.h
  33. 12 0
      include/smci/uid/CAppLoader.h
  34. 2 1
      include/uapi/linux/compat_qcedev.h
  35. 387 0
      include/uapi/linux/qcedev.h
  36. 1 0
      include/uapi/linux/qcota.h
  37. 1 1
      include/uapi/linux/qrng.h
  38. 186 0
      include/uapi/linux/qseecom.h
  39. 196 0
      include/uapi/linux/qseecom_api.h
  40. 110 0
      include/uapi/linux/smcinvoke.h
  41. 3 2
      linux/misc/qseecom_priv.h
  42. 740 0
      linux/misc/qseecomi.h
  43. 6 3
      linux/qcedev.h
  44. 5 2
      pineapple.bzl
  45. 58 129
      qseecom/qseecom.c
  46. 24 20
      securemsm_kernel.bzl
  47. 1 5
      securemsm_kernel_product_board.mk
  48. 5 6
      securemsm_kernel_vendor_board.mk
  49. 45 23
      securemsm_modules.bzl
  50. 29 15
      smcinvoke/smcinvoke.c
  51. 4 4
      smcinvoke/smcinvoke_kernel.c
  52. 1 1
      smmu-proxy/qti-smmu-proxy-common.c
  53. 0 1
      smmu-proxy/qti-smmu-proxy-tvm.c
  54. 15 6
      ssg_kernel_headers.py
  55. 2 1
      tz_log/tz_log.c

+ 52 - 4
Android.bp

@@ -1,5 +1,5 @@
 headers_src = [
-    "include/linux/smc*ke.h",
+    "include/uapi/linux/smc*ke.h",
     "include/linux/smc*_object.h",
     "include/linux/IClientE*v.h",
 ]
@@ -25,24 +25,72 @@ genrule {
         smcinvoke_kernel_headers_verbose +
         "--header_arch arm64 " +
         "--gen_dir $(genDir) " +
-        "--smcinvoke_headers_to_expose $(locations include/linux/smc*ke.h) $(locations include/linux/smc*_object.h) $(locations include/linux/IClientE*v.h) " +
+        "--smcinvoke_headers_to_expose $(locations include/uapi/linux/smc*ke.h) $(locations include/linux/smc*_object.h) $(locations include/linux/IClientE*v.h) " +
         "--unifdef $(location unifdef) " +
         "--headers_install $(location headers_install.sh)",
     out: smcinvoke_headers_out,
 }
 
-
 cc_library_headers {
     name: "smcinvoke_kernel_headers",
-    export_include_dirs: ["."] + ["include"],
+    export_include_dirs: ["."] + ["include"] + ["include/uapi"],
     generated_headers: ["qti_generate_smcinvoke_kernel_headers"],
     export_generated_headers: ["qti_generate_smcinvoke_kernel_headers"],
     vendor: true,
     recovery_available: true
 }
 
+qseecom_headers_src = [
+    "include/uapi/linux/qsee*om.h",
+    "include/uapi/linux/qsee*api.h",
+]
+
+qseecom_headers_out = [
+    "include/linux/qseecom.h",
+    "include/linux/qseecom_api.h",
+]
+
+qseecom_kernel_headers_verbose = "--verbose "
+
+genrule {
+    name: "qti_generate_qseecom_kernel_headers",
+    tools: ["headers_install.sh",
+            "unifdef"
+    ],
+    tool_files: [
+         "ssg_kernel_headers.py",
+    ],
+    srcs: qseecom_headers_src,
+    cmd: "python3 -u $(location ssg_kernel_headers.py) " +
+        qseecom_kernel_headers_verbose +
+        "--header_arch arm64 " +
+        "--gen_dir $(genDir) " +
+        "--smcinvoke_headers_to_expose $(locations include/uapi/linux/qsee*om.h) $(locations include/uapi/linux/qsee*api.h) " +
+        "--unifdef $(location unifdef) " +
+        "--headers_install $(location headers_install.sh)",
+    out: qseecom_headers_out,
+}
+
+
+cc_library_headers {
+    name: "qseecom_kernel_headers",
+    export_include_dirs: ["."] + ["include"] + ["include/uapi"],
+    generated_headers: ["qti_generate_qseecom_kernel_headers"],
+    export_generated_headers: ["qti_generate_qseecom_kernel_headers"],
+    vendor: true,
+    recovery_available: true
+}
+
+
 cc_library_headers {
     name: "smmu_proxy_uapi_header",
     vendor_available: true,
     export_include_dirs: ["smmu-proxy/uapi/"],
 }
+
+cc_library_headers {
+    name: "securemsm_kernel_uapi_headers",
+    vendor_available: true,
+    host_supported: true,
+    export_include_dirs: ["include/uapi"],
+}

+ 3 - 4
Android.mk

@@ -16,14 +16,15 @@ DLKM_DIR := $(TOP)/device/qcom/common/dlkm
 
 SEC_KERNEL_DIR := $(TOP)/vendor/qcom/opensource/securemsm-kernel
 
-LOCAL_EXPORT_KO_INCLUDE_DIRS := $(LOCAL_PATH)/include/
+LOCAL_EXPORT_KO_INCLUDE_DIRS := $(LOCAL_PATH)/include/ \
+                                $(LOCAL_PATH)/include/uapi
 
 SSG_SRC_FILES := \
 	$(wildcard $(LOCAL_PATH)/*) \
  	$(wildcard $(LOCAL_PATH)/*/*) \
  	$(wildcard $(LOCAL_PATH)/*/*/*) \
  	$(wildcard $(LOCAL_PATH)/*/*/*/*)
-
+LOCAL_MODULE_DDK_BUILD := true
 # This is set once per LOCAL_PATH, not per (kernel) module
 KBUILD_OPTIONS := SSG_ROOT=$(SEC_KERNEL_DIR)
 KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
@@ -110,7 +111,6 @@ LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/Build_external_kernelmodule.mk
 ###################################################
 ###################################################
-ifneq (, $(filter true, $(TARGET_ENABLE_QSEECOM) $(TARGET_BOARD_AUTO)))
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES           := $(SSG_SRC_FILES)
 LOCAL_MODULE              := qseecom_dlkm.ko
@@ -119,7 +119,6 @@ LOCAL_MODULE_TAGS         := optional
 LOCAL_MODULE_DEBUG_ENABLE := true
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/Build_external_kernelmodule.mk
-endif #TARGET_ENABLE_QSEECOM OR TARGET_BOARD_AUTO
 ###################################################
 ###################################################
 ifeq ($(TARGET_USES_SMMU_PROXY), true)

+ 30 - 14
BUILD.bazel

@@ -10,41 +10,57 @@ ddk_headers(
     name = "smcinvoke_kernel_headers",
     hdrs = glob([
         "include/linux/smcinvoke*.h",
+        "include/uapi/linux/smcinvoke*.h",
         "include/linux/IClientE*.h",
         "include/linux/ITrustedCameraDriver.h",
         "include/linux/CTrustedCameraDriver.h",
-        "linux/misc/qseecom_kernel.h",
-        "linux/misc/qseecom_priv.h"
     ]),
-    includes = ["include/linux", "linux", "include"]
+    includes = [
+        "include",
+        "include/linux",
+        "linux",
+        "include/uapi/linux",
+    ],
 )
 
 ddk_headers(
-    name = "securemsm_kernel_headers",
-    hdrs = [
+    name = "qseecom_kernel_headers",
+    hdrs = glob([
+        "include/uapi/linux/qseecom.h",
+        "include/uapi/linux/qseecom_api.h",
         "linux/misc/qseecom_kernel.h",
-        "linux/misc/qseecom_priv.h"
-    ],
-    includes = ["linux"]
+        "linux/misc/qseecom_priv.h",
+        "linux/misc/qseecomi.h",
+    ]),
+    includes = ["linux", "include/uapi", "include/uapi/linux"]
 )
+
 ddk_headers(
     name = "hdcp_qseecom_dlkm",
     hdrs = glob([
+        ":smcinvoke_kernel_headers",
         "linux/*.h",
-        "linux/misc/qseecom_kernel.h",
-        "hdcp_qseecom/*.h",
-        "config/*.h"
+        "include/linux/*h",
+        "include/smci/uid/*h",
+        "include/smci/interface/*h",
+        "linux/misc/*.h",
+        "config/*.h",
     ]),
-    includes = [".","linux","config"]
+    includes = [
+        ".",
+        "config",
+        "include",
+        "linux",
+    ],
 )
 
 ddk_headers(
     name = "qcedev_local_headers",
     hdrs = glob([
-        "linux/*.h",
+        "include/uapi/linux/*.h",
         "crypto-qti/*.h"
     ]),
-    includes = [".", "crypto-qti"]
+    includes = ["include/uapi", "include/uapi/linux", "crypto-qti"]
 )
 
 ddk_headers(

+ 9 - 5
Kbuild

@@ -1,6 +1,8 @@
 LINUXINCLUDE += -I$(SSG_MODULE_ROOT)/ \
                 -I$(SSG_MODULE_ROOT)/linux/ \
-                -I$(SSG_MODULE_ROOT)/include/linux/
+                -I$(SSG_MODULE_ROOT)/include/linux/ \
+                -I$(SSG_MODULE_ROOT)/include/uapi/ \
+                -I$(SSG_MODULE_ROOT)/include/uapi/linux/
 
 ifneq ($(CONFIG_ARCH_QTI_VM), y)
     LINUXINCLUDE += -include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig.h
@@ -11,11 +13,13 @@ endif
 ifneq (, $(filter y, $(CONFIG_QTI_QUIN_GVM) $(CONFIG_ARCH_KHAJE) $(CONFIG_ARCH_SA8155)))
     include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_qseecom.conf
     LINUXINCLUDE += -include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_qseecom.h
-
-    obj-$(CONFIG_QSEECOM) += qseecom_dlkm.o
-    qseecom_dlkm-objs := qseecom/qseecom.o
+else
+    LINUXINCLUDE += -include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_qseecom_compat.h
 endif
 
+obj-$(CONFIG_QSEECOM) += qseecom_dlkm.o
+qseecom_dlkm-objs := qseecom/qseecom.o
+
 include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_smcinvoke.conf
 LINUXINCLUDE += -include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_smcinvoke.h
 
@@ -35,7 +39,7 @@ obj-$(CONFIG_CRYPTO_DEV_QCRYPTO) += qcrypto-msm_dlkm.o
 qcrypto-msm_dlkm-objs := crypto-qti/qcrypto.o
 
 obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom_dlkm.o
-hdcp_qseecom_dlkm-objs := hdcp/hdcp_qseecom.o
+hdcp_qseecom_dlkm-objs := hdcp/hdcp_main.o hdcp/hdcp_smcinvoke.o hdcp/hdcp_qseecom.o
 
 obj-$(CONFIG_HW_RANDOM_MSM_LEGACY) += qrng_dlkm.o
 qrng_dlkm-objs := qrng/msm_rng.o

+ 2 - 0
config/sec-kernel_defconfig.conf

@@ -3,3 +3,5 @@ export CONFIG_CRYPTO_DEV_QCEDEV=m
 export CONFIG_CRYPTO_DEV_QCRYPTO=m
 export CONFIG_HDCP_QSEECOM=m
 export CONFIG_HW_RANDOM_MSM_LEGACY=m
+export CONFIG_QSEECOM_PROXY=m
+export CONFIG_QSEECOM=m

+ 1 - 1
config/sec-kernel_defconfig_qseecom.conf

@@ -1 +1 @@
-export CONFIG_QSEECOM=m
+export CONFIG_QTI_CRYPTO_FDE=m

+ 6 - 0
config/sec-kernel_defconfig_qseecom_compat.h

@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved..
+ */
+
+#define  CONFIG_QSEECOM_COMPAT 1

+ 2 - 1
crypto-qti/compat_qcedev.c

@@ -3,6 +3,7 @@
  * QTI CE 32-bit compatibility syscall for 64-bit systems
  *
  * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -10,7 +11,7 @@
 #include <linux/uaccess.h>
 #include "linux/qcedev.h"
 #include <linux/compat.h>
-#include "compat_qcedev.h"
+#include "linux/compat_qcedev.h"
 
 static void *compat_alloc_user_space(int size){
     return NULL;

+ 1 - 0
linux/fips_status.h → crypto-qti/fips_status.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _FIPS_STATUS__H

+ 4 - 2
crypto-qti/qce.h

@@ -109,8 +109,10 @@ enum qce_req_op_enum {
 enum qce_offload_op_enum {
 	QCE_OFFLOAD_NONE = 0, /* kernel pipe */
 	QCE_OFFLOAD_HLOS_HLOS = 1,
-	QCE_OFFLOAD_HLOS_CPB = 2,
-	QCE_OFFLOAD_CPB_HLOS = 3,
+	QCE_OFFLOAD_HLOS_HLOS_1 = 2,
+	QCE_OFFLOAD_HLOS_CPB = 3,
+	QCE_OFFLOAD_HLOS_CPB_1 = 4,
+	QCE_OFFLOAD_CPB_HLOS = 5,
 	QCE_OFFLOAD_OPER_LAST
 };
 

+ 48 - 28
crypto-qti/qce50.c

@@ -3,6 +3,7 @@
  * QTI Crypto Engine driver.
  *
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #define pr_fmt(fmt) "QCE50: %s: " fmt, __func__
@@ -21,12 +22,12 @@
 #include <linux/delay.h>
 #include <linux/crypto.h>
 #include <linux/bitops.h>
-#include "linux/qcrypto.h"
 #include <crypto/hash.h>
 #include <crypto/sha1.h>
 #include <soc/qcom/socinfo.h>
 #include <linux/iommu.h>
 
+#include "qcrypto.h"
 #include "qce.h"
 #include "qce50.h"
 #include "qcryptohw_50.h"
@@ -204,8 +205,9 @@ static uint32_t _std_init_vector_sha256[] = {
  */
 static bool is_offload_op(int op)
 {
-	return (op == QCE_OFFLOAD_HLOS_HLOS || op == QCE_OFFLOAD_HLOS_CPB ||
-		op == QCE_OFFLOAD_CPB_HLOS);
+	return (op == QCE_OFFLOAD_HLOS_HLOS || op == QCE_OFFLOAD_HLOS_HLOS_1 ||
+		op == QCE_OFFLOAD_CPB_HLOS || op == QCE_OFFLOAD_HLOS_CPB ||
+		op == QCE_OFFLOAD_HLOS_CPB_1);
 }
 
 static uint32_t qce_get_config_be(struct qce_device *pce_dev,
@@ -245,7 +247,7 @@ void qce_get_crypto_status(void *handle, struct qce_error *error)
 	dump_status_regs(status);
 #endif
 
-	if (status[0] != QCE_STATUS1_NO_ERROR) {
+	if (status[0] != QCE_STATUS1_NO_ERROR || status[1]) {
 		if (pce_dev->ce_bam_info.minor_version >= 8) {
 			if (status[2] & CRYPTO58_TIMER_EXPIRED) {
 				error->timer_error = true;
@@ -283,7 +285,7 @@ void qce_get_crypto_status(void *handle, struct qce_error *error)
 	}
 
 	error->no_error = true;
-	pr_err("%s: No crypto error, status1 = 0x%x\n",
+	pr_info("%s: No crypto error, status1 = 0x%x\n",
 		   __func__, status[0]);
 
 	return;
@@ -295,28 +297,8 @@ static int qce_crypto_config(struct qce_device *pce_dev,
 {
 	uint32_t config_be = 0;
 
-	switch (offload_op) {
-	case QCE_OFFLOAD_NONE:
-		config_be = qce_get_config_be(pce_dev,
-		pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_NONE]);
-		break;
-	case QCE_OFFLOAD_HLOS_HLOS:
-		config_be = qce_get_config_be(pce_dev,
-		pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_HLOS]);
-		break;
-	case QCE_OFFLOAD_HLOS_CPB:
-		config_be = qce_get_config_be(pce_dev,
-		pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_CPB]);
-		break;
-	case QCE_OFFLOAD_CPB_HLOS:
-		config_be = qce_get_config_be(pce_dev,
-		pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_CPB_HLOS]);
-		break;
-	default:
-		pr_err("%s: Valid pipe config not set, offload op = %d\n",
-					__func__, offload_op);
-		return -EINVAL;
-	}
+	config_be = qce_get_config_be(pce_dev,
+		    pce_dev->ce_bam_info.pipe_pair_index[offload_op]);
 
 	pce_dev->reg.crypto_cfg_be = config_be;
 	pce_dev->reg.crypto_cfg_le = (config_be |
@@ -2418,6 +2400,8 @@ exit:
 	return rc;
 }
 
+#define MAX_RESET_TIME_RETRIES 1000
+
 int qce_manage_timeout(void *handle, int req_info)
 {
 	struct qce_device *pce_dev = (struct qce_device *) handle;
@@ -2425,6 +2409,8 @@ int qce_manage_timeout(void *handle, int req_info)
 	struct ce_request_info *preq_info;
 	qce_comp_func_ptr_t qce_callback;
 	uint16_t op = pce_dev->ce_request_info[req_info].offload_op;
+	struct qce_error error = {0};
+	int retries = 0;
 
 	preq_info = &pce_dev->ce_request_info[req_info];
 	qce_callback = preq_info->qce_cb;
@@ -2435,11 +2421,22 @@ int qce_manage_timeout(void *handle, int req_info)
 	if (qce_sps_pipe_reset(pce_dev, op))
 		pr_err("%s: pipe reset failed\n", __func__);
 
-	qce_enable_clock_gating(pce_dev);
+	qce_get_crypto_status(pce_dev, &error);
+	while (!error.no_error && retries < MAX_RESET_TIME_RETRIES) {
+		usleep_range(3000, 5000);
+		retries++;
+		qce_get_crypto_status(pce_dev, &error);
+		pr_info("%s: waiting for reset to complete\n", __func__);
+	}
+
+	// Write memory barrier
+	wmb();
 
 	if (_qce_unlock_other_pipes(pce_dev, req_info))
 		pr_err("%s: fail unlock other pipes\n", __func__);
 
+	qce_enable_clock_gating(pce_dev);
+
 	if (!atomic_read(&preq_info->in_use)) {
 		pr_err("request information %d already done\n", req_info);
 		return -ENXIO;
@@ -3368,6 +3365,8 @@ static int qce_sps_init(struct qce_device *pce_dev)
 			continue;
 		else if ((i > 0) && !(pce_dev->offload_pipes_support))
 			break;
+		if (!pce_dev->ce_bam_info.pipe_pair_index[i])
+			continue;
 		rc = qce_sps_init_ep_conn(pce_dev,
 			&pce_dev->ce_bam_info.producer[i], i, true);
 		if (rc)
@@ -3616,6 +3615,8 @@ static void qce_sps_exit(struct qce_device *pce_dev)
 			continue;
 		else if ((i > 0) && !(pce_dev->offload_pipes_support))
 			break;
+		if (!pce_dev->ce_bam_info.pipe_pair_index[i])
+			continue;
 		qce_sps_exit_ep_conn(pce_dev,
 				&pce_dev->ce_bam_info.consumer[i]);
 		qce_sps_exit_ep_conn(pce_dev,
@@ -5358,6 +5359,8 @@ static int _qce_suspend(void *handle)
 			continue;
 		else if ((i > 0) && !(pce_dev->offload_pipes_support))
 			break;
+		if (!pce_dev->ce_bam_info.pipe_pair_index[i])
+			continue;
 		sps_pipe_info = pce_dev->ce_bam_info.consumer[i].pipe;
 		sps_disconnect(sps_pipe_info);
 
@@ -5384,6 +5387,8 @@ static int _qce_resume(void *handle)
 			continue;
 		else if ((i > 0) && !(pce_dev->offload_pipes_support))
 			break;
+		if (!pce_dev->ce_bam_info.pipe_pair_index[i])
+			continue;
 		sps_pipe_info = pce_dev->ce_bam_info.consumer[i].pipe;
 		sps_connect_info = &pce_dev->ce_bam_info.consumer[i].connect;
 		memset(sps_connect_info->desc.base, 0x00,
@@ -6251,6 +6256,9 @@ static int __qce_get_device_tree_data(struct platform_device *pdev,
 	pce_dev->request_bw_before_clk = of_property_read_bool(
 		(&pdev->dev)->of_node, "qcom,request-bw-before-clk");
 
+	for (i = 0; i < QCE_OFFLOAD_OPER_LAST; i++)
+		pce_dev->ce_bam_info.pipe_pair_index[i] = 0;
+
 	pce_dev->kernel_pipes_support = true;
 	if (of_property_read_u32((&pdev->dev)->of_node,
 				"qcom,bam-pipe-pair",
@@ -6270,18 +6278,30 @@ static int __qce_get_device_tree_data(struct platform_device *pdev,
 			pr_err("Fail to get bam offload cpb-hlos pipe pair info.\n");
 			return -EINVAL;
 		}
+
 		if (of_property_read_u32((&pdev->dev)->of_node,
 			"qcom,bam-pipe-offload-hlos-hlos",
 		&pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_HLOS])) {
 			pr_err("Fail to get bam offload hlos-hlos info.\n");
 			return -EINVAL;
 		}
+		if (of_property_read_u32((&pdev->dev)->of_node,
+			"qcom,bam-pipe-offload-hlos-hlos-1",
+		&pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_HLOS_1])) {
+			pr_info("No bam offload hlos-hlos-1 info.\n");
+		}
+
 		if (of_property_read_u32((&pdev->dev)->of_node,
 			"qcom,bam-pipe-offload-hlos-cpb",
 		&pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_CPB])) {
 			pr_err("Fail to get bam offload hlos-cpb info\n");
 			return -EINVAL;
 		}
+		if (of_property_read_u32((&pdev->dev)->of_node,
+			"qcom,bam-pipe-offload-hlos-cpb-1",
+		&pce_dev->ce_bam_info.pipe_pair_index[QCE_OFFLOAD_HLOS_CPB_1])) {
+			pr_info("No bam offload hlos-cpb-1 info\n");
+		}
 	}
 
 	if (of_property_read_u32((&pdev->dev)->of_node,

+ 24 - 11
crypto-qti/qcedev.c

@@ -3,6 +3,7 @@
  * QTI CE device driver.
  *
  * Copyright (c) 2010-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/mman.h>
@@ -22,16 +23,16 @@
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
-#include "linux/qcom_crypto_device.h"
 #include "linux/qcedev.h"
 #include <linux/interconnect.h>
 #include <linux/delay.h>
+#include "linux/compat_qcedev.h"
 
 #include <crypto/hash.h>
 #include "qcedevi.h"
 #include "qce.h"
 #include "qcedev_smmu.h"
-#include "compat_qcedev.h"
+#include "qcom_crypto_device.h"
 
 #include <linux/compat.h>
 
@@ -39,11 +40,16 @@
 #define CE_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
 #define MAX_CEHW_REQ_TRANSFER_SIZE (128*32*1024)
 /*
- * Max wait time once a crypto request is done.
- * Assuming 5ms per crypto operation, this is calculated for
- * the scenario of having 3 offload reqs + 1 tz req + buffer.
+ * Max wait time once a crypto request is submitted.
  */
-#define MAX_CRYPTO_WAIT_TIME 25
+#define MAX_CRYPTO_WAIT_TIME 1500
+/*
+ * Max wait time once a offload crypto request is submitted.
+ * This is low due to expected timeout and key pause errors.
+ * This is temporary, and we can use the 1500 value once the
+ * core irqs are enabled.
+ */
+#define MAX_OFFLOAD_CRYPTO_WAIT_TIME 20
 
 #define MAX_REQUEST_TIME 5000
 
@@ -563,12 +569,15 @@ static int start_offload_cipher_req(struct qcedev_control *podev,
 		return -EINVAL;
 	}
 
-	if (qcedev_areq->offload_cipher_op_req.is_copy_op) {
+	if (qcedev_areq->offload_cipher_op_req.is_copy_op ||
+	    qcedev_areq->offload_cipher_op_req.encrypt) {
 		creq.dir = QCE_ENCRYPT;
 	} else {
 		switch(qcedev_areq->offload_cipher_op_req.op) {
 		case QCEDEV_OFFLOAD_HLOS_HLOS:
+		case QCEDEV_OFFLOAD_HLOS_HLOS_1:
 		case QCEDEV_OFFLOAD_HLOS_CPB:
+		case QCEDEV_OFFLOAD_HLOS_CPB_1:
 			creq.dir = QCE_DECRYPT;
 			break;
 		case QCEDEV_OFFLOAD_CPB_HLOS:
@@ -732,6 +741,7 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 	struct qcedev_async_req *new_req = NULL;
 	int retries = 0;
 	int req_wait = MAX_REQUEST_TIME;
+	unsigned int crypto_wait = 0;
 
 	qcedev_areq->err = 0;
 	podev = handle->cntl;
@@ -753,12 +763,15 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 			case QCEDEV_CRYPTO_OPER_CIPHER:
 				ret = start_cipher_req(podev,
 						&current_req_info);
+				crypto_wait = MAX_CRYPTO_WAIT_TIME;
 				break;
 			case QCEDEV_CRYPTO_OPER_OFFLOAD_CIPHER:
 				ret = start_offload_cipher_req(podev,
 						&current_req_info);
+				crypto_wait = MAX_OFFLOAD_CRYPTO_WAIT_TIME;
 				break;
 			default:
+				crypto_wait = MAX_CRYPTO_WAIT_TIME;
 
 				ret = start_sha_req(podev,
 						&current_req_info);
@@ -804,7 +817,7 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 	qcedev_areq->timed_out = false;
 	if (ret == 0)
 		wait = wait_for_completion_timeout(&qcedev_areq->complete,
-				msecs_to_jiffies(MAX_CRYPTO_WAIT_TIME));
+				msecs_to_jiffies(crypto_wait));
 
 	if (!wait) {
 	/*
@@ -815,6 +828,9 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 	 */
 		pr_err("%s: wait timed out, req info = %d\n", __func__,
 					current_req_info);
+		spin_lock_irqsave(&podev->lock, flags);
+		qcedev_areq->timed_out = true;
+		spin_unlock_irqrestore(&podev->lock, flags);
 		qcedev_check_crypto_status(qcedev_areq, podev->qce);
 		if (qcedev_areq->offload_cipher_op_req.err ==
 			QCEDEV_OFFLOAD_NO_ERROR) {
@@ -828,13 +844,10 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 			}
 			return 0;
 		}
-		spin_lock_irqsave(&podev->lock, flags);
-		qcedev_areq->timed_out = true;
 		ret = qce_manage_timeout(podev->qce, current_req_info);
 		if (ret)
 			pr_err("%s: error during manage timeout", __func__);
 
-		spin_unlock_irqrestore(&podev->lock, flags);
 		req_done((unsigned long) podev);
 		if (qcedev_areq->offload_cipher_op_req.err !=
 						QCEDEV_OFFLOAD_NO_ERROR)

+ 3 - 2
crypto-qti/qcedevi.h

@@ -3,6 +3,7 @@
  * QTI crypto Driver
  *
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __CRYPTO_MSM_QCEDEVI_H
@@ -11,8 +12,8 @@
 #include <linux/interrupt.h>
 #include <linux/cdev.h>
 #include <crypto/hash.h>
-#include "linux/qcom_crypto_device.h"
-#include "linux/fips_status.h"
+#include "qcom_crypto_device.h"
+#include "fips_status.h"
 #include "qce.h"
 #include "qcedev_smmu.h"
 

+ 1 - 0
linux/qcom_crypto_device.h → crypto-qti/qcom_crypto_device.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __QCOM_CRYPTO_DEVICE__H

+ 4 - 3
crypto-qti/qcrypto.c

@@ -3,6 +3,7 @@
  * QTI Crypto driver
  *
  * Copyright (c) 2010-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -25,10 +26,10 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/cache.h>
-#include "linux/qcom_crypto_device.h"
 #include <linux/interconnect.h>
 #include <linux/hardirq.h>
-#include "linux/qcrypto.h"
+#include "qcrypto.h"
+#include "qcom_crypto_device.h"
 
 #include <crypto/ctr.h>
 #include <crypto/des.h>
@@ -45,7 +46,7 @@
 #include <crypto/internal/hash.h>
 #include <crypto/internal/aead.h>
 
-#include "linux/fips_status.h"
+#include "fips_status.h"
 
 #include "qce.h"
 

+ 1 - 0
linux/qcrypto.h → crypto-qti/qcrypto.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _DRIVERS_CRYPTO_MSM_QCRYPTO_H_

+ 123 - 0
hdcp/hdcp1.h

@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#pragma once
+// AUTOGENERATED FILE: DO NOT EDIT
+
+#include <linux/types.h>
+#include "smcinvoke_object.h"
+
+#define HDCP1_PROVISION 0
+#define HDCP1_VERIFY 1
+#define HDCP1_SET_ENCRYPTION 2
+#define HDCP1_SET_ENCRYPTION_V2 3
+#define HDCP1_SET_KEY 4
+#define HDCP1_SET_KEY_V2 5
+#define HDCP1_SET_MODE 6
+
+static inline int32_t hdcp1_release(struct Object self)
+{
+	return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t hdcp1_retain(struct Object self)
+{
+	return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t hdcp1_provision(struct Object self, uint32_t keyFormat_val,
+		   const void *key_ptr, size_t key_len,
+		   const void *dps_ptr, size_t dps_len)
+{
+	union ObjectArg a[3] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&keyFormat_val, sizeof(uint32_t)};
+	a[1].bi = (struct ObjectBufIn) {key_ptr, key_len * 1};
+	a[2].bi = (struct ObjectBufIn) {dps_ptr, dps_len * 1};
+
+	return Object_invoke(self, HDCP1_PROVISION, a,
+		 ObjectCounts_pack(3, 0, 0, 0));
+}
+
+static inline int32_t hdcp1_verify(struct Object self, uint32_t deviceType_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&deviceType_val, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP1_VERIFY, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp1_set_encryption(struct Object self, uint32_t enable_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&enable_val, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP1_SET_ENCRYPTION, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp1_set_encryption_v2(struct Object self, uint32_t enable_val,
+		   uint32_t deviceType_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+	struct {
+		uint32_t m_enable;
+		uint32_t m_deviceType;
+	} i;
+
+	a[0].b = (struct ObjectBuf) {&i, 8};
+	i.m_enable = enable_val;
+	i.m_deviceType = deviceType_val;
+
+	return Object_invoke(self, HDCP1_SET_ENCRYPTION_V2, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp1_set_key(struct Object self, void *ksv_ptr, size_t ksv_len,
+		 size_t *ksv_lenout)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+	int32_t result = 0;
+
+	a[0].b = (struct ObjectBuf) {ksv_ptr, ksv_len * 1};
+
+	result = Object_invoke(self, HDCP1_SET_KEY, a,
+		   ObjectCounts_pack(0, 1, 0, 0));
+
+	*ksv_lenout = a[0].b.size / 1;
+
+	return result;
+}
+
+static inline int32_t hdcp1_set_key_v2(struct Object self, void *ksv_ptr,
+		size_t ksv_len, size_t *ksv_lenout,
+		uint32_t deviceType_val)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+	int32_t result = 0;
+
+	a[1].b = (struct ObjectBuf) {ksv_ptr, ksv_len * 1};
+	a[0].b = (struct ObjectBuf) {&deviceType_val, sizeof(uint32_t)};
+
+	result = Object_invoke(self, HDCP1_SET_KEY_V2, a,
+		   ObjectCounts_pack(1, 1, 0, 0));
+
+	*ksv_lenout = a[1].b.size / 1;
+
+	return result;
+}
+
+static inline int32_t hdcp1_set_mode(struct Object self, int32_t mode_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&mode_val, sizeof(int32_t)};
+
+	return Object_invoke(self, HDCP1_SET_MODE, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}

+ 27 - 0
hdcp/hdcp1_ops.h

@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#pragma once
+// AUTOGENERATED FILE: DO NOT EDIT
+
+#include <linux/types.h>
+#include "smcinvoke_object.h"
+
+#define IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE 0
+
+static inline int32_t hdcp1_ops_release(struct Object self)
+{
+	return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t hdcp1_ops_retain(struct Object self)
+{
+	return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t hdcp1_ops_notify_topology_change(struct Object self)
+{
+	return Object_invoke(self, IHDCP1OPS_NOTIFY_TOPOLOGY_CHANGE, 0, 0);
+}

+ 303 - 0
hdcp/hdcp2p2.h

@@ -0,0 +1,303 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#pragma once
+// AUTOGENERATED FILE: DO NOT EDIT
+
+#include <linux/types.h>
+#include "smcinvoke_object.h"
+
+#define HDCP2P2_PROVISION_KEY 0
+#define HDCP2P2_VERIFY_KEY 1
+#define HDCP2P2_TX_INIT 2
+#define HDCP2P2_TX_DEINIT 3
+#define HDCP2P2_RCVD_MSG 4
+#define HDCP2P2_SEND_TIMEOUT 5
+#define HDCP2P2_SET_HW_KEY 6
+#define HDCP2P2_QUERY_STREAM_TYPE 7
+#define HDCP2P2_INIT 8
+#define HDCP2P2_DEINIT 9
+#define HDCP2P2_VERSION 10
+#define HDCP2P2_SESSION_INIT 11
+#define HDCP2P2_SESSION_DEINIT 12
+#define HDCP2P2_START_AUTH 13
+#define HDCP2P2_SESSION_OPEN_STREAM 14
+#define HDCP2P2_SESSION_CLOSE_STREAM 15
+#define HDCP2P2_FORCE_ENCRYPTION 16
+#define HDCP2P2_DELETE_PAIRING_INFO 17
+
+static inline int32_t hdcp2p2_release(struct Object self)
+{
+	return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t hdcp2p2_retain(struct Object self)
+{
+	return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t hdcp2p2_provision_key(struct Object self, const void *key_ptr,
+		 size_t key_len,
+		 const void *dps_ptr,
+		 size_t dps_len)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+
+	a[0].bi = (struct ObjectBufIn) {key_ptr, key_len * 1};
+	a[1].bi = (struct ObjectBufIn) {dps_ptr, dps_len * 1};
+
+	return Object_invoke(self, HDCP2P2_PROVISION_KEY, a,
+		 ObjectCounts_pack(2, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_verify_key(struct Object self)
+{
+	return Object_invoke(self, HDCP2P2_VERIFY_KEY, 0, 0);
+}
+
+static inline int32_t hdcp2p2_tx_init(struct Object self, uint32_t sessionid_val,
+		   uint32_t *ctxhandle_ptr)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&sessionid_val, sizeof(uint32_t)};
+	a[1].b = (struct ObjectBuf) {ctxhandle_ptr, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_TX_INIT, a,
+						 ObjectCounts_pack(1, 1, 0, 0));
+}
+
+static inline int32_t hdcp2p2_tx_deinit(struct Object self, uint32_t ctxhandle_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_TX_DEINIT, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_rcvd_msg(
+	struct Object self, const void *reqMsg_ptr, size_t reqMsg_len,
+	uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
+	size_t *resMsg_lenout, uint32_t *timeout_ptr, uint32_t *flag_ptr)
+{
+	union ObjectArg a[4] = {{{0, 0}}};
+	int32_t result = 0;
+	struct {
+		uint32_t m_timeout;
+		uint32_t m_flag;
+	} o;
+
+	a[2].b = (struct ObjectBuf) {&o, 8};
+	a[0].bi = (struct ObjectBufIn) {reqMsg_ptr, reqMsg_len * 1};
+	a[1].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+	a[3].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
+
+	result = Object_invoke(self, HDCP2P2_RCVD_MSG, a,
+		   ObjectCounts_pack(2, 2, 0, 0));
+
+	*resMsg_lenout = a[3].b.size / 1;
+	*timeout_ptr = o.m_timeout;
+	*flag_ptr = o.m_flag;
+
+	return result;
+}
+
+static inline int32_t hdcp2p2_send_timeout(struct Object self, uint32_t ctxhandle_val,
+		void *resMsg_ptr, size_t resMsg_len,
+		size_t *resMsg_lenout,
+		uint32_t *timeout_ptr)
+{
+	union ObjectArg a[3] = {{{0, 0}}};
+	int32_t result = 0;
+
+	a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+	a[1].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
+	a[2].b = (struct ObjectBuf) {timeout_ptr, sizeof(uint32_t)};
+
+	result = Object_invoke(self, HDCP2P2_SEND_TIMEOUT, a,
+		   ObjectCounts_pack(1, 2, 0, 0));
+
+	*resMsg_lenout = a[1].b.size / 1;
+
+	return result;
+}
+
+static inline int32_t hdcp2p2_set_hw_key(struct Object self, uint32_t ctxhandle_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_SET_HW_KEY, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_query_stream_type(
+	struct Object self, uint32_t ctxhandle_val, void *resMsg_ptr, size_t resMsg_len,
+	size_t *resMsg_lenout, uint32_t *timeout_ptr)
+{
+	union ObjectArg a[3] = {{{0, 0}}};
+	int32_t result = 0;
+
+	a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+	a[1].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
+	a[2].b = (struct ObjectBuf) {timeout_ptr, sizeof(uint32_t)};
+
+	result = Object_invoke(self, HDCP2P2_QUERY_STREAM_TYPE, a,
+		   ObjectCounts_pack(1, 2, 0, 0));
+
+	*resMsg_lenout = a[1].b.size / 1;
+
+	return result;
+}
+
+static inline int32_t hdcp2p2_init(struct Object self, uint32_t clientVersion_val,
+		uint32_t *appversion_ptr)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&clientVersion_val, sizeof(uint32_t)};
+	a[1].b = (struct ObjectBuf) {appversion_ptr, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_INIT, a,
+						 ObjectCounts_pack(1, 1, 0, 0));
+}
+
+static inline int32_t hdcp2p2_deinit(struct Object self)
+{
+	return Object_invoke(self, HDCP2P2_DEINIT, 0, 0);
+}
+
+static inline int32_t hdcp2p2_version(struct Object self, uint32_t *appversion_ptr)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {appversion_ptr, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_VERSION, a,
+		 ObjectCounts_pack(0, 1, 0, 0));
+}
+
+static inline int32_t hdcp2p2_session_init(struct Object self, uint32_t deviceId_val,
+		uint32_t *sessionId_ptr)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&deviceId_val, sizeof(uint32_t)};
+	a[1].b = (struct ObjectBuf) {sessionId_ptr, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_SESSION_INIT, a,
+		 ObjectCounts_pack(1, 1, 0, 0));
+}
+
+static inline int32_t hdcp2p2_session_deinit(struct Object self,
+		  uint32_t sessionId_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].b = (struct ObjectBuf) {&sessionId_val, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_SESSION_DEINIT, a,
+		ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_start_auth(struct Object self, uint32_t ctxhandle_val,
+		  void *resMsg_ptr, size_t resMsg_len,
+		  size_t *resMsg_lenout,
+		  uint32_t *timeout_ptr,
+		  uint32_t *flag_ptr,
+		  uint32_t *tzctxhandle_ptr)
+{
+	union ObjectArg a[3] = {{{0, 0}}};
+	int32_t result = 0;
+	struct {
+		uint32_t m_timeout;
+		uint32_t m_flag;
+		uint32_t m_tzctxhandle;
+	} o;
+
+	a[1].b = (struct ObjectBuf) {&o, 12};
+	a[0].b = (struct ObjectBuf) {&ctxhandle_val, sizeof(uint32_t)};
+	a[2].b = (struct ObjectBuf) {resMsg_ptr, resMsg_len * 1};
+
+	result = Object_invoke(self, HDCP2P2_START_AUTH, a,
+		   ObjectCounts_pack(1, 2, 0, 0));
+
+	*resMsg_lenout = a[2].b.size / 1;
+	*timeout_ptr = o.m_timeout;
+	*flag_ptr = o.m_flag;
+	*tzctxhandle_ptr = o.m_tzctxhandle;
+
+	return result;
+}
+
+static inline int32_t hdcp2p2_session_open_stream(struct Object self,
+		   uint32_t sessionid_val,
+		   uint32_t vcpayloadid_val,
+		   uint32_t stream_number_val,
+		   uint32_t streamMediaType_val,
+		   uint32_t *resStreamId_ptr)
+{
+	union ObjectArg a[2] = {{{0, 0}}};
+	struct {
+		uint32_t m_sessionid;
+		uint32_t m_vcpayloadid;
+		uint32_t m_stream_number;
+		uint32_t m_streamMediaType;
+	} i;
+
+	a[0].b = (struct ObjectBuf) {&i, 16};
+	i.m_sessionid = sessionid_val;
+	i.m_vcpayloadid = vcpayloadid_val;
+	i.m_stream_number = stream_number_val;
+	i.m_streamMediaType = streamMediaType_val;
+	a[1].b = (struct ObjectBuf) {resStreamId_ptr, sizeof(uint32_t)};
+
+	return Object_invoke(self, HDCP2P2_SESSION_OPEN_STREAM, a,
+		 ObjectCounts_pack(1, 1, 0, 0));
+}
+
+static inline int32_t hdcp2p2_session_close_stream(struct Object self,
+		uint32_t sessionid_val,
+		uint32_t streamId_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+	struct {
+		uint32_t m_sessionid;
+		uint32_t m_streamId;
+	} i;
+
+	a[0].b = (struct ObjectBuf) {&i, 8};
+	i.m_sessionid = sessionid_val;
+	i.m_streamId = streamId_val;
+
+	return Object_invoke(self, HDCP2P2_SESSION_CLOSE_STREAM, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_force_encryption(struct Object self,
+		uint32_t ctxhandle_val,
+		uint32_t enable_val)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
+	struct {
+		uint32_t m_ctxhandle;
+		uint32_t m_enable;
+	} i;
+
+	a[0].b = (struct ObjectBuf) {&i, 8};
+	i.m_ctxhandle = ctxhandle_val;
+	i.m_enable = enable_val;
+
+	return Object_invoke(self, HDCP2P2_FORCE_ENCRYPTION, a,
+		 ObjectCounts_pack(1, 0, 0, 0));
+}
+
+static inline int32_t hdcp2p2_delete_pairing_info(struct Object self)
+{
+	return Object_invoke(self, HDCP2P2_DELETE_PAIRING_INFO, 0, 0);
+}

+ 316 - 0
hdcp/hdcp_main.c

@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "hdcp_main.h"
+#include "hdcp_qseecom.h"
+#include "hdcp_smcinvoke.h"
+
+struct hdcp_ta_interface ta_interface;
+static DEFINE_MUTEX(hdcp1_mutex_g);
+static DEFINE_MUTEX(hdcp2_mutex_g);
+
+void select_interface(bool use_smcinvoke)
+{
+	if (use_smcinvoke) {
+		ta_interface.trusted_app_hdcp1_init = &hdcp1_init_smcinvoke;
+		ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_smcinvoke;
+		ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_smcinvoke;
+		ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_smcinvoke;
+		ta_interface.trusted_app_hdcp1_start = &hdcp1_start_smcinvoke;
+		ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_smcinvoke;
+		ta_interface.trusted_app_hdcp2_init = &hdcp2_init_smcinvoke;
+		ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_smcinvoke;
+		ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_smcinvoke;
+		ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_smcinvoke;
+		ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_smcinvoke;
+		ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_smcinvoke;
+		ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_smcinvoke;
+		ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_smcinvoke;
+	} else {
+		ta_interface.trusted_app_hdcp1_init = &hdcp1_init_qseecom;
+		ta_interface.trusted_app_hdcp1_feature_supported = &hdcp1_feature_supported_qseecom;
+		ta_interface.trusted_app_hdcp1_set_enc = &hdcp1_set_enc_qseecom;
+		ta_interface.trusted_app_hdcp1_ops_notify = &hdcp1_ops_notify_qseecom;
+		ta_interface.trusted_app_hdcp1_start = &hdcp1_start_qseecom;
+		ta_interface.trusted_app_hdcp1_stop = &hdcp1_stop_qseecom;
+		ta_interface.trusted_app_hdcp2_init = &hdcp2_init_qseecom;
+		ta_interface.trusted_app_hdcp2_deinit = &hdcp2_deinit_qseecom;
+		ta_interface.trusted_app_hdcp2_app_start = &hdcp2_app_start_qseecom;
+		ta_interface.trusted_app_hdcp2_app_start_auth = &hdcp2_app_start_auth_qseecom;
+		ta_interface.trusted_app_hdcp2_app_process_msg = &hdcp2_app_process_msg_qseecom;
+		ta_interface.trusted_app_hdcp2_app_enable_encryption = &hdcp2_app_enable_encryption_qseecom;
+		ta_interface.trusted_app_hdcp2_app_query_stream = &hdcp2_app_query_stream_qseecom;
+		ta_interface.trusted_app_hdcp2_app_stop = &hdcp2_app_stop_qseecom;
+		ta_interface.trusted_app_hdcp2_feature_supported = &hdcp2_feature_supported_qseecom;
+		ta_interface.trusted_app_hdcp2_force_encryption = &hdcp2_force_encryption_qseecom;
+		ta_interface.trusted_app_hdcp2_open_stream = &hdcp2_open_stream_qseecom;
+		ta_interface.trusted_app_hdcp2_close_stream = &hdcp2_close_stream_qseecom;
+		ta_interface.trusted_app_hdcp2_update_app_data = &hdcp2_update_app_data_qseecom;
+	}
+}
+
+int hdcp1_count_ones(u8 *array, u8 len)
+{
+	int i, j, count = 0;
+
+	for (i = 0; i < len; i++)
+		for (j = 0; j < 8; j++)
+			count += (((array[i] >> j) & 0x1) ? 1 : 0);
+
+	return count;
+}
+
+
+
+int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb)
+{
+	int const number_of_ones = 20;
+	u8 aksv[5] = {0};
+
+	pr_debug("AKSV=%02x%08x\n", aksv_msb, aksv_lsb);
+
+	aksv[0] = aksv_lsb & 0xFF;
+	aksv[1] = (aksv_lsb >> 8) & 0xFF;
+	aksv[2] = (aksv_lsb >> 16) & 0xFF;
+	aksv[3] = (aksv_lsb >> 24) & 0xFF;
+	aksv[4] = aksv_msb & 0xFF;
+
+	/* check there are 20 ones in AKSV */
+	if (hdcp1_count_ones(aksv, 5) != number_of_ones) {
+		pr_err("AKSV bit count failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+
+bool hdcp2_feature_supported(void *data)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp2_mutex_g);
+	ret = ta_interface.trusted_app_hdcp2_feature_supported(data);
+	mutex_unlock(&hdcp2_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp2_feature_supported);
+
+int hdcp2_force_encryption(void *ctx, uint32_t enable)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp2_mutex_g);
+	ret = ta_interface.trusted_app_hdcp2_force_encryption(ctx, enable);
+	mutex_unlock(&hdcp2_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp2_force_encryption);
+
+int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
+				   struct hdcp2_app_data *app_data)
+{
+	int ret = 0;
+	uint32_t req_len = 0;
+
+	if (!ctx || !app_data) {
+		pr_err("invalid input\n");
+		return -EINVAL;
+	}
+
+	req_len = app_data->request.length;
+
+	mutex_lock(&hdcp2_mutex_g);
+	switch (cmd) {
+	case HDCP2_CMD_START:
+		ret = ta_interface.trusted_app_hdcp2_app_start(ctx, req_len);
+		break;
+	case HDCP2_CMD_START_AUTH:
+		ret = ta_interface.trusted_app_hdcp2_app_start_auth(ctx, req_len);
+		break;
+	case HDCP2_CMD_PROCESS_MSG:
+		ret = ta_interface.trusted_app_hdcp2_app_process_msg(ctx, req_len);
+		break;
+	case HDCP2_CMD_TIMEOUT:
+		ret = ta_interface.trusted_app_hdcp2_app_timeout(ctx, req_len);
+		break;
+	case HDCP2_CMD_EN_ENCRYPTION:
+		ret = ta_interface.trusted_app_hdcp2_app_enable_encryption(ctx, req_len);
+		break;
+	case HDCP2_CMD_QUERY_STREAM:
+		ret = ta_interface.trusted_app_hdcp2_app_query_stream(ctx, req_len);
+		break;
+	case HDCP2_CMD_STOP:
+		ret = ta_interface.trusted_app_hdcp2_app_stop(ctx);
+		break;
+	default:
+		goto error;
+	}
+
+	if (ret)
+		goto error;
+
+	ret = ta_interface.trusted_app_hdcp2_update_app_data(ctx, app_data);
+
+error:
+	mutex_unlock(&hdcp2_mutex_g);
+	return ret;
+}
+EXPORT_SYMBOL(hdcp2_app_comm);
+
+int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id, uint8_t stream_number,
+		  uint32_t *stream_id)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp2_mutex_g);
+	ret = ta_interface.trusted_app_hdcp2_open_stream(ctx, vc_payload_id, stream_number,
+		   stream_id);
+	mutex_unlock(&hdcp2_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp2_open_stream);
+
+int hdcp2_close_stream(void *ctx, uint32_t stream_id)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp2_mutex_g);
+	ret = ta_interface.trusted_app_hdcp2_close_stream(ctx, stream_id);
+	mutex_unlock(&hdcp2_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp2_close_stream);
+
+void *hdcp2_init(u32 device_type)
+{
+	void *data = NULL;
+
+	mutex_lock(&hdcp2_mutex_g);
+	data = ta_interface.trusted_app_hdcp2_init(device_type);
+	mutex_unlock(&hdcp2_mutex_g);
+
+	return data;
+}
+EXPORT_SYMBOL(hdcp2_init);
+
+void hdcp2_deinit(void *ctx)
+{
+	ta_interface.trusted_app_hdcp2_deinit(ctx);
+}
+EXPORT_SYMBOL(hdcp2_deinit);
+
+void *hdcp1_init(void)
+{
+	void *data = NULL;
+
+	mutex_lock(&hdcp1_mutex_g);
+	data = ta_interface.trusted_app_hdcp1_init();
+	mutex_unlock(&hdcp1_mutex_g);
+
+	return data;
+}
+EXPORT_SYMBOL(hdcp1_init);
+
+void hdcp1_deinit(void *data)
+{
+	kfree(data);
+}
+EXPORT_SYMBOL(hdcp1_deinit);
+
+bool hdcp1_feature_supported(void *data)
+{
+	bool supported = false;
+
+	mutex_lock(&hdcp1_mutex_g);
+	supported = ta_interface.trusted_app_hdcp1_feature_supported(data);
+	mutex_unlock(&hdcp1_mutex_g);
+
+	return supported;
+}
+EXPORT_SYMBOL(hdcp1_feature_supported);
+
+int hdcp1_set_enc(void *data, bool enable)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp1_mutex_g);
+	ret = ta_interface.trusted_app_hdcp1_set_enc(data, enable);
+	mutex_unlock(&hdcp1_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp1_set_enc);
+
+int hdcp1_ops_notify(void *data, void *topo, bool is_authenticated)
+{
+	int ret = 0;
+
+	ret = ta_interface.trusted_app_hdcp1_ops_notify(data, topo, is_authenticated);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp1_ops_notify);
+
+int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb)
+{
+	int ret = 0;
+
+	mutex_lock(&hdcp1_mutex_g);
+	ret = ta_interface.trusted_app_hdcp1_start(data, aksv_msb, aksv_lsb);
+	mutex_unlock(&hdcp1_mutex_g);
+
+	return ret;
+}
+EXPORT_SYMBOL(hdcp1_start);
+
+void hdcp1_stop(void *data)
+{
+	mutex_lock(&hdcp1_mutex_g);
+	ta_interface.trusted_app_hdcp1_stop(data);
+	mutex_unlock(&hdcp1_mutex_g);
+}
+EXPORT_SYMBOL(hdcp1_stop);
+
+static int __init hdcp_module_init(void)
+{
+	struct device_node *np = NULL;
+	bool use_smcinvoke = false;
+
+	np = of_find_compatible_node(NULL, NULL, "qcom,hdcp");
+	if (!np) {
+		/*select qseecom interface as default if hdcp node
+		*is not present in dtsi
+		 */
+		 select_interface(use_smcinvoke);
+		return 0;
+		}
+
+	use_smcinvoke = of_property_read_bool(np, "qcom,use-smcinvoke");
+
+	select_interface(use_smcinvoke);
+
+	return 0;
+}
+
+static void __exit hdcp_module_exit(void)
+{
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("HDCP driver");
+
+module_init(hdcp_module_init);
+module_exit(hdcp_module_exit);

+ 108 - 0
hdcp/hdcp_main.h

@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __HDCP_MAIN_H__
+#define __HDCP_MAIN_H__
+
+#include <linux/cdev.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/hdcp_qseecom.h>
+#include <linux/io.h>
+#include <linux/ion.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <misc/qseecom_kernel.h>
+
+#define HDCP2P2_APP_NAME "hdcp2p2"
+#define HDCP1_APP_NAME "hdcp1"
+#define HDCP1OPS_APP_NAME "ops"
+#define HDCPSRM_APP_NAME "hdcpsrm"
+#define QSEECOM_SBUFF_SIZE 0x1000
+
+#define MAX_REC_ID_LIST_SIZE 160
+#define MAX_TX_MESSAGE_SIZE 129
+#define MAX_RX_MESSAGE_SIZE 534
+#define MAX_TOPOLOGY_ELEMS 32
+#define HDCP1_NOTIFY_TOPOLOGY 1
+#define HDCP1_AKSV_SIZE 8
+
+#define HDCP_CLIENT_MAKE_VERSION(maj, min, patch) \
+	((((maj)&0xFF) << 16) | (((min)&0xFF) << 8) | ((patch)&0xFF))
+
+#define HCDP_TXMTR_GET_MAJOR_VERSION(v) (((v) >> 16) & 0xFF)
+#define HCDP_TXMTR_GET_MINOR_VERSION(v) (((v) >> 8) & 0xFF)
+#define HCDP_TXMTR_GET_PATCH_VERSION(v) ((v)&0xFF)
+
+#define HDCP_CLIENT_MAJOR_VERSION 2
+#define HDCP_CLIENT_MINOR_VERSION 1
+#define HDCP_CLIENT_PATCH_VERSION 0
+
+#define HDCP_SUCCESS 0
+
+/* Wait 200ms after authentication */
+#define SLEEP_FORCE_ENCRYPTION_MS 200
+
+#define SLEEP_SET_HW_KEY_MS 300
+
+/* flags set by tz in response message */
+#define HDCP_TXMTR_SUBSTATE_INIT 0
+#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST 1
+#define HDCP_TXMTR_SUBSTATE_PROCESSED_RECIEVERID_LIST 2
+#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_STREAM_READY_MESSAGE 3
+#define HDCP_TXMTR_SUBSTATE_REPEATER_AUTH_COMPLETE 4
+
+enum hdcp_state {
+	HDCP_STATE_INIT = 0x00,
+	HDCP_STATE_APP_LOADED = 0x01,
+	HDCP_STATE_SESSION_INIT = 0x02,
+	HDCP_STATE_TXMTR_INIT = 0x04,
+	HDCP_STATE_AUTHENTICATED = 0x08,
+	HDCP_STATE_ERROR = 0x10
+};
+
+struct hdcp_ta_interface
+{
+	void *(*trusted_app_hdcp1_init)(void);
+	bool (*trusted_app_hdcp1_feature_supported)(void *data);
+	int (*trusted_app_hdcp1_set_enc)(void *data,bool enable);
+	int (*trusted_app_hdcp1_ops_notify)(void *data, void *topo,
+		bool is_authenticated);
+	int (*trusted_app_hdcp1_start)(void *data, u32 *aksv_msb,
+		  u32 *aksv_lsb);
+	void (*trusted_app_hdcp1_stop)(void *data);
+	void *(*trusted_app_hdcp2_init)(u32 device_type);
+	void (*trusted_app_hdcp2_deinit)(void *ctx);
+	int (*trusted_app_hdcp2_app_start)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_start_auth)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_process_msg)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_timeout)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_enable_encryption)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_query_stream)(void *ctx, uint32_t req_len);
+	int (*trusted_app_hdcp2_app_stop)(void *ctx);
+	bool (*trusted_app_hdcp2_feature_supported)(void *ctx);
+	int (*trusted_app_hdcp2_force_encryption)(void *ctx, uint32_t enable);
+	int (*trusted_app_hdcp2_open_stream)(void *ctx, uint8_t vc_payload_id,
+		 uint8_t stream_number, uint32_t *stream_id);
+	int (*trusted_app_hdcp2_close_stream)(void *ctx, uint32_t stream_id);
+	int (*trusted_app_hdcp2_update_app_data)(void *ctx,
+		 struct hdcp2_app_data *app_data);
+};
+
+int hdcp1_validate_aksv(u32 aksv_msb, u32 aksv_lsb);
+
+#endif /* __HDCP_MAIN_H__ */

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 685 - 989
hdcp/hdcp_qseecom.c


+ 326 - 0
hdcp/hdcp_qseecom.h

@@ -0,0 +1,326 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __HDCP_QSEECOM_H__
+#define __HDCP_QSEECOM_H__
+
+#include <linux/hdcp_qseecom.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "hdcp_main.h"
+
+struct hdcp1_qsee_handle {
+	struct qseecom_handle *qseecom_handle;
+	struct qseecom_handle *hdcpops_handle;
+	bool feature_supported;
+	uint32_t device_type;
+	enum hdcp_state hdcp_state;
+	char *app_name;
+};
+
+struct hdcp2_qsee_handle {
+	struct hdcp2_app_data app_data;
+	uint32_t tz_ctxhandle;
+	bool feature_supported;
+	enum hdcp_state hdcp_state;
+	struct qseecom_handle *qseecom_handle;
+	struct qseecom_handle *hdcpsrm_qseecom_handle;
+	uint32_t session_id;
+	bool legacy_app;
+	uint32_t device_type;
+	char *app_name;
+	unsigned char *req_buf;
+	unsigned char *res_buf;
+	int (*app_init)(struct hdcp2_qsee_handle *handle);
+	int (*tx_init)(struct hdcp2_qsee_handle *handle);
+};
+
+struct hdcp1_key_set_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp1_key_set_rsp {
+	uint32_t commandid;
+	uint32_t ret;
+	uint8_t ksv[HDCP1_AKSV_SIZE];
+} __packed;
+
+struct hdcp1_ops_notify_req {
+	uint32_t commandid;
+	uint32_t device_type;
+	uint8_t recv_id_list[MAX_REC_ID_LIST_SIZE];
+	int32_t recv_id_len;
+	struct hdcp1_topology topology;
+	bool is_authenticated;
+} __packed;
+
+struct hdcp1_ops_notify_rsp {
+	uint32_t commandid;
+	uint32_t ret;
+} __packed;
+
+struct hdcp1_set_enc_req {
+	uint32_t commandid;
+	uint32_t enable;
+} __packed;
+
+struct hdcp1_set_enc_rsp {
+	uint32_t commandid;
+	uint32_t ret;
+} __packed;
+
+struct hdcp1_key_verify_req {
+	uint32_t commandid;
+	uint32_t key_type;
+} __packed;
+
+struct hdcp1_key_verify_rsp {
+	uint32_t commandId;
+	uint32_t ret;
+} __packed;
+
+struct hdcp_init_v1_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_init_v1_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t ctxhandle;
+	uint32_t timeout;
+	uint32_t msglen;
+	uint8_t message[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_init_req {
+	uint32_t commandid;
+	uint32_t clientversion;
+} __packed;
+
+struct hdcp_init_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t appversion;
+} __packed;
+
+struct hdcp_session_init_req {
+	uint32_t commandid;
+	uint32_t deviceid;
+} __packed;
+
+struct hdcp_session_init_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t sessionid;
+} __packed;
+
+struct hdcp_tx_init_v1_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_tx_init_v1_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t ctxhandle;
+	uint32_t timeout;
+	uint32_t msglen;
+	uint8_t message[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_tx_init_req {
+	uint32_t commandid;
+	uint32_t sessionid;
+} __packed;
+
+struct hdcp_tx_init_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t ctxhandle;
+} __packed;
+
+struct hdcp_version_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_version_rsp {
+	uint32_t status;
+	uint32_t commandId;
+	uint32_t appversion;
+} __packed;
+
+struct hdcp_session_open_stream_req {
+	uint32_t commandid;
+	uint32_t sessionid;
+	uint32_t vcpayloadid;
+	uint32_t stream_number;
+	uint32_t streamMediaType;
+} __packed;
+
+struct hdcp_session_open_stream_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t streamid;
+} __packed;
+
+struct hdcp_session_close_stream_req {
+	uint32_t commandid;
+	uint32_t sessionid;
+	uint32_t streamid;
+} __packed;
+
+struct hdcp_session_close_stream_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_force_encryption_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+	uint32_t enable;
+} __packed;
+
+struct hdcp_force_encryption_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_tx_deinit_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+} __packed;
+
+struct hdcp_tx_deinit_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_session_deinit_req {
+	uint32_t commandid;
+	uint32_t sessionid;
+} __packed;
+
+struct hdcp_session_deinit_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_deinit_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_deinit_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_query_stream_type_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+} __packed;
+
+struct hdcp_query_stream_type_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t timeout;
+	uint32_t msglen;
+	uint8_t msg[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_set_hw_key_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+} __packed;
+
+struct hdcp_set_hw_key_rsp {
+	uint32_t status;
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_send_timeout_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+} __packed;
+
+struct hdcp_send_timeout_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t timeout;
+	uint32_t msglen;
+	uint8_t message[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_start_auth_req {
+	uint32_t commandid;
+	uint32_t ctxHandle;
+} __packed;
+
+struct hdcp_start_auth_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t ctxhandle;
+	uint32_t timeout;
+	uint32_t msglen;
+	uint8_t message[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_rcvd_msg_req {
+	uint32_t commandid;
+	uint32_t ctxhandle;
+	uint32_t msglen;
+	uint8_t msg[MAX_RX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_rcvd_msg_rsp {
+	uint32_t status;
+	uint32_t commandid;
+	uint32_t state;
+	uint32_t timeout;
+	uint32_t flag;
+	uint32_t msglen;
+	uint8_t msg[MAX_TX_MESSAGE_SIZE];
+} __packed;
+
+struct hdcp_verify_key_req {
+	uint32_t commandid;
+} __packed;
+
+struct hdcp_verify_key_rsp {
+	uint32_t status;
+	uint32_t commandId;
+} __packed;
+
+#define HDCP1_SET_KEY 202
+#define HDCP1_KEY_VERIFY 204
+#define HDCP1_SET_ENC 205
+
+/* DP device type */
+#define DEVICE_TYPE_DP 0x8002
+
+void *hdcp1_init_qseecom(void);
+bool hdcp1_feature_supported_qseecom(void *data);
+int hdcp1_set_enc_qseecom(void *data, bool enable);
+int hdcp1_ops_notify_qseecom(void *data, void *topo, bool is_authenticated);
+int hdcp1_start_qseecom(void *data, u32 *aksv_msb, u32 *aksv_lsb);
+void hdcp1_stop_qseecom(void *data);
+
+void *hdcp2_init_qseecom(u32 device_type);
+void hdcp2_deinit_qseecom(void *ctx);
+int hdcp2_app_start_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_start_auth_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_process_msg_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_timeout_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_enable_encryption_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_query_stream_qseecom(void *ctx, uint32_t req_len);
+int hdcp2_app_stop_qseecom(void *ctx);
+bool hdcp2_feature_supported_qseecom(void *ctx);
+int hdcp2_force_encryption_qseecom(void *ctx, uint32_t enable);
+int hdcp2_open_stream_qseecom(void *ctx, uint8_t vc_payload_id,
+		  uint8_t stream_number, uint32_t *stream_id);
+int hdcp2_close_stream_qseecom(void *ctx, uint32_t stream_id);
+int hdcp2_update_app_data_qseecom(void *ctx, struct hdcp2_app_data *app_data);
+
+#endif /* __HDCP_QSEECOM_H__ */

+ 1090 - 0
hdcp/hdcp_smcinvoke.c

@@ -0,0 +1,1090 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <include/linux/smcinvoke.h>
+#include <include/linux/IClientEnv.h>
+#include <include/linux/smcinvoke_object.h>
+#include <include/smci/uid/CAppClient.h>
+#include <include/smci/uid/CAppLoader.h>
+#include <include/smci/interface/IAppClient.h>
+#include <include/smci/interface/IAppController.h>
+#include <include/smci/interface/IAppLoader.h>
+#include <include/smci/interface/IOpener.h>
+#include "hdcp_main.h"
+#include "hdcp_smcinvoke.h"
+#include "hdcp1.h"
+#include "hdcp1_ops.h"
+#include "hdcp2p2.h"
+
+static int hdcp1_verify_key(struct hdcp1_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!handle) {
+		pr_err("invalid HDCP 1.x handle\n");
+		return -EINVAL;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("%s app not loaded\n", HDCP1_APP_NAME);
+		return -EINVAL;
+	}
+
+	ret = hdcp1_verify(handle->hdcp1_app_obj, 1);
+	if (ret)
+		pr_err("hdcp1_verify failed error:%d\n", ret);
+
+	return ret;
+}
+
+static int hdcp1_key_set(struct hdcp1_smcinvoke_handle *handle,
+		 uint32_t *aksv_msb, uint32_t *aksv_lsb)
+{
+	int ret = 0;
+	uint8_t *ksvRes = NULL;
+	size_t ksvResLen = 0;
+
+	ksvRes = kmalloc(HDCP1_AKSV_SIZE, GFP_KERNEL);
+	if (!ksvRes)
+		return -EINVAL;
+
+	if (aksv_msb == NULL || aksv_lsb == NULL) {
+		pr_err("invalid aksv\n");
+		return -EINVAL;
+	}
+
+	if (!handle) {
+		pr_err("invalid HDCP 1.x handle\n");
+		return -EINVAL;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("hdcp1 app not loaded\n");
+		return -EINVAL;
+	}
+
+	ret = hdcp1_set_key(handle->hdcp1_app_obj, ksvRes, HDCP1_AKSV_SIZE,
+				 &ksvResLen);
+	if (ret) {
+		pr_err("hdcp1_set_key failed ret=%d\n", ret);
+		return -ENOKEY;
+	}
+
+	/* copy bytes into msb and lsb */
+	*aksv_msb = ksvRes[0] << 24 | ksvRes[1] << 16 | ksvRes[2] << 8 | ksvRes[3];
+	*aksv_lsb = ksvRes[4] << 24 | ksvRes[5] << 16 | ksvRes[6] << 8 | ksvRes[7];
+
+	ret = hdcp1_validate_aksv(*aksv_msb, *aksv_lsb);
+	if (ret)
+		pr_err("aksv validation failed (%d)\n", ret);
+
+	return ret;
+}
+
+int load_app(char *app_name, struct Object *app_obj,
+			 struct Object *app_controller_obj)
+{
+	int ret = 0;
+	uint8_t *buffer = NULL;
+	struct qtee_shm shm = {0};
+	size_t size = 0;
+	struct Object client_env = {NULL, NULL};
+	struct Object app_loader = {NULL, NULL};
+
+	ret = get_client_env_object(&client_env);
+	if (ret) {
+		pr_err("get_client_env_object failed :%d\n", ret);
+		client_env.invoke = NULL;
+		client_env.context = NULL;
+		goto error;
+	}
+
+	ret = IClientEnv_open(client_env, CAppLoader_UID, &app_loader);
+	if (ret) {
+		pr_err("IClientEnv_open failed :%d\n", ret);
+		app_loader.invoke = NULL;
+		app_loader.context = NULL;
+		goto error;
+	}
+
+	buffer = firmware_request_from_smcinvoke(app_name, &size, &shm);
+	if (buffer == NULL) {
+		pr_err("firmware_request_from_smcinvoke failed\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = IAppLoader_loadFromBuffer(app_loader, (const void *)buffer, size,
+			app_controller_obj);
+	if (ret) {
+		pr_err("IAppLoader_loadFromBuffer failed :%d\n", ret);
+		app_controller_obj->invoke = NULL;
+		app_controller_obj->context = NULL;
+		goto error;
+	}
+
+	ret = IAppController_getAppObject(*app_controller_obj, app_obj);
+	if (ret) {
+		pr_err("IAppController_getAppObject failed :%d\n", ret);
+		goto error;
+	}
+
+error:
+	qtee_shmbridge_free_shm(&shm);
+	Object_ASSIGN_NULL(app_loader);
+	Object_ASSIGN_NULL(client_env);
+	return ret;
+}
+
+static int hdcp1_app_load(struct hdcp1_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!handle) {
+		pr_err("invalid input\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state & HDCP_STATE_APP_LOADED)
+		goto error;
+
+	ret = load_app(HDCP1_APP_NAME, &(handle->hdcp1_app_obj),
+		   &(handle->hdcp1_appcontroller_obj));
+	if (ret) {
+		pr_err("hdcp1 TA load failed :%d\n", ret);
+		goto error;
+	}
+
+	if (Object_isNull(handle->hdcp1_app_obj)) {
+		pr_err("hdcp1_app_obj is NULL\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = load_app(HDCP1OPS_APP_NAME, &(handle->hdcp1ops_app_obj),
+		   &(handle->hdcp1ops_appcontroller_obj));
+	if (ret) {
+		pr_err("hdcp1ops TA load failed :%d\n", ret);
+		goto error;
+	}
+
+	if (Object_isNull(handle->hdcp1ops_app_obj)) {
+		pr_err("hdcp1ops_app_obj is NULL\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->hdcp_state |= HDCP_STATE_APP_LOADED;
+
+error:
+	return ret;
+}
+
+static void hdcp1_app_unload(struct hdcp1_smcinvoke_handle *handle)
+{
+	if (!handle || !!handle->hdcp1_app_obj.context) {
+		pr_err("invalid handle\n");
+		return;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_warn("hdcp1 app not loaded\n");
+		return;
+	}
+
+	Object_ASSIGN_NULL(handle->hdcp1_app_obj);
+	Object_ASSIGN_NULL(handle->hdcp1_appcontroller_obj);
+	Object_ASSIGN_NULL(handle->hdcp1ops_app_obj);
+	Object_ASSIGN_NULL(handle->hdcp1ops_appcontroller_obj);
+
+	handle->hdcp_state &= ~HDCP_STATE_APP_LOADED;
+	pr_debug("%s app unloaded\n", HDCP1_APP_NAME);
+}
+
+void *hdcp1_init_smcinvoke(void)
+{
+	struct hdcp1_smcinvoke_handle *handle =
+		kzalloc(sizeof(struct hdcp1_smcinvoke_handle), GFP_KERNEL);
+
+	if (!handle)
+		goto error;
+
+error:
+	return handle;
+}
+
+bool hdcp1_feature_supported_smcinvoke(void *data)
+{
+	int ret = 0;
+	bool supported = false;
+	struct hdcp1_smcinvoke_handle *handle = data;
+
+	if (!handle) {
+		pr_err("invalid handle\n");
+		goto error;
+	}
+
+	if (handle->feature_supported) {
+		supported = true;
+		goto error;
+	}
+
+	ret = hdcp1_app_load(handle);
+	if (!ret && (handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		if (!hdcp1_verify_key(handle)) {
+			pr_debug("HDCP 1.x supported\n");
+			handle->feature_supported = true;
+			supported = true;
+		}
+		hdcp1_app_unload(handle);
+	}
+error:
+	return supported;
+}
+
+int hdcp1_set_enc_smcinvoke(void *data, bool enable)
+{
+	int ret = 0;
+	struct hdcp1_smcinvoke_handle *handle = data;
+
+	if (!handle || !handle->hdcp1_app_obj.context) {
+		pr_err("invalid HDCP 1.x handle\n");
+		return -EINVAL;
+	}
+
+	if (!handle->feature_supported) {
+		pr_err("HDCP 1.x not supported\n");
+		return -EINVAL;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("%s app not loaded\n", HDCP1_APP_NAME);
+		return -EINVAL;
+	}
+
+	ret = hdcp1_set_encryption(handle->hdcp1_app_obj, enable);
+	if (ret)
+		pr_err("hdcp1_set_encryption failed :%d\n", ret);
+
+	return ret;
+}
+
+int hdcp1_ops_notify_smcinvoke(void *data, void *topo, bool is_authenticated)
+{
+	int ret = 0;
+	struct hdcp1_smcinvoke_handle *handle = data;
+
+	if (!handle || !handle->hdcp1ops_app_obj.context) {
+		pr_err("invalid HDCP 1.x ops handle\n");
+		return -EINVAL;
+	}
+
+	if (!handle->feature_supported) {
+		pr_err("HDCP 1.x not supported\n");
+		return -EINVAL;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("%s app not loaded\n", HDCP1OPS_APP_NAME);
+		return -EINVAL;
+	}
+
+	ret = hdcp1_ops_notify_topology_change(handle->hdcp1ops_app_obj);
+	if (ret)
+		pr_err("hdcp1_ops_notify_topology_change failed, ret=%d\n", ret);
+
+	return ret;
+}
+
+int hdcp1_start_smcinvoke(void *data, u32 *aksv_msb, u32 *aksv_lsb)
+{
+	int ret = 0;
+	struct hdcp1_smcinvoke_handle *handle = data;
+
+	if (!aksv_msb || !aksv_lsb) {
+		pr_err("invalid aksv output buffer\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!handle) {
+		pr_err("invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!handle->feature_supported) {
+		pr_err("feature not supported\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+		pr_debug("%s app already loaded\n", HDCP1_APP_NAME);
+		goto error;
+	}
+
+	ret = hdcp1_app_load(handle);
+	if (ret)
+		goto error;
+
+	ret = hdcp1_key_set(handle, aksv_msb, aksv_lsb);
+	if (ret)
+		goto key_error;
+
+	pr_debug("success\n");
+	return ret;
+
+key_error:
+	hdcp1_app_unload(handle);
+error:
+	return ret;
+}
+
+void hdcp1_stop_smcinvoke(void *data)
+{
+	struct hdcp1_smcinvoke_handle *hdcp1_handle = data;
+
+	Object_ASSIGN_NULL(hdcp1_handle->hdcp1_app_obj);
+	Object_ASSIGN_NULL(hdcp1_handle->hdcp1_appcontroller_obj);
+	Object_ASSIGN_NULL(hdcp1_handle->hdcp1ops_app_obj);
+	Object_ASSIGN_NULL(hdcp1_handle->hdcp1ops_appcontroller_obj);
+}
+
+void *hdcp2_init_smcinvoke(u32 device_type)
+{
+	struct hdcp2_smcinvoke_handle *handle =
+		kzalloc(sizeof(struct hdcp2_smcinvoke_handle), GFP_KERNEL);
+
+	if (!handle)
+		goto error;
+
+	handle->device_type = device_type;
+
+error:
+	return handle;
+}
+
+void hdcp2_deinit_smcinvoke(void *ctx)
+{
+	kfree_sensitive(ctx);
+}
+
+int hdcp_get_version(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+	uint32_t app_major_version = 0;
+	uint32_t appversion = 0;
+
+	if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+		pr_err("hdcp2p2 TA already loaded\n");
+		goto error;
+	}
+
+	ret = hdcp2p2_version(handle->hdcp2_app_obj, &appversion);
+	if (ret) {
+		pr_err("hdcp2p2_version failed :%d\n", ret);
+		goto error;
+	}
+	app_major_version = HCDP_TXMTR_GET_MAJOR_VERSION(appversion);
+
+	pr_debug("hdp2p2 app major version %d, app version %d\n", app_major_version,
+			 appversion);
+error:
+	return ret;
+}
+
+int hdcp2_app_init(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+	uint32_t app_minor_version = 0;
+	uint32_t clientversion = 0;
+	uint32_t appversion = 0;
+
+	if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+		pr_err("hdcp2p2 TA already loaded\n");
+		goto error;
+	}
+
+	clientversion = HDCP_CLIENT_MAKE_VERSION(HDCP_CLIENT_MAJOR_VERSION,
+					HDCP_CLIENT_MINOR_VERSION,
+					HDCP_CLIENT_PATCH_VERSION);
+
+	ret = hdcp2p2_init(handle->hdcp2_app_obj, clientversion, &appversion);
+	if (ret) {
+		pr_err("hdcp2p2_init failed:%d\n", ret);
+		goto error;
+	}
+
+	app_minor_version = HCDP_TXMTR_GET_MINOR_VERSION(appversion);
+	if (app_minor_version != HDCP_CLIENT_MINOR_VERSION) {
+		pr_err("client-app minor version mismatch app(%d), client(%d)\n",
+			   app_minor_version, HDCP_CLIENT_MINOR_VERSION);
+		ret = -1;
+		goto error;
+	}
+
+	pr_err("client version major(%d), minor(%d), patch(%d)\n",
+		   HDCP_CLIENT_MAJOR_VERSION, HDCP_CLIENT_MINOR_VERSION,
+		   HDCP_CLIENT_PATCH_VERSION);
+
+	pr_err("app version major(%d), minor(%d), patch(%d)\n",
+		   HCDP_TXMTR_GET_MAJOR_VERSION(appversion),
+		   HCDP_TXMTR_GET_MINOR_VERSION(appversion),
+		   HCDP_TXMTR_GET_PATCH_VERSION(appversion));
+error:
+	return ret;
+}
+
+int hdcp2_app_tx_init(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+	uint32_t ctxhandle = 0;
+
+	if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+		pr_err("session not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state & HDCP_STATE_TXMTR_INIT) {
+		pr_err("txmtr already initialized\n");
+		goto error;
+	}
+
+	ret = hdcp2p2_tx_init(handle->hdcp2_app_obj, handle->session_id, &ctxhandle);
+	if (ret) {
+		pr_err("hdcp2p2_tx_init failed :%d\n", ret);
+		goto error;
+	}
+
+	handle->tz_ctxhandle = ctxhandle;
+	handle->hdcp_state |= HDCP_STATE_TXMTR_INIT;
+
+error:
+	return ret;
+}
+
+int hdcp2_app_tx_deinit(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("hdcp2p2 TA not loaded\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
+		pr_err("txmtr not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_tx_deinit(handle->hdcp2_app_obj, handle->tz_ctxhandle);
+	if (ret) {
+		pr_err("hdcp2p2_tx_deinit failed :%d\n", ret);
+		goto error;
+	}
+	handle->hdcp_state &= ~HDCP_STATE_TXMTR_INIT;
+
+error:
+	return ret;
+}
+
+static int hdcp2_app_load(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!handle) {
+		pr_err("invalid input\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+		pr_err("hdcp2p2 TA already loaded\n");
+		goto error;
+	}
+
+	ret = load_app(HDCP2P2_APP_NAME, &(handle->hdcp2_app_obj),
+				   &(handle->hdcp2_appcontroller_obj));
+	if (ret) {
+		pr_err("hdcp2p2 TA load_app failed :%d\n", ret);
+		goto error;
+	}
+
+	if (Object_isNull(handle->hdcp2_app_obj)) {
+		pr_err("hdcp2p2 app object is NULL\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = load_app(HDCPSRM_APP_NAME, &(handle->hdcpsrm_app_obj),
+		   &(handle->hdcpsrm_appcontroller_obj));
+	if (ret) {
+		pr_err("hdcpsrm TA load failed :%d\n", ret);
+		goto error;
+	}
+
+	if (Object_isNull(handle->hdcpsrm_app_obj)) {
+		pr_err("hdcpsrm app object is NULL\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp_get_version(handle);
+	if (ret) {
+		pr_err("library get version failed\n");
+		goto error;
+	}
+
+	ret = hdcp2_app_init(handle);
+	if (ret) {
+		pr_err("app init failed\n");
+		goto error;
+	}
+
+	handle->hdcp_state |= HDCP_STATE_APP_LOADED;
+
+error:
+	return ret;
+}
+
+static int hdcp2_app_unload(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	ret = hdcp2p2_deinit(handle->hdcp2_app_obj);
+	if (ret) {
+		pr_err("hdcp2p2_deinit failed:%d\n", ret);
+		goto error;
+	}
+
+	Object_ASSIGN_NULL(handle->hdcp2_app_obj);
+	Object_ASSIGN_NULL(handle->hdcp2_appcontroller_obj);
+	Object_ASSIGN_NULL(handle->hdcpsrm_app_obj);
+	Object_ASSIGN_NULL(handle->hdcpsrm_appcontroller_obj);
+
+	handle->hdcp_state &= ~HDCP_STATE_APP_LOADED;
+
+error:
+	return ret;
+}
+
+static int hdcp2_verify_key(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("%s app not loaded\n", HDCP2P2_APP_NAME);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_verify_key(handle->hdcp2_app_obj);
+	if (ret) {
+		pr_err("hdcp2p2_verify_key failed:%d\n", ret);
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+static int hdcp2_app_session_init(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+	uint32_t sessionId = 0;
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("hdcp2p2 app not loaded\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state & HDCP_STATE_SESSION_INIT) {
+		pr_err("session already initialized\n");
+		goto error;
+	}
+
+	if (Object_isNull(handle->hdcp2_app_obj)) {
+		pr_err("hdcp2_app_obj is NULL\n");
+		goto error;
+	}
+
+	ret = hdcp2p2_session_init(handle->hdcp2_app_obj, handle->device_type,
+			&sessionId);
+	if (ret) {
+		pr_err("hdcp2p2_session_init failed ret:%d\n", ret);
+		goto error;
+	}
+
+	handle->session_id = sessionId;
+	handle->hdcp_state |= HDCP_STATE_SESSION_INIT;
+error:
+	return ret;
+}
+
+static int hdcp2_app_session_deinit(struct hdcp2_smcinvoke_handle *handle)
+{
+	int ret = 0;
+
+	if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+		pr_err("hdcp2p2 app not loaded\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+		pr_err("session not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_session_deinit(handle->hdcp2_app_obj, handle->session_id);
+	if (ret) {
+		pr_err("hdcp2p2_session_deinit failed:%d\n", ret);
+		goto error;
+	}
+
+	handle->hdcp_state &= ~HDCP_STATE_SESSION_INIT;
+error:
+	return ret;
+}
+
+int hdcp2_app_start_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = (struct hdcp2_smcinvoke_handle *)ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.data = kmalloc(MAX_RX_MESSAGE_SIZE, GFP_KERNEL);
+	if (!handle->app_data.request.data) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.response.data = kmalloc(MAX_TX_MESSAGE_SIZE, GFP_KERNEL);
+	if (!handle->app_data.response.data) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2_app_load(handle);
+	if (ret)
+		goto error;
+
+	ret = hdcp2_app_session_init(handle);
+	if (ret)
+		goto error;
+
+	ret = hdcp2_app_tx_init(handle);
+	if (ret)
+		goto error;
+
+error:
+	return ret;
+}
+
+int hdcp2_app_start_auth_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+	size_t resMsgOut = 0;
+	uint32_t timeout = 0;
+	uint32_t flag = 0;
+	uint32_t ctxhandle = 0;
+
+	uint8_t resMsg[MAX_TX_MESSAGE_SIZE] = {0};
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.length = req_len;
+
+	if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+		pr_err("session not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
+		pr_err("txmtr not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_start_auth(handle->hdcp2_app_obj, handle->tz_ctxhandle,
+	  resMsg, MAX_TX_MESSAGE_SIZE, &resMsgOut, &timeout,
+	  &flag, &ctxhandle);
+	if (ret) {
+		pr_err("hdcp2p2_start_auth failed :%d\n", ret);
+		goto error;
+	}
+
+	memcpy(handle->app_data.response.data, resMsg, resMsgOut);
+
+	handle->app_data.response.length = resMsgOut;
+	handle->app_data.timeout = timeout;
+	handle->app_data.repeater_flag = false;
+
+	handle->tz_ctxhandle = ctxhandle;
+
+error:
+	return ret;
+}
+
+int hdcp2_app_process_msg_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+	size_t resMsgLen = 0;
+	uint32_t timeout = 0;
+	uint32_t flag = 0;
+
+	uint8_t resMsg[MAX_TX_MESSAGE_SIZE] = {0};
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.length = req_len;
+
+	if (!handle->app_data.request.data) {
+		pr_err("invalid request buffer\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_rcvd_msg(
+		handle->hdcp2_app_obj, handle->app_data.request.data,
+		handle->app_data.request.length, handle->tz_ctxhandle, resMsg,
+		MAX_TX_MESSAGE_SIZE, &resMsgLen, &timeout, &flag);
+	if (ret) {
+		pr_err("hdcp2p2_rcvd_msg failed :%d\n", ret);
+		goto error;
+	}
+
+	memcpy(handle->app_data.response.data, resMsg, resMsgLen);
+
+	/* check if it's a repeater */
+	if (flag == HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST)
+		handle->app_data.repeater_flag = true;
+
+	handle->app_data.response.length = resMsgLen;
+	handle->app_data.timeout = timeout;
+
+error:
+	return ret;
+}
+
+int hdcp2_app_timeout_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+	uint32_t timeout = 0;
+	size_t resMsgLenOut = 0;
+
+	uint8_t resMsg[MAX_TX_MESSAGE_SIZE] = {0};
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.length = req_len;
+
+	ret = hdcp2p2_send_timeout(handle->hdcp2_app_obj, handle->tz_ctxhandle,
+		resMsg, MAX_TX_MESSAGE_SIZE, &resMsgLenOut,
+		&timeout);
+	if (ret) {
+		pr_err("hdcp2p2_send_timeout failed :%d\n", ret);
+		goto error;
+	}
+
+	memcpy(handle->app_data.response.data, resMsg, resMsgLenOut);
+
+	handle->app_data.response.length = resMsgLenOut;
+	handle->app_data.timeout = timeout;
+
+error:
+	return ret;
+}
+
+int hdcp2_app_enable_encryption_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.length = req_len;
+
+	/*
+	 * wait at least 200ms before enabling encryption
+	 * as per hdcp2p2 specifications.
+	 */
+	msleep(SLEEP_SET_HW_KEY_MS);
+
+	ret = hdcp2p2_set_hw_key(handle->hdcp2_app_obj, handle->tz_ctxhandle);
+	if (ret) {
+		pr_err("hdcp2p2_set_hw_key failed:%d\n", ret);
+		goto error;
+	}
+
+	handle->hdcp_state |= HDCP_STATE_AUTHENTICATED;
+error:
+	return ret;
+}
+
+int hdcp2_app_query_stream_smcinvoke(void *ctx, uint32_t req_len)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	uint32_t timeout = 0;
+	size_t resMsgLenOut = 0;
+
+	uint8_t resMsg[MAX_TX_MESSAGE_SIZE] = {0};
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	handle->app_data.request.length = req_len;
+
+	ret = hdcp2p2_query_stream_type(
+		handle->hdcp2_app_obj, handle->tz_ctxhandle, resMsg,
+		MAX_TX_MESSAGE_SIZE, &resMsgLenOut, &timeout);
+	if (ret) {
+		pr_err("hdcp2p2_query_stream_type failed :%d\n", ret);
+		goto error;
+	}
+
+	memcpy(handle->app_data.response.data, resMsg, resMsgLenOut);
+
+	handle->app_data.response.length = resMsgLenOut;
+	handle->app_data.timeout = timeout;
+error:
+	return ret;
+}
+
+int hdcp2_app_stop_smcinvoke(void *ctx)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto end;
+	}
+
+	ret = hdcp2_app_tx_deinit(handle);
+	if (ret)
+		goto end;
+
+	ret = hdcp2_app_session_deinit(handle);
+	if (ret)
+		goto end;
+
+	ret = hdcp2_app_unload(handle);
+
+	kfree(handle->app_data.request.data);
+	kfree(handle->app_data.response.data);
+
+end:
+	return ret;
+}
+
+bool hdcp2_feature_supported_smcinvoke(void *ctx)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+	bool supported = false;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("invalid input\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->feature_supported) {
+		supported = true;
+		goto error;
+	}
+
+	ret = hdcp2_app_load(handle);
+	if (!ret) {
+		if (!hdcp2_verify_key(handle)) {
+			pr_debug("HDCP 2.2 supported\n");
+			handle->feature_supported = true;
+			supported = true;
+		}
+		hdcp2_app_unload(handle);
+	}
+error:
+	return supported;
+}
+
+int hdcp2_force_encryption_smcinvoke(void *ctx, uint32_t enable)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (handle->hdcp_state == HDCP_STATE_AUTHENTICATED)
+		msleep(SLEEP_FORCE_ENCRYPTION_MS);
+
+	ret = hdcp2p2_force_encryption(handle->hdcp2_app_obj, handle->tz_ctxhandle,
+		enable);
+	if (ret) {
+		pr_err("hdcp2p2_force_encryption failed :%d\n", ret);
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+int hdcp2_open_stream_smcinvoke(void *ctx, uint8_t vc_payload_id,
+		uint8_t stream_number, uint32_t *stream_id)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+	uint32_t streamid = 0;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+		pr_err("session not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
+		pr_err("txmtr not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_session_open_stream(handle->hdcp2_app_obj,
+		   handle->session_id, vc_payload_id,
+		   stream_number, 0, &streamid);
+	if (ret) {
+		pr_err("hdcp2p2_session_open_stream failed :%d\n", ret);
+		goto error;
+	}
+
+	*stream_id = streamid;
+
+error:
+	return ret;
+}
+
+int hdcp2_close_stream_smcinvoke(void *ctx, uint32_t stream_id)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ctx;
+
+	if (!handle) {
+		pr_err("Invalid handle\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+		pr_err("session not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
+		pr_err("txmtr not initialized\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = hdcp2p2_session_close_stream(handle->hdcp2_app_obj,
+		handle->session_id, stream_id);
+	if (ret) {
+		pr_err("hdcp2p2_session_close_stream failed :%d\n", ret);
+		goto error;
+	}
+
+error:
+	return ret;
+}
+
+int hdcp2_update_app_data_smcinvoke(void *ctx, struct hdcp2_app_data *app_data)
+{
+	struct hdcp2_smcinvoke_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ctx;
+
+	if (!handle || !app_data) {
+		pr_err("Invalid handle\n");
+		return -EINVAL;
+	}
+
+	app_data->request.data = handle->app_data.request.data;
+	app_data->request.length = handle->app_data.request.length;
+	app_data->response.data = handle->app_data.response.data;
+	app_data->response.length = handle->app_data.response.length;
+	app_data->timeout = handle->app_data.timeout;
+	app_data->repeater_flag = handle->app_data.repeater_flag;
+	return ret;
+}

+ 62 - 0
hdcp/hdcp_smcinvoke.h

@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __HDCP_SMCINVOKE_H__
+#define __HDCP_SMCINVOKE_H__
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <include/linux/smcinvoke_object.h>
+
+#include "hdcp_main.h"
+
+struct hdcp1_smcinvoke_handle {
+	struct Object hdcp1_app_obj;
+	struct Object hdcp1_appcontroller_obj;
+	struct Object hdcp1ops_app_obj;
+	struct Object hdcp1ops_appcontroller_obj;
+	bool feature_supported;
+	uint32_t device_type;
+	enum hdcp_state hdcp_state;
+};
+
+struct hdcp2_smcinvoke_handle {
+	struct hdcp2_app_data app_data;
+	uint32_t tz_ctxhandle;
+	bool feature_supported;
+	enum hdcp_state hdcp_state;
+	struct Object hdcp2_app_obj;
+	struct Object hdcp2_appcontroller_obj;
+	struct Object hdcpsrm_app_obj;
+	struct Object hdcpsrm_appcontroller_obj;
+	uint32_t session_id;
+	uint32_t device_type;
+};
+
+void *hdcp1_init_smcinvoke(void);
+bool hdcp1_feature_supported_smcinvoke(void *data);
+int hdcp1_set_enc_smcinvoke(void *data, bool enable);
+int hdcp1_ops_notify_smcinvoke(void *data, void *topo, bool is_authenticated);
+int hdcp1_start_smcinvoke(void *data, u32 *aksv_msb, u32 *aksv_lsb);
+void hdcp1_stop_smcinvoke(void *data);
+
+void *hdcp2_init_smcinvoke(u32 device_type);
+void hdcp2_deinit_smcinvoke(void *ctx);
+int hdcp2_app_start_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_start_auth_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_process_msg_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_timeout_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_enable_encryption_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_query_stream_smcinvoke(void *ctx, uint32_t req_len);
+int hdcp2_app_stop_smcinvoke(void *ctx);
+bool hdcp2_feature_supported_smcinvoke(void *ctx);
+int hdcp2_force_encryption_smcinvoke(void *ctx, uint32_t enable);
+int hdcp2_open_stream_smcinvoke(void *ctx, uint8_t vc_payload_id,
+		uint8_t stream_number, uint32_t *stream_id);
+int hdcp2_close_stream_smcinvoke(void *ctx, uint32_t stream_id);
+int hdcp2_update_app_data_smcinvoke(void *ctx, struct hdcp2_app_data *app_data);
+
+#endif /* __HDCP_SMCINVOKE_H__ */

+ 15 - 11
include/linux/smcinvoke.h

@@ -3,8 +3,8 @@
  * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
-#ifndef _UAPI_SMCINVOKE_H_
-#define _UAPI_SMCINVOKE_H_
+#ifndef _SMCINVOKE_H_
+#define _SMCINVOKE_H_
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
@@ -20,8 +20,8 @@ struct smcinvoke_buf {
 
 struct smcinvoke_obj {
 	__s64 fd;
-	__s32 cb_server_fd;
-	__s32 reserved;
+	__s64 cb_server_fd;
+	__s64 reserved;
 };
 
 union smcinvoke_arg {
@@ -36,6 +36,7 @@ union smcinvoke_arg {
  * @result - result of invoke operation
  * @argsize - size of each of arguments
  * @args - args is pointer to buffer having all arguments
+ * @reserved: IN/OUT: Usage is not defined but should be set to 0
  */
 struct smcinvoke_cmd_req {
 	__u32 op;
@@ -43,42 +44,45 @@ struct smcinvoke_cmd_req {
 	__s32 result;
 	__u32 argsize;
 	__u64 args;
+	__s64 reserved;
 };
 
 /*
  * struct smcinvoke_accept: structure to process CB req from TEE
  * @has_resp: IN: Whether IOCTL is carrying response data
- * @txn_id: OUT: An id that should be passed as it is for response
  * @result: IN: Outcome of operation op
- * @cbobj_id: OUT: Callback object which is target of operation op
  * @op: OUT: Operation to be performed on target object
  * @counts: OUT: Number of arguments, embedded in buffer pointed by
  *               buf_addr, to complete operation
  * @reserved: IN/OUT: Usage is not defined but should be set to 0.
  * @argsize: IN: Size of any argument, all of equal size, embedded
  *               in buffer pointed by buf_addr
+ * @txn_id: OUT: An id that should be passed as it is for response
+ * @cbobj_id: OUT: Callback object which is target of operation op
  * @buf_len: IN: Len of buffer pointed by buf_addr
  * @buf_addr: IN: Buffer containing all arguments which are needed
  *                to complete operation op
  */
 struct smcinvoke_accept {
 	__u32 has_resp;
-	__u32 txn_id;
 	__s32 result;
-	__s32 cbobj_id;
 	__u32 op;
 	__u32 counts;
 	__s32 reserved;
 	__u32 argsize;
+	__u64 txn_id;
+	__s64 cbobj_id;
 	__u64 buf_len;
 	__u64 buf_addr;
 };
 
 /*
  * @cb_buf_size: IN: Max buffer size for any callback obj implemented by client
+ * @reserved: IN/OUT: Usage is not defined but should be set to 0
  */
 struct smcinvoke_server {
-	__u32 cb_buf_size;
+	__u64 cb_buf_size;
+	__s64 reserved;
 };
 
 #define SMCINVOKE_IOC_MAGIC    0x98
@@ -93,7 +97,7 @@ struct smcinvoke_server {
 	_IOWR(SMCINVOKE_IOC_MAGIC, 3, struct smcinvoke_server)
 
 #define SMCINVOKE_IOCTL_ACK_LOCAL_OBJ \
-	_IOWR(SMCINVOKE_IOC_MAGIC, 4, __s32)
+	_IOWR(SMCINVOKE_IOC_MAGIC, 4, __s64)
 
 /*
   * smcinvoke logging buffer is for communicating with the smcinvoke driver additional
@@ -103,4 +107,4 @@ struct smcinvoke_server {
 #define SMCINVOKE_IOCTL_LOG \
 	_IOC(_IOC_READ|_IOC_WRITE, SMCINVOKE_IOC_MAGIC, 255, SMCINVOKE_LOG_BUF_SIZE)
 
-#endif /* _UAPI_SMCINVOKE_H_ */
+#endif /* _SMCINVOKE_H_ */

+ 1 - 1
include/linux/smcinvoke_object.h

@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/firmware.h>
 #include <linux/qtee_shmbridge.h>
+#include "smcinvoke.h"
 
 /*
  * Method bits are not modified by transport layers.  These describe the
@@ -190,7 +191,6 @@ static inline void Object_replace(struct Object *loc, struct Object objNew)
 int smcinvoke_release_from_kernel_client(int fd);
 
 int get_root_fd(int *root_fd);
-
 int process_invoke_request_from_kernel_client(
 		int fd, struct smcinvoke_cmd_req *req);
 

+ 48 - 0
include/smci/interface/IAppClient.h

@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/** @cond */
+
+#pragma once
+
+
+#include "smcinvoke_object.h"
+
+
+#define IAppClient_ERROR_APP_NOT_FOUND INT32_C(10)
+#define IAppClient_ERROR_APP_RESTART_FAILED INT32_C(11)
+#define IAppClient_ERROR_APP_UNTRUSTED_CLIENT INT32_C(12)
+#define IAppClient_ERROR_CLIENT_CRED_PARSING_FAILURE INT32_C(13)
+#define IAppClient_ERROR_APP_LOAD_FAILED INT32_C(14)
+
+#define IAppClient_OP_getAppObject 0
+
+static inline int32_t
+IAppClient_release(struct Object self)
+{
+  return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t
+IAppClient_retain(struct Object self)
+{
+  return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t
+IAppClient_getAppObject(struct Object self, const void *appDistName_ptr, size_t appDistName_len,struct Object *obj_ptr)
+{
+  int32_t result;
+  union ObjectArg a[2];
+  a[0].bi = (struct ObjectBufIn) { appDistName_ptr, appDistName_len * 1 };
+
+  result = Object_invoke(self, IAppClient_OP_getAppObject, a, ObjectCounts_pack(1, 0, 0, 1));
+
+  *obj_ptr = a[1].o;
+
+  return result;
+}
+
+
+

+ 143 - 0
include/smci/interface/IAppController.h

@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/** @cond */
+#pragma once
+
+#include "smcinvoke_object.h"
+
+
+#define IAppController_CBO_INTERFACE_WAIT UINT32_C(1)
+
+#define IAppController_ERROR_APP_SUSPENDED INT32_C(10)
+#define IAppController_ERROR_APP_BLOCKED_ON_LISTENER INT32_C(11)
+#define IAppController_ERROR_APP_UNLOADED INT32_C(12)
+#define IAppController_ERROR_APP_IN_USE INT32_C(13)
+#define IAppController_ERROR_NOT_SUPPORTED INT32_C(14)
+#define IAppController_ERROR_CBO_UNKNOWN INT32_C(15)
+#define IAppController_ERROR_APP_UNLOAD_NOT_ALLOWED INT32_C(16)
+#define IAppController_ERROR_APP_DISCONNECTED INT32_C(17)
+#define IAppController_ERROR_USER_DISCONNECT_REJECTED INT32_C(18)
+#define IAppController_ERROR_STILL_RUNNING INT32_C(19)
+
+#define IAppController_OP_openSession 0
+#define IAppController_OP_unload 1
+#define IAppController_OP_getAppObject 2
+#define IAppController_OP_installCBO 3
+#define IAppController_OP_disconnect 4
+#define IAppController_OP_restart 5
+
+static inline int32_t
+IAppController_release(struct Object self)
+{
+  return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t
+IAppController_retain(struct Object self)
+{
+  return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t
+IAppController_openSession(struct Object self, uint32_t cancelCode_val, uint32_t connectionMethod_val, uint32_t connectionData_val, uint32_t paramTypes_val, uint32_t exParamTypes_val, const void *i1_ptr, size_t i1_len, const void *i2_ptr, size_t i2_len, const void *i3_ptr, size_t i3_len, const void *i4_ptr, size_t i4_len, void *o1_ptr, size_t o1_len, size_t *o1_lenout, void *o2_ptr, size_t o2_len, size_t *o2_lenout, void *o3_ptr, size_t o3_len, size_t *o3_lenout, void *o4_ptr, size_t o4_len, size_t *o4_lenout,struct Object imem1_val,struct Object imem2_val,struct Object imem3_val,struct Object imem4_val, uint32_t *memrefOutSz1_ptr, uint32_t *memrefOutSz2_ptr, uint32_t *memrefOutSz3_ptr, uint32_t *memrefOutSz4_ptr,struct Object *session_ptr, uint32_t *retValue_ptr, uint32_t *retOrigin_ptr)
+{
+  union ObjectArg a[15];
+  struct {
+    uint32_t m_cancelCode;
+    uint32_t m_connectionMethod;
+    uint32_t m_connectionData;
+    uint32_t m_paramTypes;
+    uint32_t m_exParamTypes;
+  } i;
+
+  struct {
+    uint32_t m_memrefOutSz1;
+    uint32_t m_memrefOutSz2;
+    uint32_t m_memrefOutSz3;
+    uint32_t m_memrefOutSz4;
+    uint32_t m_retValue;
+    uint32_t m_retOrigin;
+  } o;
+  int32_t result;
+
+  a[0].b = (struct ObjectBuf) { &i, 20 };
+  a[5].b = (struct ObjectBuf) { &o, 24 };
+  i.m_cancelCode = cancelCode_val;
+  i.m_connectionMethod = connectionMethod_val;
+  i.m_connectionData = connectionData_val;
+  i.m_paramTypes = paramTypes_val;
+  i.m_exParamTypes = exParamTypes_val;
+  a[1].bi = (struct ObjectBufIn) { i1_ptr, i1_len * 1 };
+  a[2].bi = (struct ObjectBufIn) { i2_ptr, i2_len * 1 };
+  a[3].bi = (struct ObjectBufIn) { i3_ptr, i3_len * 1 };
+  a[4].bi = (struct ObjectBufIn) { i4_ptr, i4_len * 1 };
+  a[6].b = (struct ObjectBuf) { o1_ptr, o1_len * 1 };
+  a[7].b = (struct ObjectBuf) { o2_ptr, o2_len * 1 };
+  a[8].b = (struct ObjectBuf) { o3_ptr, o3_len * 1 };
+  a[9].b = (struct ObjectBuf) { o4_ptr, o4_len * 1 };
+  a[10].o = imem1_val;
+  a[11].o = imem2_val;
+  a[12].o = imem3_val;
+  a[13].o = imem4_val;
+
+  result = Object_invoke(self, IAppController_OP_openSession, a, ObjectCounts_pack(5, 5, 4, 1));
+
+  *o1_lenout = a[6].b.size / 1;
+  *o2_lenout = a[7].b.size / 1;
+  *o3_lenout = a[8].b.size / 1;
+  *o4_lenout = a[9].b.size / 1;
+  *memrefOutSz1_ptr = o.m_memrefOutSz1;
+  *memrefOutSz2_ptr = o.m_memrefOutSz2;
+  *memrefOutSz3_ptr = o.m_memrefOutSz3;
+  *memrefOutSz4_ptr = o.m_memrefOutSz4;
+  *session_ptr = a[14].o;
+  *retValue_ptr = o.m_retValue;
+  *retOrigin_ptr = o.m_retOrigin;
+
+  return result;
+}
+
+static inline int32_t
+IAppController_unload(struct Object self)
+{
+  return Object_invoke(self, IAppController_OP_unload, 0, 0);
+}
+
+static inline int32_t
+IAppController_getAppObject(struct Object self,struct  Object *obj_ptr)
+{
+  union ObjectArg a[1];
+  int32_t result = Object_invoke(self, IAppController_OP_getAppObject, a, ObjectCounts_pack(0, 0, 0, 1));
+
+  *obj_ptr = a[0].o;
+
+  return result;
+}
+
+static inline int32_t
+IAppController_installCBO(struct Object self, uint32_t uid_val,struct Object obj_val)
+{
+  union ObjectArg a[2];
+  a[0].b = (struct ObjectBuf) { &uid_val, sizeof(uint32_t) };
+  a[1].o = obj_val;
+
+  return Object_invoke(self, IAppController_OP_installCBO, a, ObjectCounts_pack(1, 0, 1, 0));
+}
+
+static inline int32_t
+IAppController_disconnect(struct Object self)
+{
+  return Object_invoke(self, IAppController_OP_disconnect, 0, 0);
+}
+
+static inline int32_t
+IAppController_restart(struct Object self)
+{
+  return Object_invoke(self, IAppController_OP_restart, 0, 0);
+}
+
+
+

+ 105 - 0
include/smci/interface/IAppLoader.h

@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#pragma once
+
+
+#include "smcinvoke_object.h"
+#include "IAppController.h"
+
+#define IAppLoader_ERROR_INVALID_BUFFER INT32_C(10)
+#define IAppLoader_ERROR_PIL_ROLLBACK_FAILURE INT32_C(11)
+#define IAppLoader_ERROR_ELF_SIGNATURE_ERROR INT32_C(12)
+#define IAppLoader_ERROR_METADATA_INVALID INT32_C(13)
+#define IAppLoader_ERROR_MAX_NUM_APPS INT32_C(14)
+#define IAppLoader_ERROR_NO_NAME_IN_METADATA INT32_C(15)
+#define IAppLoader_ERROR_ALREADY_LOADED INT32_C(16)
+#define IAppLoader_ERROR_EMBEDDED_IMAGE_NOT_FOUND INT32_C(17)
+#define IAppLoader_ERROR_TZ_HEAP_MALLOC_FAILURE INT32_C(18)
+#define IAppLoader_ERROR_TA_APP_REGION_MALLOC_FAILURE INT32_C(19)
+#define IAppLoader_ERROR_CLIENT_CRED_PARSING_FAILURE INT32_C(20)
+#define IAppLoader_ERROR_APP_UNTRUSTED_CLIENT INT32_C(21)
+#define IAppLoader_ERROR_APP_NOT_LOADED INT32_C(22)
+#define IAppLoader_ERROR_APP_MAX_CLIENT_CONNECTIONS INT32_C(23)
+#define IAppLoader_ERROR_APP_BLACKLISTED INT32_C(24)
+
+#define IAppLoader_OP_loadFromBuffer 0
+#define IAppLoader_OP_loadFromRegion 1
+#define IAppLoader_OP_loadEmbedded 2
+#define IAppLoader_OP_connect 3
+
+static inline int32_t
+IAppLoader_release(struct Object self)
+{
+  return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t
+IAppLoader_retain(struct Object self)
+{
+  return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t
+IAppLoader_loadFromBuffer(struct Object self, const void *appElf_ptr, size_t appElf_len,struct  Object *appController_ptr)
+{
+  union ObjectArg a[2];
+  int32_t result;
+  a[0].bi = (struct ObjectBufIn) { appElf_ptr, appElf_len * 1 };
+
+
+  result = Object_invoke(self, IAppLoader_OP_loadFromBuffer, a, ObjectCounts_pack(1, 0, 0, 1));
+
+  *appController_ptr = a[1].o;
+
+  return result;
+}
+
+static inline int32_t
+IAppLoader_loadFromRegion(struct Object self,struct  Object appElf_val,struct  Object *appController_ptr)
+{
+  union ObjectArg a[2];
+  int32_t result;
+  a[0].o = appElf_val;
+
+  result = Object_invoke(self, IAppLoader_OP_loadFromRegion, a, ObjectCounts_pack(0, 0, 1, 1));
+
+  *appController_ptr = a[1].o;
+
+  return result;
+}
+
+static inline int32_t
+IAppLoader_loadEmbedded(struct Object self, const void *appName_ptr, size_t appName_len,struct  Object *appController_ptr)
+{
+  union ObjectArg a[2];
+  int32_t result;
+  a[0].bi = (struct ObjectBufIn) { appName_ptr, appName_len * 1 };
+
+  result = Object_invoke(self, IAppLoader_OP_loadEmbedded, a, ObjectCounts_pack(1, 0, 0, 1));
+
+  *appController_ptr = a[1].o;
+
+  return result;
+}
+
+static inline int32_t
+IAppLoader_connect(struct Object self, const void *appName_ptr, size_t appName_len,struct  Object *appController_ptr)
+{
+  union ObjectArg a[2];
+
+  int32_t result;
+  a[0].bi = (struct ObjectBufIn) { appName_ptr, appName_len * 1 };
+
+
+  result = Object_invoke(self, IAppLoader_OP_connect, a, ObjectCounts_pack(1, 0, 0, 1));
+
+  *appController_ptr = a[1].o;
+
+  return result;
+}
+
+
+

+ 48 - 0
include/smci/interface/IOpener.h

@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/** @cond */
+#pragma once
+
+
+#include "smcinvoke_object.h"
+
+/** 0 is not a valid service ID. */
+#define IOpener_INVALID_ID UINT32_C(0)
+
+#define IOpener_ERROR_NOT_FOUND INT32_C(10)
+#define IOpener_ERROR_PRIVILEGE INT32_C(11)
+#define IOpener_ERROR_NOT_SUPPORTED INT32_C(12)
+
+#define IOpener_OP_open 0
+
+static inline int32_t
+IOpener_release(struct Object self)
+{
+  return Object_invoke(self, Object_OP_release, 0, 0);
+}
+
+static inline int32_t
+IOpener_retain(struct Object self)
+{
+  return Object_invoke(self, Object_OP_retain, 0, 0);
+}
+
+static inline int32_t
+IOpener_open(struct Object self, uint32_t id_val,struct Object *obj_ptr)
+{
+  union ObjectArg a[2];
+  int32_t result;
+  a[0].b = (struct ObjectBuf) { &id_val, sizeof(uint32_t) };
+
+  result = Object_invoke(self, IOpener_OP_open, a, ObjectCounts_pack(1, 0, 0, 1));
+
+  *obj_ptr = a[1].o;
+
+  return result;
+}
+
+
+

+ 20 - 0
include/smci/uid/CAppClient.h

@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/**
+* @addtogroup CAppClient
+* @{
+  Class CAppClient implements \link IAppClient \endlink interface.
+  This class provides an interface to obtain app-provided functionalities.
+
+  The class ID `AppClient` is not included in the default privilege set.
+*/
+#pragma once
+
+#include <smcinvoke_object.h>
+
+#define CAppClient_UID (0x97)
+
+

+ 12 - 0
include/smci/uid/CAppLoader.h

@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#pragma once
+
+#include <include/linux/smcinvoke_object.h>
+
+
+// This class provides an interface to load Secure Applications in QSEE
+#define CAppLoader_UID (3)

+ 2 - 1
crypto-qti/compat_qcedev.h → include/uapi/linux/compat_qcedev.h

@@ -1,6 +1,7 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2014,2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _UAPI_COMPAT_QCEDEV__H

+ 387 - 0
include/uapi/linux/qcedev.h

@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _UAPI_QCEDEV__H
+#define _UAPI_QCEDEV__H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define QCEDEV_MAX_SHA_BLOCK_SIZE	64
+#define QCEDEV_MAX_BEARER	31
+#define QCEDEV_MAX_KEY_SIZE	64
+#define QCEDEV_MAX_IV_SIZE	32
+
+#define QCEDEV_MAX_BUFFERS      16
+#define QCEDEV_MAX_SHA_DIGEST	32
+
+#define QCEDEV_USE_PMEM		1
+#define QCEDEV_NO_PMEM		0
+
+#define QCEDEV_AES_KEY_128	16
+#define QCEDEV_AES_KEY_192	24
+#define QCEDEV_AES_KEY_256	32
+/**
+ *qcedev_oper_enum: Operation types
+ * @QCEDEV_OPER_ENC:		Encrypt
+ * @QCEDEV_OPER_DEC:		Decrypt
+ * @QCEDEV_OPER_ENC_NO_KEY:	Encrypt. Do not need key to be specified by
+ *				user. Key already set by an external processor.
+ * @QCEDEV_OPER_DEC_NO_KEY:	Decrypt. Do not need the key to be specified by
+ *				user. Key already set by an external processor.
+ */
+enum qcedev_oper_enum {
+	QCEDEV_OPER_DEC		= 0,
+	QCEDEV_OPER_ENC		= 1,
+	QCEDEV_OPER_DEC_NO_KEY	= 2,
+	QCEDEV_OPER_ENC_NO_KEY	= 3,
+	QCEDEV_OPER_LAST
+};
+
+/**
+ *qcedev_offload_oper_enum: Offload operation types (uses pipe keys)
+ * @QCEDEV_OFFLOAD_HLOS_HLOS:   Non-secure to non-secure (eg. audio dec).
+ * @QCEDEV_OFFLOAD_HLOS_CPB:    Non-secure to secure (eg. video dec).
+ * @QCEDEV_OFFLOAD_CPB_HLOS:    Secure to non-secure (eg. hdcp video enc).
+ */
+enum qcedev_offload_oper_enum {
+	QCEDEV_OFFLOAD_HLOS_HLOS = 1,
+	QCEDEV_OFFLOAD_HLOS_HLOS_1 = 2,
+	QCEDEV_OFFLOAD_HLOS_CPB = 3,
+	QCEDEV_OFFLOAD_HLOS_CPB_1 = 4,
+	QCEDEV_OFFLOAD_CPB_HLOS = 5,
+	QCEDEV_OFFLOAD_OPER_LAST
+};
+
+/**
+ *qcedev_offload_err_enum: Offload error conditions
+ * @QCEDEV_OFFLOAD_NO_ERROR:        Successful crypto operation.
+ * @QCEDEV_OFFLOAD_GENERIC_ERROR:   Generic error in crypto status.
+ * @QCEDEV_OFFLOAD_TIMER_EXPIRED_ERROR:     Pipe key timer expired.
+ * @QCEDEV_OFFLOAD_KEY_PAUSE_ERROR:     Pipe key pause (means GPCE is paused).
+ */
+enum qcedev_offload_err_enum {
+	QCEDEV_OFFLOAD_NO_ERROR = 0,
+	QCEDEV_OFFLOAD_GENERIC_ERROR = 1,
+	QCEDEV_OFFLOAD_KEY_TIMER_EXPIRED_ERROR = 2,
+	QCEDEV_OFFLOAD_KEY_PAUSE_ERROR = 3
+};
+
+/**
+ *qcedev_oper_enum: Cipher algorithm types
+ * @QCEDEV_ALG_DES:		DES
+ * @QCEDEV_ALG_3DES:		3DES
+ * @QCEDEV_ALG_AES:		AES
+ */
+enum qcedev_cipher_alg_enum {
+	QCEDEV_ALG_DES		= 0,
+	QCEDEV_ALG_3DES		= 1,
+	QCEDEV_ALG_AES		= 2,
+	QCEDEV_ALG_LAST
+};
+
+/**
+ *qcedev_cipher_mode_enum : AES mode
+ * @QCEDEV_AES_MODE_CBC:		CBC
+ * @QCEDEV_AES_MODE_ECB:		ECB
+ * @QCEDEV_AES_MODE_CTR:		CTR
+ * @QCEDEV_AES_MODE_XTS:		XTS
+ * @QCEDEV_AES_MODE_CCM:		CCM
+ * @QCEDEV_DES_MODE_CBC:		CBC
+ * @QCEDEV_DES_MODE_ECB:		ECB
+ */
+enum qcedev_cipher_mode_enum {
+	QCEDEV_AES_MODE_CBC	= 0,
+	QCEDEV_AES_MODE_ECB	= 1,
+	QCEDEV_AES_MODE_CTR	= 2,
+	QCEDEV_AES_MODE_XTS	= 3,
+	QCEDEV_AES_MODE_CCM	= 4,
+	QCEDEV_DES_MODE_CBC	= 5,
+	QCEDEV_DES_MODE_ECB	= 6,
+	QCEDEV_AES_DES_MODE_LAST
+};
+
+/**
+ *enum qcedev_sha_alg_enum : Secure Hashing Algorithm
+ * @QCEDEV_ALG_SHA1:		Digest returned: 20 bytes (160 bits)
+ * @QCEDEV_ALG_SHA256:		Digest returned: 32 bytes (256 bit)
+ * @QCEDEV_ALG_SHA1_HMAC:	HMAC returned 20 bytes (160 bits)
+ * @QCEDEV_ALG_SHA256_HMAC:	HMAC returned 32 bytes (256 bit)
+ * @QCEDEV_ALG_AES_CMAC:		Configurable MAC size
+ */
+enum qcedev_sha_alg_enum {
+	QCEDEV_ALG_SHA1		= 0,
+	QCEDEV_ALG_SHA256	= 1,
+	QCEDEV_ALG_SHA1_HMAC	= 2,
+	QCEDEV_ALG_SHA256_HMAC	= 3,
+	QCEDEV_ALG_AES_CMAC	= 4,
+	QCEDEV_ALG_SHA_ALG_LAST
+};
+
+/**
+ * struct buf_info - Buffer information
+ * @offset:			Offset from the base address of the buffer
+ *				(Used when buffer is allocated using PMEM)
+ * @vaddr:			Virtual buffer address pointer
+ * @len:				Size of the buffer
+ */
+struct	buf_info {
+	union {
+		__u32	offset;
+		__u8		*vaddr;
+	};
+	__u32	len;
+};
+
+/**
+ * struct qcedev_vbuf_info - Source and destination Buffer information
+ * @src:				Array of buf_info for input/source
+ * @dst:				Array of buf_info for output/destination
+ */
+struct	qcedev_vbuf_info {
+	struct buf_info	src[QCEDEV_MAX_BUFFERS];
+	struct buf_info	dst[QCEDEV_MAX_BUFFERS];
+};
+
+/**
+ * struct qcedev_pmem_info - Stores PMEM buffer information
+ * @fd_src:			Handle to /dev/adsp_pmem used to allocate
+ *				memory for input/src buffer
+ * @src:				Array of buf_info for input/source
+ * @fd_dst:			Handle to /dev/adsp_pmem used to allocate
+ *				memory for output/dst buffer
+ * @dst:				Array of buf_info for output/destination
+ * @pmem_src_offset:		The offset from input/src buffer
+ *				(allocated by PMEM)
+ */
+struct	qcedev_pmem_info {
+	int		fd_src;
+	struct buf_info	src[QCEDEV_MAX_BUFFERS];
+	int		fd_dst;
+	struct buf_info	dst[QCEDEV_MAX_BUFFERS];
+};
+
+/**
+ * struct qcedev_cipher_op_req - Holds the ciphering request information
+ * @use_pmem (IN):	Flag to indicate if buffer source is PMEM
+ *			QCEDEV_USE_PMEM/QCEDEV_NO_PMEM
+ * @pmem (IN):		Stores PMEM buffer information.
+ *			Refer struct qcedev_pmem_info
+ * @vbuf (IN/OUT):	Stores Source and destination Buffer information
+ *			Refer to struct qcedev_vbuf_info
+ * @data_len (IN):	Total Length of input/src and output/dst in bytes
+ * @in_place_op (IN):	Indicates whether the operation is inplace where
+ *			source == destination
+ *			When using PMEM allocated memory, must set this to 1
+ * @enckey (IN):		128 bits of confidentiality key
+ *			enckey[0] bit 127-120, enckey[1] bit 119-112,..
+ *			enckey[15] bit 7-0
+ * @encklen (IN):	Length of the encryption key(set to 128  bits/16
+ *			bytes in the driver)
+ * @iv (IN/OUT):		Initialisation vector data
+ *			This is updated by the driver, incremented by
+ *			number of blocks encrypted/decrypted.
+ * @ivlen (IN):		Length of the IV
+ * @byteoffset (IN):	Offset in the Cipher BLOCK (applicable and to be set
+ *			for AES-128 CTR mode only)
+ * @alg (IN):		Type of ciphering algorithm: AES/DES/3DES
+ * @mode (IN):		Mode use when using AES algorithm: ECB/CBC/CTR
+ *			Apllicabel when using AES algorithm only
+ * @op (IN):		Type of operation: QCEDEV_OPER_DEC/QCEDEV_OPER_ENC or
+ *			QCEDEV_OPER_ENC_NO_KEY/QCEDEV_OPER_DEC_NO_KEY
+ *
+ *If use_pmem is set to 0, the driver assumes that memory was not allocated
+ * via PMEM, and kernel will need to allocate memory and copy data from user
+ * space buffer (data_src/dta_dst) and process accordingly and copy data back
+ * to the user space buffer
+ *
+ * If use_pmem is set to 1, the driver assumes that memory was allocated via
+ * PMEM.
+ * The kernel driver will use the fd_src to determine the kernel virtual address
+ * base that maps to the user space virtual address base for the  buffer
+ * allocated in user space.
+ * The final input/src and output/dst buffer pointer will be determined
+ * by adding the offsets to the kernel virtual addr.
+ *
+ * If use of hardware key is supported in the target, user can configure the
+ * key parameters (encklen, enckey) to use the hardware key.
+ * In order to use the hardware key, set encklen to 0 and set the enckey
+ * data array to 0.
+ */
+struct	qcedev_cipher_op_req {
+	__u8				use_pmem;
+	union {
+		struct qcedev_pmem_info	pmem;
+		struct qcedev_vbuf_info	vbuf;
+	};
+	__u32			entries;
+	__u32			data_len;
+	__u8				in_place_op;
+	__u8				enckey[QCEDEV_MAX_KEY_SIZE];
+	__u32			encklen;
+	__u8				iv[QCEDEV_MAX_IV_SIZE];
+	__u32			ivlen;
+	__u32			byteoffset;
+	enum qcedev_cipher_alg_enum	alg;
+	enum qcedev_cipher_mode_enum	mode;
+	enum qcedev_oper_enum		op;
+};
+
+/**
+ * struct qcedev_sha_op_req - Holds the hashing request information
+ * @data (IN):			Array of pointers to the data to be hashed
+ * @entries (IN):		Number of buf_info entries in the data array
+ * @data_len (IN):		Length of data to be hashed
+ * @digest (IN/OUT):		Returns the hashed data information
+ * @diglen (OUT):		Size of the hashed/digest data
+ * @authkey (IN):		Pointer to authentication key for HMAC
+ * @authklen (IN):		Size of the authentication key
+ * @alg (IN):			Secure Hash algorithm
+ */
+struct	qcedev_sha_op_req {
+	struct buf_info			data[QCEDEV_MAX_BUFFERS];
+	__u32			entries;
+	__u32			data_len;
+	__u8				digest[QCEDEV_MAX_SHA_DIGEST];
+	__u32			diglen;
+	__u8				*authkey;
+	__u32			authklen;
+	enum qcedev_sha_alg_enum	alg;
+};
+
+/**
+ * struct pattern_info - Holds pattern information for pattern-based
+ * decryption/encryption for AES ECB, counter, and CBC modes.
+ * @patt_sz (IN):       Total number of blocks.
+ * @proc_data_sz (IN):  Number of blocks to be processed.
+ * @patt_offset (IN):   Start of the segment.
+ */
+struct pattern_info {
+	__u8 patt_sz;
+	__u8 proc_data_sz;
+	__u8 patt_offset;
+};
+
+/**
+ * struct qcedev_offload_cipher_op_req - Holds the offload request information
+ * @vbuf (IN/OUT):      Stores Source and destination Buffer information.
+ *                      Refer to struct qcedev_vbuf_info.
+ * @entries (IN):       Number of entries to be processed as part of request.
+ * @data_len (IN):      Total Length of input/src and output/dst in bytes
+ * @in_place_op (IN):   Indicates whether the operation is inplace where
+ *                      source == destination.
+ * @encklen (IN):       Length of the encryption key(set to 128  bits/16
+ *                      bytes in the driver).
+ * @iv (IN/OUT):        Initialisation vector data
+ *                      This is updated by the driver, incremented by
+ *                      number of blocks encrypted/decrypted.
+ * @ivlen (IN):         Length of the IV.
+ * @iv_ctr_size (IN):   IV counter increment mask size.
+ *                      Driver sets the mask value based on this size.
+ * @byteoffset (IN):    Offset in the Cipher BLOCK (applicable and to be set
+ *                      for AES-128 CTR mode only).
+ * @block_offset (IN):  Offset in the block that needs a skip of encrypt/
+ *                      decrypt.
+ * @pattern_valid (IN): Indicates the request contains a valid pattern.
+ * @pattern_info (IN):  The pattern to be used for the offload request.
+ * @is_copy_op (IN):    Offload operations sometimes requires a copy between
+ *                      secure and non-secure buffers without any encrypt/
+ *                      decrypt operations.
+ * @alg (IN):           Type of ciphering algorithm: AES/DES/3DES.
+ * @mode (IN):          Mode use when using AES algorithm: ECB/CBC/CTR.
+ *                      Applicable when using AES algorithm only.
+ * @op (IN):            Type of operation.
+ *                      Refer to qcedev_offload_oper_enum.
+ * @err (OUT):          Error in crypto status.
+ *                      Refer to qcedev_offload_err_enum.
+ */
+struct qcedev_offload_cipher_op_req {
+	struct qcedev_vbuf_info vbuf;
+	__u32 entries;
+	__u32 data_len;
+	__u32 in_place_op;
+	__u32 encklen;
+	__u8 iv[QCEDEV_MAX_IV_SIZE];
+	__u32 ivlen;
+	__u32 iv_ctr_size;
+	__u32 byteoffset;
+	__u8 block_offset;
+	__u8 is_pattern_valid;
+	__u8 is_copy_op;
+	__u8 encrypt;
+	struct pattern_info pattern_info;
+	enum qcedev_cipher_alg_enum alg;
+	enum qcedev_cipher_mode_enum mode;
+	enum qcedev_offload_oper_enum op;
+	enum qcedev_offload_err_enum err;
+};
+
+/**
+ * struct qfips_verify_t - Holds data for FIPS Integrity test
+ * @kernel_size  (IN):		Size of kernel Image
+ * @kernel       (IN):		pointer to buffer containing the kernel Image
+ */
+struct qfips_verify_t {
+	unsigned int kernel_size;
+	void *kernel;
+};
+
+/**
+ * struct qcedev_map_buf_req - Holds the mapping request information
+ * fd (IN):            Array of fds.
+ * num_fds (IN):       Number of fds in fd[].
+ * fd_size (IN):       Array of sizes corresponding to each fd in fd[].
+ * fd_offset (IN):     Array of offset corresponding to each fd in fd[].
+ * vaddr (OUT):        Array of mapped virtual address corresponding to
+ *			each fd in fd[].
+ */
+struct qcedev_map_buf_req {
+	__s32         fd[QCEDEV_MAX_BUFFERS];
+	__u32        num_fds;
+	__u32        fd_size[QCEDEV_MAX_BUFFERS];
+	__u32        fd_offset[QCEDEV_MAX_BUFFERS];
+	__u64        buf_vaddr[QCEDEV_MAX_BUFFERS];
+};
+
+/**
+ * struct qcedev_unmap_buf_req - Holds the hashing request information
+ * fd (IN):            Array of fds to unmap
+ * num_fds (IN):       Number of fds in fd[].
+ */
+struct  qcedev_unmap_buf_req {
+	__s32         fd[QCEDEV_MAX_BUFFERS];
+	__u32        num_fds;
+};
+
+struct file;
+
+#define QCEDEV_IOC_MAGIC	0x87
+
+#define QCEDEV_IOCTL_ENC_REQ		\
+	_IOWR(QCEDEV_IOC_MAGIC, 1, struct qcedev_cipher_op_req)
+#define QCEDEV_IOCTL_DEC_REQ		\
+	_IOWR(QCEDEV_IOC_MAGIC, 2, struct qcedev_cipher_op_req)
+#define QCEDEV_IOCTL_SHA_INIT_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 3, struct qcedev_sha_op_req)
+#define QCEDEV_IOCTL_SHA_UPDATE_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 4, struct qcedev_sha_op_req)
+#define QCEDEV_IOCTL_SHA_FINAL_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 5, struct qcedev_sha_op_req)
+#define QCEDEV_IOCTL_GET_SHA_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 6, struct qcedev_sha_op_req)
+#define QCEDEV_IOCTL_LOCK_CE	\
+	_IO(QCEDEV_IOC_MAGIC, 7)
+#define QCEDEV_IOCTL_UNLOCK_CE	\
+	_IO(QCEDEV_IOC_MAGIC, 8)
+#define QCEDEV_IOCTL_GET_CMAC_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 9, struct qcedev_sha_op_req)
+#define QCEDEV_IOCTL_MAP_BUF_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 10, struct qcedev_map_buf_req)
+#define QCEDEV_IOCTL_UNMAP_BUF_REQ	\
+	_IOWR(QCEDEV_IOC_MAGIC, 11, struct qcedev_unmap_buf_req)
+#define QCEDEV_IOCTL_OFFLOAD_OP_REQ		\
+	_IOWR(QCEDEV_IOC_MAGIC, 12, struct qcedev_offload_cipher_op_req)
+#endif /* _UAPI_QCEDEV__H */

+ 1 - 0
linux/qcota.h → include/uapi/linux/qcota.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _UAPI_QCOTA_H

+ 1 - 1
linux/qrng.h → include/uapi/linux/qrng.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #ifndef _UAPI_QRNG_H_
 #define _UAPI_QRNG_H_

+ 186 - 0
include/uapi/linux/qseecom.h

@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2017, 2019, 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QSEECOM_H_
+#define _QSEECOM_H_
+
+#pragma message("Warning: This header file will be deprecated in future")
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define MAX_ION_FD  4
+#define MAX_APP_NAME_SIZE  64
+#define QSEECOM_HASH_SIZE  32
+
+#define ICE_KEY_SIZE 32
+#define ICE_SALT_SIZE 32
+
+/*
+ * struct qseecom_ion_fd_info - ion fd handle data information
+ * @fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct qseecom_ion_fd_info {
+	__s32 fd;
+	__u32 cmd_buf_offset;
+};
+
+enum qseecom_key_management_usage_type {
+	QSEOS_KM_USAGE_DISK_ENCRYPTION = 0x01,
+	QSEOS_KM_USAGE_FILE_ENCRYPTION = 0x02,
+	QSEOS_KM_USAGE_UFS_ICE_DISK_ENCRYPTION = 0x03,
+	QSEOS_KM_USAGE_SDCC_ICE_DISK_ENCRYPTION = 0x04,
+	QSEOS_KM_USAGE_MAX
+};
+
+struct qseecom_create_key_req {
+	unsigned char hash32[QSEECOM_HASH_SIZE];
+	enum qseecom_key_management_usage_type usage;
+};
+
+struct qseecom_wipe_key_req {
+	enum qseecom_key_management_usage_type usage;
+	int wipe_key_flag;/* 1->remove key from storage(alone with clear key) */
+			  /* 0->do not remove from storage (clear key) */
+};
+
+struct qseecom_update_key_userinfo_req {
+	unsigned char current_hash32[QSEECOM_HASH_SIZE];
+	unsigned char new_hash32[QSEECOM_HASH_SIZE];
+	enum qseecom_key_management_usage_type usage;
+};
+
+#define SHA256_DIGEST_LENGTH	(256/8)
+/*
+ * struct qseecom_save_partition_hash_req
+ * @partition_id - partition id.
+ * @hash[SHA256_DIGEST_LENGTH] -  sha256 digest.
+ */
+struct qseecom_save_partition_hash_req {
+	int partition_id; /* in */
+	char digest[SHA256_DIGEST_LENGTH]; /* in */
+};
+
+/*
+ * struct qseecom_is_es_activated_req
+ * @is_activated - 1=true , 0=false
+ */
+struct qseecom_is_es_activated_req {
+	int is_activated; /* out */
+};
+
+/*
+ * struct qseecom_mdtp_cipher_dip_req
+ * @in_buf - input buffer
+ * @in_buf_size - input buffer size
+ * @out_buf - output buffer
+ * @out_buf_size - output buffer size
+ * @direction - 0=encrypt, 1=decrypt
+ */
+struct qseecom_mdtp_cipher_dip_req {
+	__u8 *in_buf;
+	__u32 in_buf_size;
+	__u8 *out_buf;
+	__u32 out_buf_size;
+	__u32 direction;
+};
+
+struct qseecom_qteec_req {
+	void    *req_ptr;
+	__u32    req_len;
+	void    *resp_ptr;
+	__u32    resp_len;
+};
+
+struct qseecom_qteec_modfd_req {
+	void    *req_ptr;
+	__u32    req_len;
+	void    *resp_ptr;
+	__u32    resp_len;
+	struct qseecom_ion_fd_info ifd_data[MAX_ION_FD];
+};
+
+#define MAX_CE_PIPE_PAIR_PER_UNIT 3
+
+struct qseecom_ce_pipe_entry {
+	int valid;
+	unsigned int ce_num;
+	unsigned int ce_pipe_pair;
+};
+
+struct qseecom_ice_data_t {
+	int flag;
+};
+
+#define MAX_CE_INFO_HANDLE_SIZE 32
+struct qseecom_ce_info_req {
+	unsigned char handle[MAX_CE_INFO_HANDLE_SIZE];
+	unsigned int usage;
+	unsigned int unit_num;
+	unsigned int num_ce_pipe_entries;
+	struct qseecom_ce_pipe_entry ce_pipe_entry[MAX_CE_PIPE_PAIR_PER_UNIT];
+};
+
+struct qseecom_ice_key_data_t {
+	__u8 key[ICE_KEY_SIZE];
+	__u32 key_len;
+	__u8 salt[ICE_SALT_SIZE];
+	__u32 salt_len;
+};
+
+struct file;
+
+
+#define QSEECOM_IOC_MAGIC    0x97
+
+
+#define QSEECOM_IOCTL_CREATE_KEY_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 17, struct qseecom_create_key_req)
+
+#define QSEECOM_IOCTL_WIPE_KEY_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 18, struct qseecom_wipe_key_req)
+
+#define QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 19, struct qseecom_save_partition_hash_req)
+
+#define QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 20, struct qseecom_is_es_activated_req)
+
+#define QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 24, struct qseecom_update_key_userinfo_req)
+
+#define QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 30, struct qseecom_qteec_modfd_req)
+
+#define QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 31, struct qseecom_qteec_req)
+
+#define QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 32, struct qseecom_qteec_modfd_req)
+
+#define QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 33, struct qseecom_qteec_modfd_req)
+
+#define QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 34, struct qseecom_mdtp_cipher_dip_req)
+
+#define QSEECOM_IOCTL_GET_CE_PIPE_INFO \
+	_IOWR(QSEECOM_IOC_MAGIC, 40, struct qseecom_ce_info_req)
+
+#define QSEECOM_IOCTL_FREE_CE_PIPE_INFO \
+	_IOWR(QSEECOM_IOC_MAGIC, 41, struct qseecom_ce_info_req)
+
+#define QSEECOM_IOCTL_QUERY_CE_PIPE_INFO \
+	_IOWR(QSEECOM_IOC_MAGIC, 42, struct qseecom_ce_info_req)
+
+#define QSEECOM_IOCTL_SET_ICE_INFO \
+	_IOWR(QSEECOM_IOC_MAGIC, 43, struct qseecom_ice_data_t)
+
+#define QSEECOM_IOCTL_FBE_CLEAR_KEY \
+	_IOWR(QSEECOM_IOC_MAGIC, 44, struct qseecom_ice_key_data_t)
+
+#endif /* _QSEECOM_H_ */

+ 196 - 0
include/uapi/linux/qseecom_api.h

@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2017, 2019, 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QSEECOM_API_H_
+#define _QSEECOM_API_H_
+
+#pragma message("Warning: This header file will be deprecated in future")
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include "qseecom.h"
+
+/*
+ * struct qseecom_register_listener_req -
+ *      for register listener ioctl request
+ * @listener_id - service id (shared between userspace and QSE)
+ * @ifd_data_fd - ion handle
+ * @virt_sb_base - shared buffer base in user space
+ * @sb_size - shared buffer size
+ */
+struct qseecom_register_listener_req {
+	__u32 listener_id; /* in */
+	__s32 ifd_data_fd; /* in */
+	void *virt_sb_base; /* in */
+	__u32 sb_size; /* in */
+};
+
+/*
+ * struct qseecom_send_cmd_req - for send command ioctl request
+ * @cmd_req_len - command buffer length
+ * @cmd_req_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ */
+struct qseecom_send_cmd_req {
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+};
+
+/*
+ * struct qseecom_send_modfd_cmd_req - for send command ioctl request
+ * @cmd_req_len - command buffer length
+ * @cmd_req_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ * @ifd_data_fd - ion handle to memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct qseecom_send_modfd_cmd_req {
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+	struct qseecom_ion_fd_info ifd_data[MAX_ION_FD];
+};
+
+/*
+ * struct qseecom_load_img_data - for sending image length information and
+ * ion file descriptor to the qseecom driver. ion file descriptor is used
+ * for retrieving the ion file handle and in turn the physical address of
+ * the image location.
+ * @mdt_len - Length of the .mdt file in bytes.
+ * @img_len - Length of the .mdt + .b00 +..+.bxx images files in bytes
+ * @ion_fd - Ion file descriptor used when allocating memory.
+ * @img_name - Name of the image.
+ * @app_arch - Architecture of the image, i.e. 32bit or 64bit app
+ */
+struct qseecom_load_img_req {
+	__u32 mdt_len; /* in */
+	__u32 img_len; /* in */
+	__s32  ifd_data_fd; /* in */
+	char	 img_name[MAX_APP_NAME_SIZE]; /* in */
+	__u32 app_arch; /* in */
+	__u32 app_id; /* out*/
+};
+
+struct qseecom_set_sb_mem_param_req {
+	__s32 ifd_data_fd; /* in */
+	void *virt_sb_base; /* in */
+	__u32 sb_len; /* in */
+};
+
+/*
+ * struct qseecom_qseos_version_req - get qseos version
+ * @qseos_version - version number
+ */
+struct qseecom_qseos_version_req {
+	unsigned int qseos_version; /* in */
+};
+
+/*
+ * struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
+ * @app_name[MAX_APP_NAME_SIZE]-  name of the app.
+ * @app_id - app id.
+ */
+struct qseecom_qseos_app_load_query {
+	char app_name[MAX_APP_NAME_SIZE]; /* in */
+	__u32 app_id; /* out */
+	__u32 app_arch;
+};
+
+struct qseecom_send_svc_cmd_req {
+	__u32 cmd_id;
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+};
+
+/*
+ * struct qseecom_send_modfd_resp - for send command ioctl request
+ * @req_len - command buffer length
+ * @req_buf - command buffer
+ * @ifd_data_fd - ion handle to memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct qseecom_send_modfd_listener_resp {
+	void *resp_buf_ptr; /* in */
+	unsigned int resp_len; /* in */
+	struct qseecom_ion_fd_info ifd_data[MAX_ION_FD]; /* in */
+};
+
+struct qseecom_sg_entry {
+	__u32 phys_addr;
+	__u32 len;
+};
+
+struct qseecom_sg_entry_64bit {
+	__u64 phys_addr;
+	__u32 len;
+} __attribute__ ((packed));
+
+
+struct file;
+
+
+#define QSEECOM_IOC_MAGIC    0x97
+
+
+#define QSEECOM_IOCTL_REGISTER_LISTENER_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 1, struct qseecom_register_listener_req)
+
+#define QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ \
+	_IO(QSEECOM_IOC_MAGIC, 2)
+
+#define QSEECOM_IOCTL_SEND_CMD_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 3, struct qseecom_send_cmd_req)
+
+#define QSEECOM_IOCTL_SEND_MODFD_CMD_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 4, struct qseecom_send_modfd_cmd_req)
+
+#define QSEECOM_IOCTL_RECEIVE_REQ \
+	_IO(QSEECOM_IOC_MAGIC, 5)
+
+#define QSEECOM_IOCTL_SEND_RESP_REQ \
+	_IO(QSEECOM_IOC_MAGIC, 6)
+
+#define QSEECOM_IOCTL_LOAD_APP_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 7, struct qseecom_load_img_req)
+
+#define QSEECOM_IOCTL_SET_MEM_PARAM_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 8, struct qseecom_set_sb_mem_param_req)
+
+#define QSEECOM_IOCTL_UNLOAD_APP_REQ \
+	_IO(QSEECOM_IOC_MAGIC, 9)
+
+#define QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 10, struct qseecom_qseos_version_req)
+
+#define QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 13, struct qseecom_load_img_req)
+
+#define QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ \
+	_IO(QSEECOM_IOC_MAGIC, 14)
+
+#define QSEECOM_IOCTL_APP_LOADED_QUERY_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 15, struct qseecom_qseos_app_load_query)
+
+#define QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 16, struct qseecom_send_svc_cmd_req)
+
+#define QSEECOM_IOCTL_SEND_MODFD_RESP \
+	_IOWR(QSEECOM_IOC_MAGIC, 21, struct qseecom_send_modfd_listener_resp)
+
+#define QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ \
+	_IOWR(QSEECOM_IOC_MAGIC, 35, struct qseecom_send_modfd_cmd_req)
+
+#define QSEECOM_IOCTL_SEND_MODFD_RESP_64 \
+	_IOWR(QSEECOM_IOC_MAGIC, 36, struct qseecom_send_modfd_listener_resp)
+
+#endif /* _QSEECOM_API_H_ */

+ 110 - 0
include/uapi/linux/smcinvoke.h

@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _UAPI_SMCINVOKE_H_
+#define _UAPI_SMCINVOKE_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define SMCINVOKE_USERSPACE_OBJ_NULL	-1
+#define DEFAULT_CB_OBJ_THREAD_CNT	4
+#define SMCINVOKE_TZ_MIN_BUF_SIZE	4096
+
+struct smcinvoke_buf {
+	__u64 addr;
+	__u64 size;
+};
+
+struct smcinvoke_obj {
+	__s64 fd;
+	__s64 cb_server_fd;
+	__s64 reserved;
+};
+
+union smcinvoke_arg {
+	struct smcinvoke_buf b;
+	struct smcinvoke_obj o;
+};
+
+/*
+ * struct smcinvoke_cmd_req: This structure is transparently sent to TEE
+ * @op - Operation to be performed
+ * @counts - number of aruments passed
+ * @result - result of invoke operation
+ * @argsize - size of each of arguments
+ * @args - args is pointer to buffer having all arguments
+ * @reserved: IN/OUT: Usage is not defined but should be set to 0
+ */
+struct smcinvoke_cmd_req {
+	__u32 op;
+	__u32 counts;
+	__s32 result;
+	__u32 argsize;
+	__u64 args;
+	__s64 reserved;
+};
+
+/*
+ * struct smcinvoke_accept: structure to process CB req from TEE
+ * @has_resp: IN: Whether IOCTL is carrying response data
+ * @result: IN: Outcome of operation op
+ * @op: OUT: Operation to be performed on target object
+ * @counts: OUT: Number of arguments, embedded in buffer pointed by
+ *               buf_addr, to complete operation
+ * @reserved: IN/OUT: Usage is not defined but should be set to 0.
+ * @argsize: IN: Size of any argument, all of equal size, embedded
+ *               in buffer pointed by buf_addr
+ * @txn_id: OUT: An id that should be passed as it is for response
+ * @cbobj_id: OUT: Callback object which is target of operation op
+ * @buf_len: IN: Len of buffer pointed by buf_addr
+ * @buf_addr: IN: Buffer containing all arguments which are needed
+ *                to complete operation op
+ */
+struct smcinvoke_accept {
+	__u32 has_resp;
+	__s32 result;
+	__u32 op;
+	__u32 counts;
+	__s32 reserved;
+	__u32 argsize;
+	__u64 txn_id;
+	__s64 cbobj_id;
+	__u64 buf_len;
+	__u64 buf_addr;
+};
+
+/*
+ * @cb_buf_size: IN: Max buffer size for any callback obj implemented by client
+ * @reserved: IN/OUT: Usage is not defined but should be set to 0
+ */
+struct smcinvoke_server {
+	__u64 cb_buf_size;
+	__s64 reserved;
+};
+
+#define SMCINVOKE_IOC_MAGIC    0x98
+
+#define SMCINVOKE_IOCTL_INVOKE_REQ \
+	_IOWR(SMCINVOKE_IOC_MAGIC, 1, struct smcinvoke_cmd_req)
+
+#define SMCINVOKE_IOCTL_ACCEPT_REQ \
+	_IOWR(SMCINVOKE_IOC_MAGIC, 2, struct smcinvoke_accept)
+
+#define SMCINVOKE_IOCTL_SERVER_REQ \
+	_IOWR(SMCINVOKE_IOC_MAGIC, 3, struct smcinvoke_server)
+
+#define SMCINVOKE_IOCTL_ACK_LOCAL_OBJ \
+	_IOWR(SMCINVOKE_IOC_MAGIC, 4, __s64)
+
+/*
+  * smcinvoke logging buffer is for communicating with the smcinvoke driver additional
+  * info for debugging to be included in driver's log (if any)
+  */
+#define SMCINVOKE_LOG_BUF_SIZE 100
+#define SMCINVOKE_IOCTL_LOG \
+	_IOC(_IOC_READ|_IOC_WRITE, SMCINVOKE_IOC_MAGIC, 255, SMCINVOKE_LOG_BUF_SIZE)
+
+#endif /* _UAPI_SMCINVOKE_H_ */

+ 3 - 2
linux/misc/qseecom_priv.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __QSEECOM_PRIV_H_
@@ -18,8 +18,9 @@ static inline int qseecom_process_listener_from_smcinvoke(uint32_t *result,
 {
         return -EOPNOTSUPP;
 }
-#endif
 
 int get_qseecom_kernel_fun_ops(void);
+#endif
+
 
 #endif

+ 740 - 0
linux/misc/qseecomi.h

@@ -0,0 +1,740 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __QSEECOMI_H_
+#define __QSEECOMI_H_
+
+/* we need to include qseecom.h present in securemsm-kernel */
+#include "../../include/uapi/linux/qseecom.h"
+
+#define QSEECOM_KEY_ID_SIZE   32
+
+#define QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD  -19   /*0xFFFFFFED*/
+#define QSEOS_RESULT_FAIL_UNSUPPORTED_CE_PIPE -63
+#define QSEOS_RESULT_FAIL_KS_OP               -64
+#define QSEOS_RESULT_FAIL_KEY_ID_EXISTS       -65
+#define QSEOS_RESULT_FAIL_MAX_KEYS            -66
+#define QSEOS_RESULT_FAIL_SAVE_KS             -67
+#define QSEOS_RESULT_FAIL_LOAD_KS             -68
+#define QSEOS_RESULT_FAIL_KS_ALREADY_DONE     -69
+#define QSEOS_RESULT_FAIL_KEY_ID_DNE          -70
+#define QSEOS_RESULT_FAIL_INCORRECT_PSWD      -71
+#define QSEOS_RESULT_FAIL_MAX_ATTEMPT         -72
+#define QSEOS_RESULT_FAIL_PENDING_OPERATION   -73
+
+#define SMCINVOKE_RESULT_INBOUND_REQ_NEEDED	3
+
+enum qseecom_command_scm_resp_type {
+	QSEOS_APP_ID = 0xEE01,
+	QSEOS_LISTENER_ID
+};
+
+enum qseecom_qceos_cmd_id {
+	QSEOS_APP_START_COMMAND      = 0x01,
+	QSEOS_APP_SHUTDOWN_COMMAND,
+	QSEOS_APP_LOOKUP_COMMAND,
+	QSEOS_REGISTER_LISTENER,
+	QSEOS_DEREGISTER_LISTENER,
+	QSEOS_CLIENT_SEND_DATA_COMMAND,
+	QSEOS_LISTENER_DATA_RSP_COMMAND,
+	QSEOS_LOAD_EXTERNAL_ELF_COMMAND,
+	QSEOS_UNLOAD_EXTERNAL_ELF_COMMAND,
+	QSEOS_GET_APP_STATE_COMMAND,
+	QSEOS_LOAD_SERV_IMAGE_COMMAND,
+	QSEOS_UNLOAD_SERV_IMAGE_COMMAND,
+	QSEOS_APP_REGION_NOTIFICATION,
+	QSEOS_REGISTER_LOG_BUF_COMMAND,
+	QSEOS_RPMB_PROVISION_KEY_COMMAND,
+	QSEOS_RPMB_ERASE_COMMAND,
+	QSEOS_GENERATE_KEY  = 0x11,
+	QSEOS_DELETE_KEY,
+	QSEOS_MAX_KEY_COUNT,
+	QSEOS_SET_KEY,
+	QSEOS_UPDATE_KEY_USERINFO,
+	QSEOS_TEE_OPEN_SESSION,
+	QSEOS_TEE_INVOKE_COMMAND,
+	QSEOS_TEE_INVOKE_MODFD_COMMAND = QSEOS_TEE_INVOKE_COMMAND,
+	QSEOS_TEE_CLOSE_SESSION,
+	QSEOS_TEE_REQUEST_CANCELLATION,
+	QSEOS_CONTINUE_BLOCKED_REQ_COMMAND,
+	QSEOS_RPMB_CHECK_PROV_STATUS_COMMAND = 0x1B,
+	QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C,
+	QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D,
+	QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E,
+	QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F,
+	QSEOS_FSM_LTEOTA_REQ_CMD = 0x109,
+	QSEOS_FSM_LTEOTA_REQ_RSP_CMD = 0x110,
+	QSEOS_FSM_IKE_REQ_CMD = 0x203,
+	QSEOS_FSM_IKE_REQ_RSP_CMD = 0x204,
+	QSEOS_FSM_OEM_FUSE_WRITE_ROW = 0x301,
+	QSEOS_FSM_OEM_FUSE_READ_ROW = 0x302,
+	QSEOS_FSM_ENCFS_REQ_CMD = 0x403,
+	QSEOS_FSM_ENCFS_REQ_RSP_CMD = 0x404,
+	QSEOS_DIAG_FUSE_REQ_CMD = 0x501,
+	QSEOS_DIAG_FUSE_REQ_RSP_CMD = 0x502,
+	QSEOS_CMD_MAX     = 0xEFFFFFFF
+};
+
+enum qseecom_qceos_cmd_status {
+	QSEOS_RESULT_SUCCESS = 0,
+	QSEOS_RESULT_INCOMPLETE,
+	QSEOS_RESULT_BLOCKED_ON_LISTENER,
+	QSEOS_RESULT_CBACK_REQUEST,
+	QSEOS_RESULT_FAILURE  = 0xFFFFFFFF
+};
+
+enum qseecom_pipe_type {
+	QSEOS_PIPE_ENC = 0x1,
+	QSEOS_PIPE_ENC_XTS = 0x2,
+	QSEOS_PIPE_AUTH = 0x4,
+	QSEOS_PIPE_ENUM_FILL = 0x7FFFFFFF
+};
+
+/* QSEE Reentrancy support phase */
+enum qseecom_qsee_reentrancy_phase {
+	QSEE_REENTRANCY_PHASE_0 = 0,
+	QSEE_REENTRANCY_PHASE_1,
+	QSEE_REENTRANCY_PHASE_2,
+	QSEE_REENTRANCY_PHASE_3,
+	QSEE_REENTRANCY_PHASE_MAX = 0xFF
+};
+
+struct qsee_apps_region_info_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t addr;
+	uint32_t size;
+} __packed;
+
+struct qsee_apps_region_info_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint64_t addr;
+	uint32_t size;
+} __packed;
+
+struct qseecom_check_app_ireq {
+	uint32_t qsee_cmd_id;
+	char     app_name[MAX_APP_NAME_SIZE];
+} __packed;
+
+struct qseecom_load_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;		/* Length of the mdt file */
+	uint32_t img_len;		/* Length of .bxx and .mdt files */
+	uint32_t phy_addr;		/* phy addr of the start of image */
+	char     app_name[MAX_APP_NAME_SIZE];	/* application name*/
+} __packed;
+
+struct qseecom_load_app_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint64_t phy_addr;
+	char     app_name[MAX_APP_NAME_SIZE];
+} __packed;
+
+struct qseecom_unload_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  app_id;
+} __packed;
+
+struct qseecom_load_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint32_t phy_addr;
+} __packed;
+
+struct qseecom_load_lib_image_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint64_t phy_addr;
+} __packed;
+
+struct qseecom_unload_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+} __packed;
+
+struct qseecom_register_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t sb_ptr;
+	uint32_t sb_len;
+} __packed;
+
+struct qseecom_register_listener_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint64_t sb_ptr;
+	uint32_t sb_len;
+} __packed;
+
+struct qseecom_unregister_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  listener_id;
+} __packed;
+
+struct qseecom_client_send_data_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t app_id;
+	uint32_t req_ptr;
+	uint32_t req_len;
+	uint32_t rsp_ptr;/* First 4 bytes should be the return status */
+	uint32_t rsp_len;
+	uint32_t sglistinfo_ptr;
+	uint32_t sglistinfo_len;
+} __packed;
+
+struct qseecom_client_send_data_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t app_id;
+	uint64_t req_ptr;
+	uint32_t req_len;
+	uint64_t rsp_ptr;
+	uint32_t rsp_len;
+	uint64_t sglistinfo_ptr;
+	uint32_t sglistinfo_len;
+} __packed;
+
+struct qseecom_reg_log_buf_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t phy_addr;
+	uint32_t len;
+} __packed;
+
+struct qseecom_reg_log_buf_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint64_t phy_addr;
+	uint32_t len;
+} __packed;
+
+/* send_data resp */
+struct qseecom_client_listener_data_irsp {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t status;
+	uint32_t sglistinfo_ptr;
+	uint32_t sglistinfo_len;
+} __packed;
+
+struct qseecom_client_listener_data_64bit_irsp {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t status;
+	uint64_t sglistinfo_ptr;
+	uint32_t sglistinfo_len;
+} __packed;
+
+/*
+ * struct qseecom_command_scm_resp - qseecom response buffer
+ * @cmd_status: value from enum tz_sched_cmd_status
+ * @sb_in_rsp_addr: points to physical location of response
+ *                buffer
+ * @sb_in_rsp_len: length of command response
+ */
+struct qseecom_command_scm_resp {
+	uint32_t result;
+	enum qseecom_command_scm_resp_type resp_type;
+	unsigned int data;
+} __packed;
+
+struct qseecom_rpmb_provision_key {
+	uint32_t key_type;
+};
+
+struct qseecom_client_send_service_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t key_type; /* in */
+	unsigned int req_len; /* in */
+	uint32_t rsp_ptr; /* in/out */
+	unsigned int rsp_len; /* in/out */
+} __packed;
+
+struct qseecom_client_send_service_64bit_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t key_type;
+	unsigned int req_len;
+	uint64_t rsp_ptr;
+	unsigned int rsp_len;
+} __packed;
+
+struct qseecom_key_generate_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+} __packed;
+
+struct qseecom_key_select_ireq {
+	uint32_t qsee_command_id;
+	uint32_t ce;
+	uint32_t pipe;
+	uint32_t pipe_type;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+} __packed;
+
+struct qseecom_key_delete_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t hash32[QSEECOM_HASH_SIZE];
+
+} __packed;
+
+struct qseecom_key_userinfo_update_ireq {
+	uint32_t qsee_command_id;
+	uint32_t flags;
+	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
+	uint8_t current_hash32[QSEECOM_HASH_SIZE];
+	uint8_t new_hash32[QSEECOM_HASH_SIZE];
+} __packed;
+
+struct qseecom_key_max_count_query_ireq {
+	uint32_t flags;
+} __packed;
+
+struct qseecom_key_max_count_query_irsp {
+	uint32_t max_key_count;
+} __packed;
+
+struct qseecom_qteec_ireq {
+	uint32_t    qsee_cmd_id;
+	uint32_t    app_id;
+	uint32_t    req_ptr;
+	uint32_t    req_len;
+	uint32_t    resp_ptr;
+	uint32_t    resp_len;
+	uint32_t    sglistinfo_ptr;
+	uint32_t    sglistinfo_len;
+} __packed;
+
+struct qseecom_qteec_64bit_ireq {
+	uint32_t    qsee_cmd_id;
+	uint32_t    app_id;
+	uint64_t    req_ptr;
+	uint32_t    req_len;
+	uint64_t    resp_ptr;
+	uint32_t    resp_len;
+	uint64_t    sglistinfo_ptr;
+	uint32_t    sglistinfo_len;
+} __packed;
+
+struct qseecom_client_send_fsm_diag_req {
+	uint32_t qsee_cmd_id;
+	uint32_t req_ptr;
+	uint32_t req_len;
+	uint32_t rsp_ptr;
+	uint32_t rsp_len;
+} __packed;
+
+struct qseecom_continue_blocked_request_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t app_or_session_id; /*legacy: app_id; smcinvoke: session_id*/
+} __packed;
+
+/**********      ARMV8 SMC INTERFACE TZ MACRO     *******************/
+
+#define TZ_SVC_APP_MGR                   1     /* Application management */
+#define TZ_SVC_LISTENER                  2     /* Listener service management */
+#define TZ_SVC_EXTERNAL                  3     /* External image loading */
+#define TZ_SVC_RPMB                      4     /* RPMB */
+#define TZ_SVC_KEYSTORE                  5     /* Keystore management */
+#define TZ_SVC_FUSE                      8     /* Fuse services */
+#define TZ_SVC_ES                        16    /* Enterprise Security */
+#define TZ_SVC_MDTP                      18    /* Mobile Device Theft */
+
+/*----------------------------------------------------------------------------
+ * Owning Entity IDs (defined by ARM SMC doc)
+ * ---------------------------------------------------------------------------
+ */
+#define TZ_OWNER_ARM                     0     /** ARM Architecture call ID */
+#define TZ_OWNER_CPU                     1     /** CPU service call ID */
+#define TZ_OWNER_SIP                     2     /** SIP service call ID */
+#define TZ_OWNER_OEM                     3     /** OEM service call ID */
+#define TZ_OWNER_STD                     4     /** Standard service call ID */
+
+/** Values 5-47 are reserved for future use */
+
+/** Trusted Application call IDs */
+#define TZ_OWNER_TZ_APPS                 48
+#define TZ_OWNER_TZ_APPS_RESERVED        49
+/** Trusted OS Call IDs */
+#define TZ_OWNER_QSEE_OS                 50
+#define TZ_OWNER_MOBI_OS                 51
+#define TZ_OWNER_OS_RESERVED_3           52
+#define TZ_OWNER_OS_RESERVED_4           53
+#define TZ_OWNER_OS_RESERVED_5           54
+#define TZ_OWNER_OS_RESERVED_6           55
+#define TZ_OWNER_OS_RESERVED_7           56
+#define TZ_OWNER_OS_RESERVED_8           57
+#define TZ_OWNER_OS_RESERVED_9           58
+#define TZ_OWNER_OS_RESERVED_10          59
+#define TZ_OWNER_OS_RESERVED_11          60
+#define TZ_OWNER_OS_RESERVED_12          61
+#define TZ_OWNER_OS_RESERVED_13          62
+#define TZ_OWNER_OS_RESERVED_14          63
+
+#define TZ_SVC_INFO                      6    /* Misc. information services */
+
+/** Trusted Application call groups */
+#define TZ_SVC_APP_ID_PLACEHOLDER        0    /* SVC bits will contain App ID */
+
+/** General helper macro to create a bitmask from bits low to high. */
+#define TZ_MASK_BITS(h, l)     ((0xffffffff >> (32 - ((h - l) + 1))) << l)
+
+/*
+ * Macro used to define an SMC ID based on the owner ID,
+ * service ID, and function number.
+ */
+#define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \
+	((uint32_t)((((o & 0x3f) << 24) | (s & 0xff) << 8) | (f & 0xff)))
+
+#define TZ_SYSCALL_PARAM_NARGS_MASK  TZ_MASK_BITS(3, 0)
+#define TZ_SYSCALL_PARAM_TYPE_MASK   TZ_MASK_BITS(1, 0)
+
+#define TZ_SYSCALL_CREATE_PARAM_ID(nargs, p1, p2, p3, \
+	p4, p5, p6, p7, p8, p9, p10) \
+	((nargs&TZ_SYSCALL_PARAM_NARGS_MASK)+ \
+	((p1&TZ_SYSCALL_PARAM_TYPE_MASK)<<4)+ \
+	((p2&TZ_SYSCALL_PARAM_TYPE_MASK)<<6)+ \
+	((p3&TZ_SYSCALL_PARAM_TYPE_MASK)<<8)+ \
+	((p4&TZ_SYSCALL_PARAM_TYPE_MASK)<<10)+ \
+	((p5&TZ_SYSCALL_PARAM_TYPE_MASK)<<12)+ \
+	((p6&TZ_SYSCALL_PARAM_TYPE_MASK)<<14)+ \
+	((p7&TZ_SYSCALL_PARAM_TYPE_MASK)<<16)+ \
+	((p8&TZ_SYSCALL_PARAM_TYPE_MASK)<<18)+ \
+	((p9&TZ_SYSCALL_PARAM_TYPE_MASK)<<20)+ \
+	((p10&TZ_SYSCALL_PARAM_TYPE_MASK)<<22))
+
+/*
+ * Macros used to create the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_CREATE_PARAM_ID_0 0
+#define TZ_SYSCALL_CREATE_PARAM_ID_1(p1) \
+	TZ_SYSCALL_CREATE_PARAM_ID(1, p1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_2(p1, p2) \
+	TZ_SYSCALL_CREATE_PARAM_ID(2, p1, p2, 0, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_3(p1, p2, p3) \
+	TZ_SYSCALL_CREATE_PARAM_ID(3, p1, p2, p3, 0, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_4(p1, p2, p3, p4) \
+	TZ_SYSCALL_CREATE_PARAM_ID(4, p1, p2, p3, p4, 0, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_5(p1, p2, p3, p4, p5) \
+	TZ_SYSCALL_CREATE_PARAM_ID(5, p1, p2, p3, p4, p5, 0, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_6(p1, p2, p3, p4, p5, p6) \
+	TZ_SYSCALL_CREATE_PARAM_ID(6, p1, p2, p3, p4, p5, p6, 0, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_7(p1, p2, p3, p4, p5, p6, p7) \
+	TZ_SYSCALL_CREATE_PARAM_ID(7, p1, p2, p3, p4, p5, p6, p7, 0, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_8(p1, p2, p3, p4, p5, p6, p7, p8) \
+	TZ_SYSCALL_CREATE_PARAM_ID(8, p1, p2, p3, p4, p5, p6, p7, p8, 0, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \
+	TZ_SYSCALL_CREATE_PARAM_ID(9, p1, p2, p3, p4, p5, p6, p7, p8, p9, 0)
+#define TZ_SYSCALL_CREATE_PARAM_ID_10(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) \
+	TZ_SYSCALL_CREATE_PARAM_ID(10, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+/*
+ * Macro used to obtain the Parameter ID associated with the syscall
+ */
+#define TZ_SYSCALL_GET_PARAM_ID(CMD_ID)        CMD_ID ## _PARAM_ID
+
+/** Helper macro to extract the owning entity from the SMC ID. */
+#define TZ_SYSCALL_OWNER_ID(r0)   ((r0 & TZ_MASK_BITS(29, 24)) >> 24)
+
+/** Helper macro for checking whether an owning entity is of type trusted OS. */
+#define IS_OWNER_TRUSTED_OS(owner_id) \
+			(((owner_id >= 50) && (owner_id <= 63)) ? 1:0)
+
+#define TZ_SYSCALL_PARAM_TYPE_VAL              0x0     /* type of value */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RO           0x1     /* type of buffer RO */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RW           0x2     /* type of buffer RW */
+
+#define TZ_OS_APP_START_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x01)
+
+#define TZ_OS_APP_START_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_SHUTDOWN_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x02)
+
+#define TZ_OS_APP_SHUTDOWN_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_LOOKUP_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x03)
+
+#define TZ_OS_APP_LOOKUP_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_GET_STATE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x04)
+
+#define TZ_OS_APP_GET_STATE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x05)
+
+#define TZ_OS_APP_REGION_NOTIFICATION_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x06)
+
+#define TZ_OS_REGISTER_LOG_BUFFER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x07)
+
+#define TZ_OS_LOAD_SERVICES_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_APP_MGR, 0x08)
+
+#define TZ_OS_UNLOAD_SERVICES_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_SECBOOT_GET_FUSE_INFO \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_FUSE, 0x09)
+
+#define TZ_SECBOOT_GET_FUSE_INFO_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_4(\
+	TZ_SYSCALL_PARAM_TYPE_BUF_RO, \
+	TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_REGISTER_LISTENER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x01)
+
+#define TZ_OS_REGISTER_LISTENER_SMCINVOKE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x06)
+
+#define TZ_OS_REGISTER_LISTENER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x02)
+
+#define TZ_OS_DEREGISTER_LISTENER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x03)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x01)
+
+#define TZ_OS_LOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_QSAPP_SEND_DATA_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x01)
+
+
+#define TZ_APP_QSAPP_SEND_DATA_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_5( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_EXTERNAL, 0x02)
+
+#define TZ_OS_UNLOAD_EXTERNAL_IMAGE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x01)
+
+#define TZ_INFO_IS_SVC_AVAILABLE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_INFO, 0x03)
+
+#define TZ_INFO_GET_FEATURE_VERSION_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x01)
+
+#define TZ_OS_RPMB_PROVISION_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_RPMB_ERASE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x02)
+
+#define TZ_OS_RPMB_ERASE_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_RPMB_CHECK_PROV_STATUS_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_RPMB, 0x03)
+
+#define TZ_OS_RPMB_CHECK_PROV_STATUS_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_0
+
+#define TZ_OS_KS_GEN_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x01)
+
+#define TZ_OS_KS_GEN_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_DEL_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x02)
+
+#define TZ_OS_KS_DEL_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x03)
+
+#define TZ_OS_KS_GET_MAX_KEYS_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x04)
+
+#define TZ_OS_KS_SET_PIPE_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_KS_UPDATE_KEY_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x05)
+
+#define TZ_OS_KS_UPDATE_KEY_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_2( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, 0x01)
+
+#define TZ_ES_SAVE_PARTITION_HASH_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_3( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_ID					\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x02)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_ID_PARAM_ID				\
+	TZ_SYSCALL_CREATE_PARAM_ID_5(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_CLOSE_SESSION_ID					\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x03)
+
+#define TZ_APP_GPAPP_CLOSE_SESSION_ID_PARAM_ID				\
+	TZ_SYSCALL_CREATE_PARAM_ID_5(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_ID					\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x04)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_ID_PARAM_ID				\
+	TZ_SYSCALL_CREATE_PARAM_ID_5(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_REQUEST_CANCELLATION_ID				\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x05)
+
+#define TZ_APP_GPAPP_REQUEST_CANCELLATION_ID_PARAM_ID			\
+	TZ_SYSCALL_CREATE_PARAM_ID_5(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_MDTP_CIPHER_DIP_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MDTP, 0x1)
+
+#define TZ_MDTP_CIPHER_DIP_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_5( \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RO, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x04)
+
+#define TZ_OS_CONTINUE_BLOCKED_REQUEST_SMCINVOKE_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x07)
+
+#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x06)
+
+#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_7( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID			\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x07)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID_PARAM_ID		\
+	TZ_SYSCALL_CREATE_PARAM_ID_7(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID			\
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS,			\
+	TZ_SVC_APP_ID_PLACEHOLDER, 0x09)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID_PARAM_ID		\
+	TZ_SYSCALL_CREATE_PARAM_ID_7(					\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW,	\
+	TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \
+	TZ_SYSCALL_CREATE_PARAM_ID_4( \
+	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+	TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#endif /* __QSEECOMI_H_ */

+ 6 - 3
linux/qcedev.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _QCEDEV__H
@@ -8,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
-#include "fips_status.h"
 
 #define QCEDEV_MAX_SHA_BLOCK_SIZE	64
 #define QCEDEV_MAX_BEARER	31
@@ -49,8 +49,10 @@ enum qcedev_oper_enum {
  */
 enum qcedev_offload_oper_enum {
 	QCEDEV_OFFLOAD_HLOS_HLOS = 1,
-	QCEDEV_OFFLOAD_HLOS_CPB = 2,
-	QCEDEV_OFFLOAD_CPB_HLOS = 3,
+	QCEDEV_OFFLOAD_HLOS_HLOS_1 = 2,
+	QCEDEV_OFFLOAD_HLOS_CPB = 3,
+	QCEDEV_OFFLOAD_HLOS_CPB_1 = 4,
+	QCEDEV_OFFLOAD_CPB_HLOS = 5,
 	QCEDEV_OFFLOAD_OPER_LAST
 };
 
@@ -309,6 +311,7 @@ struct qcedev_offload_cipher_op_req {
 	__u8 block_offset;
 	__u8 is_pattern_valid;
 	__u8 is_copy_op;
+	__u8 encrypt;
 	struct pattern_info pattern_info;
 	enum qcedev_cipher_alg_enum alg;
 	enum qcedev_cipher_mode_enum mode;

+ 5 - 2
pineapple.bzl

@@ -11,8 +11,11 @@ def define_pineapple():
             "qcedev-mod_dlkm",
             "qrng_dlkm",
             "qcrypto-msm_dlkm",
-            "smmu_proxy_dlkm"
+            "smmu_proxy_dlkm",
+            "qseecom_dlkm"
         ],
         extra_options = [
-            "CONFIG_QCOM_SMCINVOKE"]
+            "CONFIG_QCOM_SMCINVOKE",
+            "CONFIG_QSEECOM_COMPAT",
+        ],
     )

+ 58 - 129
qseecom/qseecom.c

@@ -3,7 +3,7 @@
  * QTI Secure Execution Environment Communicator (QSEECOM) driver
  *
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #define pr_fmt(fmt) "QSEECOM: %s: " fmt, __func__
@@ -25,7 +25,6 @@
 #include <linux/msm_ion.h>
 #include <linux/types.h>
 #include <linux/clk.h>
-#include <linux/qseecom.h>
 #include <linux/elf.h>
 #include <linux/firmware.h>
 #include <linux/freezer.h>
@@ -33,7 +32,6 @@
 #include <linux/regulator/consumer.h>
 #include <linux/dma-mapping.h>
 #include <soc/qcom/qseecom_scm.h>
-#include <soc/qcom/qseecomi.h>
 #include <asm/cacheflush.h>
 #include <linux/delay.h>
 #include <linux/signal.h>
@@ -47,6 +45,7 @@
 #include <linux/qtee_shmbridge.h>
 #include <linux/mem-buf.h>
 #include <linux/version.h>
+#include "linux/qseecom_api.h"
 #include "ice.h"
 #if IS_ENABLED(CONFIG_QSEECOM_PROXY)
 #include <linux/qseecom_kernel.h>
@@ -54,6 +53,7 @@
 #else
 #include "misc/qseecom_kernel.h"
 #endif
+#include "misc/qseecomi.h"
 
 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(6,0,0))
 #define KERNEL_VERSION_LEGACY
@@ -120,6 +120,40 @@
 #define FDE_FLAG_POS    4
 #define ENABLE_KEY_WRAP_IN_KS    (1 << FDE_FLAG_POS)
 
+/*
+ * sg list buf format version
+ * 1: Legacy format to support only 512 SG list entries
+ * 2: new format to support > 512 entries
+ */
+#define QSEECOM_SG_LIST_BUF_FORMAT_VERSION_1    1
+#define QSEECOM_SG_LIST_BUF_FORMAT_VERSION_2    2
+
+struct qseecom_sg_list_buf_hdr_64bit {
+	struct qseecom_sg_entry_64bit  blank_entry;     /* must be all 0 */
+	__u32 version;          /* sg list buf format version */
+	__u64 new_buf_phys_addr;        /* PA of new buffer */
+	__u32 nents_total;              /* Total number of SG entries */
+} __packed;
+
+#define QSEECOM_SG_LIST_BUF_HDR_SZ_64BIT        \
+			sizeof(struct qseecom_sg_list_buf_hdr_64bit)
+
+#define MAX_CE_PIPE_PAIR_PER_UNIT 3
+#define INVALID_CE_INFO_UNIT_NUM 0xffffffff
+
+#define CE_PIPE_PAIR_USE_TYPE_FDE 0
+#define CE_PIPE_PAIR_USE_TYPE_PFE 1
+
+#define SG_ENTRY_SZ             sizeof(struct qseecom_sg_entry)
+#define SG_ENTRY_SZ_64BIT       sizeof(struct qseecom_sg_entry_64bit)
+
+enum qseecom_bandwidth_request_mode {
+	INACTIVE = 0,
+	LOW,
+	MEDIUM,
+	HIGH,
+};
+
 enum qseecom_clk_definitions {
 	CLK_DFAB = 0,
 	CLK_SFPB,
@@ -346,6 +380,7 @@ struct qseecom_control {
 	struct task_struct *unload_app_kthread_task;
 	wait_queue_head_t unload_app_kthread_wq;
 	atomic_t unload_app_kthread_state;
+	bool no_user_contig_mem_support;
 };
 
 struct qseecom_unload_app_pending_list {
@@ -1930,50 +1965,6 @@ perf_enable_exit:
 	return ret;
 }
 
-static int qseecom_scale_bus_bandwidth(struct qseecom_dev_handle *data,
-						void __user *argp)
-{
-	int32_t ret = 0;
-	int32_t req_mode;
-
-	if (qseecom.no_clock_support)
-		return 0;
-
-	ret = copy_from_user(&req_mode, argp, sizeof(req_mode));
-	if (ret) {
-		pr_err("copy_from_user failed\n");
-		return ret;
-	}
-	if (req_mode > HIGH) {
-		pr_err("Invalid bandwidth mode (%d)\n", req_mode);
-		return -EINVAL;
-	}
-
-	/*
-	 * Register bus bandwidth needs if bus scaling feature is enabled;
-	 * otherwise, qseecom enable/disable clocks for the client directly.
-	 */
-	if (qseecom.support_bus_scaling) {
-		mutex_lock(&qsee_bw_mutex);
-		ret = __qseecom_register_bus_bandwidth_needs(data, req_mode);
-		mutex_unlock(&qsee_bw_mutex);
-	} else {
-		pr_debug("Bus scaling feature is NOT enabled\n");
-		pr_debug("request bandwidth mode %d for the client\n",
-				req_mode);
-		if (req_mode != INACTIVE) {
-			ret = qseecom_perf_enable(data);
-			if (ret)
-				pr_err("Failed to vote for clock with err %d\n",
-						ret);
-		} else {
-			qsee_disable_clock_vote(data, CLK_DFAB);
-			qsee_disable_clock_vote(data, CLK_SFPB);
-		}
-	}
-	return ret;
-}
-
 static void __qseecom_add_bw_scale_down_timer(uint32_t duration)
 {
 	if (qseecom.no_clock_support)
@@ -4730,6 +4721,8 @@ static void __qseecom_free_coherent_buf(uint32_t size,
 	dma_free_coherent(qseecom.dev, size, vaddr, paddr);
 }
 
+
+#if IS_ENABLED(CONFIG_QSEECOM)
 static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname,
 				uint32_t *app_id)
 {
@@ -4869,6 +4862,7 @@ exit_free_img_data:
 		__qseecom_free_coherent_buf(fw_size, img_data, pa);
 	return ret;
 }
+#endif
 
 static int qseecom_load_commonlib_image(struct qseecom_dev_handle *data,
 					char *cmnlib_name)
@@ -5016,6 +5010,7 @@ static int qseecom_unload_commonlib_image(void)
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_QSEECOM)
 static int __qseecom_start_app(struct qseecom_handle **handle,
 						char *app_name, uint32_t size)
 {
@@ -5323,6 +5318,7 @@ static int __qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
 	return ret;
 }
 
+#if IS_ENABLED(CONFIG_QSEECOM)
 #if IS_ENABLED(CONFIG_QSEECOM_PROXY)
 const static struct qseecom_drv_ops qseecom_driver_ops = {
        .qseecom_send_command = __qseecom_send_command,
@@ -5358,6 +5354,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
 }
 EXPORT_SYMBOL(qseecom_send_command);
 #endif
+#endif
 
 int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high)
 {
@@ -5439,7 +5436,7 @@ int qseecom_process_listener_from_smcinvoke(uint32_t *result,
 	return ret;
 }
 EXPORT_SYMBOL(qseecom_process_listener_from_smcinvoke);
-
+#endif
 static int qseecom_send_resp(void)
 {
 	qseecom.send_resp_flag = 1;
@@ -7905,80 +7902,6 @@ long qseecom_ioctl(struct file *file,
 		atomic_dec(&data->ioctl_count);
 		break;
 	}
-	case QSEECOM_IOCTL_PERF_ENABLE_REQ:{
-		if ((data->type != QSEECOM_GENERIC) &&
-			(data->type != QSEECOM_CLIENT_APP)) {
-			pr_err("perf enable req: invalid handle (%d)\n",
-								data->type);
-			ret = -EINVAL;
-			break;
-		}
-		if ((data->type == QSEECOM_CLIENT_APP) &&
-			(data->client.app_id == 0)) {
-			pr_err("perf enable req:invalid handle(%d) appid(%d)\n",
-					data->type, data->client.app_id);
-			ret = -EINVAL;
-			break;
-		}
-		atomic_inc(&data->ioctl_count);
-		if (qseecom.support_bus_scaling) {
-			mutex_lock(&qsee_bw_mutex);
-			__qseecom_register_bus_bandwidth_needs(data, HIGH);
-			mutex_unlock(&qsee_bw_mutex);
-		} else {
-			ret = qseecom_perf_enable(data);
-			if (ret)
-				pr_err("Fail to vote for clocks %d\n", ret);
-		}
-		atomic_dec(&data->ioctl_count);
-		break;
-	}
-	case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
-		if ((data->type != QSEECOM_SECURE_SERVICE) &&
-			(data->type != QSEECOM_CLIENT_APP)) {
-			pr_err("perf disable req: invalid handle (%d)\n",
-								data->type);
-			ret = -EINVAL;
-			break;
-		}
-		if ((data->type == QSEECOM_CLIENT_APP) &&
-			(data->client.app_id == 0)) {
-			pr_err("perf disable: invalid handle (%d)app_id(%d)\n",
-					data->type, data->client.app_id);
-			ret = -EINVAL;
-			break;
-		}
-		atomic_inc(&data->ioctl_count);
-		if (!qseecom.support_bus_scaling) {
-			qsee_disable_clock_vote(data, CLK_DFAB);
-			qsee_disable_clock_vote(data, CLK_SFPB);
-		} else {
-			mutex_lock(&qsee_bw_mutex);
-			qseecom_unregister_bus_bandwidth_needs(data);
-			mutex_unlock(&qsee_bw_mutex);
-		}
-		atomic_dec(&data->ioctl_count);
-		break;
-	}
-
-	case QSEECOM_IOCTL_SET_BUS_SCALING_REQ: {
-		/* If crypto clock is not handled by HLOS, return directly. */
-		if (qseecom.no_clock_support) {
-			pr_debug("crypto clock is not handled by HLOS\n");
-			break;
-		}
-		if ((data->client.app_id == 0) ||
-			(data->type != QSEECOM_CLIENT_APP)) {
-			pr_err("set bus scale: invalid handle (%d) appid(%d)\n",
-					data->type, data->client.app_id);
-			ret = -EINVAL;
-			break;
-		}
-		atomic_inc(&data->ioctl_count);
-		ret = qseecom_scale_bus_bandwidth(data, argp);
-		atomic_dec(&data->ioctl_count);
-		break;
-	}
 	case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("load ext elf req: invalid client handle (%d)\n",
@@ -9584,12 +9507,18 @@ static int qseecom_register_shmbridge(struct platform_device *pdev)
 		qtee_shmbridge_deregister(qseecom.ta_bridge_handle);
 		return ret;
 	}
-	ret = qseecom_register_heap_shmbridge(pdev, "user_contig_mem",
-					&qseecom.user_contig_bridge_handle);
-	if (ret) {
-		qtee_shmbridge_deregister(qseecom.qseecom_bridge_handle);
-		qtee_shmbridge_deregister(qseecom.ta_bridge_handle);
-		return ret;
+
+	/* no-user-contig-mem is present in dtsi if user_contig_region is not needed*/
+	qseecom.no_user_contig_mem_support = of_property_read_bool((&pdev->dev)->of_node,
+						"qcom,no-user-contig-mem-support");
+	if (!qseecom.no_user_contig_mem_support) {
+		ret = qseecom_register_heap_shmbridge(pdev, "user_contig_mem",
+						&qseecom.user_contig_bridge_handle);
+		if (ret) {
+			qtee_shmbridge_deregister(qseecom.qseecom_bridge_handle);
+			qtee_shmbridge_deregister(qseecom.ta_bridge_handle);
+			return ret;
+		}
 	}
 	return 0;
 }
@@ -9633,7 +9562,7 @@ static int qseecom_probe(struct platform_device *pdev)
 	if (rc)
 		goto exit_deinit_bus;
 
-#if IS_ENABLED(CONFIG_QSEECOM_PROXY)
+#if IS_ENABLED(CONFIG_QSEECOM) && IS_ENABLED(CONFIG_QSEECOM_PROXY)
 	/*If the api fails to get the func ops, print the error and continue
 	* Do not treat it as fatal*/
 	rc = get_qseecom_kernel_fun_ops();

+ 24 - 20
securemsm_kernel.bzl

@@ -1,7 +1,13 @@
-load("//build/kernel/kleaf:kernel.bzl", "kernel_modules_install",
-                                        "ddk_module")
-load(":securemsm_modules.bzl", "securemsm_modules",
-                           "securemsm_modules_by_config")
+load(
+    "//build/kernel/kleaf:kernel.bzl",
+    "ddk_module",
+    "kernel_modules_install",
+)
+load(
+    ":securemsm_modules.bzl",
+    "securemsm_modules",
+    "securemsm_modules_by_config",
+)
 load("//build/bazel_common_rules/dist:dist.bzl", "copy_to_dist_dir")
 
 def _replace_formatting_codes(target, variant, s):
@@ -11,9 +17,9 @@ def _replace_formatting_codes(target, variant, s):
 
 def _console_print(target, variant, module, message):
     if module:
-        print('{}: {}: securemsm-kernel: {}: {}'.format(target, variant, module, message))
+        print("{}: {}: securemsm-kernel: {}: {}".format(target, variant, module, message))
     else:
-        print('{}: {}: securemsm-kernel: {} '.format(target, variant, message))
+        print("{}: {}: securemsm-kernel: {} ".format(target, variant, message))
 
 def _get_options(target, variant, target_config_option, modules, extra_options):
     all_options = {option: True for option in extra_options}
@@ -37,7 +43,7 @@ def _get_options(target, variant, target_config_option, modules, extra_options):
         all_options[target_config_option] = True
 
     if redundant_options:
-        _console_print(target, variant, None, 'INFO: The following options are already declared either by a module or the target, no need to redeclare: \n{}'.format('\n'.join(redundant_options)))
+        _console_print(target, variant, None, "INFO: The following options are already declared either by a module or the target, no need to redeclare: \n{}".format("\n".join(redundant_options)))
 
     return all_options
 
@@ -51,7 +57,7 @@ def _get_module_srcs(target, variant, module, options):
     globbed_srcs = native.glob(["{}{}".format(module_path, _replace_formatting_codes(target, variant, src)) for src in srcs])
 
     if not globbed_srcs:
-        _console_print(target, variant, module["name"], 'WARNING: Module has no sources attached!')
+        _console_print(target, variant, module["name"], "WARNING: Module has no sources attached!")
 
     return globbed_srcs
 
@@ -79,27 +85,25 @@ def define_target_variant_modules(target, variant, modules, extra_options = [],
             deps = ["//msm-kernel:all_headers"] + [_replace_formatting_codes(target, variant, dep) for dep in module["deps"]],
             hdrs = module["hdrs"],
             local_defines = target_local_defines,
-            copts = module["copts"]
-
+            copts = module["copts"],
         )
         module_rules.append(rule_name)
 
     copy_to_dist_dir(
-          name = "{}_securemsm-kernel_dist".format(kernel_build_variant),
-          data = module_rules,
-          dist_dir = "out/target/product/{}/dlkm/lib/modules/".format(target),
-          flat = True,
-          wipe_dist_dir = False,
-          allow_duplicate_filenames = False,
-          mode_overrides = {"**/*": "644"},
-          log = "info",
+        name = "{}_securemsm-kernel_dist".format(kernel_build_variant),
+        data = module_rules,
+        dist_dir = "out/target/product/{}/dlkm/lib/modules/".format(target),
+        flat = True,
+        wipe_dist_dir = False,
+        allow_duplicate_filenames = False,
+        mode_overrides = {"**/*": "644"},
+        log = "info",
     )
 
-
     kernel_modules_install(
         name = "{}_modules_install".format(kernel_build_variant),
         kernel_build = "//msm-kernel:{}".format(kernel_build_variant),
-        kernel_modules = module_rules
+        kernel_modules = module_rules,
     )
 
 def define_consolidate_gki_modules(target, modules, extra_options = [], config_option = None):

+ 1 - 5
securemsm_kernel_product_board.mk

@@ -16,16 +16,12 @@ PRODUCT_PACKAGES += qcrypto-msm_dlkm.ko
 PRODUCT_PACKAGES += hdcp_qseecom_dlkm.ko
 PRODUCT_PACKAGES += qrng_dlkm.ko
 PRODUCT_PACKAGES += smcinvoke_dlkm.ko
+PRODUCT_PACKAGES += qseecom_dlkm.ko
 
 ifeq ($(TARGET_USES_SMMU_PROXY), true)
 PRODUCT_PACKAGES += smmu_proxy_dlkm.ko
 endif
 
-#Enable Qseecom if TARGET_ENABLE_QSEECOM or TARGET_BOARD_AUTO is set to true
-ifneq (, $(filter true, $(TARGET_ENABLE_QSEECOM) $(TARGET_BOARD_AUTO)))
-PRODUCT_PACKAGES += qseecom_dlkm.ko
-endif #TARGET_ENABLE_QSEECOM OR TARGET_BOARD_AUTO
-
 endif #ENABLE_SECUREMSM_DLKM
 
 

+ 5 - 6
securemsm_kernel_vendor_board.mk

@@ -24,14 +24,13 @@ BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
 BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
 BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
 
-ifeq ($(TARGET_USES_SMMU_PROXY), true)
-BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smmu_proxy_dlkm.ko
-endif
 
-#Enable Qseecom if TARGET_ENABLE_QSEECOM or TARGET_BOARD_AUTO is set to true
-ifneq (, $(filter true, $(TARGET_ENABLE_QSEECOM) $(TARGET_BOARD_AUTO)))
 BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
 BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
 BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
-endif #TARGET_ENABLE_QSEECOM OR TARGET_BOARD_AUTO
+
+ifeq ($(TARGET_USES_SMMU_PROXY), true)
+BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smmu_proxy_dlkm.ko
+endif
+
 endif #ENABLE_SECUREMSM_DLKM

+ 45 - 23
securemsm_modules.bzl

@@ -22,12 +22,11 @@ securemsm_modules_by_config = {}
 
 def register_securemsm_module(name, path = None, config_option = None, default_srcs = [], config_srcs = {}, deps = [], srcs = [], copts = [], hdrs = []):
     processed_config_srcs = {}
-
     for config_src_name in config_srcs:
         config_src = config_srcs[config_src_name]
 
         if type(config_src) == "list":
-            processed_config_srcs[config_src_name] = { True: config_src }
+            processed_config_srcs[config_src_name] = {True: config_src}
         else:
             processed_config_srcs[config_src_name] = config_src
 
@@ -48,46 +47,69 @@ def register_securemsm_module(name, path = None, config_option = None, default_s
     if config_option:
         securemsm_modules_by_config[config_option] = name
 
-
 # ------------------------------------ SECUREMSM MODULE DEFINITIONS ---------------------------------
 register_securemsm_module(
-    name = "smcinvoke_dlkm",
-    path = SMCINVOKE_PATH,
+    name = "qseecom_dlkm",
+    path = QSEECOM_PATH,
     default_srcs = [
-            "smcinvoke.c",
-            "smcinvoke_kernel.c",
-            "trace_smcinvoke.h",
-            "IQSEEComCompat.h",
-            "IQSEEComCompatAppLoader.h",
-
+        "qseecom.c",
+        "ice.h",
     ],
-    deps = [":smcinvoke_kernel_headers"],
-    hdrs = [":smcinvoke_kernel_headers"],
+    deps = [":qseecom_kernel_headers"],
+    #srcs = ["config/sec-kernel_defconfig_qseecom.h"],
+    #copts = ["-include", "config/sec-kernel_defconfig_qseecom.h"],
 )
 
+
 register_securemsm_module(
-    name = "qseecom_dlkm",
-    path = QSEECOM_PATH,
-    default_srcs = ["qseecom.c",
-                    "ice.h"],
-    deps = [":securemsm_kernel_headers"],
-    srcs = ["config/sec-kernel_defconfig_qseecom.h"],
-    copts = ["-include", "config/sec-kernel_defconfig_qseecom.h"],
+    name = "smcinvoke_dlkm",
+    path = SMCINVOKE_PATH,
+    default_srcs = [
+        "smcinvoke.c",
+        "smcinvoke_kernel.c",
+        "trace_smcinvoke.h",
+        "IQSEEComCompat.h",
+        "IQSEEComCompatAppLoader.h",
+    ],
+    deps = [":smcinvoke_kernel_headers", ":qseecom_kernel_headers", "%b_qseecom_dlkm"],
+    hdrs = [":smcinvoke_kernel_headers"],
 )
 
 register_securemsm_module(
     name = "tz_log_dlkm",
     path = TZLOG_PATH,
+    deps = [":qseecom_kernel_headers"],
     default_srcs = ["tz_log.c"],
 )
 
 register_securemsm_module(
     name = "hdcp_qseecom_dlkm",
     path = HDCP_PATH,
-    default_srcs = ["hdcp_qseecom.c"],
-    deps = [":hdcp_qseecom_dlkm","%b_smcinvoke_dlkm"],
+    default_srcs = [
+        "hdcp_qseecom.c",
+        "hdcp_qseecom.h",
+        "hdcp_main.c",
+        "smcinvoke_object.h",
+        "hdcp_main.h",
+        "hdcp_smcinvoke.c",
+        "hdcp_smcinvoke.h",
+        "CAppClient.h",
+        "CAppLoader.h",
+        "IAppClient.h",
+        "IAppController.h",
+        "IAppLoader.h",
+        "IClientEnv.h",
+        "IOpener.h",
+        "hdcp1.h",
+        "hdcp1_ops.h",
+        "hdcp2p2.h",
+    ],
+    deps = [":hdcp_qseecom_dlkm", "%b_smcinvoke_dlkm", "%b_qseecom_dlkm"],
     srcs = ["config/sec-kernel_defconfig.h"],
-    copts = ["-include", "config/sec-kernel_defconfig.h"],
+    copts = [
+        "-include",
+        "config/sec-kernel_defconfig.h",
+    ],
 )
 
 register_securemsm_module(

+ 29 - 15
smcinvoke/smcinvoke.c

@@ -27,8 +27,8 @@
 #include <linux/firmware.h>
 #include <linux/qcom_scm.h>
 #include <linux/freezer.h>
+#include <linux/ratelimit.h>
 #include <asm/cacheflush.h>
-#include <soc/qcom/qseecomi.h>
 #include <linux/qtee_shmbridge.h>
 #include <linux/kthread.h>
 #include "smcinvoke.h"
@@ -40,6 +40,7 @@
 #else
 #include "misc/qseecom_kernel.h"
 #endif
+#include "misc/qseecomi.h"
 
 #define CREATE_TRACE_POINTS
 #include "trace_smcinvoke.h"
@@ -62,6 +63,18 @@
 #define SMCINVOKE_MEM_PERM_RW			6
 #define SMCINVOKE_SCM_EBUSY_WAIT_MS		30
 #define SMCINVOKE_SCM_EBUSY_MAX_RETRY		200
+#define TZCB_ERR_RATELIMIT_INTERVAL		(1*HZ)
+#define TZCB_ERR_RATELIMIT_BURST		1
+
+//print tzcb err per sec
+#define tzcb_err_ratelimited(fmt, ...) 	do {		\
+	static DEFINE_RATELIMIT_STATE(_rs, 		\
+			TZCB_ERR_RATELIMIT_INTERVAL,	\
+			TZCB_ERR_RATELIMIT_BURST);	\
+	if (__ratelimit(&_rs))				\
+		pr_err(fmt, ##__VA_ARGS__);		\
+} while(0)
+
 
 
 /* TZ defined values - Start */
@@ -385,7 +398,7 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, phys_addr_t in_paddr,
 		struct smcinvoke_cmd_req *req,
 		union smcinvoke_arg *args_buf,
 		bool *tz_acked, uint32_t context_type,
-		struct qtee_shm *in_shm, struct qtee_shm *out_shm);
+		struct qtee_shm *in_shm, struct qtee_shm *out_shm, bool retry);
 
 static void process_piggyback_data(void *buf, size_t buf_size);
 static void add_mem_obj_info_to_async_side_channel_locked(void *buf, size_t buf_size, struct list_head *l_pending_mem_obj);
@@ -559,7 +572,7 @@ static int smcinvoke_release_tz_object(struct qtee_shm *in_shm, struct qtee_shm
 	ret = prepare_send_scm_msg(in_buf, in_shm->paddr,
 			SMCINVOKE_TZ_MIN_BUF_SIZE, out_buf, out_shm->paddr,
 			SMCINVOKE_TZ_MIN_BUF_SIZE, &req, NULL,
-			&release_handles, context_type, in_shm, out_shm);
+			&release_handles, context_type, in_shm, out_shm, false);
 	process_piggyback_data(out_buf, SMCINVOKE_TZ_MIN_BUF_SIZE);
 	if (ret) {
 		pr_err_ratelimited("Failed to release object(0x%x), ret:%d\n",
@@ -1712,13 +1725,13 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
 		}
 		if (ret == 0) {
 			if (srvr_info->is_server_suspended == 0) {
-			pr_err("CBobj timed out waiting on cbtxn :%d,cb-tzhandle:%d, retry:%d, op:%d counts :%d\n",
-					cb_txn->txn_id,cb_req->hdr.tzhandle, cbobj_retries,
-					cb_req->hdr.op, cb_req->hdr.counts);
-			pr_err("CBobj %d timedout pid %x,tid %x, srvr state=%d, srvr id:%u\n",
-					cb_req->hdr.tzhandle, current->pid,
-					current->tgid, srvr_info->state,
-					srvr_info->server_id);
+				tzcb_err_ratelimited("CBobj timed out waiting on cbtxn :%d,cb-tzhandle:%d, retry:%d, op:%d counts :%d\n",
+						cb_txn->txn_id,cb_req->hdr.tzhandle, cbobj_retries,
+						cb_req->hdr.op, cb_req->hdr.counts);
+				tzcb_err_ratelimited("CBobj %d timedout pid %x,tid %x, srvr state=%d, srvr id:%u\n",
+						cb_req->hdr.tzhandle, current->pid,
+						current->tgid, srvr_info->state,
+						srvr_info->server_id);
 			}
 		} else {
 			/* wait_event returned due to a signal */
@@ -1874,7 +1887,8 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, phys_addr_t in_paddr,
 		struct smcinvoke_cmd_req *req,
 		union smcinvoke_arg *args_buf,
 		bool *tz_acked, uint32_t context_type,
-		struct qtee_shm *in_shm, struct qtee_shm *out_shm)
+		struct qtee_shm *in_shm, struct qtee_shm *out_shm,
+		bool retry)
 {
 	int ret = 0, cmd, retry_count = 0;
 	u64 response_type;
@@ -1899,7 +1913,7 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, phys_addr_t in_paddr,
 				msleep(SMCINVOKE_SCM_EBUSY_WAIT_MS);
 			}
 
-		} while ((ret == -EBUSY) &&
+		} while (retry && (ret == -EBUSY) &&
 				(retry_count++ < SMCINVOKE_SCM_EBUSY_MAX_RETRY));
 
 		if (!ret && !is_inbound_req(response_type)) {
@@ -2071,7 +2085,7 @@ static int marshal_in_tzcb_req(const struct smcinvoke_cb_txn *cb_txn,
 
 	user_req->txn_id = cb_txn->txn_id;
 	if (get_uhandle_from_tzhandle(tzcb_req->hdr.tzhandle, srvr_id,
-			&user_req->cbobj_id, TAKE_LOCK,
+			(int32_t*)(&user_req->cbobj_id), TAKE_LOCK,
 			SMCINVOKE_OBJ_TYPE_TZ_OBJ)) {
 		ret = -EINVAL;
 		goto out;
@@ -2785,7 +2799,7 @@ static long process_invoke_req(struct file *filp, unsigned int cmd,
 	ret = prepare_send_scm_msg(in_msg, in_shm.paddr, inmsg_size,
 			out_msg, out_shm.paddr, outmsg_size,
 			&req, args_buf, &tz_acked, context_type,
-			&in_shm, &out_shm);
+			&in_shm, &out_shm, true);
 
 	/*
 	 * If scm_call is success, TZ owns responsibility to release
@@ -3212,7 +3226,7 @@ static int smcinvoke_probe(struct platform_device *pdev)
 	}
 	smcinvoke_pdev = pdev;
 
-#if !IS_ENABLED(CONFIG_QSEECOM) && IS_ENABLED(CONFIG_QSEECOM_PROXY)
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT) && IS_ENABLED(CONFIG_QSEECOM_PROXY)
 	/*If the api fails to get the func ops, print the error and continue
 	* Do not treat it as fatal*/
 	rc = get_qseecom_kernel_fun_ops();

+ 4 - 4
smcinvoke/smcinvoke_kernel.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #include <linux/file.h>
 #include <linux/fs.h>
@@ -16,10 +16,10 @@
 #include "smcinvoke.h"
 #include "smcinvoke_object.h"
 #include "IClientEnv.h"
-#if !IS_ENABLED(CONFIG_QSEECOM)
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
 #include "IQSEEComCompat.h"
 #include "IQSEEComCompatAppLoader.h"
-#include "linux/qseecom.h"
+#include "linux/qseecom_api.h"
 #if IS_ENABLED(CONFIG_QSEECOM_PROXY)
 #include <linux/qseecom_kernel.h>
 #else
@@ -323,7 +323,7 @@ int32_t get_client_env_object(struct Object *clientEnvObj)
 }
 EXPORT_SYMBOL(get_client_env_object);
 
-#if !IS_ENABLED(CONFIG_QSEECOM)
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
 
 static int load_app(struct qseecom_compat_context *cxt, const char *app_name)
 {

+ 1 - 1
smmu-proxy/qti-smmu-proxy-common.c

@@ -5,7 +5,7 @@
 
 #include <linux/cdev.h>
 #include "qti-smmu-proxy-common.h"
-#include "../include/linux/smcinvoke.h"
+#include "smcinvoke.h"
 #include "../include/linux/ITrustedCameraDriver.h"
 #include "../include/linux/CTrustedCameraDriver.h"
 #include "../include/linux/IClientEnv.h"

+ 0 - 1
smmu-proxy/qti-smmu-proxy-tvm.c

@@ -367,7 +367,6 @@ static void smmu_proxy_process_msg(void *buf, size_t size)
 	struct smmu_proxy_resp_hdr *resp;
 	int ret = -EINVAL;
 
-	pr_err("%s: smmu-proxy message received\n", __func__);
 	if (size < sizeof(*msg_hdr) || msg_hdr->msg_size != size) {
 		pr_err("%s: message received is not of a proper size: 0x%lx, 0x:%lx\n",
 		       __func__, size, msg_hdr->msg_size);

+ 15 - 6
ssg_kernel_headers.py

@@ -1,5 +1,5 @@
 # Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
-# Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+# Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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 as published by
@@ -29,7 +29,10 @@ def run_headers_install(verbose, gen_dir, headers_install, unifdef, prefix, h):
     # ex. out/soong/.temp/sbox/<temp hash value>/out/linux/smcinvoke.h
     # After the build is complete, you can find the headers that you exposed located in the following gen path:
     # out/soong/.intermediates/.../qti_generate_smcinvoke_kernel_headers/gen/
-    out_h = os.path.join(gen_dir, h[len(prefix):])
+    if 'include/uapi' in h:
+        out_h = os.path.join(gen_dir,'include', h[len(prefix):])
+    else:
+        out_h = os.path.join(gen_dir, h[len(prefix):])
     (out_h_dirname, out_h_basename) = os.path.split(out_h)
     env = os.environ.copy()
     env["LOC_UNIFDEF"] = unifdef
@@ -54,10 +57,16 @@ def gen_smcinvoke_headers(verbose, gen_dir, headers_install, unifdef, smcinvoke_
         # h will be the relative path from the repo root directory securemsm-kernel ex. <parent directory structure>/securemsm-kernel/linux/smcinvoke.h
         # So we need to split the string and keep the directory structure we want to expose i.e. just linux/smcinvoke.h
         topDirectory = 'securemsm-kernel'
-        directorySplitLocation = '/'+ topDirectory +'/'
-        smcinvoke_headers_to_expose_prefix = os.path.join(h.split(directorySplitLocation)[0], topDirectory) + os.sep
-        if not run_headers_install(verbose, gen_dir, headers_install, unifdef, smcinvoke_headers_to_expose_prefix, h):
-                error_count += 1
+        if 'include/uapi' in h:
+            directorySplitLocation = '/'+ topDirectory +'/'
+            smcinvoke_headers_to_expose_prefix = os.path.join(h.split(directorySplitLocation)[0], topDirectory, 'include', 'uapi') + os.sep
+            if not run_headers_install(verbose, gen_dir, headers_install, unifdef, smcinvoke_headers_to_expose_prefix, h):
+                    error_count += 1
+        else:
+            directorySplitLocation = '/'+ topDirectory +'/'
+            smcinvoke_headers_to_expose_prefix = os.path.join(h.split(directorySplitLocation)[0], topDirectory) + os.sep
+            if not run_headers_install(verbose, gen_dir, headers_install, unifdef, smcinvoke_headers_to_expose_prefix, h):
+                    error_count += 1
     return error_count
 
 def main():

+ 2 - 1
tz_log/tz_log.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #include <linux/debugfs.h>
 #include <linux/errno.h>
@@ -17,10 +18,10 @@
 #include <linux/of.h>
 #include <linux/dma-buf.h>
 #include <linux/qcom_scm.h>
-#include <soc/qcom/qseecomi.h>
 #include <linux/qtee_shmbridge.h>
 #include <linux/proc_fs.h>
 #include <linux/version.h>
+#include "misc/qseecomi.h"
 
 /* QSEE_LOG_BUF_SIZE = 32K */
 #define QSEE_LOG_BUF_SIZE 0x8000

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.