Эх сурвалжийг харах

Misc: hdcp : Add smcinvoke support for hdcp driver

Change-Id: I76b0e8f24df7f3e36288b1383fc7203bb295c181
Signed-off-by:Sarthak Patidar <[email protected]>
Sarthak Patidar 1 жил өмнө
parent
commit
1efb70736f

+ 1 - 1
Android.mk

@@ -23,7 +23,7 @@ SSG_SRC_FILES := \
  	$(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)

+ 21 - 8
BUILD.bazel

@@ -14,28 +14,41 @@ ddk_headers(
         "include/linux/ITrustedCameraDriver.h",
         "include/linux/CTrustedCameraDriver.h",
         "linux/misc/qseecom_kernel.h",
-        "linux/misc/qseecom_priv.h"
+        "linux/misc/qseecom_priv.h",
     ]),
-    includes = ["include/linux", "linux", "include"]
+    includes = [
+        "include",
+        "include/linux",
+        "linux",
+    ],
 )
 
 ddk_headers(
     name = "securemsm_kernel_headers",
     hdrs = [
         "linux/misc/qseecom_kernel.h",
-        "linux/misc/qseecom_priv.h"
+        "linux/misc/qseecom_priv.h",
     ],
-    includes = ["linux"]
+    includes = ["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(

+ 1 - 1
Kbuild

@@ -35,7 +35,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

+ 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__ */

+ 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
pineapple.bzl

@@ -14,5 +14,6 @@ def define_pineapple():
             "smmu_proxy_dlkm"
         ],
         extra_options = [
-            "CONFIG_QCOM_SMCINVOKE"]
+            "CONFIG_QCOM_SMCINVOKE",
+        ],
     )

+ 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):

+ 34 - 14
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,18 +47,16 @@ 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,
     default_srcs = [
-            "smcinvoke.c",
-            "smcinvoke_kernel.c",
-            "trace_smcinvoke.h",
-            "IQSEEComCompat.h",
-            "IQSEEComCompatAppLoader.h",
-
+        "smcinvoke.c",
+        "smcinvoke_kernel.c",
+        "trace_smcinvoke.h",
+        "IQSEEComCompat.h",
+        "IQSEEComCompatAppLoader.h",
     ],
     deps = [":smcinvoke_kernel_headers"],
     hdrs = [":smcinvoke_kernel_headers"],
@@ -68,8 +65,10 @@ register_securemsm_module(
 register_securemsm_module(
     name = "qseecom_dlkm",
     path = QSEECOM_PATH,
-    default_srcs = ["qseecom.c",
-                    "ice.h"],
+    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"],
@@ -84,10 +83,31 @@ register_securemsm_module(
 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"],
     srcs = ["config/sec-kernel_defconfig.h"],
-    copts = ["-include", "config/sec-kernel_defconfig.h"],
+    copts = [
+        "-include",
+        "config/sec-kernel_defconfig.h",
+    ],
 )
 
 register_securemsm_module(

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно