platform: msm_shared: Add support for qseecom in bootloader

Add qseecom support in appsbootloader

Change-Id: Idc6dc4cc9a77ffd06dd95798e93eed780959d767
diff --git a/app/rpmbtests/qseecom_lk_test.c b/app/rpmbtests/qseecom_lk_test.c
new file mode 100644
index 0000000..0bfcb9b
--- /dev/null
+++ b/app/rpmbtests/qseecom_lk_test.c
@@ -0,0 +1,358 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+
+//#include "qseecom_legacy.h"
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+
+/* commands supported from sample client */
+#define CLIENT_CMD0_GET_VERSION             0
+#define CLIENT_CMD1_BASIC_DATA              1
+#define CLIENT_CMD2_REGISTER_SB_PTR         2
+#define CLIENT_CMD3_RUN_CRYTPO_TEST         3
+#define CLIENT_CMD4_RUN_CRYTPO_PERF         4
+#define CLIENT_CMD5_RUN_SFS_TEST            5
+#define CLIENT_CMD6_RUN_BUF_ALIGNMENT_TEST  6
+#define CLIENT_CMD7_RUN_CRYPTO_RSA_TEST     7
+#define CLIENT_CMD8_RUN_RSA_PERF_TEST       8
+#define CLIENT_CMD9_RUN_CMNLIB_TEST         9
+#define CLIENT_CMD10_RUN_CORE_TEST          10
+#define CLIENT_CMD11_RUN_SECURECHANNEL_TEST 11
+#define CLIENT_CMD12_RUN_SERVICES_TEST      12
+#define CLIENT_CMD13_RUN_MISC_TEST          13
+#define CLIENT_CMD17_RUN_STORAGE_TEST       17
+#define CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1       50
+
+#define __64KB__ 0x10000
+#define __32KB__ 0x8000
+#define __16KB__ 0x4000
+#define __8KB__ 0x2000
+#define __4KB__ 0x1000
+#define __2KB__ 0x800
+#define __1KB__ 0x400
+
+#define LISTENER_TEST_SERVICE			0x100
+
+struct qsc_send_cmd {
+     unsigned int cmd_id;
+     unsigned int data;
+     unsigned int data2;
+     unsigned int len;
+     unsigned int start_pkt;
+     unsigned int end_pkt;
+     unsigned int test_buf_size;
+};
+
+struct qsc_send_cmd_rsp {
+  unsigned int data;
+  int status;
+};
+
+
+int listener_test_cmd_handler (void* buf, uint32_t size)
+{
+	uint32 *req = 0;
+	uint32 rsp = 0;
+
+	if ((!buf) || (size < 4)) {
+		dprintf(CRITICAL, "Invalid listener cmd handler inputs\n");
+		return -1;
+	}
+
+	req = (uint32 *)buf;
+	if (*req == (100 * 100)) {
+		dprintf(CRITICAL, "Listener Success\n");
+		rsp = *req * 100;
+		dprintf(CRITICAL, "rsp = %u\n", rsp);
+		memcpy (buf, &rsp, sizeof(uint32));
+		return 0;
+	} else {
+		dprintf(CRITICAL, "Listener Failure, req:%u\n", *req);
+		rsp = 0;
+		memcpy (buf, &rsp, sizeof(uint32));
+		return 0;
+	}
+}
+
+static struct qseecom_listener_services listeners[] = {
+		{
+			.service_name = "Listener Test service",
+			.id = LISTENER_TEST_SERVICE,
+			.sb_size = (20 * 1024),
+			.service_cmd_handler = listener_test_cmd_handler,
+		},
+};
+
+int qsc_run_get_version(char *appname, uint32_t iterations)
+{
+	struct qsc_send_cmd send_cmd;
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+	uint32_t i = 0, ret = 0, err = -1;
+
+	dprintf(CRITICAL, "%s:Get_version\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+	/* Start the application */
+	for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret;
+		}
+		dprintf(CRITICAL, "apphandle %u\n", ret);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		dprintf(CRITICAL, "apphandle %u\n", ret);
+		send_cmd.cmd_id = CLIENT_CMD0_GET_VERSION;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		dprintf(ALWAYS, "The version of %s is: %u\n", appname, msgrsp.data);
+		/* Shutdown the application */
+		dprintf(ALWAYS, "Shutting down %s\n", appname);
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+		dprintf(ALWAYS, "Shutting down %s\n", appname);
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+
+    }
+err_ret_shutdown:
+	if (err) {
+		if (qseecom_shutdown_app(ret))
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+	}
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+	return err;
+}
+
+
+int qsc_run_start_stop_app_basic_test(char *appname, uint32_t iterations)
+{
+	uint32_t i = 0;
+	int ret = 0;			/* return value */
+	int err = 0;			/* return value */
+	struct qsc_send_cmd send_cmd = {0};
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+
+	dprintf(CRITICAL, "%s:Basic_start_stop_test\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+	/* Start the application */
+    for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_ret;
+		}
+		/* Send data using send command to QSEE application */
+		send_cmd.cmd_id = CLIENT_CMD1_BASIC_DATA;
+		send_cmd.start_pkt = 0;
+		send_cmd.end_pkt = 0;
+		send_cmd.test_buf_size = 0;
+		send_cmd.data = 100;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		if (((msgrsp.data)/100) != 10) {
+			dprintf(CRITICAL, "App Comm Error:%u\n", msgrsp.data);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		dprintf(CRITICAL, "msg.rsp:%u\n", msgrsp.data);
+		/* Shutdown the application */
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_ret;
+		}
+    }
+err_ret_shutdown:
+    if (err) {
+		if (qseecom_shutdown_app(ret))
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+    }
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+		return err;
+}
+
+
+
+int qsc_run_start_stop_app_listener_test(char *appname, uint32_t iterations)
+{
+	uint32_t i = 0;
+	int ret = 0;			/* return value */
+	int err = 0;			/* return value */
+	struct qsc_send_cmd send_cmd;
+	struct qsc_send_cmd_rsp msgrsp={0};	/* response data sent from QSEE */
+
+	dprintf(CRITICAL, "%s:qsc_run_start_stop_app_listener_test\n", __func__);
+
+	dprintf(CRITICAL, "(This may take a few minutes please wait....)\n");
+
+	ret = qseecom_register_listener(&listeners[0]);
+	if (ret < 0) {
+		dprintf(CRITICAL, "Reg Listener: fail: ret:%d\n", ret);
+		err = -1;
+		goto err_ret;
+	}
+	/* Start the application */
+    for  (i = 0;  i < iterations;  i++) {
+		dprintf(CRITICAL, "iteration %d\n", i);
+		ret = qseecom_start_app(appname);
+		if (ret <= 0) {
+			dprintf(CRITICAL, "Start app: fail: ret:%d\n", ret);
+			err = -1;
+			goto err_dereg;
+		}
+		/* Send data using send command to QSEE application */
+		send_cmd.cmd_id = CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1;
+		send_cmd.start_pkt = 0;
+		send_cmd.end_pkt = 0;
+		send_cmd.test_buf_size = 0;
+		send_cmd.data = 100;
+		err = qseecom_send_command(ret, &send_cmd, sizeof(struct qsc_send_cmd), &msgrsp, sizeof(struct qsc_send_cmd_rsp));
+		if (err) {
+			dprintf(CRITICAL, "Send app: fail\n");
+			goto err_ret_shutdown;
+		}
+		if (((msgrsp.data)/100) != 10) {
+			dprintf(CRITICAL, "App Comm Error:%u Status:%d\n", msgrsp.data, msgrsp.status);
+			err = -1;
+			goto err_ret_shutdown;
+		}
+		/* Shutdown the application */
+		err = qseecom_shutdown_app(ret);
+		if (err) {
+			dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+			goto err_dereg;
+		}
+    }
+
+err_ret_shutdown:
+	if (err) {
+	   	if (qseecom_shutdown_app(ret))
+	   		dprintf(CRITICAL, "Failed to shutdown app: %d\n",err);
+	}
+err_dereg:
+	ret = qseecom_deregister_listener(listeners[0].id);
+	if (ret < 0) {
+		dprintf(CRITICAL, "DeReg Listener: fail: ret:%d\n", ret);
+		err = -1;
+	}
+err_ret:
+	if (err)
+		dprintf(CRITICAL, "Test %u failed with error %d, shutting down %s\n", CLIENT_CMD0_GET_VERSION, err, appname);
+	else
+		dprintf(CRITICAL, "Test %u passed for iterations %u executing %s\n", CLIENT_CMD0_GET_VERSION, iterations, appname);
+	return err;
+}
+
+int qseecom_test_cmd_handler(const char *arg) {
+	char *token = NULL;
+	char * appname = NULL;
+	uint32_t test = 0;
+	uint32_t iterations = 0;
+
+	token = strtok((char *)arg, " ");
+	if (!token) {
+		dprintf(CRITICAL, "Appname not provided, error\n");
+		return -1;
+	}
+	appname = token;
+
+	token = strtok(NULL, " ");
+	if (!token) {
+		dprintf(CRITICAL, "Test not provided, error\n");
+		return -1;
+	}
+	test = atoi(token);
+
+	token = strtok(NULL, " ");
+	if (token)
+		iterations = atoi(token);
+	else
+		dprintf(CRITICAL, "iterations not provided\n");
+
+	switch (test) {
+		case CLIENT_CMD0_GET_VERSION:
+		{
+			qsc_run_get_version(appname, iterations);
+			break;
+		}
+		case CLIENT_CMD1_BASIC_DATA:
+		{
+			qsc_run_start_stop_app_basic_test(appname, iterations);
+			break;
+		}
+
+		case CLIENT_APPSBL_QSEECOM_RUN_LISTENER_FRAMEWORK_TEST_1:
+		{
+			qsc_run_start_stop_app_listener_test(appname, iterations);
+			break;
+		}
+	}
+	dprintf(CRITICAL, "test:%u iterations:%u\n", test, iterations);
+	return 0;
+}
+
diff --git a/platform/msm_shared/include/qseecom_lk.h b/platform/msm_shared/include/qseecom_lk.h
new file mode 100644
index 0000000..dd130ed
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk.h
@@ -0,0 +1,164 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _QSEECOM_LK_H_
+#define _QSEECOM_LK_H_
+
+#define MAX_APP_NAME_SIZE  32
+#define QSEECOM_HASH_SIZE  32
+
+/* TZ Diagnostic Area legacy version number */
+#define TZBSP_DIAG_MAJOR_VERSION_LEGACY 2
+
+/*
+ * Log ring buffer position
+ */
+struct tzdbg_log_pos_t {
+	uint16_t wrap;
+	uint16_t offset;
+};
+
+ /*
+ * Log ring buffer
+ */
+struct tzdbg_log_t {
+	struct tzdbg_log_pos_t log_pos;
+	/* open ended array to the end of the 4K IMEM buffer */
+	uint8_t log_buf[];
+};
+struct scm_desc {
+	uint32_t arginfo;
+	uint32_t args[10];
+	uint32_t ret[3];
+	/* private */
+	void *extra_arg_buf;
+	uint64_t x5;
+};
+/*
+ * 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 {
+	uint32_t listener_id; /* in */
+	void *virt_sb_base; /* in */
+	uint32_t 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_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 {
+	int32_t fd;
+	uint32_t cmd_buf_offset;
+};
+
+/*
+ * struct qseecom_listener_send_resp_req - signal to continue the send_cmd req.
+ * Used as a trigger from HLOS service to notify QSEECOM that it's done with its
+ * operation and provide the response for QSEECOM can continue the incomplete
+ * command execution
+ * @resp_len - Length of the response
+ * @resp_buf - Response buffer where the response of the cmd should go.
+ */
+struct qseecom_send_resp_req {
+	void *resp_buf; /* in */
+	unsigned int resp_len; /* in */
+};
+
+/*
+ * 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.
+*/
+struct qseecom_load_img_req {
+	uint32_t mdt_len; /* in */
+	uint32_t img_len; /* in */
+	int32_t  ifd_data_fd; /* in */
+	char  img_name[MAX_APP_NAME_SIZE]; /* in */
+	int app_id; /* out*/
+};
+
+struct qseecom_set_sb_mem_param_req {
+	int32_t ifd_data_fd; /* in */
+	void *virt_sb_base; /* in */
+	uint32_t 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 */
+	int app_id; /* out */
+};
+
+struct qseecom_send_svc_cmd_req {
+	uint32_t cmd_id;
+	void *cmd_req_buf; /* in */
+	unsigned int cmd_req_len; /* in */
+	void *resp_buf; /* in/out */
+	unsigned int resp_len; /* in/out */
+};
+
+
+#endif /* _QSEECOM_LK_H_ */
diff --git a/platform/msm_shared/include/qseecom_lk_api.h b/platform/msm_shared/include/qseecom_lk_api.h
new file mode 100644
index 0000000..c26da9b
--- /dev/null
+++ b/platform/msm_shared/include/qseecom_lk_api.h
@@ -0,0 +1,189 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __QSEECOM_LK_API_H_
+#define __QSEECOM_LK_API_H_
+
+#define MAX_APP_NAME_LEN 32
+
+#include <stdint.h>
+/**
+* Qseecom Init
+*	To be called before any calls to qsee secure apps.
+*
+* @return int
+*   Success:	Init succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_init();
+
+/**
+* Qseecom Tz Init
+*	To be called before any calls to qsee secure apps.
+*
+* @return int
+*   Success:	Tz init succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_tz_init();
+
+/**
+* Qseecom Exit
+*	To be called before exit of lk.
+*	Once this is called no calls to
+*	Qsee Apps.
+*
+* @return int
+*   Success:	Exit succeeded.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_exit();
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+*   App name of the Secure App to be started
+*   The app_name provided should be the same
+*   name as the partition/ file and should
+*   be the same name mentioned in TZ_APP_NAME
+*   in the secure app.
+*
+* @return int
+*   Success:	handle to be used for all calls to
+*   			Secure app. Always greater than zero.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_start_app(char *app_name);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to be shutdown
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle);
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to send the cmd
+*
+* @param void *send_buf
+*   Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+*   Size of the request buffer
+*
+* @param void *resp_buf
+*   Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+*   Size of the response buffer
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+			uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len);
+
+typedef int (*ListenerCallback)(void*, uint32_t);
+
+/**
+ * @param char* service_name
+ * 	 The name of the listener service.
+ * @param uint32_t  id
+ * 	 The id used to register a listener with
+ * 	 QSEE in the secure side. This id should
+ * 	 be unique.
+ * @param ListenerCallback service_cmd_handler
+ *   This is the service cmd handler, this cb
+ *   is called for a specific service request.
+ *   The input params are,
+ * 		@param void *buf
+ * 		  The shared buffer which contains the
+ * 		  request from the secure side. The service
+ * 		  also updates this buffer with the response.
+ * 		@param uint32_t size
+ * 		  The size of the shared buffer.
+ *      @return int
+ *        Success:	Exit succeeded.
+ *        Failure:	Error code (negative only).
+ */
+struct qseecom_listener_services {
+	char *service_name;
+	uint32_t  id;
+	uint32_t sb_size;
+	ListenerCallback service_cmd_handler;
+};
+
+/**
+* Registers a Listener Service with QSEE
+*  This api should be called after all
+*  service specific initialization is
+*  completed, once this is called the
+*  service_cmd_handler for the service can
+*  be called.
+*
+* @param struct qseecom_listener_services listnr
+*   Listener structure that contains all the info
+*   to register a listener service.
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr);
+
+/**
+* De-Registers a Listener Service with QSEE
+*  This api should be called before exiting lk and
+*  all service de-init should be done before calling
+*  the api. service_cmd_handler will not be called
+*  after this api is called.
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be de-registered
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id);
+
+#endif /* __QSEECOM_API_LK_H_ */
diff --git a/platform/msm_shared/include/qseecomi_lk.h b/platform/msm_shared/include/qseecomi_lk.h
new file mode 100644
index 0000000..1209833
--- /dev/null
+++ b/platform/msm_shared/include/qseecomi_lk.h
@@ -0,0 +1,520 @@
+/* Copyright (c) 2013-2014, 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __QSEECOMI_LK_H_
+#define __QSEECOMI_LK_H_
+
+#include <qseecom_lk.h>
+
+#define QSEECOM_KEY_ID_SIZE   32
+
+#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
+
+enum qseecom_command_scm_resp_type {
+	QSEOS_APP_ID = 0xEE01,
+	QSEOS_LISTENER_ID,
+    QSEOS_PIPE_ENUM_FILL1 = 0x7FFFFFFF
+};
+
+typedef enum
+{
+  QSEE_APP_START_COMMAND = 0x01,
+  QSEE_APP_SHUTDOWN_COMMAND,
+  QSEE_APP_LOOKUP_COMMAND,
+  QSEE_REGISTER_LISTENER,
+  QSEE_DEREGISTER_LISTENER,
+  QSEE_CLIENT_SEND_DATA_COMMAND,
+  QSEE_LISTENER_DATA_RSP_COMMAND,
+  QSEE_LOAD_EXTERNAL_ELF_COMMAND,
+  QSEE_UNLOAD_EXTERNAL_ELF_COMMAND,
+  QSEE_GET_APP_STATE_COMMAND,
+  QSEE_LOAD_SERV_IMAGE_COMMAND,
+  QSEE_UNLOAD_SERV_IMAGE_COMMAND,
+  QSEE_APP_REGION_NOTIFICATION,
+  QSEE_REGISTER_LOG_BUF_COMMAND,
+  QSEE_RPMB_PROVISION_KEY_COMMAND,
+  QSEE_RPMB_ERASE_COMMAND,
+  QSEE_KS_GEN_KEY_COMMAND,
+  QSEE_KS_DEL_KEY_COMMAND,
+  QSEE_KS_GET_MAX_KEYS_COMMAND,
+  QSEE_KS_SET_PIPE_KEY_COMMAND,
+  QSEE_KS_UPDATE_KEY_COMMAND,
+  QSEE_GP_OPEN_SESSION,
+  QSEE_GP_INVOKE_COMMAND,
+  QSEE_GP_CLOSE_SESSION,
+  QSEOS_PIPE_ENUM_FILL2 = 0x7FFFFFFF
+}qsee_smc_command_type;
+
+enum qseecom_qceos_cmd_status {
+	QSEOS_RESULT_SUCCESS = 0,
+	QSEOS_RESULT_INCOMPLETE,
+	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
+};
+
+struct __attribute__ ((packed)) qsee_apps_region_info_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t addr;
+	uint32_t size;
+};
+
+struct __attribute__ ((packed)) qseecom_check_app_ireq {
+	uint32_t qsee_cmd_id;
+	char     app_name[MAX_APP_NAME_SIZE];
+};
+
+struct __attribute__ ((packed)) 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*/
+};
+
+struct __attribute__ ((packed)) qseecom_unload_app_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  app_id;
+};
+
+struct __attribute__ ((packed)) qseecom_load_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t mdt_len;
+	uint32_t img_len;
+	uint32_t phy_addr;
+};
+
+struct __attribute__ ((packed)) qseecom_unload_lib_image_ireq {
+	uint32_t qsee_cmd_id;
+};
+
+struct __attribute__ ((packed)) qseecom_register_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t sb_ptr;
+	uint32_t sb_len;
+};
+
+struct __attribute__ ((packed)) qseecom_unregister_listener_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t  listener_id;
+};
+
+struct __attribute__ ((packed)) 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;
+};
+
+struct __attribute__ ((packed)) qseecom_reg_log_buf_ireq {
+	uint32_t qsee_cmd_id;
+	uint32_t phy_addr;
+	uint32_t len;
+};
+
+/* send_data resp */
+struct __attribute__ ((packed)) qseecom_client_listener_data_irsp {
+	uint32_t qsee_cmd_id;
+	uint32_t listener_id;
+	uint32_t status;
+};
+
+/*
+ * 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 __attribute__ ((packed)) qseecom_command_scm_resp {
+	uint32_t result;
+	enum qseecom_command_scm_resp_type resp_type;
+	unsigned int data;
+};
+
+struct qseecom_rpmb_provision_key {
+	uint32_t key_type;
+};
+
+struct __attribute__ ((packed)) 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 */
+};
+
+struct __attribute__ ((packed)) 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];
+};
+
+struct __attribute__ ((packed)) 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];
+};
+
+struct __attribute__ ((packed)) 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];
+
+};
+
+struct __attribute__ ((packed)) 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];
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_ireq {
+	uint32_t flags;
+};
+
+struct __attribute__ ((packed)) qseecom_key_max_count_query_irsp {
+	uint32_t max_key_count;
+};
+
+struct __attribute__ ((packed)) 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;
+};
+
+struct __attribute__ ((packed)) qseecom_client_send_fsm_key_req {
+	uint32_t qsee_cmd_id;
+	uint32_t req_ptr;
+	uint32_t req_len;
+	uint32_t rsp_ptr;
+	uint32_t rsp_len;
+};
+
+
+/**********      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_ES                        16    /* Enterprise Security */
+
+/*----------------------------------------------------------------------------
+ * 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
+
+#define TZ_SYSCALL_PARAM_TYPE_VAL              0x0     /** type of value */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RO           0x1     /** type of buffer read-only */
+#define TZ_SYSCALL_PARAM_TYPE_BUF_RW           0x2     /** type of buffer read-write */
+
+#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_OS_REGISTER_LISTENER_ID \
+	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x01)
+
+#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_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)
+
+#endif /* __QSEECOMI_LK_H_ */
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
new file mode 100644
index 0000000..bd073a6
--- /dev/null
+++ b/platform/msm_shared/qseecom_lk.c
@@ -0,0 +1,1166 @@
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define pr_fmt(fmt) "QSEECOM: %s: " fmt, __func__
+
+#include <partition_parser.h>
+#include <qseecom_lk.h>
+#include <scm.h>
+#include <qseecomi_lk.h>
+#include "qseecom_lk_api.h"
+#include <debug.h>
+#include <kernel/mutex.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <arch/defines.h>
+#include <string.h>
+#include <platform/iomap.h>
+#include <platform.h>
+
+#define QSEOS_VERSION_14  0x14
+#define QSEEE_VERSION_00  0x400000
+#define QSEE_VERSION_20   0x800000
+
+
+#define QSEOS_CHECK_VERSION_CMD  0x00001803
+
+#define MAX_SCM_ARGS 10
+#define N_EXT_SCM_ARGS 7
+#define FIRST_EXT_ARG_IDX 3
+
+#define N_REGISTER_ARGS (MAX_SCM_ARGS - N_EXT_SCM_ARGS + 1)
+
+#define QSEE_LOG_BUF_SIZE (4096)
+#define GENERIC_ERROR -1
+#define LISTENER_ALREADY_PRESENT_ERROR -2
+
+#define TZ_CALL 6
+enum qseecom_client_handle_type {
+	QSEECOM_CLIENT_APP = 1,
+	QSEECOM_LISTENER_SERVICE,
+	QSEECOM_SECURE_SERVICE,
+	QSEECOM_GENERIC,
+	QSEECOM_UNAVAILABLE_CLIENT_APP,
+};
+
+struct qseecom_registered_listener_list {
+	struct list_node node;
+	struct qseecom_register_listener_req svc;
+	ListenerCallback CallbackFn;
+};
+
+struct qseecom_registered_app_list {
+	struct list_node node;
+	uint32_t  app_id;
+	uint32_t  ref_cnt;
+	char app_name[MAX_APP_NAME_SIZE];
+	int  handle;
+};
+
+struct qseecom_control {
+	struct list_node  registered_listener_list_head;
+	mutex_t           registered_listener_list_lock;
+
+	struct list_node  registered_app_list_head;
+	mutex_t           registered_app_list_lock;
+
+	uint32_t          qseos_version;
+	uint32_t          qsee_version;
+	int               handle;
+	bool              commonlib_loaded;
+	mutex_t           global_data_lock;
+	uint32_t          cmnlib_loaded;
+	uint32_t          qseecom_init_done;
+	uint32_t          qseecom_tz_init_done;
+};
+
+struct qseecom_listener_handle {
+	uint32_t               id;
+};
+
+static struct qseecom_reg_log_buf_ireq logbuf_req;
+static struct qseecom_control qseecom;
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+          struct qseecom_client_listener_data_irsp *send_data_rsp);
+
+/*
+ * Appsbl runs in Aarch32 when this is ported for Aarch64,
+ * change return type for uint64_t.
+ */
+static uint32_t __qseecom_uvirt_to_kphys(uint64_t virt)
+{
+	dprintf(SPEW, "%s called\n", __func__);
+	return (uint32_t)platform_get_virt_to_phys_mapping((addr_t)virt);
+}
+
+static int _disp_log_stats(struct tzdbg_log_t *log, uint32_t log_len,
+		uint32_t startOffset, uint32_t endOffset)
+{
+	uint32_t MaxBufSize = 0;
+	uint32_t LogBufSize = 0;
+	uint32_t LogBufFirstHalf = 0;
+	uint32_t len = 0;
+	char *pCurPos, *pPrintPos = NULL;
+	void *pLogBuf = NULL;
+	int ret = GENERIC_ERROR;
+
+	MaxBufSize = QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t);
+
+	dprintf(SPEW, "%s called\n", __func__);
+	if (startOffset < endOffset)
+	{
+		LogBufSize = endOffset - startOffset;
+		pLogBuf = malloc(LogBufSize);
+		if (NULL == pLogBuf)
+		{
+			ret = GENERIC_ERROR;
+			dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+			goto err;
+		}
+		memset(pLogBuf, 0, LogBufSize);
+		memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufSize);
+	}
+	else if ( endOffset < startOffset)
+	{
+		LogBufSize =  MaxBufSize - (startOffset - endOffset);
+		LogBufFirstHalf = MaxBufSize - startOffset;
+		pLogBuf = malloc(LogBufSize);
+		if (NULL == pLogBuf)
+		{
+			ret = GENERIC_ERROR;
+			dprintf(CRITICAL, "Failed to alloc buffer to print TZ Log:%u\n", LogBufSize);
+			goto err;
+		}
+		memset(pLogBuf, 0, LogBufSize);
+		memscpy(pLogBuf, LogBufSize, (char *)((uint32_t)log->log_buf + startOffset), LogBufFirstHalf);
+		memscpy((char *)((uint32_t)pLogBuf+ LogBufFirstHalf), (LogBufSize - LogBufFirstHalf), log->log_buf, endOffset);
+	}
+	else //endOffset == startOffset
+	{
+		ret = 0;
+		goto err;
+	}
+
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	pCurPos = pLogBuf;
+	pPrintPos = pCurPos;
+	while (len < LogBufSize)
+	{
+			//QSEE separate each line by "\r \n"
+			if ((*pCurPos == '\r')&&(*(pCurPos+1) == '\n'))
+			{
+				//update the line to dump
+				*pCurPos = '\0';
+				len++;
+				pCurPos++;
+				*pCurPos = '\0';
+				len++;
+				pCurPos++;
+				dprintf(ALWAYS, "%s\n", pPrintPos);
+				pPrintPos = pCurPos;
+				continue;
+			}
+			len++;
+			pCurPos++;
+	}
+	ret = 0;
+	free(pLogBuf);
+err:
+	return ret;
+}
+
+static int qseecom_scm_call(uint32_t svc_id, uint32_t tz_cmd_id, void *cmd_buf,
+		size_t cmd_len, void *resp_buf, size_t resp_len)
+{
+	void *req = NULL;
+	struct qseecom_command_scm_resp *resp = NULL;
+	struct qseecom_client_listener_data_irsp send_data_rsp = {0};
+	int ret = GENERIC_ERROR;
+	uint32_t qseos_cmd_id = 0;
+
+	if ((!cmd_buf) || (!resp_buf))
+			return GENERIC_ERROR;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.registered_app_list_lock);
+	req = cmd_buf;
+	qseos_cmd_id = *(uint32_t *)req;
+	resp = (struct qseecom_command_scm_resp *) resp_buf;
+
+	do {
+		ret = scm_call(svc_id, tz_cmd_id, req, cmd_len,
+				resp_buf, resp_len);
+
+		if (ret) {
+			dprintf(CRITICAL, "ERROR: scm_call to load failed : ret %d\n", ret);
+			ret = GENERIC_ERROR;
+			goto err;
+		}
+
+		if (svc_id == TZ_CALL) {
+			goto err;
+		}
+
+		switch (resp->result) {
+			case QSEOS_RESULT_SUCCESS:
+				if(((resp->resp_type != QSEOS_APP_ID) || (resp->data <= 0)) &&
+					((qseos_cmd_id == QSEE_CLIENT_SEND_DATA_COMMAND) ||
+							(qseos_cmd_id == QSEE_LISTENER_DATA_RSP_COMMAND)))
+				{
+					dprintf(CRITICAL, "ERROR: Resp type %d or Resp Data %d incorrect\n",
+							resp->resp_type, resp->data);
+					ret = GENERIC_ERROR;
+					goto err;
+				}
+				goto err;
+			case QSEOS_RESULT_FAILURE:
+				dprintf(CRITICAL, "scm call failed w/response result%d\n", resp->result);
+				ret = GENERIC_ERROR;
+				goto err;
+			case  QSEOS_RESULT_INCOMPLETE:
+				if(resp->resp_type != QSEOS_LISTENER_ID)
+				{
+					ret = GENERIC_ERROR;
+					dprintf(CRITICAL, "Listener service incorrect resp->result:%d resp->resp_type:%d\n",
+							resp->result, resp->resp_type);
+					goto err;
+				}
+				__qseecom_process_incomplete_cmd(resp, &send_data_rsp);
+				req = (void *)&send_data_rsp;
+				qseos_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+				break;
+			default:
+				dprintf(CRITICAL, "scm call return unknown response %d\n",	resp->result);
+				ret = GENERIC_ERROR;
+				goto err;
+		}
+	} while(true);
+
+err:
+	mutex_release(&qseecom.registered_app_list_lock);
+	return ret;
+
+}
+
+static int __qseecom_process_incomplete_cmd(struct qseecom_command_scm_resp *resp,
+		struct qseecom_client_listener_data_irsp *send_data_rsp)
+{
+	int ret = 0;
+	struct qseecom_registered_listener_list *entry;
+
+	if ((!resp) || (!send_data_rsp))
+	{
+		return GENERIC_ERROR;
+	}
+
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+
+	list_for_every_entry(&qseecom.registered_listener_list_head,
+			entry, struct qseecom_registered_listener_list, node) {
+		if (resp->data == entry->svc.listener_id) {
+			arch_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+			entry->CallbackFn(entry->svc.virt_sb_base, entry->svc.sb_size);
+			arch_clean_invalidate_cache_range((addr_t) entry->svc.virt_sb_base, entry->svc.sb_size);
+			break;
+		}
+	}
+	send_data_rsp->qsee_cmd_id = QSEE_LISTENER_DATA_RSP_COMMAND;
+	send_data_rsp->listener_id  = entry->svc.listener_id;
+	send_data_rsp->status  = 0;
+	mutex_release(&qseecom.global_data_lock);
+	return ret;
+}
+
+static int __qseecom_load_app(const char *app_name, unsigned int *app_id)
+{
+	int index = INVALID_PTN;
+	unsigned long long ptn = 0;
+	unsigned long long size = 0;
+	void *buf = NULL;
+	void *req = NULL;
+	struct qseecom_load_app_ireq load_req = {0};
+	struct qseecom_command_scm_resp resp;
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	int ret = GENERIC_ERROR;
+	uint8_t lun = 0;
+
+	if (!app_name)
+		return GENERIC_ERROR;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	index = partition_get_index(app_name);
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
+	size = partition_get_size(index);
+
+	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+				__func__, app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	ptn = partition_get_offset(index);
+	if(ptn == 0) {
+		dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	if (mmc_read(ptn, (unsigned int *) buf, size)) {
+		dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	load_req.qsee_cmd_id = QSEE_APP_START_COMMAND;
+	load_req.img_len = size;
+	load_req.mdt_len = 0;
+	dprintf(SPEW, "phy_addr:%u img_len:%u\n", load_req.phy_addr, load_req.img_len);
+
+	memscpy(&load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+	req = (void *)&load_req;
+
+	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogStart = (uint32_t) log->log_pos.offset;
+
+	arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+				sizeof(struct qseecom_load_lib_image_ireq),
+							&resp, sizeof(resp));
+	if(ret == 0)
+		*app_id = resp.data;
+	else
+		*app_id = 0;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			QseeLogStart, QseeLogNewStart);
+err:
+	if (buf)
+		free(buf);
+	return ret;
+}
+
+static int qseecom_load_commonlib_image(char * app_name)
+{
+	int index = INVALID_PTN;
+	unsigned long long ptn = 0;
+	unsigned long long size = 0;
+	void *buf = NULL;
+	void *req = NULL;
+	struct qseecom_load_app_ireq load_req = {0};
+	struct qseecom_command_scm_resp resp = {0};
+	int ret = GENERIC_ERROR;
+	uint8_t lun = 0;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	index = partition_get_index(app_name);
+	lun = partition_get_lun(index);
+	mmc_set_lun(lun);
+
+	size = partition_get_size(index);
+
+	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
+				__func__, app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	ptn = partition_get_offset(index);
+	if(ptn == 0) {
+		dprintf(CRITICAL, "ERROR: No %s found\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	if (mmc_read(ptn, (unsigned int *) buf, size)) {
+		dprintf(CRITICAL, "ERROR: Cannot read %s image\n", app_name);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	load_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	load_req.qsee_cmd_id = QSEE_LOAD_SERV_IMAGE_COMMAND;
+	load_req.img_len = size;
+	load_req.mdt_len = 0;
+
+	memscpy(load_req.app_name, MAX_APP_NAME_SIZE, app_name, MAX_APP_NAME_SIZE);
+	req = (void *)&load_req;
+
+	arch_clean_invalidate_cache_range((addr_t) load_req.phy_addr, load_req.img_len);
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req,
+				sizeof(struct qseecom_load_lib_image_ireq),
+							&resp, sizeof(resp));
+	if(ret == 0)
+		ret = resp.data;
+
+err:
+	if (buf)
+		free(buf);
+	return ret;
+}
+
+static int qseecom_unload_commonlib_image(void)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_unload_lib_image_ireq unload_req = {0};
+	struct qseecom_command_scm_resp resp;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	/* Populate the remaining parameters */
+	unload_req.qsee_cmd_id = QSEE_UNLOAD_SERV_IMAGE_COMMAND;
+	/* SCM_CALL to load the image */
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &unload_req,
+			sizeof(struct qseecom_unload_lib_image_ireq),
+						&resp, sizeof(resp));
+	return ret;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list *
+	__qseecom_add_app_entry(char *app_name, uint32_t app_id)
+{
+	struct qseecom_registered_app_list *entry = NULL;
+	int32_t ret = GENERIC_ERROR;
+
+	if ((!app_name) || (app_id == 0)) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	entry = malloc(sizeof(*entry));
+	if (!entry) {
+		dprintf(CRITICAL, "malloc for app entry failed\n");
+		ret =  GENERIC_ERROR;
+		goto err;
+	}
+	entry->app_id = app_id;
+	entry->ref_cnt = 1;
+	strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
+
+	dprintf(SPEW, "%s: Adding app:%s app_id:%u to list\n", __func__, entry->app_name, entry->app_id);
+	list_add_tail(&qseecom.registered_app_list_head, &entry->node);
+	ret = 0;
+err:
+	if (entry && (ret < 0)) {
+		free(entry);
+		return NULL;
+	}
+	return entry;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static int
+	__qseecom_remove_app_entry(struct qseecom_registered_app_list *entry)
+{
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	list_delete(&entry->node);
+	free(entry);
+
+	return 0;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+struct qseecom_registered_listener_list *
+	__qseecom_check_listener_exists(uint32_t listener_id)
+{
+	struct qseecom_registered_listener_list *entry = NULL;
+	bool listener_present = false;
+
+	if (!listener_id) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	list_for_every_entry(&qseecom.registered_listener_list_head,
+			entry, struct qseecom_registered_listener_list, node) {
+		if (entry->svc.listener_id == listener_id) {
+			listener_present = true;
+			break;
+		}
+	}
+	if (listener_present)
+		return entry;
+	else
+		return NULL;
+}
+
+/*
+ * This function is called with the global
+ * data mutex acquired.
+ */
+static struct qseecom_registered_app_list
+	*__qseecom_check_handle_exists(int handle)
+{
+	struct qseecom_registered_app_list *entry;
+	bool app_present = false;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s: Invalid Input\n", __func__);
+		return NULL;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	list_for_every_entry(&qseecom.registered_app_list_head,
+			entry, struct qseecom_registered_app_list, node) {
+		if (entry->handle == handle) {
+			app_present = true;
+			break;
+		}
+	}
+
+	if (app_present == true)
+		return entry;
+	else
+		return NULL;
+
+}
+
+
+static struct qseecom_registered_app_list *
+	__qseecom_check_app_exists(char *app_name)
+{
+	struct qseecom_registered_app_list *entry = NULL;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	list_for_every_entry(&qseecom.registered_app_list_head,
+			entry, struct qseecom_registered_app_list, node) {
+		if (!strncmp(app_name, entry->app_name, 32)) {
+			dprintf(SPEW, "%s: app_name:%s\n", __func__, app_name);
+			return entry;
+		}
+	}
+	return NULL;
+}
+
+static int qseecom_unload_app(uint32_t app_id)
+{
+	int ret = 0;
+	struct qseecom_command_scm_resp resp;
+	struct qseecom_unload_app_ireq req;
+
+	dprintf(SPEW, "%s called\n", __func__);
+	/* Populate the structure for sending scm call to load image */
+	req.qsee_cmd_id = QSEE_APP_SHUTDOWN_COMMAND;
+	req.app_id = app_id;
+
+	/* SCM_CALL to unload the app */
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+			sizeof(struct qseecom_unload_app_ireq),
+			&resp, sizeof(resp));
+
+	return ret;
+}
+
+
+static int __qseecom_send_cmd(uint32_t app_id, struct qseecom_send_cmd_req *req)
+{
+	int ret = 0;
+	struct qseecom_client_send_data_ireq send_data_req;
+	struct qseecom_command_scm_resp resp;
+	void *buf = NULL;
+	uint32_t size = 0;
+
+	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
+		dprintf(CRITICAL, "%s: cmd buffer or response buffer is null\n",
+				__func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+	/* Allocate for req or rsp len whichever is higher, both req and rsp point
+	 * to the same buffer
+	 */
+	size = (req->cmd_req_len > req->resp_len) ? req->cmd_req_len : req->resp_len;
+
+	/* The req rsp buffer will be xPU protected by TZ during a TZ APP call
+	 * This will still be protected during a listener call and there is a
+	 * possibility of prefetching happening, which will cause xPU violation.
+	 * Hence using (device memory with xN set) to prevent I or D prefetching.
+	 * This is a contiguous region of 1MB used only for this, hence will not
+	 * free this.
+	 */
+	buf = (void *)RPMB_SND_RCV_BUF;
+	if (!buf) {
+		dprintf(CRITICAL, "%s: Aloc failed for app_id:%d of size:%d\n",
+				__func__, app_id, size);
+		return GENERIC_ERROR;
+	}
+
+	memscpy(buf, ROUNDUP(size, PAGE_SIZE), req->cmd_req_buf, req->cmd_req_len);
+
+	send_data_req.qsee_cmd_id = QSEE_CLIENT_SEND_DATA_COMMAND;
+	send_data_req.app_id = app_id;
+
+	/* Currently on 8994 only 32-bit phy addr is supported
+	 * Hence downcasting is okay
+	 */
+	send_data_req.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	send_data_req.req_len = req->cmd_req_len;
+	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	send_data_req.rsp_len = req->resp_len;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+				(void *)&send_data_req,
+				sizeof(send_data_req), (void *)&resp, sizeof(resp));
+
+	memscpy(req->resp_buf, req->resp_len, (void *)send_data_req.rsp_ptr, send_data_req.rsp_len);
+	return ret;
+}
+
+/**
+* Start a Secure App
+*
+* @param char* app_name
+*   App name of the Secure App to be started
+*
+* @return int
+*   Success:	handle to be used for all calls to
+*   			Secure app. Always greater than zero.
+*   Failure:	Error code (negative only).
+*/
+int qseecom_start_app(char *app_name)
+{
+	int32_t ret = GENERIC_ERROR;
+	int handle = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	unsigned int app_id = 0;
+
+	if (!app_name) {
+		dprintf(CRITICAL, "%s: Input error\n", __func__);
+		goto err;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)){
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	/* Load commonlib image*/
+	if (!qseecom.cmnlib_loaded) {
+		ret = qseecom_load_commonlib_image("cmnlib");
+		if (ret) {
+			mutex_release(&qseecom.global_data_lock);
+			dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
+					__func__, ret);
+			goto err;
+		}
+		qseecom.cmnlib_loaded = 1;
+	}
+	/* Check if App already exits, if exits increase ref_cnt
+	 * and return handle, else load the app from partition,
+	 * call into TZ to load it, add to list and then return
+	 * handle.
+	 */
+
+	entry = __qseecom_check_app_exists(app_name);
+	if (!entry) {
+		mutex_release(&qseecom.global_data_lock);
+		/* load the app and get the app_id  */
+		dprintf(INFO, "%s: Loading app %s for the first time'\n",
+				__func__, app_name);
+
+		ret = __qseecom_load_app(app_name, &app_id);
+		if ((ret < 0) || (app_id ==0)) {
+			dprintf(CRITICAL, "%s: __qseecom_load_app failed with err:%d for app:%s\n",
+					__func__, ret, app_name);
+			ret = GENERIC_ERROR;
+			goto err;
+		}
+		mutex_acquire(&qseecom.global_data_lock);
+		entry = __qseecom_add_app_entry(app_name, app_id);
+		if (!entry)
+		{
+			dprintf(CRITICAL, "%s: __qseecom_add_app_entry failed\n", __func__);
+			ret = GENERIC_ERROR;
+			mutex_release(&qseecom.global_data_lock);
+			goto err;
+		}
+		qseecom.handle++;
+		entry->handle = qseecom.handle;
+		handle = entry->handle;
+		mutex_release(&qseecom.global_data_lock);
+	}
+	else {
+		entry->ref_cnt++;
+		handle = entry->handle;
+		mutex_release(&qseecom.global_data_lock);
+	}
+	return handle;
+err:
+	return ret;
+}
+
+/**
+* Shutdown a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to be shutdown
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_shutdown_app(int handle)
+{
+	int ret = GENERIC_ERROR;
+	int ref_cnt = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s: Invalid Handle %d\n", __func__, handle);
+		goto err;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	entry = __qseecom_check_handle_exists(handle);
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Shutdown on an app that was never loaded handle:%d\n",
+				__func__, handle);
+		ret = GENERIC_ERROR;
+		mutex_release(&qseecom.global_data_lock);
+		goto err;
+	}
+
+	/* Decrement ref_cnt by 1, if ref_cnt is 0 after
+	 * decrementing unload the app by calling into
+	 * TZ else just return.
+	 */
+
+	if(entry->ref_cnt != 0)
+		entry->ref_cnt--;
+	ref_cnt = entry->ref_cnt;
+	mutex_release(&qseecom.global_data_lock);
+	if (ref_cnt == 0) {
+		log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+		QseeLogStart = (uint32_t) log->log_pos.offset;
+
+		ret = qseecom_unload_app(entry->app_id);
+		arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+		QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+		_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+				QseeLogStart, QseeLogNewStart);
+		if(ret) {
+			dprintf(CRITICAL, "%s: qseecom_unload_app failed with err:%d for handle:%d\n",
+					__func__, ret, handle);
+			goto err;
+		}
+		mutex_acquire(&qseecom.global_data_lock);
+		ret = __qseecom_remove_app_entry(entry);
+		mutex_release(&qseecom.global_data_lock);
+		if(ret) {
+			dprintf(CRITICAL, "%s: __qseecom_remove_app_entry failed with err:%d for handle:%d\n",
+					__func__, ret, handle);
+			goto err;
+		}
+	}
+	ret = 0;
+err:
+	return ret;
+}
+
+/**
+* Send cmd to a Secure App
+*
+* @param int handle
+*   Handle  of the Secure App to send the cmd
+*
+* @param void *send_buf
+*   Pointer to the App request buffer
+*
+* @param uint32_t sbuf_len
+*   Size of the request buffer
+*
+* @param void *resp_buf
+*   Pointer to the App response buffer
+*
+* @param uint32_t rbuf_len
+*   Size of the response buffer
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_send_command(int handle, void *send_buf,
+			uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len)
+{
+	int ret = GENERIC_ERROR;
+	uint32_t app_id = 0;
+	struct qseecom_registered_app_list *entry = NULL;
+	struct qseecom_send_cmd_req req = {0, 0, 0, 0};
+	struct tzdbg_log_t *log = NULL;
+	uint32_t QseeLogStart = 0;
+	uint32_t QseeLogNewStart = 0;
+
+	if (handle <= 0) {
+		dprintf(CRITICAL, "%s Handle is Invalid\n", __func__);
+		return GENERIC_ERROR;
+	}
+
+	if((!send_buf) || (!resp_buf)) {
+		dprintf(CRITICAL, "%s: Input Buffers invalid\n", __func__);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_acquire(&qseecom.global_data_lock);
+	if ((!qseecom.qseecom_init_done)
+			|| (!qseecom.qseecom_tz_init_done)) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	entry = __qseecom_check_handle_exists(handle);
+	if (!entry) {
+		dprintf(CRITICAL, "%s: Send cmd on an app that was never loaded handle:%d\n",
+				__func__, handle);
+		ret = GENERIC_ERROR;
+		mutex_release(&qseecom.global_data_lock);
+		goto err;
+	}
+
+	app_id = entry->app_id;
+	mutex_release(&qseecom.global_data_lock);
+
+	req.cmd_req_len = sbuf_len;
+	req.resp_len = rbuf_len;
+	req.cmd_req_buf = send_buf;
+	req.resp_buf = resp_buf;
+
+	log = (struct tzdbg_log_t *)logbuf_req.phy_addr;
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogStart = (uint32_t) log->log_pos.offset;
+
+	ret = __qseecom_send_cmd(app_id, &req);
+	if (ret) {
+		dprintf(CRITICAL, "%s __qseecom_send_cmd failed with err:%d for handle:%d\n",
+				__func__, ret, handle);
+		goto err;
+	}
+	arch_invalidate_cache_range((addr_t) logbuf_req.phy_addr, logbuf_req.len);
+	QseeLogNewStart = (uint32_t) log->log_pos.offset;
+
+	_disp_log_stats((struct tzdbg_log_t *) logbuf_req.phy_addr, QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			QseeLogStart, QseeLogNewStart);
+	ret = 0;
+	dprintf(SPEW, "sending cmd_req->rsp size: %u, ptr: 0x%p\n",
+			req.resp_len, req.resp_buf);
+err:
+	return ret;
+}
+
+/**
+* Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be registered
+*
+* @param uint32_t sb_size
+*   Shared buffer size required for the listener
+*   service.
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_register_listener(struct qseecom_listener_services *listnr)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_registered_listener_list *new_entry = NULL;
+	struct qseecom_register_listener_ireq req;
+	struct qseecom_command_scm_resp resp;
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if (!qseecom.qseecom_init_done) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	mutex_release(&qseecom.global_data_lock);
+
+	mutex_acquire(&qseecom.registered_listener_list_lock);
+
+	if ((!listnr)) {
+		dprintf(CRITICAL, "%s Invalid Input listnr\n", __func__);
+		return GENERIC_ERROR;
+	}
+
+	if ((!listnr->id) || (!listnr->sb_size) || (!listnr->service_cmd_handler)) {
+		dprintf(CRITICAL, "%s Invalid Input listnr_id:%d sb_size:%d\n",
+				__func__, listnr->id, listnr->sb_size);
+		return GENERIC_ERROR;
+	}
+	dprintf(SPEW, "%s called\n", __func__);
+	new_entry = __qseecom_check_listener_exists(listnr->id);
+	if (new_entry) {
+		dprintf(CRITICAL, "Service is not unique and is already registered\n");
+		ret = LISTENER_ALREADY_PRESENT_ERROR;
+		goto err;
+	}
+
+	new_entry = malloc(sizeof(*new_entry));
+	if (!new_entry) {
+		dprintf(CRITICAL, "%s new_entry malloc failed for size:%d\n", __func__, sizeof(*new_entry));
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	memset(new_entry, 0, sizeof(*new_entry));
+	new_entry->svc.listener_id = listnr->id;
+	new_entry->svc.sb_size = listnr->sb_size;
+	new_entry->CallbackFn = listnr->service_cmd_handler;
+
+	new_entry->svc.virt_sb_base = memalign(PAGE_SIZE, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+	if (!new_entry->svc.virt_sb_base) {
+		dprintf(CRITICAL, "%s virt_sb_base malloc failed for size:%d\n", __func__, listnr->sb_size);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	memset(new_entry->svc.virt_sb_base, 0, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+	arch_clean_invalidate_cache_range((addr_t) new_entry->svc.virt_sb_base, ROUNDUP(listnr->sb_size, PAGE_SIZE));
+
+	req.qsee_cmd_id = QSEE_REGISTER_LISTENER;
+	req.listener_id = new_entry->svc.listener_id;
+	req.sb_len = new_entry->svc.sb_size;
+	/* convert to 32bit addr for tz */
+	req.sb_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) new_entry->svc.virt_sb_base);
+
+	resp.result = QSEOS_RESULT_INCOMPLETE;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+					sizeof(req), &resp, sizeof(resp));
+	if (ret) {
+		dprintf(CRITICAL, "qseecom_scm_call failed with err: %d\n", ret);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	/* Add entry to Listener list */
+	list_add_tail(&qseecom.registered_listener_list_head, &new_entry->node);
+err:
+	if ((ret) &&
+			(ret != LISTENER_ALREADY_PRESENT_ERROR)) {
+		if ((new_entry) &&
+				(new_entry->svc.virt_sb_base))
+			free(new_entry->svc.virt_sb_base);
+		if (new_entry)
+			free(new_entry);
+	}
+	mutex_release(&qseecom.registered_listener_list_lock);
+	return ret;
+}
+
+/**
+* De-Registers a Listener Service with QSEE
+*
+* @param uint32_t listnr_id
+*   Pre-defined Listener ID to be de-registered
+*
+* @return int
+*   Status:
+*     0 - Success
+*     Negative value indicates failure.
+*/
+int qseecom_deregister_listener(uint32_t listnr_id)
+{
+	int ret = GENERIC_ERROR;
+	struct qseecom_registered_listener_list *new_entry = NULL;
+	struct qseecom_unregister_listener_ireq req;
+	struct qseecom_command_scm_resp resp;
+
+	mutex_acquire(&qseecom.global_data_lock);
+	if (!qseecom.qseecom_init_done) {
+		dprintf(CRITICAL, "%s qseecom_init not done\n",
+							__func__);
+		mutex_release(&qseecom.global_data_lock);
+		return ret;
+	}
+	mutex_release(&qseecom.global_data_lock);
+
+	mutex_acquire(&qseecom.registered_listener_list_lock);
+	dprintf(SPEW, "%s called\n", __func__);
+	new_entry = __qseecom_check_listener_exists(listnr_id);
+	if (!new_entry) {
+		dprintf(CRITICAL, "Service not present\n");
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	req.qsee_cmd_id = QSEE_DEREGISTER_LISTENER;
+	req.listener_id = listnr_id;
+	resp.result = QSEOS_RESULT_INCOMPLETE;
+
+	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+					sizeof(req), &resp, sizeof(resp));
+	if (ret) {
+		dprintf(CRITICAL, "scm_call() failed with err: %d (lstnr id=%d)\n",
+				ret, req.listener_id);
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+
+	list_delete(&new_entry->node);
+
+err:
+	if (ret == 0) {
+		if (new_entry)
+			free(new_entry);
+	}
+	mutex_release(&qseecom.registered_listener_list_lock);
+	return ret;
+}
+
+int qseecom_tz_init()
+{
+	struct qsee_apps_region_info_ireq req;
+	struct qseecom_command_scm_resp resp;
+	int rc = GENERIC_ERROR;
+	/* register log buffer scm request */
+	void *buf = NULL;
+	/* Register app region with TZ */
+	req.qsee_cmd_id = QSEE_APP_REGION_NOTIFICATION;
+	req.addr = APP_REGION_ADDR;
+	req.size = APP_REGION_SIZE;
+	dprintf(ALWAYS, "secure app region addr=0x%x size=0x%x",
+					req.addr, req.size);
+	rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+			&req, sizeof(req),
+			&resp, sizeof(resp));
+	dprintf(ALWAYS, "TZ App region notif returned with status:%d addr:%x size:%d\n",
+			rc, req.addr, req.size);
+	if (rc)
+		goto err;
+	buf = memalign(PAGE_SIZE, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+	if (!buf) {
+		rc = GENERIC_ERROR;
+		goto err;
+	}
+	memset(buf, 0, ROUNDUP(QSEE_LOG_BUF_SIZE, PAGE_SIZE));
+	logbuf_req.qsee_cmd_id = QSEE_REGISTER_LOG_BUF_COMMAND;
+	logbuf_req.phy_addr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	logbuf_req.len = QSEE_LOG_BUF_SIZE;
+
+	rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+			&logbuf_req, sizeof(logbuf_req),
+			&resp, sizeof(resp));
+	dprintf(ALWAYS, "TZ App log region register returned with status:%d addr:%x size:%d\n",
+			rc, logbuf_req.phy_addr, logbuf_req.len);
+	if (rc)
+		goto err;
+err:
+	if (!rc) {
+		qseecom.qseecom_tz_init_done = 1;
+		dprintf(ALWAYS, "Qseecom TZ Init Done in Appsbl\n");
+	}
+	return rc;
+}
+
+int qseecom_init()
+{
+	int rc = GENERIC_ERROR;
+
+	memset (&qseecom, 0, sizeof(struct qseecom_control));
+	dprintf(SPEW, "%s called\n", __func__);
+	mutex_init(&(qseecom.global_data_lock));
+	mutex_init(&(qseecom.registered_app_list_lock));
+	mutex_init(&(qseecom.registered_listener_list_lock));
+
+	list_initialize(&(qseecom.registered_app_list_head));
+	list_initialize(&(qseecom.registered_listener_list_head));
+
+	qseecom.qseos_version = QSEOS_VERSION_14;
+	rc = 0;
+
+	if (!rc) {
+		qseecom.qseecom_init_done = 1;
+		dprintf(ALWAYS, "Qseecom Init Done in Appsbl\n");
+	}
+	return rc;
+}
+
+int qseecom_exit()
+{
+	dprintf(SPEW, "%s called\n", __func__);
+
+	if (logbuf_req.phy_addr)
+		free((void *)logbuf_req.phy_addr);
+	qseecom.qseecom_init_done = 0;
+	dprintf(ALWAYS, "Qseecom De-Init Done in Appsbl\n");
+	return 0;
+}