Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,23 @@
#
# Makefile for the <t-base trusted UI driver
#
GUD_ROOT_FOLDER := drivers/gud/
# add our modules to kernel.
obj-$(CONFIG_TRUSTONIC_TRUSTED_UI) += TlcTui.o
TlcTui-y := main.o tlcTui.o trustedui.o tui-hal.o
# Release mode by default
ccflags-y += -DNDEBUG
ccflags-y += -Wno-declaration-after-statement
ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG
# MobiCore Driver includes
ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/public
# MobiCore TlcTui required includes
ccflags-y += -I$(GUD_ROOT_FOLDER)/TlcTui/inc \
-I$(GUD_ROOT_FOLDER)/TlcTui/public

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define MOBICORE_COMPONENT_BUILD_TAG \
"t-base-EXYNOS64-Android-310A-V002-20150826_162546_62"

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2013-2015 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __DCITUI_H__
#define __DCITUI_H__
/**< Responses have bit 31 set */
#define RSP_ID_MASK (1U << 31)
#define RSP_ID(cmd_id) (((uint32_t)(cmd_id)) | RSP_ID_MASK)
#define IS_CMD(cmd_id) ((((uint32_t)(cmd_id)) & RSP_ID_MASK) == 0)
#define IS_RSP(cmd_id) ((((uint32_t)(cmd_id)) & RSP_ID_MASK) == RSP_ID_MASK)
#define CMD_ID_FROM_RSP(rsp_id) (rsp_id & (~RSP_ID_MASK))
/**
* Return codes of driver commands.
*/
#define TUI_DCI_OK 0x00030000
#define TUI_DCI_ERR_UNKNOWN_CMD 0x00030001
#define TUI_DCI_ERR_NOT_SUPPORTED 0x00030002
#define TUI_DCI_ERR_INTERNAL_ERROR 0x00030003
#define TUI_DCI_ERR_NO_RESPONSE 0x00030004
#define TUI_DCI_ERR_BAD_PARAMETERS 0x00030005
#define TUI_DCI_ERR_NO_EVENT 0x00030006
#define TUI_DCI_ERR_OUT_OF_DISPLAY 0x00030007
/* ... add more error codes when needed */
/**
* Notification ID's for communication Trustlet Connector -> Driver.
*/
#define NOT_TUI_NONE 0
/* NWd system event that closes the current TUI session*/
#define NOT_TUI_CANCEL_EVENT 1
/**
* Command ID's for communication Driver -> Trustlet Connector.
*/
#define CMD_TUI_SW_NONE 0
/* SWd request to NWd to start the TUI session */
#define CMD_TUI_SW_OPEN_SESSION 1
/* SWd request to NWd to close the TUI session */
#define CMD_TUI_SW_CLOSE_SESSION 2
/* SWd request to NWd stop accessing display controller */
#define CMD_TUI_SW_STOP_DISPLAY 3
/**
* Maximum data length.
*/
#define MAX_DCI_DATA_LEN (1024*100)
/* Command payload */
struct tui_alloc_data_t {
uint32_t alloc_size;
uint32_t num_of_buff;
};
union dci_cmd_payload_t {
struct tui_alloc_data_t alloc_data;
};
/* Command */
struct dci_command_t {
uint32_t id;
union dci_cmd_payload_t payload;
};
/* TUI frame buffer (output from NWd) */
struct tui_alloc_buffer_t {
uint64_t pa;
};
#define MAX_DCI_BUFFER_NUMBER 4
/* Response */
struct dci_response_t {
uint32_t id; /* must be command ID | RSP_ID_MASK */
uint32_t return_code;
struct tui_alloc_buffer_t alloc_buffer[MAX_DCI_BUFFER_NUMBER];
};
/* DCI buffer */
struct tui_dci_msg_t {
uint32_t nwd_notif; /* Notification from TlcTui to DrTui */
struct dci_command_t cmd_nwd; /* Command from DrTui to TlcTui */
struct dci_response_t nwd_rsp; /* Response from TlcTui to DrTui */
};
/**
* Driver UUID. Update accordingly after reserving UUID
*/
#define DR_TUI_UUID { { 7, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
#endif /* __DCITUI_H__ */

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __TBASE_TUI_H__
#define __TBASE_TUI_H__
#define TRUSTEDUI_MODE_OFF 0x00
#define TRUSTEDUI_MODE_ALL 0xff
#define TRUSTEDUI_MODE_TUI_SESSION 0x01
#define TRUSTEDUI_MODE_VIDEO_SECURED 0x02
#define TRUSTEDUI_MODE_INPUT_SECURED 0x04
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI
int trustedui_blank_inc(void);
int trustedui_blank_dec(void);
int trustedui_blank_get_counter(void);
void trustedui_blank_set_counter(int counter);
int trustedui_get_current_mode(void);
void trustedui_set_mode(int mode);
int trustedui_set_mask(int mask);
int trustedui_clear_mask(int mask);
#endif /* CONFIG_TRUSTONIC_TRUSTED_UI */
#endif /* __TBASE_TUI_H__ */

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioctl.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include "tui_ioctl.h"
#include "tlcTui.h"
#include "mobicore_driver_api.h"
#include "dciTui.h"
#include "tui-hal.h"
#include "build_tag.h"
/*static int tui_dev_major_number = 122; */
/*module_param(tui_dev_major_number, int, 0000); */
/*MODULE_PARM_DESC(major, */
/* "The device major number used to register a unique char device driver"); */
/* Static variables */
static struct cdev tui_cdev;
static long tui_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
int ret = -ENOTTY;
int __user *uarg = (int __user *)arg;
if (_IOC_TYPE(cmd) != TUI_IO_MAGIC)
return -EINVAL;
pr_info("t-base-tui module: ioctl 0x%x ", cmd);
switch (cmd) {
case TUI_IO_NOTIFY:
pr_info("TUI_IO_NOTIFY\n");
if (tlc_notify_event(arg))
ret = 0;
else
ret = -EFAULT;
break;
case TUI_IO_WAITCMD: {
uint32_t cmd_id;
pr_info("TUI_IO_WAITCMD\n");
ret = tlc_wait_cmd(&cmd_id);
if (ret)
return ret;
/* Write command id to user */
pr_debug("IOCTL: sending command %d to user.\n", cmd_id);
if (copy_to_user(uarg, &cmd_id, sizeof(cmd_id)))
ret = -EFAULT;
else
ret = 0;
/* Reset the value of the command, to ensure that commands sent
* due to interrupted wait_for_completion are TLC_TUI_CMD_NONE.
*/
reset_global_command_id();
break;
}
case TUI_IO_ACK: {
struct tlc_tui_response_t rsp_id;
pr_info("TUI_IO_ACK\n");
/* Read user response */
if (copy_from_user(&rsp_id, uarg, sizeof(rsp_id)))
ret = -EFAULT;
else
ret = 0;
pr_debug("IOCTL: User completed command %d.\n", rsp_id.id);
ret = tlc_ack_cmd(&rsp_id);
if (ret)
return ret;
break;
}
default:
pr_info("undefined!\n");
return -ENOTTY;
}
return ret;
}
static const struct file_operations tui_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tui_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = tui_ioctl,
#endif
};
/*--------------------------------------------------------------------------- */
static int __init tlc_tui_init(void)
{
pr_info("Loading t-base-tui module.\n");
pr_debug("\n=============== Running TUI Kernel TLC ===============\n");
pr_info("%s\n", MOBICORE_COMPONENT_BUILD_TAG);
dev_t devno;
int err;
static struct class *tui_class;
err = alloc_chrdev_region(&devno, 0, 1, TUI_DEV_NAME);
if (err) {
pr_debug(KERN_ERR "Unable to allocate Trusted UI device number\n");
return err;
}
cdev_init(&tui_cdev, &tui_fops);
tui_cdev.owner = THIS_MODULE;
/* tui_cdev.ops = &tui_fops; */
err = cdev_add(&tui_cdev, devno, 1);
if (err) {
pr_debug(KERN_ERR "Unable to add Trusted UI char device\n");
unregister_chrdev_region(devno, 1);
return err;
}
tui_class = class_create(THIS_MODULE, "tui_cls");
device_create(tui_class, NULL, devno, NULL, TUI_DEV_NAME);
if (!hal_tui_init())
return -EPERM;
return 0;
}
static void __exit tlc_tui_exit(void)
{
pr_info("Unloading t-base-tui module.\n");
unregister_chrdev_region(tui_cdev.dev, 1);
cdev_del(&tui_cdev);
hal_tui_exit();
}
module_init(tlc_tui_init);
module_exit(tlc_tui_exit);
MODULE_AUTHOR("Trustonic Limited");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("<t-base TUI");

View file

@ -0,0 +1,295 @@
/*
* Copyright (c) 2014-2015 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/types.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/fb.h>
#include <video/s3c-fb.h>
#include <t-base-tui.h>
#include "tui_ioctl.h"
#include "dciTui.h"
#include "tlcTui.h"
#include "tui-hal.h"
#define TUI_MEMPOOL_SIZE 0
struct tui_mempool {
void *va;
unsigned long pa;
size_t size;
};
static struct tui_mempool g_tui_mem_pool;
static bool allocate_tui_memory_pool(struct tui_mempool *pool, size_t size)
{
bool ret = false;
void *tui_mem_pool = NULL;
pr_info("%s %s:%d\n", __func__, __FILE__, __LINE__);
if (!size) {
pr_debug("TUI frame buffer: nothing to allocate.");
return true;
}
tui_mem_pool = kmalloc(size, GFP_KERNEL);
if (!tui_mem_pool) {
pr_debug("ERROR Could not allocate TUI memory pool");
} else if (ksize(tui_mem_pool) < size) {
pr_err("TUI mem pool size too small: req'd=%d alloc'd=%d", size,
ksize(tui_mem_pool));
kfree(tui_mem_pool);
} else {
pool->va = tui_mem_pool;
pool->pa = virt_to_phys(tui_mem_pool);
pool->size = ksize(tui_mem_pool);
ret = true;
}
return ret;
}
static void free_tui_memory_pool(struct tui_mempool *pool)
{
kfree(pool->va);
memset(pool, 0, sizeof(*pool));
}
static int is_device_ok(struct device *fbdev, void *p)
{
return 1;
}
static struct device *get_fb_dev(void)
{
struct device *fbdev = NULL;
/* get the first framebuffer device */
/* [TODO] Handle properly when there are more than one framebuffer */
fbdev = class_find_device(fb_class, NULL, NULL, is_device_ok);
if (NULL == fbdev) {
pr_debug("ERROR cannot get framebuffer device\n");
return NULL;
}
return fbdev;
}
static struct fb_info *get_fb_info(struct device *fbdev)
{
struct fb_info *fb_info;
if (!fbdev->p) {
pr_debug("ERROR framebuffer device has no private data\n");
return NULL;
}
fb_info = (struct fb_info *)dev_get_drvdata(fbdev);
if (!fb_info) {
pr_debug("ERROR framebuffer device has no fb_info\n");
return NULL;
}
return fb_info;
}
static void blank_framebuffer(int getref)
{
struct device *fbdev = NULL;
struct fb_info *fb_info;
struct s3c_fb_win *win;
struct s3c_fb *sfb;
fbdev = get_fb_dev();
if (!fbdev)
return;
fb_info = get_fb_info(fbdev);
if (!fb_info)
return;
/*
* hold a reference to the dsim device, to prevent it from going into
* power management during tui session
*/
win = fb_info->par;
sfb = win->parent;
if (getref)
pm_runtime_get_sync(sfb->dev);
/* blank the framebuffer */
lock_fb_info(fb_info);
console_lock();
fb_info->flags |= FBINFO_MISC_USEREVENT;
pr_info("%s call fb_blank\n", __func__);
fb_blank(fb_info, FB_BLANK_POWERDOWN);
fb_info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
unlock_fb_info(fb_info);
pr_info("%s call s3c_fb_deactivate_vsync\n", __func__);
s3c_fb_deactivate_vsync(sfb);
}
static void unblank_framebuffer(int releaseref)
{
struct device *fbdev = NULL;
struct fb_info *fb_info;
struct s3c_fb_win *win;
struct s3c_fb *sfb;
fbdev = get_fb_dev();
if (!fbdev)
return;
fb_info = get_fb_info(fbdev);
if (!fb_info)
return;
/*
* Release the reference we took at the beginning of the TUI session
*/
win = fb_info->par;
sfb = win->parent;
pr_info("%s call s3c_fb_activate_vsync\n", __func__);
s3c_fb_activate_vsync(sfb);
/*
* Unblank the framebuffer
*/
console_lock();
fb_info->flags |= FBINFO_MISC_USEREVENT;
fb_blank(fb_info, FB_BLANK_UNBLANK);
fb_info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
if (releaseref)
pm_runtime_put_sync(sfb->dev);
}
uint32_t hal_tui_init(void)
{
/* Allocate memory pool for the framebuffer
*/
if (!allocate_tui_memory_pool(&g_tui_mem_pool, TUI_MEMPOOL_SIZE))
return TUI_DCI_ERR_INTERNAL_ERROR;
return TUI_DCI_OK;
}
void hal_tui_exit(void)
{
/* delete memory pool if any */
if (g_tui_mem_pool.va)
free_tui_memory_pool(&g_tui_mem_pool);
}
uint32_t hal_tui_alloc(
struct tui_alloc_buffer_t allocbuffer[MAX_DCI_BUFFER_NUMBER],
size_t allocsize, uint32_t number)
{
uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
if (!allocbuffer) {
pr_debug("%s(%d): allocbuffer is null\n", __func__, __LINE__);
return TUI_DCI_ERR_INTERNAL_ERROR;
}
pr_debug("%s(%d): Requested size=0x%x x %u chunks\n", __func__,
__LINE__, allocsize, number);
if ((size_t)allocsize == 0) {
pr_debug("%s(%d): Nothing to allocate\n", __func__, __LINE__);
return TUI_DCI_OK;
}
if (number != 3) {
pr_debug("%s(%d): Unexpected number of buffers requested\n",
__func__, __LINE__);
return TUI_DCI_ERR_INTERNAL_ERROR;
}
if ((size_t)(allocsize*number) <= g_tui_mem_pool.size) {
/* requested buffer fits in the memory pool */
unsigned int i;
for (i = 0; i < number; i++) {
pr_info("%s(%d): allocbuffer + %d = 0x%p\n", __func__,
__LINE__, i, allocbuffer+i);
allocbuffer[i].pa =
(uint64_t) (g_tui_mem_pool.pa + i * allocsize);
pr_info("%s(%d): allocated at %llx\n", __func__,
__LINE__, allocbuffer[i].pa);
}
ret = TUI_DCI_OK;
} else {
/* requested buffer is bigger than the memory pool, return an
error */
pr_debug("%s(%d): Memory pool too small\n", __func__, __LINE__);
ret = TUI_DCI_ERR_INTERNAL_ERROR;
}
return ret;
}
void hal_tui_free(void)
{
}
uint32_t hal_tui_deactivate(void)
{
/* Set linux TUI flag */
trustedui_set_mask(TRUSTEDUI_MODE_TUI_SESSION);
trustedui_blank_set_counter(0);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
blank_framebuffer(1);
/* TODO-[2014-03-19]-julare01: disabled for Arndale board but this
* should be re enabled and put into a HAL */
/* disable_irq(gpio_to_irq(190)); */
#endif
trustedui_set_mask(TRUSTEDUI_MODE_VIDEO_SECURED|
TRUSTEDUI_MODE_INPUT_SECURED);
return TUI_DCI_OK;
}
uint32_t hal_tui_activate(void)
{
/* Protect NWd */
trustedui_clear_mask(TRUSTEDUI_MODE_VIDEO_SECURED|
TRUSTEDUI_MODE_INPUT_SECURED);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
pr_info("Unblanking\n");
/* TODO-[2014-03-19]-julare01: disabled for Arndale board but this
* should be re enabled and put into a HAL */
/* enable_irq(gpio_to_irq(190));*/
unblank_framebuffer(1);
#endif
/* Clear linux TUI flag */
trustedui_set_mode(TRUSTEDUI_MODE_OFF);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
pr_info("Unsetting TUI flag (blank counter=%d)",
trustedui_blank_get_counter());
if (0 < trustedui_blank_get_counter())
blank_framebuffer(0);
#endif
return TUI_DCI_OK;
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef TUI_IOCTL_H_
#define TUI_IOCTL_H_
/* Response header */
struct tlc_tui_response_t {
uint32_t id;
uint32_t return_code;
};
/* Command IDs */
#define TLC_TUI_CMD_NONE 0
#define TLC_TUI_CMD_START_ACTIVITY 1
#define TLC_TUI_CMD_STOP_ACTIVITY 2
/* Return codes */
#define TLC_TUI_OK 0
#define TLC_TUI_ERROR 1
#define TLC_TUI_ERR_UNKNOWN_CMD 2
/*
* defines for the ioctl TUI driver module function call from user space.
*/
#define TUI_DEV_NAME "t-base-tui"
#define TUI_IO_MAGIC 't'
#define TUI_IO_NOTIFY _IOW(TUI_IO_MAGIC, 1, uint32_t)
#define TUI_IO_WAITCMD _IOR(TUI_IO_MAGIC, 2, uint32_t)
#define TUI_IO_ACK _IOW(TUI_IO_MAGIC, 3, struct tlc_tui_response_t)
#ifdef INIT_COMPLETION
#define reinit_completion(x) INIT_COMPLETION(*(x))
#endif
#endif /* TUI_IOCTL_H_ */

View file

@ -0,0 +1,379 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include "mobicore_driver_api.h"
#include "tui_ioctl.h"
#include "tlcTui.h"
#include "dciTui.h"
#include "tui-hal.h"
/* ------------------------------------------------------------- */
/* Globals */
struct tui_dci_msg_t *dci;
DECLARE_COMPLETION(dci_comp);
DECLARE_COMPLETION(io_comp);
/* ------------------------------------------------------------- */
/* Static */
static const uint32_t DEVICE_ID = MC_DEVICE_ID_DEFAULT;
static struct task_struct *thread_id;
static uint32_t g_cmd_id = TLC_TUI_CMD_NONE;
static struct mc_session_handle dr_session_handle = {0, 0};
static struct tlc_tui_response_t g_user_rsp = {
TLC_TUI_CMD_NONE, TLC_TUI_ERR_UNKNOWN_CMD};
/* Functions */
/* ------------------------------------------------------------- */
static bool tlc_open_driver(void)
{
bool ret = false;
enum mc_result mc_ret;
struct mc_uuid_t dr_uuid = DR_TUI_UUID;
/* Allocate WSM buffer for the DCI */
mc_ret = mc_malloc_wsm(DEVICE_ID, 0, sizeof(struct tui_dci_msg_t),
(uint8_t **)&dci, 0);
if (MC_DRV_OK != mc_ret) {
pr_debug("ERROR %s: Allocation of DCI WSM failed: %d\n",
__func__, mc_ret);
return false;
}
/* Clear the session handle */
memset(&dr_session_handle, 0, sizeof(dr_session_handle));
/* The device ID (default device is used */
dr_session_handle.device_id = DEVICE_ID;
/* Open session with the Driver */
mc_ret = mc_open_session(&dr_session_handle, &dr_uuid, (uint8_t *)dci,
(uint32_t)sizeof(struct tui_dci_msg_t));
if (MC_DRV_OK != mc_ret) {
pr_debug("ERROR %s: Open driver session failed: %d\n",
__func__, mc_ret);
ret = false;
} else {
ret = true;
}
return ret;
}
/* ------------------------------------------------------------- */
static bool tlc_open(void)
{
bool ret = false;
enum mc_result mc_ret;
/* Open the tbase device */
pr_debug("%s: Opening tbase device\n", __func__);
mc_ret = mc_open_device(DEVICE_ID);
/* In case the device is already open, mc_open_device will return an
* error (MC_DRV_ERR_INVALID_OPERATION). But in this case, we can
* continue, even though mc_open_device returned an error. Stop in all
* other case of error
*/
if (MC_DRV_OK != mc_ret && MC_DRV_ERR_INVALID_OPERATION != mc_ret) {
pr_debug("ERROR %s: Error %d opening device\n", __func__,
mc_ret);
return false;
}
pr_debug("%s: Opening driver session\n", __func__);
ret = tlc_open_driver();
return ret;
}
/* ------------------------------------------------------------- */
static void tlc_wait_cmd_from_driver(void)
{
uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
/* Wait for a command from secure driver */
ret = mc_wait_notification(&dr_session_handle, -1);
if (MC_DRV_OK == ret)
pr_debug("tlc_wait_cmd_from_driver: Got a command\n");
else
pr_debug("ERROR %s: mc_wait_notification() failed: %d\n",
__func__, ret);
}
static uint32_t send_cmd_to_user(uint32_t command_id)
{
uint32_t ret = TUI_DCI_ERR_NO_RESPONSE;
/* Init shared variables */
g_cmd_id = command_id;
g_user_rsp.id = TLC_TUI_CMD_NONE;
g_user_rsp.return_code = TLC_TUI_ERR_UNKNOWN_CMD;
/* Give way to ioctl thread */
complete(&dci_comp);
pr_debug("send_cmd_to_user: give way to ioctl thread\n");
/* Wait for ioctl thread to complete */
wait_for_completion(&io_comp);
pr_debug("send_cmd_to_user: Got an answer from ioctl thread.\n");
reinit_completion(&io_comp);
/* Check id of the cmd processed by ioctl thread (paranoia) */
if (g_user_rsp.id != command_id) {
pr_debug("ERROR %s: Wrong response id 0x%08x iso 0x%08x\n",
__func__, dci->nwd_rsp.id, RSP_ID(command_id));
ret = TUI_DCI_ERR_INTERNAL_ERROR;
} else {
/* retrieve return code */
switch (g_user_rsp.return_code) {
case TLC_TUI_OK:
ret = TUI_DCI_OK;
break;
case TLC_TUI_ERROR:
ret = TUI_DCI_ERR_INTERNAL_ERROR;
break;
case TLC_TUI_ERR_UNKNOWN_CMD:
ret = TUI_DCI_ERR_UNKNOWN_CMD;
break;
}
}
return ret;
}
/* ------------------------------------------------------------- */
static void tlc_process_cmd(void)
{
uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
uint32_t command_id = CMD_TUI_SW_NONE;
if (NULL == dci) {
pr_debug("ERROR %s: DCI has not been set up properly - exiting\n",
__func__);
return;
} else {
command_id = dci->cmd_nwd.id;
}
/* Warn if previous response was not acknowledged */
if (CMD_TUI_SW_NONE == command_id) {
pr_debug("ERROR %s: Notified without command\n", __func__);
return;
} else {
if (dci->nwd_rsp.id != CMD_TUI_SW_NONE)
pr_debug("%s: Warning, previous response not ack\n",
__func__);
}
/* Handle command */
switch (command_id) {
case CMD_TUI_SW_OPEN_SESSION:
pr_debug("%s: CMD_TUI_SW_OPEN_SESSION.\n", __func__);
/* Start android TUI activity */
ret = send_cmd_to_user(TLC_TUI_CMD_START_ACTIVITY);
if (TUI_DCI_OK != ret)
break;
/* allocate TUI frame buffer */
ret = hal_tui_alloc(dci->nwd_rsp.alloc_buffer,
dci->cmd_nwd.payload.alloc_data.alloc_size,
dci->cmd_nwd.payload.alloc_data.num_of_buff);
if (TUI_DCI_OK != ret)
break;
/* Deactivate linux UI drivers */
ret = hal_tui_deactivate();
if (TUI_DCI_OK != ret) {
hal_tui_free();
send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY);
break;
}
break;
case CMD_TUI_SW_CLOSE_SESSION:
pr_debug("%s: CMD_TUI_SW_CLOSE_SESSION.\n", __func__);
/* Activate linux UI drivers */
ret = hal_tui_activate();
hal_tui_free();
/* Stop android TUI activity */
ret = send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY);
break;
default:
pr_debug("ERROR %s: Unknown command %d\n",
__func__, command_id);
break;
}
/* Fill in response to SWd, fill ID LAST */
pr_debug("%s: return 0x%08x to cmd 0x%08x\n",
__func__, ret, command_id);
dci->nwd_rsp.return_code = ret;
dci->nwd_rsp.id = RSP_ID(command_id);
/* Acknowledge command */
dci->cmd_nwd.id = CMD_TUI_SW_NONE;
/* Notify SWd */
pr_debug("DCI RSP NOTIFY CORE\n");
ret = mc_notify(&dr_session_handle);
if (MC_DRV_OK != ret)
pr_debug("ERROR %s: Notify failed: %d\n", __func__, ret);
}
/* ------------------------------------------------------------- */
static void tlc_close_driver(void)
{
enum mc_result ret;
/* Close session with the Driver */
ret = mc_close_session(&dr_session_handle);
if (MC_DRV_OK != ret) {
pr_debug("ERROR %s: Closing driver session failed: %d\n",
__func__, ret);
}
}
/* ------------------------------------------------------------- */
static void tlc_close(void)
{
enum mc_result ret;
pr_debug("%s: Closing driver session\n", __func__);
tlc_close_driver();
pr_debug("%s: Closing tbase\n", __func__);
/* Close the tbase device */
ret = mc_close_device(DEVICE_ID);
if (MC_DRV_OK != ret) {
pr_debug("ERROR %s: Closing tbase device failed: %d\n",
__func__, ret);
}
}
void reset_global_command_id(void)
{
g_cmd_id = TLC_TUI_CMD_NONE;
}
/* ------------------------------------------------------------- */
bool tlc_notify_event(uint32_t event_type)
{
bool ret = false;
enum mc_result result;
if (NULL == dci) {
pr_debug("ERROR tlc_notify_event: DCI has not been set up properly - exiting\n");
return false;
}
/* Prepare notification message in DCI */
pr_debug("tlc_notify_event: event_type = %d\n", event_type);
dci->nwd_notif = event_type;
/* Signal the Driver */
pr_debug("DCI EVENT NOTIFY CORE\n");
result = mc_notify(&dr_session_handle);
if (MC_DRV_OK != result) {
pr_debug("ERROR tlc_notify_event: mc_notify failed: %d\n",
result);
ret = false;
} else {
ret = true;
}
return ret;
}
/* ------------------------------------------------------------- */
/**
*/
int main_thread(void *uarg)
{
pr_debug("main_thread: TlcTui start!\n");
/* Open session on the driver */
if (!tlc_open()) {
pr_debug("ERROR main_thread: open driver failed!\n");
return 1;
}
/* TlcTui main thread loop */
for (;;) {
/* Wait for a command from the DrTui on DCI*/
tlc_wait_cmd_from_driver();
/* Something has been received, process it. */
tlc_process_cmd();
}
/* Close tlc. Note that this frees the DCI pointer.
* Do not use this pointer after tlc_close().*/
tlc_close();
return 0;
}
int tlc_wait_cmd(uint32_t *cmd_id)
{
/* Create the TlcTui Main thread and start secure driver (only
1st time) */
if (dr_session_handle.session_id == 0) {
thread_id = kthread_run(main_thread, NULL, "dci_thread");
if (!thread_id) {
pr_debug(KERN_ERR "Unable to start Trusted UI main thread\n");
return -EFAULT;
}
}
/* Wait for signal from DCI handler */
/* In case of an interrupted sys call, return with -EINTR */
if (wait_for_completion_interruptible(&dci_comp)) {
pr_debug("interrupted by system\n");
return -ERESTARTSYS;
}
reinit_completion(&dci_comp);
*cmd_id = g_cmd_id;
return 0;
}
int tlc_ack_cmd(struct tlc_tui_response_t *rsp_id)
{
g_user_rsp = *rsp_id;
/* Send signal to DCI */
complete(&io_comp);
return 0;
}
/** @} */

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2013-2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef TLCTUI_H_
#define TLCTUI_H_
void reset_global_command_id(void);
int tlc_wait_cmd(uint32_t *cmd_id);
int tlc_ack_cmd(struct tlc_tui_response_t *rsp_id);
bool tlc_notify_event(uint32_t event_type);
#endif /* TLCTUI_H_ */

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2013 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/**
* File : trustedui.c
* Created : 26-02-2010
*/
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/t-base-tui.h>
static int trustedui_mode = TRUSTEDUI_MODE_OFF;
static int trustedui_blank_counter;
static DEFINE_SPINLOCK(trustedui_lock);
int trustedui_blank_inc(void)
{
unsigned long flags;
int newvalue;
spin_lock_irqsave(&trustedui_lock, flags);
newvalue = ++trustedui_blank_counter;
spin_unlock_irqrestore(&trustedui_lock, flags);
return newvalue;
}
EXPORT_SYMBOL(trustedui_blank_inc);
int trustedui_blank_dec(void)
{
unsigned long flags;
int newvalue;
spin_lock_irqsave(&trustedui_lock, flags);
newvalue = --trustedui_blank_counter;
spin_unlock_irqrestore(&trustedui_lock, flags);
return newvalue;
}
EXPORT_SYMBOL(trustedui_blank_dec);
int trustedui_blank_get_counter(void)
{
unsigned long flags;
int newvalue;
spin_lock_irqsave(&trustedui_lock, flags);
newvalue = trustedui_blank_counter;
spin_unlock_irqrestore(&trustedui_lock, flags);
return newvalue;
}
EXPORT_SYMBOL(trustedui_blank_get_counter);
void trustedui_blank_set_counter(int counter)
{
unsigned long flags;
spin_lock_irqsave(&trustedui_lock, flags);
trustedui_blank_counter = counter;
spin_unlock_irqrestore(&trustedui_lock, flags);
}
EXPORT_SYMBOL(trustedui_blank_set_counter);
int trustedui_get_current_mode(void)
{
unsigned long flags;
int mode;
spin_lock_irqsave(&trustedui_lock, flags);
mode = trustedui_mode;
spin_unlock_irqrestore(&trustedui_lock, flags);
return mode;
}
EXPORT_SYMBOL(trustedui_get_current_mode);
void trustedui_set_mode(int mode)
{
unsigned long flags;
spin_lock_irqsave(&trustedui_lock, flags);
trustedui_mode = mode;
spin_unlock_irqrestore(&trustedui_lock, flags);
}
EXPORT_SYMBOL(trustedui_set_mode);
int trustedui_set_mask(int mask)
{
unsigned long flags;
int mode;
spin_lock_irqsave(&trustedui_lock, flags);
mode = trustedui_mode |= mask;
spin_unlock_irqrestore(&trustedui_lock, flags);
return mode;
}
EXPORT_SYMBOL(trustedui_set_mask);
int trustedui_clear_mask(int mask)
{
unsigned long flags;
int mode;
spin_lock_irqsave(&trustedui_lock, flags);
mode = trustedui_mode &= ~mask;
spin_unlock_irqrestore(&trustedui_lock, flags);
return mode;
}
EXPORT_SYMBOL(trustedui_clear_mask);
MODULE_AUTHOR("Trustonic Limited");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("<t-base TUI");

View file

@ -0,0 +1,295 @@
/*
* Copyright (c) 2014-2015 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/types.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/fb.h>
#include <video/s3c-fb.h>
#include <t-base-tui.h>
#include "tui_ioctl.h"
#include "dciTui.h"
#include "tlcTui.h"
#include "tui-hal.h"
#define TUI_MEMPOOL_SIZE 0
struct tui_mempool {
void *va;
unsigned long pa;
size_t size;
};
static struct tui_mempool g_tui_mem_pool;
static bool allocate_tui_memory_pool(struct tui_mempool *pool, size_t size)
{
bool ret = false;
void *tui_mem_pool = NULL;
pr_info("%s %s:%d\n", __func__, __FILE__, __LINE__);
if (!size) {
pr_debug("TUI frame buffer: nothing to allocate.");
return true;
}
tui_mem_pool = kmalloc(size, GFP_KERNEL);
if (!tui_mem_pool) {
pr_debug("ERROR Could not allocate TUI memory pool");
} else if (ksize(tui_mem_pool) < size) {
pr_err("TUI mem pool size too small: req'd=%d alloc'd=%d", size,
ksize(tui_mem_pool));
kfree(tui_mem_pool);
} else {
pool->va = tui_mem_pool;
pool->pa = virt_to_phys(tui_mem_pool);
pool->size = ksize(tui_mem_pool);
ret = true;
}
return ret;
}
static void free_tui_memory_pool(struct tui_mempool *pool)
{
kfree(pool->va);
memset(pool, 0, sizeof(*pool));
}
static int is_device_ok(struct device *fbdev, void *p)
{
return 1;
}
static struct device *get_fb_dev(void)
{
struct device *fbdev = NULL;
/* get the first framebuffer device */
/* [TODO] Handle properly when there are more than one framebuffer */
fbdev = class_find_device(fb_class, NULL, NULL, is_device_ok);
if (NULL == fbdev) {
pr_debug("ERROR cannot get framebuffer device\n");
return NULL;
}
return fbdev;
}
static struct fb_info *get_fb_info(struct device *fbdev)
{
struct fb_info *fb_info;
if (!fbdev->p) {
pr_debug("ERROR framebuffer device has no private data\n");
return NULL;
}
fb_info = (struct fb_info *)dev_get_drvdata(fbdev);
if (!fb_info) {
pr_debug("ERROR framebuffer device has no fb_info\n");
return NULL;
}
return fb_info;
}
static void blank_framebuffer(int getref)
{
struct device *fbdev = NULL;
struct fb_info *fb_info;
struct s3c_fb_win *win;
struct s3c_fb *sfb;
fbdev = get_fb_dev();
if (!fbdev)
return;
fb_info = get_fb_info(fbdev);
if (!fb_info)
return;
/*
* hold a reference to the dsim device, to prevent it from going into
* power management during tui session
*/
win = fb_info->par;
sfb = win->parent;
if (getref)
pm_runtime_get_sync(sfb->dev);
/* blank the framebuffer */
lock_fb_info(fb_info);
console_lock();
fb_info->flags |= FBINFO_MISC_USEREVENT;
pr_info("%s call fb_blank\n", __func__);
fb_blank(fb_info, FB_BLANK_POWERDOWN);
fb_info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
unlock_fb_info(fb_info);
pr_info("%s call s3c_fb_deactivate_vsync\n", __func__);
s3c_fb_deactivate_vsync(sfb);
}
static void unblank_framebuffer(int releaseref)
{
struct device *fbdev = NULL;
struct fb_info *fb_info;
struct s3c_fb_win *win;
struct s3c_fb *sfb;
fbdev = get_fb_dev();
if (!fbdev)
return;
fb_info = get_fb_info(fbdev);
if (!fb_info)
return;
/*
* Release the reference we took at the beginning of the TUI session
*/
win = fb_info->par;
sfb = win->parent;
pr_info("%s call s3c_fb_activate_vsync\n", __func__);
s3c_fb_activate_vsync(sfb);
/*
* Unblank the framebuffer
*/
console_lock();
fb_info->flags |= FBINFO_MISC_USEREVENT;
fb_blank(fb_info, FB_BLANK_UNBLANK);
fb_info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
if (releaseref)
pm_runtime_put_sync(sfb->dev);
}
uint32_t hal_tui_init(void)
{
/* Allocate memory pool for the framebuffer
*/
if (!allocate_tui_memory_pool(&g_tui_mem_pool, TUI_MEMPOOL_SIZE))
return TUI_DCI_ERR_INTERNAL_ERROR;
return TUI_DCI_OK;
}
void hal_tui_exit(void)
{
/* delete memory pool if any */
if (g_tui_mem_pool.va)
free_tui_memory_pool(&g_tui_mem_pool);
}
uint32_t hal_tui_alloc(
struct tui_alloc_buffer_t allocbuffer[MAX_DCI_BUFFER_NUMBER],
size_t allocsize, uint32_t number)
{
uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR;
if (!allocbuffer) {
pr_debug("%s(%d): allocbuffer is null\n", __func__, __LINE__);
return TUI_DCI_ERR_INTERNAL_ERROR;
}
pr_debug("%s(%d): Requested size=0x%x x %u chunks\n", __func__,
__LINE__, allocsize, number);
if ((size_t)allocsize == 0) {
pr_debug("%s(%d): Nothing to allocate\n", __func__, __LINE__);
return TUI_DCI_OK;
}
if (number != 3) {
pr_debug("%s(%d): Unexpected number of buffers requested\n",
__func__, __LINE__);
return TUI_DCI_ERR_INTERNAL_ERROR;
}
if ((size_t)(allocsize*number) <= g_tui_mem_pool.size) {
/* requested buffer fits in the memory pool */
unsigned int i;
for (i = 0; i < number; i++) {
pr_info("%s(%d): allocbuffer + %d = 0x%p\n", __func__,
__LINE__, i, allocbuffer+i);
allocbuffer[i].pa =
(uint64_t) (g_tui_mem_pool.pa + i * allocsize);
pr_info("%s(%d): allocated at %llx\n", __func__,
__LINE__, allocbuffer[i].pa);
}
ret = TUI_DCI_OK;
} else {
/* requested buffer is bigger than the memory pool, return an
error */
pr_debug("%s(%d): Memory pool too small\n", __func__, __LINE__);
ret = TUI_DCI_ERR_INTERNAL_ERROR;
}
return ret;
}
void hal_tui_free(void)
{
}
uint32_t hal_tui_deactivate(void)
{
/* Set linux TUI flag */
trustedui_set_mask(TRUSTEDUI_MODE_TUI_SESSION);
trustedui_blank_set_counter(0);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
blank_framebuffer(1);
/* TODO-[2014-03-19]-julare01: disabled for Arndale board but this
* should be re enabled and put into a HAL */
/* disable_irq(gpio_to_irq(190)); */
#endif
trustedui_set_mask(TRUSTEDUI_MODE_VIDEO_SECURED|
TRUSTEDUI_MODE_INPUT_SECURED);
return TUI_DCI_OK;
}
uint32_t hal_tui_activate(void)
{
/* Protect NWd */
trustedui_clear_mask(TRUSTEDUI_MODE_VIDEO_SECURED|
TRUSTEDUI_MODE_INPUT_SECURED);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
pr_info("Unblanking\n");
/* TODO-[2014-03-19]-julare01: disabled for Arndale board but this
* should be re enabled and put into a HAL */
/* enable_irq(gpio_to_irq(190));*/
unblank_framebuffer(1);
#endif
/* Clear linux TUI flag */
trustedui_set_mode(TRUSTEDUI_MODE_OFF);
#ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK
pr_info("Unsetting TUI flag (blank counter=%d)",
trustedui_blank_get_counter());
if (0 < trustedui_blank_get_counter())
blank_framebuffer(0);
#endif
return TUI_DCI_OK;
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2014 TRUSTONIC LIMITED
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _TUI_HAL_H_
#define _TUI_HAL_H_
#include <linux/types.h>
uint32_t hal_tui_init(void);
void hal_tui_exit(void);
uint32_t hal_tui_alloc(
struct tui_alloc_buffer_t allocbuffer[MAX_DCI_BUFFER_NUMBER],
size_t allocsize, uint32_t number);
void hal_tui_free(void);
uint32_t hal_tui_deactivate(void);
uint32_t hal_tui_activate(void);
#endif