msm: gud: Remove gud driver

Complete removal of gud mobicore driver.
The driver author delivers an updated version of this driver to
interested parties directly rendering this version obsolete.

Bug: 65468975
Change-Id: I40498d3203b1d6ca04f2b5a2e65461851d84d2d4
Acked-by: Tony Hamilton <tonyh@qti.qualcomm.com>
Signed-off-by: Trudy Shearer <tshearer@codeaurora.org>
Signed-off-by: Siqi Lin <siqilin@google.com>
This commit is contained in:
Trudy Shearer 2017-05-18 17:31:51 +01:00 committed by Artem Borisov
parent 7b53ae9e92
commit b1d9580ebb
30 changed files with 0 additions and 7956 deletions

View file

@ -146,8 +146,6 @@ source "drivers/virt/Kconfig"
source "drivers/devfreq/Kconfig"
source "drivers/gud/Kconfig"
source "drivers/coresight/Kconfig"
endmenu

View file

@ -138,7 +138,4 @@ obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_PM_DEVFREQ) += devfreq/
#MobiCore
obj-$(CONFIG_MOBICORE_SUPPORT) += gud/
obj-$(CONFIG_CORESIGHT) += coresight/

View file

@ -1,32 +0,0 @@
#
# MobiCore configuration
#
config MOBICORE_SUPPORT
tristate "Linux MobiCore Support"
#depends on ARM_TRUSTZONE
---help---
Enable Linux Kernel MobiCore Support
config MOBICORE_DEBUG
bool "MobiCore Module debug mode"
depends on MOBICORE_SUPPORT
---help---
Enable Debug mode in the MobiCore Driver.
It enables printing information about mobicore operations
config MOBICORE_VERBOSE
bool "MobiCore Module verbose debug mode"
depends on MOBICORE_DEBUG
---help---
Enable Verbose Debug mode in the MobiCore Driver.
It enables printing extra information about mobicore operations
Beware: this is only useful for debuging deep in the driver because
it prints too much logs
config MOBICORE_API
tristate "Linux MobiCore API"
depends on MOBICORE_SUPPORT
---help---
Enable Linux Kernel MobiCore API

View file

@ -1,31 +0,0 @@
#
# Makefile for the kernel mobicore drivers
#
GUD_ROOT_FOLDER := drivers/gud
# add our modules to kernel.
obj-$(CONFIG_MOBICORE_API) += mckernelapi.o
obj-$(CONFIG_MOBICORE_SUPPORT) += mcdrvmodule.o
mcdrvmodule-objs := mobicore_driver/logging.o mobicore_driver/main.o
mckernelapi-objs := mobicore_kernelapi/main.o \
mobicore_kernelapi/clientlib.o \
mobicore_kernelapi/device.o \
mobicore_kernelapi/session.o \
mobicore_kernelapi/connection.o
# Release mode by default
ccflags-y := -DNDEBUG
ccflags-y += -Wno-declaration-after-statement
ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG
ccflags-$(CONFIG_MOBICORE_VERBOSE) += -DDEBUG_VERBOSE
# Choose one platform from the folder
MOBICORE_PLATFORM := $(shell (ls -1 $(PWD)/$(GUD_ROOT_FOLDER)/mobicore_driver/platforms | tail -1) )
# Use the available platform folder
ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_driver/platforms/$(MOBICORE_PLATFORM)
ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_driver/public
ccflags-y += -I$(GUD_ROOT_FOLDER)/mobicore_kernelapi/include

View file

@ -1,6 +0,0 @@
MobiCore is an operating system being shipped with TZBSP
on msm chipsets. MobiCore consists of several components in
the secure world(TrustZone) and non-secure world(linux
kernel, Android user space). The MobiCore driver
communicates with the MobiCore kernel that exists in
TrustZone.

View file

@ -1,29 +0,0 @@
/**
*
* <!-- Copyright Giesecke & Devrient GmbH 2012-2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 MOBICORE_COMPONENT_BUILD_TAG "*** GC_MSM8960_Release_V010 ###"

View file

@ -1,336 +0,0 @@
/** MobiCore driver module.(interface to the secure world SWD)
* @addtogroup MCD_MCDIMPL_KMOD_LOGGING MobiCore Driver Logging Subsystem.
* @ingroup MCD_MCDIMPL_KMOD
* @{
* @file
* MobiCore Driver Logging Subsystem.
* The logging subsytem provides the interface between the Mobicore trace
* buffer and the Linux log
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#include "mc_drv_module.h"
#include "mc_drv_module_linux_api.h"
#include "mc_drv_module_fastcalls.h"
/* Default len of the log ring buffer 256KB*/
#define LOG_BUF_SIZE (64 * PAGE_SIZE)
/* Max Len of a log line for printing */
#define LOG_LINE_SIZE 256
static uint32_t log_size = LOG_BUF_SIZE;
module_param(log_size, uint, 0);
MODULE_PARM_DESC(log_size, " Size of the MobiCore log ringbuffer "
"(or 256KB default).");
/*----------------------------------------------------------------------------*/
/* Definitions for log version 2 */
#define LOG_TYPE_MASK (0x0007)
#define LOG_TYPE_CHAR 0
#define LOG_TYPE_INTEGER 1
/* Field length */
#define LOG_LENGTH_MASK (0x00F8)
#define LOG_LENGTH_SHIFT 3
/* Extra attributes */
#define LOG_EOL (0x0100)
#define LOG_INTEGER_DECIMAL (0x0200)
#define LOG_INTEGER_SIGNED (0x0400)
struct logmsg_struct {
/* Type and format of data */
uint16_t ctrl;
/* Unique value for each event source */
uint16_t source;
/* Value, if any */
uint32_t log_data;
};
/** MobiCore log previous position */
static uint32_t log_pos;
/** MobiCore log buffer structure */
static struct mc_trace_buf *log_buf;
/** Log Thread task structure */
struct task_struct *log_thread;
/** Log Line buffer */
static char *log_line;
static void log_msg(struct logmsg_struct *msg);
/*----------------------------------------------------------------------------*/
static void log_eol(void)
{
if (!strnlen(log_line, LOG_LINE_SIZE))
return;
printk(KERN_INFO "%s\n", log_line);
log_line[0] = 0;
}
/*----------------------------------------------------------------------------*/
/**
* Put a char to the log line if there is enough space if not then also
* output the line. Assume nobody else is updating the line! */
static void log_char(char ch)
{
uint32_t len;
if (ch == '\n' || ch == '\r') {
log_eol();
return;
}
if (strnlen(log_line, LOG_LINE_SIZE) >= LOG_LINE_SIZE - 1) {
printk(KERN_INFO "%s\n", log_line);
log_line[0] = 0;
}
len = strnlen(log_line, LOG_LINE_SIZE);
log_line[len] = ch;
log_line[len + 1] = 0;
}
/*----------------------------------------------------------------------------*/
/**
* Put a string to the log line if there is enough space if not then also
* output the line. Assume nobody else is updating the line! */
static void log_str(const char *s)
{
int i;
for (i = 0; i < strnlen(s, LOG_LINE_SIZE); i++)
log_char(s[i]);
}
/*----------------------------------------------------------------------------*/
static uint32_t process_v1log(void)
{
char *last_char = log_buf->buff + log_buf->write_pos;
char *buff = log_buf->buff + log_pos;
while (buff != last_char) {
log_char(*(buff++));
/* Wrap around */
if (buff - (char *)log_buf >= log_size)
buff = log_buf->buff;
}
return buff - log_buf->buff;
}
/*----------------------------------------------------------------------------*/
static uint32_t process_v2log(void)
{
char *last_msg = log_buf->buff + log_buf->write_pos;
char *buff = log_buf->buff + log_pos;
while (buff != last_msg) {
log_msg((struct logmsg_struct *)buff);
buff += sizeof(struct logmsg_struct);
/* Wrap around */
if (buff + sizeof(struct logmsg_struct) >
(char *)log_buf + log_size)
buff = log_buf->buff;
}
return buff - log_buf->buff;
}
static const uint8_t HEX2ASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/*----------------------------------------------------------------------------*/
static void dbg_raw_nro(uint32_t format, uint32_t value)
{
int digits = 1;
uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16;
int width = (format & LOG_LENGTH_MASK) >> LOG_LENGTH_SHIFT;
int negative = FALSE;
uint32_t digit_base = 1;
if ((format & LOG_INTEGER_SIGNED) != 0 && ((signed int)value) < 0) {
negative = TRUE;
value = (uint32_t)(-(signed int)value);
width--;
}
/* Find length and divider to get largest digit */
while (value / digit_base >= base) {
digit_base *= base;
digits++;
}
if (width > digits) {
char ch = (base == 10) ? ' ' : '0';
while (width > digits) {
log_char(ch);
width--;
}
}
if (negative)
log_char('-');
while (digits-- > 0) {
uint32_t d = value / digit_base;
log_char(HEX2ASCII[d]);
value = value - d * digit_base;
digit_base /= base;
}
}
/*----------------------------------------------------------------------------*/
static void log_msg(struct logmsg_struct *msg)
{
unsigned char msgtxt[5];
int mpos = 0;
switch (msg->ctrl & LOG_TYPE_MASK) {
case LOG_TYPE_CHAR: {
uint32_t ch;
ch = msg->log_data;
while (ch != 0) {
msgtxt[mpos++] = ch&0xFF;
ch >>= 8;
}
msgtxt[mpos] = 0;
log_str(msgtxt);
break;
}
case LOG_TYPE_INTEGER: {
dbg_raw_nro(msg->ctrl, msg->log_data);
break;
}
default:
break;
}
if (msg->ctrl & LOG_EOL)
log_eol();
}
/*----------------------------------------------------------------------------*/
static int log_worker(void *p)
{
if (log_buf == NULL)
return -EFAULT;
/* The thread should have never started */
if (log_buf == NULL)
return -EFAULT;
while (!kthread_should_stop()) {
if (log_buf->write_pos == log_pos)
schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
switch (log_buf->version) {
case 1:
log_pos = process_v1log();
break;
case 2:
log_pos = process_v2log();
break;
default:
MCDRV_DBG_ERROR("Unknown Mobicore log data "
"version %d logging disabled.",
log_buf->version);
log_pos = log_buf->write_pos;
/* Stop the thread as we have no idea what
* happens next */
return -EFAULT;
}
}
MCDRV_DBG("Logging thread stopped!");
return 0;
}
/*----------------------------------------------------------------------------*/
/**
* Wakeup the log reader thread
* This should be called from the places where calls into MobiCore have
* generated some logs(eg, yield, SIQ...)
*/
void mobicore_log_read(void)
{
if (log_thread == NULL || IS_ERR(log_thread))
return;
wake_up_process(log_thread);
}
/*----------------------------------------------------------------------------*/
/**
* Setup mobicore kernel log. It assumes it's running on CORE 0!
* The fastcall will complain is that is not the case!
*/
long mobicore_log_setup(void *data)
{
unsigned long phys_log_buf;
union fc_generic fc_log;
log_pos = 0;
log_buf = NULL;
log_thread = NULL;
log_line = NULL;
/* Sanity check for the log size */
if (log_size < PAGE_SIZE)
return -EFAULT;
else
log_size =
get_nr_of_pages_for_buffer(NULL, log_size) * PAGE_SIZE;
log_line = kzalloc(LOG_LINE_SIZE, GFP_KERNEL);
if (IS_ERR(log_line)) {
MCDRV_DBG_ERROR("failed to allocate log line!");
return -ENOMEM;
}
log_thread = kthread_create(log_worker, NULL, "mobicore_log");
if (IS_ERR(log_thread)) {
MCDRV_DBG_ERROR("mobicore log thread creation failed!");
return -EFAULT;
}
log_pos = 0;
log_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
size_to_order(log_size));
if (!log_buf) {
MCDRV_DBG_ERROR("Failed to get page for logger!");
return -ENOMEM;
}
phys_log_buf = virt_to_phys(log_buf);
memset(&fc_log, 0, sizeof(fc_log));
fc_log.as_in.cmd = MC_FC_NWD_TRACE;
fc_log.as_in.param[0] = phys_log_buf;
fc_log.as_in.param[1] = log_size;
MCDRV_DBG("fc_log virt=%p phys=%p ", log_buf, (void *)phys_log_buf);
mc_fastcall(&fc_log);
MCDRV_DBG("fc_log out ret=0x%08x", fc_log.as_out.ret);
/* If the setup failed we must free the memory allocated */
if (fc_log.as_out.ret) {
MCDRV_DBG_ERROR("MobiCore shared traces setup failed!");
kthread_stop(log_thread);
free_pages((unsigned long)log_buf, size_to_order(log_size));
log_buf = NULL;
log_thread = NULL;
return -EIO;
}
MCDRV_DBG("fc_log Logger version %u\n", log_buf->version);
return 0;
}
/*----------------------------------------------------------------------------*/
/**
* Free kernel log componenets.
* ATTN: We can't free the log buffer because it's also in use by MobiCore and
* even if the module is unloaded MobiCore is still running.
*/
void mobicore_log_free(void)
{
if (log_thread && !IS_ERR(log_thread)) {
/* We don't really care what the thread returns for exit */
kthread_stop(log_thread);
}
kfree(log_line);
}

File diff suppressed because it is too large Load diff

View file

@ -1,238 +0,0 @@
/**
* Header file of MobiCore Driver Kernel Module.
*
* @addtogroup MCD_MCDIMPL_KMOD_IMPL
* @{
* Internal structures of the McDrvModule
* @file
*
* Header file the MobiCore Driver Kernel Module,
* its internal structures and defines.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#ifndef _MC_DRV_KMOD_H_
#define _MC_DRV_KMOD_H_
#include "mc_drv_module_linux_api.h"
#include "public/mc_drv_module_api.h"
/** Platform specific settings */
#include "platform.h"
/** ARM Specific masks and modes */
#define ARM_CPSR_MASK 0x1F
#define ARM_MONITOR_MODE 0b10110
#define ARM_SECURITY_EXTENSION_MASK 0x30
/**
* Number of page table entries in one L2 table. This is ARM specific, an
* L2 table covers 1 MiB by using 256 entry referring to 4KiB pages each.
*/
#define MC_ARM_L2_TABLE_ENTRIES 256
/** Maximum number of contiguous buffer allocations for one driver instance. */
#define MC_DRV_KMOD_CONTG_BUFFER_MAX 16
/** Number of pages for L2 tables. There are 4 table in each page. */
#define MC_DRV_KMOD_L2_TABLE_PER_PAGES 4
/** ARM level 2 (L2) table with 256 entries. Size: 1k */
struct l2table {
pte_t table_entries[MC_ARM_L2_TABLE_ENTRIES];
};
#define INVALID_ADDRESS ((void *)(-1))
/** ARM L2 PTE bits */
#define L2_FLAG_SMALL_XN (1U << 0)
#define L2_FLAG_SMALL (1U << 1)
#define L2_FLAG_B (1U << 2)
#define L2_FLAG_C (1U << 3)
#define L2_FLAG_AP0 (1U << 4)
#define L2_FLAG_AP1 (1U << 5)
#define L2_FLAG_SMALL_TEX0 (1U << 6)
#define L2_FLAG_SMALL_TEX1 (1U << 7)
#define L2_FLAG_SMALL_TEX2 (1U << 8)
#define L2_FLAG_APX (1U << 9)
#define L2_FLAG_S (1U << 10)
#define L2_FLAG_NG (1U << 11)
/**
* Contiguous buffer allocated to TLCs.
* These buffers are uses as world shared memory (wsm) and shared with
* secure world.
* The virtual kernel address is added for a simpler search algorithm.
*/
struct mc_contg_buffer {
unsigned int handle; /* unique handle */
void *virt_user_addr; /**< virtual User start address */
void *virt_kernel_addr; /**< virtual Kernel start address */
void *phys_addr; /**< physical start address */
unsigned int num_pages; /**< number of pages */
};
/** Instance data for MobiCore Daemon and TLCs. */
struct mc_instance {
/** unique handle */
unsigned int handle;
/** process that opened this instance */
pid_t pid_vnr;
/** buffer list for mmap generated address space and
its virtual client address */
struct mc_contg_buffer contg_buffers[MC_DRV_KMOD_CONTG_BUFFER_MAX];
};
/** Store for four L2 tables in one 4kb page*/
struct mc_l2_table_store {
struct l2table table[MC_DRV_KMOD_L2_TABLE_PER_PAGES];
};
/** Usage and maintenance information about mc_l2_table_store */
struct mc_l2_tables_set {
struct list_head list;
unsigned int usage_bitmap; /**< usage bitmap */
struct mc_l2_table_store *kernel_virt; /**< kernel virtual address */
struct mc_l2_table_store *phys; /**< physical address */
struct page *page; /**< pointer to page struct */
};
/**
* L2 table allocated to the Daemon or a TLC describing a world shared buffer.
* When users map a malloc()ed area into SWd, a L2 table is allocated.
* In addition, the area of maximum 1MB virtual address space is mapped into
* the L2 table and a handle for this table is returned to the user.
*/
struct mc_used_l2_table {
struct list_head list;
/** handle as communicated to user mode */
unsigned int handle;
unsigned int flags;
/** owner of this L2 table */
struct mc_instance *owner;
/** set describing where our L2 table is stored */
struct mc_l2_tables_set *set;
/** index into L2 table set */
unsigned int idx;
/** size of buffer */
unsigned int nr_of_pages;
};
#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_APP (1U << 0)
#define MC_WSM_L2_CONTAINER_WSM_LOCKED_BY_MC (1U << 1)
/** MobiCore S-SIQ interrupt context data. */
struct mc_ssiq_ctx {
/** S-SIQ interrupt counter */
atomic_t counter;
};
/** MobiCore Daemon context data. */
struct mc_daemon_ctx {
/** event semaphore */
struct semaphore sem;
struct fasync_struct *async_queue;
/** event counter */
unsigned int ssiq_counter;
};
/** MobiCore Driver Kernel Module context data. */
struct mc_drv_kmod_ctx {
/** ever incrementing counter */
atomic_t unique_counter;
/** S-SIQ interrupt context */
struct mc_ssiq_ctx ssiq_ctx;
/** MobiCore Daemon context */
struct mc_daemon_ctx daemon_ctx;
/** pointer to instance of daemon */
struct mc_instance *daemon_inst;
/** Backing store for L2 tables */
struct list_head mc_l2_tables_sets;
/** Bookkeeping for used L2 tables */
struct list_head mc_used_l2_tables;
/** semaphore to synchronize access to above lists */
struct semaphore wsm_l2_sem;
};
/** MobiCore internal trace buffer structure. */
struct mc_trace_buf {
uint32_t version; /**< version of trace buffer */
uint32_t length; /**< length of allocated buffer(includes header) */
uint32_t write_pos; /**< last write position */
char buff[1]; /**< start of the log buffer */
};
/*** MobiCore internal trace log setup. */
void mobicore_log_read(void);
long mobicore_log_setup(void *);
void mobicore_log_free(void);
#define MCDRV_DBG_ERROR(txt, ...) \
printk(KERN_ERR "mcDrvKMod [%d] %s() ### ERROR: " txt, \
task_pid_vnr(current), \
__func__, \
##__VA_ARGS__)
/* dummy function helper macro. */
#define DUMMY_FUNCTION() do {} while (0)
#if defined(DEBUG)
/* #define DEBUG_VERBOSE */
#if defined(DEBUG_VERBOSE)
#define MCDRV_DBG_VERBOSE MCDRV_DBG
#else
#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
#endif
#define MCDRV_DBG(txt, ...) \
printk(KERN_INFO "mcDrvKMod [%d on CPU%d] %s(): " txt, \
task_pid_vnr(current), \
raw_smp_processor_id(), \
__func__, \
##__VA_ARGS__)
#define MCDRV_DBG_WARN(txt, ...) \
printk(KERN_WARNING "mcDrvKMod [%d] %s() WARNING: " txt, \
task_pid_vnr(current), \
__func__, \
##__VA_ARGS__)
#define MCDRV_ASSERT(cond) \
do { \
if (unlikely(!(cond))) { \
panic("mcDrvKMod Assertion failed: %s:%d\n", \
__FILE__, __LINE__); \
} \
} while (0)
#else
#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
#define MCDRV_DBG(...) DUMMY_FUNCTION()
#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION()
#define MCDRV_ASSERT(...) DUMMY_FUNCTION()
#endif /* [not] defined(DEBUG) */
#endif /* _MC_DRV_KMOD_H_ */
/** @} */

View file

@ -1,37 +0,0 @@
/**
* Header file of MobiCore Driver Kernel Module.
*
* @addtogroup MobiCore_Driver_Kernel_Module
* @{
* Android specific defines
* @file
*
* Android specific defines
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#ifndef _MC_DRV_MODULE_ANDROID_H_
#define _MC_DRV_MODULE_ANDROID_H_
/* Defines needed to identify the Daemon in Android systems
* For the full list see:
* platform_system_core/include/private/android_filesystem_config.h in the
* Android source tree
*/
/* traditional unix root user */
#define AID_ROOT 0
/* system server */
#define AID_SYSTEM 1000
/* access to misc storage */
#define AID_MISC 9998
#define AID_NOBODY 9999
/* first app user */
#define AID_APP 10000
#endif /* _MC_DRV_MODULE_ANDROID_H_ */
/** @} */

View file

@ -1,227 +0,0 @@
/**
* Header file of MobiCore Driver Kernel Module.
*
* @addtogroup MobiCore_Driver_Kernel_Module
* @{
* Internal structures of the McDrvModule
* @file
*
* MobiCore Fast Call interface
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#ifndef _MC_DRV_MODULE_FC_H_
#define _MC_DRV_MODULE_FC_H_
#include "mc_drv_module.h"
/**
* MobiCore SMCs
*/
enum mc_smc_codes {
MC_SMC_N_YIELD = 0x3, /**< Yield to switch from NWd to SWd. */
MC_SMC_N_SIQ = 0x4 /**< SIQ to switch from NWd to SWd. */
};
/**
* MobiCore fast calls. See MCI documentation
*/
enum mc_fast_call_codes {
MC_FC_INIT = -1,
MC_FC_INFO = -2,
MC_FC_POWER = -3,
MC_FC_DUMP = -4,
MC_FC_NWD_TRACE = -31 /**< Mem trace setup fastcall */
};
/**
* return code for fast calls
*/
enum mc_fast_calls_result {
MC_FC_RET_OK = 0,
MC_FC_RET_ERR_INVALID = 1,
MC_FC_RET_ERR_ALREADY_INITIALIZED = 5
};
/*------------------------------------------------------------------------------
structure wrappers for specific fastcalls
------------------------------------------------------------------------------*/
/** generic fast call parameters */
union fc_generic {
struct {
uint32_t cmd;
uint32_t param[3];
} as_in;
struct {
uint32_t resp;
uint32_t ret;
uint32_t param[2];
} as_out;
};
/** fast call init */
union mc_fc_init {
union fc_generic as_generic;
struct {
uint32_t cmd;
uint32_t base;
uint32_t nq_info;
uint32_t mcp_info;
} as_in;
struct {
uint32_t resp;
uint32_t ret;
uint32_t rfu[2];
} as_out;
};
/** fast call info parameters */
union mc_fc_info {
union fc_generic as_generic;
struct {
uint32_t cmd;
uint32_t ext_info_id;
uint32_t rfu[2];
} as_in;
struct {
uint32_t resp;
uint32_t ret;
uint32_t state;
uint32_t ext_info;
} as_out;
};
/** fast call S-Yield parameters */
union mc_fc_s_yield {
union fc_generic as_generic;
struct {
uint32_t cmd;
uint32_t rfu[3];
} as_in;
struct {
uint32_t resp;
uint32_t ret;
uint32_t rfu[2];
} as_out;
};
/** fast call N-SIQ parameters */
union mc_fc_nsiq {
union fc_generic as_generic;
struct {
uint32_t cmd;
uint32_t rfu[3];
} as_in;
struct {
uint32_t resp;
uint32_t ret;
uint32_t rfu[2];
} as_out;
};
/*----------------------------------------------------------------------------*/
/**
* fast call to MobiCore
*
* @param fc_generic pointer to fast call data
*/
static inline void mc_fastcall(
union fc_generic *fc_generic
)
{
MCDRV_ASSERT(fc_generic != NULL);
/* We only expect to make smc calls on CPU0 otherwise something wrong
* will happen */
MCDRV_ASSERT(raw_smp_processor_id() == 0);
mb();
#ifdef MC_SMC_FASTCALL
{
int ret = 0;
MCDRV_DBG("Going into SCM()");
ret = smc_fastcall((void *)fc_generic, sizeof(*fc_generic));
MCDRV_DBG("Coming from SCM, scm_call=%i, resp=%d/0x%x\n",
ret,
fc_generic->as_out.resp, fc_generic->as_out.resp);
}
#else
{
/* SVC expect values in r0-r3 */
register u32 reg0 __asm__("r0") = fc_generic->as_in.cmd;
register u32 reg1 __asm__("r1") = fc_generic->as_in.param[0];
register u32 reg2 __asm__("r2") = fc_generic->as_in.param[1];
register u32 reg3 __asm__("r3") = fc_generic->as_in.param[2];
/* one of the famous preprocessor hacks to stingitize things.*/
#define __STR2(x) #x
#define __STR(x) __STR2(x)
/* compiler does not support certain instructions
"SMC": secure monitor call.*/
#define ASM_ARM_SMC 0xE1600070
/* "BPKT": debugging breakpoint. We keep this, as is comes
quite handy for debugging. */
#define ASM_ARM_BPKT 0xE1200070
#define ASM_THUMB_BPKT 0xBE00
__asm__ volatile (
".word " __STR(ASM_ARM_SMC) "\n"
: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
);
/* set response */
fc_generic->as_out.resp = reg0;
fc_generic->as_out.ret = reg1;
fc_generic->as_out.param[0] = reg2;
fc_generic->as_out.param[1] = reg3;
}
#endif
}
/*----------------------------------------------------------------------------*/
/**
* convert fast call return code to linux driver module error code
*
*/
static inline int convert_fc_ret(
uint32_t sret
)
{
int ret = -EFAULT;
switch (sret) {
case MC_FC_RET_OK:
ret = 0;
break;
case MC_FC_RET_ERR_INVALID:
ret = -EINVAL;
break;
case MC_FC_RET_ERR_ALREADY_INITIALIZED:
ret = -EBUSY;
break;
default:
break;
} /* end switch( sret ) */
return ret;
}
#endif /* _MC_DRV_MODULE_FC_H_ */
/** @} */

View file

@ -1,187 +0,0 @@
/**
* Header file of MobiCore Driver Kernel Module.
*
* @addtogroup MobiCore_Driver_Kernel_Module
* @{
* Wrapper for Linux API
* @file
*
* Some convenient wrappers for memory functions
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#ifndef _MC_DRV_MODULE_LINUX_API_H_
#define _MC_DRV_MODULE_LINUX_API_H_
#include <linux/version.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/kthread.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/sizes.h>
#include <asm/pgtable.h>
#include <linux/semaphore.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
/* make some nice types */
#if !defined(TRUE)
#define TRUE (1 == 1)
#endif
#if !defined(FALSE)
#define FALSE (1 != 1)
#endif
/* Linux GCC modifiers */
#if !defined(__init)
#warning "missing definition: __init"
/* define a dummy */
#define __init
#endif
#if !defined(__exit)
#warning "missing definition: __exit"
/* define a dummy */
#define __exit
#endif
#if !defined(__must_check)
#warning "missing definition: __must_check"
/* define a dummy */
#define __must_check
#endif
#if !defined(__user)
#warning "missing definition: __user"
/* define a dummy */
#define __user
#endif
#define INVALID_ORDER ((unsigned int)(-1))
/*----------------------------------------------------------------------------*/
/* get start address of the 4 KiB page where the given addres is located in. */
static inline void *get_page_start(
void *addr
)
{
return (void *)(((unsigned long)(addr)) & PAGE_MASK);
}
/*----------------------------------------------------------------------------*/
/* get offset into the 4 KiB page where the given addres is located in. */
static inline unsigned int get_offset_in_page(
void *addr
)
{
return (unsigned int)(((unsigned long)(addr)) & (~PAGE_MASK));
}
/*----------------------------------------------------------------------------*/
/* get number of pages for a given buffer. */
static inline unsigned int get_nr_of_pages_for_buffer(
void *addr_start, /* may be null */
unsigned int len
)
{
/* calculate used number of pages. Example:
offset+size newSize+PAGE_SIZE-1 nr_of_pages
0 4095 0
1 4096 1
4095 8190 1
4096 8191 1
4097 8192 2 */
return (get_offset_in_page(addr_start) + len + PAGE_SIZE-1) / PAGE_SIZE;
}
/*----------------------------------------------------------------------------*/
/**
* convert a given size to page order, which is equivalent to finding log_2(x).
* The maximum for order was 5 in Linux 2.0 corresponding to 32 pages.
* Later versions allow 9 corresponding to 512 pages, which is 2 MB on
* most platforms). Anyway, the bigger order is, the more likely it is
* that the allocation will fail.
* Size 0 1 4097 8193 12289 24577 28673 40961 61441
* Pages - 1 2 3 4 7 8 15 16
* Order INVALID_ORDER 0 1 1 2 2 3 3 4
*
* @param size
* @return order
*/
static inline unsigned int size_to_order(
unsigned int size
)
{
unsigned int order = INVALID_ORDER;
if (size != 0) {
/* ARMv5 as a CLZ instruction which count the leading zeros of
the binary representation of a value. It return a value
between 0 and 32.
Value 0 1 2 3 4 5 6 7 8 9 10 ...
CLZ 32 31 30 30 29 29 29 29 28 28 28 ...
We have excluded Size==0 before, so this is safe. */
order = __builtin_clz(
get_nr_of_pages_for_buffer(NULL, size));
/* there is a size overflow in get_nr_of_pages_for_buffer when
* the size is too large */
if (unlikely(order > 31))
return INVALID_ORDER;
order = 31 - order;
/* above algorithm rounds down: clz(5)=2 instead of 3 */
/* quick correction to fix it: */
if (((1<<order)*PAGE_SIZE) < size)
order++;
}
return order;
}
/* magic linux macro */
#if !defined(list_for_each_entry)
/* stop compiler */
#error "missing macro: list_for_each_entry()"
/* define a dummy */
#define list_for_each_entry(a, b, c) if (0)
#endif
/*----------------------------------------------------------------------------*/
/* return the page frame number of an address */
static inline unsigned int addr_to_pfn(
void *addr
)
{
/* there is no real API for this */
return ((unsigned int)(addr)) >> PAGE_SHIFT;
}
/*----------------------------------------------------------------------------*/
/* return the address of a page frame number */
static inline void *pfn_to_addr(
unsigned int pfn
)
{
/* there is no real API for this */
return (void *)(pfn << PAGE_SHIFT);
}
#endif /* _MC_DRV_MODULE_LINUX_API_H_ */
/** @} */

View file

@ -1,50 +0,0 @@
/**
* Header file of MobiCore Driver Kernel Module Platform
* specific structures
*
* @addtogroup MobiCore_Driver_Kernel_Module
* @{
* Internal structures of the McDrvModule
* @file
*
* Header file the MobiCore Driver Kernel Module,
* its internal structures and defines.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#ifndef _MC_DRV_PLATFORM_H_
#define _MC_DRV_PLATFORM_H_
/** MobiCore Interrupt for Qualcomm */
#define MC_INTR_SSIQ 280
/** Use SMC for fastcalls */
#define MC_SMC_FASTCALL
/*--------------- Implementation -------------- */
#include <mach/scm.h>
/* from following file */
#define SCM_SVC_MOBICORE 250
#define SCM_CMD_MOBICORE 1
extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
void *resp_buf, size_t resp_len);
static inline int smc_fastcall(void *fc_generic, size_t size)
{
return scm_call(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE,
fc_generic, size,
fc_generic, size);
}
/** Enable mobicore mem traces */
#define MC_MEM_TRACES
#endif /* _MC_DRV_PLATFORM_H_ */
/** @} */

View file

@ -1,311 +0,0 @@
/** @addtogroup MCD_MCDIMPL_KMOD_API Mobicore Driver Module API
* @ingroup MCD_MCDIMPL_KMOD
* @{
* Interface to Mobicore Driver Kernel Module.
* @file
*
* <h2>Introduction</h2>
* The MobiCore Driver Kernel Module is a Linux device driver, which represents
* the command proxy on the lowest layer to the secure world (Swd). Additional
* services like memory allocation via mmap and generation of a L2 tables for
* given virtual memory are also supported. IRQ functionallity receives
* information from the SWd in the non secure world (NWd).
* As customary the driver is handled as linux device driver with "open",
* "close" and "ioctl" commands. Access to the driver is possible after the
* device "/dev/mobicore" has been opened.
* The MobiCore Driver Kernel Module must be installed via
* "insmod mcDrvModule.ko".
*
*
* <h2>Version history</h2>
* <table class="customtab">
* <tr><td width="100px"><b>Date</b></td><td width="80px"><b>Version</b></td>
* <td><b>Changes</b></td></tr>
* <tr><td>2010-05-25</td><td>0.1</td><td>Initial Release</td></tr>
* </table>
*
* <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 _MC_DRV_MODULEAPI_H_
#define _MC_DRV_MODULEAPI_H_
#include "version.h"
#define MC_DRV_MOD_DEVNODE "mobicore"
#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/" MC_DRV_MOD_DEVNODE
/**
* Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
* INIT request data to SWD
*/
union mc_ioctl_init_params {
struct {
/** base address of mci buffer 4KB align */
uint32_t base;
/** notification buffer start/length [16:16] [start, length] */
uint32_t nq_offset;
/** length of notification queue */
uint32_t nq_length;
/** mcp buffer start/length [16:16] [start, length] */
uint32_t mcp_offset;
/** length of mcp buffer */
uint32_t mcp_length;
} in;
struct {
/* nothing */
} out;
};
/**
* Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
* INFO request data to the SWD
*/
union mc_ioctl_info_params {
struct {
uint32_t ext_info_id; /**< extended info ID */
} in;
struct {
uint32_t state; /**< state */
uint32_t ext_info; /**< extended info */
} out;
};
/**
* Mmap allocates and maps contiguous memory into a process.
* We use the third parameter, void *offset, to distinguish between some cases
* offset = MC_DRV_KMOD_MMAP_WSM usual operation, pages are registered in
device structure and freed later.
* offset = MC_DRV_KMOD_MMAP_MCI get Instance of MCI, allocates or mmaps
the MCI to daemon
* offset = MC_DRV_KMOD_MMAP_PERSISTENTWSM special operation, without
registration of pages
*
* In mmap(), the offset specifies which of several device I/O pages is
* requested. Linux only transfers the page number, i.e. the upper 20 bits to
* kernel module. Therefore we define our special offsets as multiples of page
* size.
*/
enum mc_mmap_memtype {
MC_DRV_KMOD_MMAP_WSM = 0,
MC_DRV_KMOD_MMAP_MCI = 4096,
MC_DRV_KMOD_MMAP_PERSISTENTWSM = 8192
};
struct mc_mmap_resp {
uint32_t handle; /**< WSN handle */
uint32_t phys_addr; /**< physical address of WSM (or NULL) */
bool is_reused; /**< if WSM memory was reused, or new allocated */
};
/**
* Data exchange structure of the MC_DRV_KMOD_IOCTL_FREE ioctl command.
*/
union mc_ioctl_free_params {
struct {
uint32_t handle; /**< driver handle */
uint32_t pid; /**< process id */
} in;
struct {
/* nothing */
} out;
};
/**
* Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 command.
*
* Allocates a physical L2 table and maps the buffer into this page.
* Returns the physical address of the L2 table.
* The page alignment will be created and the appropriated pSize and pOffsetL2
* will be modified to the used values.
*/
union mc_ioctl_app_reg_wsm_l2_params {
struct {
uint32_t buffer; /**< base address of the virtual address */
uint32_t len; /**< size of the virtual address space */
uint32_t pid; /**< process id */
} in;
struct {
uint32_t handle; /**< driver handle for locked memory */
uint32_t phys_wsm_l2_table; /* physical address of the L2 table */
} out;
};
/**
* Data exchange structure of the MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2
* command.
*/
struct mc_ioctl_app_unreg_wsm_l2_params {
struct {
uint32_t handle; /**< driver handle for locked memory */
uint32_t pid; /**< process id */
} in;
struct {
/* nothing */
} out;
};
/**
* Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 command.
*/
struct mc_ioctl_daemon_lock_wsm_l2_params {
struct {
uint32_t handle; /**< driver handle for locked memory */
} in;
struct {
uint32_t phys_wsm_l2_table;
} out;
};
/**
* Data exchange structure of the MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2
* command.
*/
struct mc_ioctl_daemon_unlock_wsm_l2_params {
struct {
uint32_t handle; /**< driver handle for locked memory */
} in;
struct {
/* nothing */
} out;
};
/**
* Data exchange structure of the MC_DRV_MODULE_FC_EXECUTE ioctl command.
*/
union mc_ioctl_fc_execute_params {
struct {
/**< base address of mobicore binary */
uint32_t phys_start_addr;
/**< length of DDR area */
uint32_t length;
} in;
struct {
/* nothing */
} out;
};
/**
* Data exchange structure of the MC_DRV_MODULE_GET_VERSION ioctl command.
*/
struct mc_ioctl_get_version_params {
struct {
uint32_t kernel_module_version;
} out;
};
/* @defgroup Mobicore_Driver_Kernel_Module_Interface IOCTL */
/* TODO: use IOCTL macros like _IOWR. See Documentation/ioctl/ioctl-number.txt,
Documentation/ioctl/ioctl-decoding.txt */
/**
* defines for the ioctl mobicore driver module function call from user space.
*/
enum mc_kmod_ioctl {
/*
* get detailed MobiCore Status
*/
MC_DRV_KMOD_IOCTL_DUMP_STATUS = 200,
/*
* initialize MobiCore
*/
MC_DRV_KMOD_IOCTL_FC_INIT = 201,
/*
* get MobiCore status
*/
MC_DRV_KMOD_IOCTL_FC_INFO = 202,
/**
* ioctl parameter to send the YIELD command to the SWD.
* Only possible in Privileged Mode.
* ioctl(fd, MC_DRV_MODULE_YIELD)
*/
MC_DRV_KMOD_IOCTL_FC_YIELD = 203,
/**
* ioctl parameter to send the NSIQ signal to the SWD.
* Only possible in Privileged Mode
* ioctl(fd, MC_DRV_MODULE_NSIQ)
*/
MC_DRV_KMOD_IOCTL_FC_NSIQ = 204,
/**
* ioctl parameter to tzbsp to start Mobicore binary from DDR.
* Only possible in Privileged Mode
* ioctl(fd, MC_DRV_KMOD_IOCTL_FC_EXECUTE)
*/
MC_DRV_KMOD_IOCTL_FC_EXECUTE = 205,
/**
* Free's memory which is formerly allocated by the driver's mmap
* command. The parameter must be this mmaped address.
* The internal instance data regarding to this address are deleted as
* well as each according memory page and its appropriated reserved bit
* is cleared (ClearPageReserved).
* Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address beeing of
* type long address
*/
MC_DRV_KMOD_IOCTL_FREE = 218,
/**
* Creates a L2 Table of the given base address and the size of the
* data.
* Parameter: mc_ioctl_app_reg_wsm_l2_params
*/
MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2 = 220,
/**
* Frees the L2 table created by a MC_DRV_KMOD_IOCTL_APP_REGISTER_WSM_L2
* ioctl.
* Parameter: mc_ioctl_app_unreg_wsm_l2_params
*/
MC_DRV_KMOD_IOCTL_APP_UNREGISTER_WSM_L2 = 221,
/* TODO: comment this. */
MC_DRV_KMOD_IOCTL_DAEMON_LOCK_WSM_L2 = 222,
MC_DRV_KMOD_IOCTL_DAEMON_UNLOCK_WSM_L2 = 223,
/**
* Return kernel driver version.
* Parameter: mc_ioctl_get_version_params
*/
MC_DRV_KMOD_IOCTL_GET_VERSION = 224,
};
#endif /* _MC_DRV_MODULEAPI_H_ */
/** @} */

View file

@ -1,100 +0,0 @@
/** @addtogroup MCD_MCDIMPL_KMOD_KAPI Mobicore Driver Module API inside Kernel.
* @ingroup MCD_MCDIMPL_KMOD
* @{
* Interface to Mobicore Driver Kernel Module inside Kernel.
* @file
*
* Interface to be used by module MobiCoreKernelAPI.
*
* <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
*
* 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.
*/
#ifndef _MOBICORE_KERNELMODULE_API_H_
#define _MOBICORE_KERNELMODULE_API_H_
struct mc_instance;
/**
* Initialize a new mobicore API instance object
*
* @return Instance or NULL if no allocation was possible.
*/
struct mc_instance *mobicore_open(
void
);
/**
* Release a mobicore instance object and all objects related to it
* @param instance instance
* @return 0 if Ok or -E ERROR
*/
int mobicore_release(
struct mc_instance *instance
);
/**
* Free a WSM buffer allocated with mobicore_allocate_wsm
* @param instance
* @param handle handle of the buffer
*
* @return 0 if no error
*
*/
int mobicore_allocate_wsm(
struct mc_instance *instance,
unsigned long requested_size,
uint32_t *handle,
void **kernel_virt_addr,
void **phys_addr
);
/**
* Free a WSM buffer allocated with mobicore_allocate_wsm
* @param instance
* @param handle handle of the buffer
*
* @return 0 if no error
*
*/
int mobicore_free(
struct mc_instance *instance,
uint32_t handle
);
/**
* Map a virtual memory buffer structure to Mobicore
* @param instance
* @param addr address of the buffer(NB it must be kernel virtual!)
* @param len buffer length
* @param handle pointer to handle
* @param phys_wsm_l2_table pointer to physical L2 table(?)
*
* @return 0 if no error
*
*/
int mobicore_map_vmem(
struct mc_instance *instance,
void *addr,
uint32_t len,
uint32_t *handle,
void **phys_wsm_l2_table
);
/**
* Unmap a virtual memory buffer from mobicore
* @param instance
* @param handle
*
* @return 0 if no error
*
*/
int mobicore_unmap_vmem(
struct mc_instance *instance,
uint32_t handle
);
#endif /* _MOBICORE_KERNELMODULE_API_H_ */
/** @} */

View file

@ -1,36 +0,0 @@
/** @addtogroup MCD_MCDIMPL_KMOD
* @{
* <!-- Copyright Giesecke & Devrient GmbH 2010-2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 _MC_DRV_VERSION_H_
#define _MC_DRV_VERSION_H_
#define MCDRVMODULEAPI_VERSION_MAJOR 0
#define MCDRVMODULEAPI_VERSION_MINOR 1
#endif /* _MC_DRV_VERSION_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,97 +0,0 @@
/**
*
* Common data types
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#ifndef COMMON_H
#define COMMON_H
#include "connection.h"
#include "mcinq.h"
void mcapi_insert_connection(
struct connection *connection
);
void mcapi_remove_connection(
uint32_t seq
);
unsigned int mcapi_unique_id(
void
);
#define MC_DAEMON_PID 0xFFFFFFFF
#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/mobicore"
/* dummy function helper macro. */
#define DUMMY_FUNCTION() do {} while (0)
#define MCDRV_ERROR(txt, ...) \
printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
__func__, \
##__VA_ARGS__)
#if defined(DEBUG)
/* #define DEBUG_VERBOSE */
#if defined(DEBUG_VERBOSE)
#define MCDRV_DBG_VERBOSE MCDRV_DBG
#else
#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
#endif
#define MCDRV_DBG(txt, ...) \
printk(KERN_INFO "mcKernelApi %s(): " txt, \
__func__, \
##__VA_ARGS__)
#define MCDRV_DBG_WARN(txt, ...) \
printk(KERN_WARNING "mcKernelApi %s() WARNING: " txt, \
__func__, \
##__VA_ARGS__)
#define MCDRV_DBG_ERROR(txt, ...) \
printk(KERN_ERR "mcKernelApi %s() ### ERROR: " txt, \
__func__, \
##__VA_ARGS__)
#define MCDRV_ASSERT(cond) \
do { \
if (unlikely(!(cond))) { \
panic("mcKernelApi Assertion failed: %s:%d\n", \
__FILE__, __LINE__); \
} \
} while (0)
#elif defined(NDEBUG)
#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
#define MCDRV_DBG(...) DUMMY_FUNCTION()
#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION()
#define MCDRV_DBG_ERROR(...) DUMMY_FUNCTION()
#define MCDRV_ASSERT(...) DUMMY_FUNCTION()
#else
#error "Define DEBUG or NDEBUG"
#endif /* [not] defined(DEBUG_MCMODULE) */
#define LOG_I MCDRV_DBG_VERBOSE
#define LOG_W MCDRV_DBG_WARN
#define LOG_E MCDRV_DBG_ERROR
#define assert(expr) MCDRV_ASSERT(expr)
#endif /* COMMON_H */
/** @} */

View file

@ -1,229 +0,0 @@
/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
* @{
* @file
*
* Connection data.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/semaphore.h>
#include <linux/time.h>
#include <net/sock.h>
#include <net/net_namespace.h>
#include "connection.h"
#include "common.h"
/* Define the initial state of the Data Available Semaphore */
#define SEM_NO_DATA_AVAILABLE 0
/*----------------------------------------------------------------------------*/
struct connection *connection_new(
void
) {
struct connection *conn = kzalloc(sizeof(struct connection),
GFP_KERNEL);
conn->sequence_magic = mcapi_unique_id();
mutex_init(&conn->data_lock);
/* No data available */
sema_init(&conn->data_available_sem, SEM_NO_DATA_AVAILABLE);
mcapi_insert_connection(conn);
return conn;
}
/*----------------------------------------------------------------------------*/
struct connection *connection_create(
int socket_descriptor,
pid_t dest
) {
struct connection *conn = connection_new();
conn->peer_pid = dest;
return conn;
}
/*----------------------------------------------------------------------------*/
void connection_cleanup(
struct connection *conn
) {
if (!conn)
return;
kfree_skb(conn->skb);
mcapi_remove_connection(conn->sequence_magic);
kfree(conn);
}
/*----------------------------------------------------------------------------*/
bool connection_connect(
struct connection *conn,
pid_t dest
) {
/* Nothing to connect */
conn->peer_pid = dest;
return true;
}
/*----------------------------------------------------------------------------*/
size_t connection_readDataMsg(
struct connection *conn,
void *buffer,
uint32_t len
) {
size_t ret = -1;
MCDRV_DBG_VERBOSE("reading connection data %u, connection data left %u",
len, conn->data_len);
/* trying to read more than the left data */
if (len > conn->data_len) {
ret = conn->data_len;
memcpy(buffer, conn->data_start, conn->data_len);
conn->data_len = 0;
} else {
ret = len;
memcpy(buffer, conn->data_start, len);
conn->data_len -= len;
conn->data_start += len;
}
if (conn->data_len == 0) {
conn->data_start = NULL;
kfree_skb(conn->skb);
conn->skb = NULL;
}
MCDRV_DBG_VERBOSE("read %u", ret);
return ret;
}
/*----------------------------------------------------------------------------*/
size_t connection_read_datablock(
struct connection *conn,
void *buffer,
uint32_t len
) {
return connection_read_data(conn, buffer, len, -1);
}
/*----------------------------------------------------------------------------*/
size_t connection_read_data(
struct connection *conn,
void *buffer,
uint32_t len,
int32_t timeout
) {
size_t ret = 0;
MCDRV_ASSERT(buffer != NULL);
MCDRV_ASSERT(conn->socket_descriptor != NULL);
MCDRV_DBG_VERBOSE("read data len = %u for PID = %u",
len, conn->sequence_magic);
do {
/* Wait until data is available or timeout
msecs_to_jiffies(-1) -> wait forever for the sem */
if (down_timeout(&(conn->data_available_sem),
msecs_to_jiffies(timeout))) {
MCDRV_DBG_VERBOSE("Timeout reading the data sem");
ret = -2;
break;
}
if (mutex_lock_interruptible(&(conn->data_lock))) {
MCDRV_DBG_ERROR("interrupted reading the data sem");
ret = -1;
break;
}
/* Have data, use it */
if (conn->data_len > 0)
ret = connection_readDataMsg(conn, buffer, len);
mutex_unlock(&(conn->data_lock));
/* There is still some data left */
if (conn->data_len > 0)
up(&conn->data_available_sem);
} while (0);
return ret;
}
/*----------------------------------------------------------------------------*/
size_t connection_write_data(
struct connection *conn,
void *buffer,
uint32_t len
) {
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh;
int ret = 0;
MCDRV_DBG_VERBOSE("buffer length %u from pid %u\n",
len, conn->sequence_magic);
do {
skb = nlmsg_new(NLMSG_SPACE(len), GFP_KERNEL);
if (!skb) {
ret = -1;
break;
}
nlh = nlmsg_put(skb, 0, conn->sequence_magic, 2,
NLMSG_LENGTH(len), NLM_F_REQUEST);
if (!nlh) {
ret = -1;
break;
}
memcpy(NLMSG_DATA(nlh), buffer, len);
netlink_unicast(conn->socket_descriptor, skb,
conn->peer_pid, MSG_DONTWAIT);
ret = len;
} while (0);
if (!ret && skb != NULL)
kfree_skb(skb);
return ret;
}
int connection_process(
struct connection *conn,
struct sk_buff *skb
)
{
int ret = 0;
do {
if (mutex_lock_interruptible(&(conn->data_lock))) {
MCDRV_DBG_ERROR("Interrupted getting data semaphore!");
ret = -1;
break;
}
kfree_skb(conn->skb);
/* Get a reference to the incomming skb */
conn->skb = skb_get(skb);
if (conn->skb) {
conn->data_msg = nlmsg_hdr(conn->skb);
conn->data_len = NLMSG_PAYLOAD(conn->data_msg, 0);
conn->data_start = NLMSG_DATA(conn->data_msg);
up(&(conn->data_available_sem));
}
mutex_unlock(&(conn->data_lock));
ret = 0;
} while (0);
return ret;
}
/** @} */

View file

@ -1,122 +0,0 @@
/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
* @{
* @file
*
* Connection data.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#ifndef CONNECTION_H_
#define CONNECTION_H_
#include <linux/semaphore.h>
#include <stddef.h>
#include <stdbool.h>
#define MAX_PAYLOAD_SIZE 128
struct connection {
struct sock *socket_descriptor; /**< Netlink socket */
uint32_t sequence_magic; /**< Random? magic to match requests/answers */
struct nlmsghdr *data_msg;
uint32_t data_len; /**< How much connection data is left */
void *data_start; /**< Start pointer of remaining data */
struct sk_buff *skb;
struct mutex data_lock; /**< Data protection lock */
struct semaphore data_available_sem; /**< Data protection semaphore */
pid_t self_pid; /**< PID address used for local connection */
pid_t peer_pid; /**< Remote PID for connection */
struct list_head list; /**< The list param for using the kernel lists*/
};
struct connection *connection_new(
void
);
struct connection *connection_create(
int socket_descriptor,
pid_t dest
);
void connection_cleanup(
struct connection *conn
);
/**
* Connect to destination.
*
* @param Destination pointer.
* @return true on success.
*/
bool connection_connect(
struct connection *conn,
pid_t dest
);
/**
* Read bytes from the connection.
*
* @param buffer Pointer to destination buffer.
* @param len Number of bytes to read.
* @return Number of bytes read.
*/
size_t connection_read_datablock(
struct connection *conn,
void *buffer,
uint32_t len
);
/**
* Read bytes from the connection.
*
* @param buffer Pointer to destination buffer.
* @param len Number of bytes to read.
* @param timeout Timeout in milliseconds
* @return Number of bytes read.
* @return -1 if select() failed (returned -1)
* @return -2 if no data available, i.e. timeout
*/
size_t connection_read_data(
struct connection *conn,
void *buffer,
uint32_t len,
int32_t timeout
);
/**
* Write bytes to the connection.
*
* @param buffer Pointer to source buffer.
* @param len Number of bytes to read.
* @return Number of bytes written.
*/
size_t connection_write_data(
struct connection *conn,
void *buffer,
uint32_t len
);
/**
* Write bytes to the connection.
*
* @param buffer Pointer to source buffer.
* @param len Number of bytes to read.
* @return Number of bytes written.
*/
int connection_process(
struct connection *conn,
struct sk_buff *skb
);
#endif /* CONNECTION_H_ */
/** @} */

View file

@ -1,257 +0,0 @@
/** @addtogroup MCD_IMPL_LIB
* @{
* @file
*
* Client library device management.
*
* Device and Trustlet Session management Funtions.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#include <linux/list.h>
#include <linux/slab.h>
#include "mc_kernel_api.h"
#include "public/mobicore_driver_api.h"
#include "device.h"
#include "common.h"
/*----------------------------------------------------------------------------*/
struct wsm *wsm_create(
void *virt_addr,
uint32_t len,
uint32_t handle,
void *phys_addr /*= NULL this may be unknown, so is can be omitted.*/
)
{
struct wsm *wsm = kzalloc(sizeof(struct wsm), GFP_KERNEL);
wsm->virt_addr = virt_addr;
wsm->len = len;
wsm->handle = handle;
wsm->phys_addr = phys_addr;
return wsm;
}
/*----------------------------------------------------------------------------*/
struct mcore_device_t *mcore_device_create(
uint32_t device_id,
struct connection *connection
) {
struct mcore_device_t *dev =
kzalloc(sizeof(struct mcore_device_t), GFP_KERNEL);
dev->device_id = device_id;
dev->connection = connection;
INIT_LIST_HEAD(&dev->session_vector);
INIT_LIST_HEAD(&dev->wsm_l2_vector);
return dev;
}
/*----------------------------------------------------------------------------*/
void mcore_device_cleanup(
struct mcore_device_t *dev
) {
struct session *tmp;
struct wsm *wsm;
struct list_head *pos, *q;
/* Delete all session objects. Usually this should not be needed
* as closeDevice()requires that all sessions have been closed before.*/
list_for_each_safe(pos, q, &dev->session_vector) {
tmp = list_entry(pos, struct session, list);
list_del(pos);
session_cleanup(tmp);
}
/* Free all allocated WSM descriptors */
list_for_each_safe(pos, q, &dev->wsm_l2_vector) {
wsm = list_entry(pos, struct wsm, list);
/* mcKMod_free(dev->instance, wsm->handle); */
list_del(pos);
kfree(wsm);
}
connection_cleanup(dev->connection);
mcore_device_close(dev);
kfree(dev);
}
/*----------------------------------------------------------------------------*/
bool mcore_device_open(
struct mcore_device_t *dev,
const char *deviceName
) {
dev->instance = mobicore_open();
return (dev->instance != NULL);
}
/*----------------------------------------------------------------------------*/
void mcore_device_close(
struct mcore_device_t *dev
) {
mobicore_release(dev->instance);
}
/*----------------------------------------------------------------------------*/
bool mcore_device_has_sessions(
struct mcore_device_t *dev
) {
return !list_empty(&dev->session_vector);
}
/*----------------------------------------------------------------------------*/
bool mcore_device_create_new_session(
struct mcore_device_t *dev,
uint32_t session_id,
struct connection *connection
) {
/* Check if session_id already exists */
if (mcore_device_resolve_session_id(dev, session_id)) {
MCDRV_DBG_ERROR(" session %u already exists", session_id);
return false;
}
struct session *session = session_create(session_id, dev->instance,
connection);
list_add_tail(&(session->list), &(dev->session_vector));
return true;
}
/*----------------------------------------------------------------------------*/
bool mcore_device_remove_session(
struct mcore_device_t *dev,
uint32_t session_id
) {
bool ret = false;
struct session *tmp;
struct list_head *pos, *q;
list_for_each_safe(pos, q, &dev->session_vector) {
tmp = list_entry(pos, struct session, list);
if (tmp->session_id == session_id) {
list_del(pos);
session_cleanup(tmp);
ret = true;
break;
}
}
return ret;
}
/*----------------------------------------------------------------------------*/
struct session *mcore_device_resolve_session_id(
struct mcore_device_t *dev,
uint32_t session_id
) {
struct session *ret = NULL;
struct session *tmp;
struct list_head *pos;
/* Get session for session_id */
list_for_each(pos, &dev->session_vector) {
tmp = list_entry(pos, struct session, list);
if (tmp->session_id == session_id) {
ret = tmp;
break;
}
}
return ret;
}
/*----------------------------------------------------------------------------*/
struct wsm *mcore_device_allocate_contiguous_wsm(
struct mcore_device_t *dev,
uint32_t len
) {
struct wsm *wsm = NULL;
do {
if (len == 0)
break;
/* Allocate shared memory */
void *virt_addr;
uint32_t handle;
void *phys_addr;
int ret = mobicore_allocate_wsm(dev->instance,
len,
&handle,
&virt_addr,
&phys_addr);
if (ret != 0)
break;
/* Register (vaddr,paddr) with device */
wsm = wsm_create(virt_addr, len, handle, phys_addr);
list_add_tail(&(wsm->list), &(dev->wsm_l2_vector));
} while (0);
/* Return pointer to the allocated memory */
return wsm;
}
/*----------------------------------------------------------------------------*/
bool mcore_device_free_contiguous_wsm(
struct mcore_device_t *dev,
struct wsm *wsm
) {
bool ret = false;
struct wsm *tmp;
struct list_head *pos;
list_for_each(pos, &dev->wsm_l2_vector) {
tmp = list_entry(pos, struct wsm, list);
if (tmp == wsm) {
ret = true;
break;
}
}
if (ret) {
MCDRV_DBG_VERBOSE("freeWsm virt_addr=0x%p, handle=%d",
wsm->virt_addr, wsm->handle);
/* ignore return code */
mobicore_free(dev->instance, wsm->handle);
list_del(pos);
kfree(wsm);
}
return ret;
}
/*----------------------------------------------------------------------------*/
struct wsm *mcore_device_find_contiguous_wsm(
struct mcore_device_t *dev,
void *virt_addr
) {
struct wsm *wsm;
struct list_head *pos;
list_for_each(pos, &dev->wsm_l2_vector) {
wsm = list_entry(pos, struct wsm, list);
if (virt_addr == wsm->virt_addr)
return wsm;
}
return NULL;
}
/** @} */

View file

@ -1,139 +0,0 @@
/** @addtogroup MCD_IMPL_LIB
* @{
* @file
*
* Client library device management.
*
* Device and Trustlet Session management Functions.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#ifndef DEVICE_H_
#define DEVICE_H_
#include <linux/list.h>
#include "connection.h"
#include "session.h"
#include "wsm.h"
struct mcore_device_t {
struct list_head session_vector; /**< MobiCore Trustlet session
associated with the device */
struct list_head wsm_l2_vector; /**< WSM L2 Table */
uint32_t device_id; /**< Device identifier */
struct connection *connection; /**< The device connection */
struct mc_instance *instance; /**< MobiCore Driver instance */
struct list_head list; /**< The list param for using the kernel lists*/
};
struct mcore_device_t *mcore_device_create(
uint32_t device_id,
struct connection *connection
);
void mcore_device_cleanup(
struct mcore_device_t *dev
);
/**
* Open the device.
* @param deviceName Name of the kernel modules device file.
* @return true if the device has been opened successfully
*/
bool mcore_device_open(
struct mcore_device_t *dev,
const char *deviceName
);
/**
* Closes the device.
*/
void mcore_device_close(
struct mcore_device_t *dev
);
/**
* Check if the device has open sessions.
* @return true if the device has one or more open sessions.
*/
bool mcore_device_has_sessions(
struct mcore_device_t *dev
);
/**
* Add a session to the device.
* @param session_id session ID
* @param connection session connection
*/
bool mcore_device_create_new_session(
struct mcore_device_t *dev,
uint32_t session_id,
struct connection *connection
);
/**
* Remove the specified session from the device.
* The session object will be destroyed and all resources associated with it
* will be freed.
*
* @param session_id Session of the session to remove.
* @return true if a session has been found and removed.
*/
bool mcore_device_remove_session(
struct mcore_device_t *dev,
uint32_t session_id
);
/**
* Get as session object for a given session ID.
* @param session_id Identified of a previously opened session.
* @return Session object if available or NULL if no session has been found.
*/
struct session *mcore_device_resolve_session_id(
struct mcore_device_t *dev,
uint32_t session_id
);
/**
* Allocate a block of contiguous WSM.
* @param len The virtual address to be registered.
* @return The virtual address of the allocated memory or NULL if no memory
* is available.
*/
struct wsm *mcore_device_allocate_contiguous_wsm(
struct mcore_device_t *dev,
uint32_t len
);
/**
* Unregister a vaddr from a device.
* @param vaddr The virtual address to be registered.
* @param paddr The physical address to be registered.
*/
bool mcore_device_free_contiguous_wsm(
struct mcore_device_t *dev,
struct wsm *wsm
);
/**
* Get a WSM object for a given virtual address.
* @param vaddr The virtual address which has been allocate with mc_malloc_wsm()
* in advance.
* @return the WSM object or NULL if no address has been found.
*/
struct wsm *mcore_device_find_contiguous_wsm(
struct mcore_device_t *dev,
void *virt_addr
);
#endif /* DEVICE_H_ */
/** @} */

View file

@ -1,125 +0,0 @@
/** @addtogroup NQ
* @{
* Notifications inform the MobiCore runtime environment that information is
* pending in a WSM buffer.
* The Trustlet Connector (TLC) and the corresponding trustlet also utilize
* this buffer to notify each other about new data within the
* Trustlet Connector Interface (TCI).
*
* The buffer is set up as a queue, which means that more than one
* notification can be written to the buffer before the switch to the other
* world is performed. Each side therefore facilitates an incoming and an
* outgoing queue for communication with the other side.
*
* Notifications hold the session ID, which is used to reference the
* communication partner in the other world.
* So if, e.g., the TLC in the normal world wants to notify his trustlet
* about new data in the TLC buffer
*
* @file
* Notification queue declarations.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NQ_H_
#define NQ_H_
/** \name NQ Size Defines
* Minimum and maximum count of elements in the notification queue.
* @{ */
#define MIN_NQ_ELEM 1 /**< Minimum notification queue elements. */
#define MAX_NQ_ELEM 64 /**< Maximum notification queue elements. */
/** @} */
/** \name NQ Length Defines
* Minimum and maximum notification queue length.
* @{ */
/**< Minimum notification length (in bytes). */
#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification))
/**< Maximum notification length (in bytes). */
#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification))
/** @} */
/** \name Session ID Defines
* Standard Session IDs.
* @{ */
/**< MCP session ID is used when directly communicating with the MobiCore
* (e.g. for starting and stopping of trustlets). */
#define SID_MCP 0
/**< Invalid session id is returned in case of an error. */
#define SID_INVALID 0xffffffff
/** @} */
/** Notification data structure. */
struct notification {
uint32_t session_id; /**< Session ID. */
int32_t payload; /**< Additional notification information. */
};
/** Notification payload codes.
* 0 indicated a plain simple notification,
* a positive value is a termination reason from the task,
* a negative value is a termination reason from MobiCore.
* Possible negative values are given below.
*/
enum notification_payload {
/**< task terminated, but exit code is invalid */
ERR_INVALID_EXIT_CODE = -1,
/**< task terminated due to session end, no exit code available */
ERR_SESSION_CLOSE = -2,
/**< task terminated due to invalid operation */
ERR_INVALID_OPERATION = -3,
/**< session ID is unknown */
ERR_INVALID_SID = -4,
/**< session is not active */
ERR_SID_NOT_ACTIVE = -5
};
/** Declaration of the notification queue header.
* layout as specified in the data structure specification.
*/
struct notification_queue_header {
uint32_t write_cnt; /**< Write counter. */
uint32_t read_cnt; /**< Read counter. */
uint32_t queue_size; /**< Queue size. */
};
/** Queue struct which defines a queue object.
* The queue struct is accessed by the queue<operation> type of
* function. elementCnt must be a power of two and the power needs
* to be smaller than power of uint32_t (obviously 32).
*/
struct notification_queue {
/**< Queue header. */
struct notification_queue_header hdr;
/**< Notification elements. */
struct notification notification[MIN_NQ_ELEM];
} ;
#endif /** NQ_H_ */
/** @} */

View file

@ -1,74 +0,0 @@
/**
* @addtogroup MC_UUID mcUuid - Universally Unique Identifier.
*
* <!-- Copyright Giesecke & Devrient GmbH 2011-2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
*
* @ingroup MC_DATA_TYPES
* @{
*/
#ifndef MC_UUID_H_
#define MC_UUID_H_
#define UUID_TYPE
/** Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
struct mc_uuid_t {
uint8_t value[16]; /**< Value of the UUID. */
};
/** UUID value used as free marker in service provider containers. */
#define MC_UUID_FREE_DEFINE \
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
static const struct mc_uuid_t MC_UUID_FREE = {
MC_UUID_FREE_DEFINE
};
/** Reserved UUID. */
#define MC_UUID_RESERVED_DEFINE \
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
static const struct mc_uuid_t MC_UUID_RESERVED = {
MC_UUID_RESERVED_DEFINE
};
/** UUID for system applications. */
#define MC_UUID_SYSTEM_DEFINE \
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE }
static const struct mc_uuid_t MC_UUID_SYSTEM = {
MC_UUID_SYSTEM_DEFINE
};
#endif /* MC_UUID_H_ */
/** @} */

View file

@ -1,181 +0,0 @@
/**
* MobiCore KernelApi module
*
* <!-- Copyright Giesecke & Devrient GmbH 2009-2012 -->
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/netlink.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/list.h>
#include "connection.h"
#include "common.h"
#define MC_DAEMON_NETLINK 17
struct mc_kernelapi_ctx {
struct sock *sk;
struct list_head peers;
atomic_t counter;
};
struct mc_kernelapi_ctx *mod_ctx; /* = NULL; */
/*----------------------------------------------------------------------------*/
/* get a unique ID */
unsigned int mcapi_unique_id(
void
)
{
return (unsigned int)atomic_inc_return(
&(mod_ctx->counter));
}
/*----------------------------------------------------------------------------*/
static struct connection *mcapi_find_connection(
uint32_t seq
)
{
struct connection *tmp;
struct list_head *pos;
/* Get session for session_id */
list_for_each(pos, &mod_ctx->peers) {
tmp = list_entry(pos, struct connection, list);
if (tmp->sequence_magic == seq)
return tmp;
}
return NULL;
}
/*----------------------------------------------------------------------------*/
void mcapi_insert_connection(
struct connection *connection
)
{
list_add_tail(&(connection->list), &(mod_ctx->peers));
connection->socket_descriptor = mod_ctx->sk;
}
void mcapi_remove_connection(
uint32_t seq
)
{
struct connection *tmp;
struct list_head *pos, *q;
/* Delete all session objects. Usually this should not be needed as
closeDevice() requires that all sessions have been closed before.*/
list_for_each_safe(pos, q, &mod_ctx->peers) {
tmp = list_entry(pos, struct connection, list);
if (tmp->sequence_magic == seq) {
list_del(pos);
break;
}
}
}
/*----------------------------------------------------------------------------*/
static int mcapi_process(
struct sk_buff *skb,
struct nlmsghdr *nlh
)
{
struct connection *c;
int length;
int seq;
pid_t pid;
int ret;
pid = nlh->nlmsg_pid;
length = nlh->nlmsg_len;
seq = nlh->nlmsg_seq;
MCDRV_DBG_VERBOSE("nlmsg len %d type %d pid 0x%X seq %d\n",
length, nlh->nlmsg_type, pid, seq);
do {
c = mcapi_find_connection(seq);
if (!c) {
MCDRV_ERROR("Invalid incomming connection - seq=%u!",
seq);
ret = -1;
break;
}
/* Pass the buffer to the appropriate connection */
connection_process(c, skb);
ret = 0;
} while (false);
return ret;
}
/*----------------------------------------------------------------------------*/
static void mcapi_callback(
struct sk_buff *skb
)
{
struct nlmsghdr *nlh = nlmsg_hdr(skb);
int len = skb->len;
int err = 0;
while (NLMSG_OK(nlh, len)) {
err = mcapi_process(skb, nlh);
/* if err or if this message says it wants a response */
if (err || (nlh->nlmsg_flags & NLM_F_ACK))
netlink_ack(skb, nlh, err);
nlh = NLMSG_NEXT(nlh, len);
}
}
/*----------------------------------------------------------------------------*/
static int __init mcapi_init(void)
{
printk(KERN_INFO "Mobicore API module initialized!\n");
mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL);
/* start kernel thread */
mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK, 0,
mcapi_callback, NULL, THIS_MODULE);
if (!mod_ctx->sk) {
MCDRV_ERROR("register of recieve handler failed");
return -EFAULT;
}
INIT_LIST_HEAD(&mod_ctx->peers);
return 0;
}
static void __exit mcapi_exit(void)
{
printk(KERN_INFO "Unloading Mobicore API module.\n");
if (mod_ctx->sk != NULL) {
netlink_kernel_release(mod_ctx->sk);
mod_ctx->sk = NULL;
}
kfree(mod_ctx);
mod_ctx = NULL;
}
module_init(mcapi_init);
module_exit(mcapi_exit);
MODULE_AUTHOR("Giesecke & Devrient GmbH");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MobiCore API driver");

View file

@ -1,483 +0,0 @@
/**
* @defgroup MCD_API MobiCore Driver API
* @addtogroup MCD_API
* @{
*
* @if DOXYGEN_MCDRV_API
* @mainpage MobiCore Driver API.
* @endif
*
* MobiCore Driver API.
*
* The MobiCore (MC) Driver API provides access functions to the MobiCore
* runtime environment and the contained Trustlets.
*
* @image html DoxyOverviewDrvApi500x.png
* @image latex DoxyOverviewDrvApi500x.png "MobiCore Overview" width=12cm
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 MCDRIVER_H_
#define MCDRIVER_H_
#define __MC_CLIENT_LIB_API
#include "mcuuid.h"
/**
* Return values of MobiCore driver functions.
*/
enum mc_result {
/**< Function call succeeded. */
MC_DRV_OK = 0,
/**< No notification available. */
MC_DRV_NO_NOTIFICATION = 1,
/**< Error during notification on communication level. */
MC_DRV_ERR_NOTIFICATION = 2,
/**< Function not implemented. */
MC_DRV_ERR_NOT_IMPLEMENTED = 3,
/**< No more resources available. */
MC_DRV_ERR_OUT_OF_RESOURCES = 4,
/**< Driver initialization failed. */
MC_DRV_ERR_INIT = 5,
/**< Unknown error. */
MC_DRV_ERR_UNKNOWN = 6,
/**< The specified device is unknown. */
MC_DRV_ERR_UNKNOWN_DEVICE = 7,
/**< The specified session is unknown.*/
MC_DRV_ERR_UNKNOWN_SESSION = 8,
/**< The specified operation is not allowed. */
MC_DRV_ERR_INVALID_OPERATION = 9,
/**< The response header from the MC is invalid. */
MC_DRV_ERR_INVALID_RESPONSE = 10,
/**< Function call timed out. */
MC_DRV_ERR_TIMEOUT = 11,
/**< Can not allocate additional memory. */
MC_DRV_ERR_NO_FREE_MEMORY = 12,
/**< Free memory failed. */
MC_DRV_ERR_FREE_MEMORY_FAILED = 13,
/**< Still some open sessions pending. */
MC_DRV_ERR_SESSION_PENDING = 14,
/**< MC daemon not reachable */
MC_DRV_ERR_DAEMON_UNREACHABLE = 15,
/**< The device file of the kernel module could not be opened. */
MC_DRV_ERR_INVALID_DEVICE_FILE = 16,
/**< Invalid parameter. */
MC_DRV_ERR_INVALID_PARAMETER = 17,
/**< Unspecified error from Kernel Module*/
MC_DRV_ERR_KERNEL_MODULE = 18,
/**< Error during mapping of additional bulk memory to session. */
MC_DRV_ERR_BULK_MAPPING = 19,
/**< Error during unmapping of additional bulk memory to session. */
MC_DRV_ERR_BULK_UNMAPPING = 20,
/**< Notification received, exit code available. */
MC_DRV_INFO_NOTIFICATION = 21,
/**< Set up of NWd connection failed. */
MC_DRV_ERR_NQ_FAILED = 22
};
/**
* Driver control command.
*/
enum mc_driver_ctrl {
MC_CTRL_GET_VERSION = 1 /**< Return the driver version */
};
/** Structure of Session Handle, includes the Session ID and the Device ID the
* Session belongs to.
* The session handle will be used for session-based MobiCore communication.
* It will be passed to calls which address a communication end point in the
* MobiCore environment.
*/
struct mc_session_handle {
uint32_t session_id; /**< MobiCore session ID */
uint32_t device_id; /**< Device ID the session belongs to */
};
/** Information structure about additional mapped Bulk buffer between the
* Trustlet Connector (Nwd) and the Trustlet (Swd). This structure is
* initialized from a Trustlet Connector by calling mc_map().
* In order to use the memory within a Trustlet the Trustlet Connector has to
* inform the Trustlet with the content of this structure via the TCI.
*/
struct mc_bulk_map {
/**< The virtual address of the Bulk buffer regarding the address space
* of the Trustlet, already includes a possible offset! */
void *secure_virt_addr;
uint32_t secure_virt_len; /**< Length of the mapped Bulk buffer */
};
/**< The default device ID */
#define MC_DEVICE_ID_DEFAULT 0
/**< Wait infinite for a response of the MC. */
#define MC_INFINITE_TIMEOUT ((int32_t)(-1))
/**< Do not wait for a response of the MC. */
#define MC_NO_TIMEOUT 0
/**< TCI/DCI must not exceed 1MiB */
#define MC_MAX_TCI_LEN 0x100000
/** Open a new connection to a MobiCore device.
*
* mc_open_device() initializes all device specific resources required to
* communicate with an MobiCore instance located on the specified device in the
* system. If the device does not exist the function will return
* MC_DRV_ERR_UNKNOWN_DEVICE.
*
* @param [in] device_id Identifier for the MobiCore device to be used.
* MC_DEVICE_ID_DEFAULT refers to the default device.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_ERR_INVALID_OPERATION if device already opened.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device_id is unknown.
* @return MC_DRV_ERR_INVALID_DEVICE_FILE if kernel module under
* /dev/mobicore cannot be opened
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_open_device(
uint32_t device_id
);
/** Close the connection to a MobiCore device.
* When closing a device, active sessions have to be closed beforehand.
* Resources associated with the device will be released.
* The device may be opened again after it has been closed.
*
* @param [in] device_id Identifier for the MobiCore device.
* MC_DEVICE_ID_DEFAULT refers to the default device.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
* @return MC_DRV_ERR_SESSION_PENDING when a session is still open.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_close_device(
uint32_t device_id
);
/** Open a new session to a Trustlet. The trustlet with the given UUID has
* to be available in the flash filesystem.
*
* Write MCP open message to buffer and notify MobiCore about the availability
* of a new command.
* Waits till the MobiCore responses with the new session ID (stored in the MCP
* buffer).
*
* @param [in,out] session On success, the session data will be returned.
* Note that session.device_id has to be the device id of an opened device.
* @param [in] uuid UUID of the Trustlet to be opened.
* @param [in] tci TCI buffer for communicating with the trustlet.
* @param [in] tci_len Length of the TCI buffer. Maximum allowed value
* is MC_MAX_TCI_LEN.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon socket occur.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when daemon returns an error.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_open_session(
struct mc_session_handle *session,
const struct mc_uuid_t *uuid,
uint8_t *tci,
uint32_t tci_len
);
/** Close a Trustlet session.
*
* Closes the specified MobiCore session. The call will block until the
* session has been closed.
*
* @pre Device device_id has to be opened in advance.
*
* @param [in] session Session to be closed.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
* @return MC_DRV_ERR_INVALID_DEVICE_FILE when daemon cannot open trustlet file.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_close_session(
struct mc_session_handle *session
);
/** Notify a session.
* Notifies the session end point about available message data.
* If the session parameter is correct, notify will always succeed.
* Corresponding errors can only be received by mc_wait_notification().
* @pre A session has to be opened in advance.
*
* @param session The session to be notified.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if session parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
*/
__MC_CLIENT_LIB_API enum mc_result mc_notify(
struct mc_session_handle *session
);
/** Wait for a notification.
*
* Wait for a notification issued by the MobiCore for a specific session.
* The timeout parameter specifies the number of milliseconds the call will wait
* for a notification.
* If the caller passes 0 as timeout value the call will immediately return.
* If timeout value is below 0 the call will block until a notification for the
session has been received.
*
* @attention if timeout is below 0, call will block:
* Caller has to trust the other side to send a notification to wake him up
* again.
*
* @param [in] session The session the notification should correspond to.
* @param [in] timeout Time in milliseconds to wait
* (MC_NO_TIMEOUT : direct return, > 0 : milliseconds,
* MC_INFINITE_TIMEOUT : wait infinitely)
*
* @return MC_DRV_OK if notification is available.
* @return MC_DRV_ERR_TIMEOUT if no notification arrived in time.
* @return MC_DRV_INFO_NOTIFICATION if a problem with the session was
* encountered. Get more details with mc_get_session_error_code().
* @return MC_DRV_ERR_NOTIFICATION if a problem with the socket occurred.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
*/
__MC_CLIENT_LIB_API enum mc_result mc_wait_notification(
struct mc_session_handle *session,
int32_t timeout
);
/**
* Allocate a block of world shared memory (WSM).
* The MC driver allocates a contiguous block of memory which can be used as
* WSM.
* This implicates that the allocated memory is aligned according to the
* alignment parameter.
* Always returns a buffer of size WSM_SIZE aligned to 4K.
*
* @param [in] device_id The ID of an opened device to retrieve the WSM from.
* @param [in] align The alignment (number of pages) of the memory block
* (e.g. 0x00000001 for 4kb).
* @param [in] len Length of the block in bytes.
* @param [out] wsm Virtual address of the world shared memory block.
* @param [in] wsm_flags Platform specific flags describing the memory to
* be allocated.
*
* @attention: align and wsm_flags are currently ignored
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
* @return MC_DRV_ERR_NO_FREE_MEMORY if no more contiguous memory is available
* in this size or for this process.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_malloc_wsm(
uint32_t device_id,
uint32_t align,
uint32_t len,
uint8_t **wsm,
uint32_t wsm_flags
);
/**
* Free a block of world shared memory (WSM).
* The MC driver will free a block of world shared memory (WSM) previously
* allocated with mc_malloc_wsm(). The caller has to assure that the address
* handed over to the driver is a valid WSM address.
*
* @param [in] device_id The ID to which the given address belongs.
* @param [in] wsm Address of WSM block to be freed.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id is invalid.
* @return MC_DRV_ERR_FREE_MEMORY_FAILED on failures.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_free_wsm(
uint32_t device_id,
uint8_t *wsm
);
/**
* Map additional bulk buffer between a Trustlet Connector (TLC) and
* the Trustlet (TL) for a session.
* Memory allocated in user space of the TLC can be mapped as additional
* communication channel (besides TCI) to the Trustlet. Limitation of the
* Trustlet memory structure apply: only 6 chunks can be mapped with a maximum
* chunk size of 1 MiB each.
*
* @attention It is up to the application layer (TLC) to inform the Trustlet
* about the additional mapped bulk memory.
*
* @param [in] session Session handle with information of the device_id and
* the session_id. The
* given buffer is mapped to the session specified in the sessionHandle.
* @param [in] buf Virtual address of a memory portion (relative to TLC)
* to be shared with the Trustlet, already includes a possible offset!
* @param [in] len length of buffer block in bytes.
* @param [out] map_info Information structure about the mapped Bulk buffer
* between the TLC (Nwd) and
* the TL (Swd).
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
* @return MC_DRV_ERR_BULK_MAPPING when buf is already uses as bulk buffer or
* when registering the buffer failed.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_map(
struct mc_session_handle *session,
void *buf,
uint32_t len,
struct mc_bulk_map *map_info
);
/**
* Remove additional mapped bulk buffer between Trustlet Connector (TLC)
* and the Trustlet (TL) for a session.
*
* @attention The bulk buffer will immediately be unmapped from the session
* context.
* @attention The application layer (TLC) must inform the TL about unmapping
* of the additional bulk memory before calling mc_unmap!
*
* @param [in] session Session handle with information of the device_id and
* the session_id. The given buffer is unmapped from the session specified
* in the sessionHandle.
* @param [in] buf Virtual address of a memory portion (relative to TLC)
* shared with the TL, already includes a possible offset!
* @param [in] map_info Information structure about the mapped Bulk buffer
* between the TLC (Nwd) and
* the TL (Swd).
* @attention The clientlib currently ignores the len field in map_info.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
* @return MC_DRV_ERR_DAEMON_UNREACHABLE when problems with daemon occur.
* @return MC_DRV_ERR_BULK_UNMAPPING when buf was not registered earlier
* or when unregistering failed.
*
* Uses a Mutex.
*/
__MC_CLIENT_LIB_API enum mc_result mc_unmap(
struct mc_session_handle *session,
void *buf,
struct mc_bulk_map *map_info
);
/**
* @attention: Not implemented.
* Execute driver specific command.
* mc_driver_ctrl() can be used to execute driver specific commands.
* Besides the control command MC_CTRL_GET_VERSION commands are implementation
* specific.
* Please refer to the corresponding specification of the driver manufacturer.
*
* @param [in] param Command ID of the command to be executed.
* @param [in, out] data Command data and response depending on command.
* @param [in] len Length of the data block.
*
* @return MC_DRV_ERR_NOT_IMPLEMENTED.
*/
__MC_CLIENT_LIB_API enum mc_result mc_driver_ctrl(
enum mc_driver_ctrl param,
uint8_t *data,
uint32_t len
);
/**
* @attention: Not implemented.
* Execute application management command.
* mc_manage() shall be used to exchange application management commands with
* the MobiCore.
* The MobiCore Application Management Protocol is described in [MCAMP].
*
* @param [in] device_id Identifier for the MobiCore device to be used.
* NULL refers to the default device.
* @param [in, out] data Command data/response data depending on command.
* @param [in] len Length of the data block.
*
* @return MC_DRV_ERR_NOT_IMPLEMENTED.
*/
__MC_CLIENT_LIB_API enum mc_result mc_manage(
uint32_t device_id,
uint8_t *data,
uint32_t len
);
/**
* Get additional error information of the last error that occured on a session.
* After the request the stored error code will be deleted.
*
* @param [in] session Session handle with information of the device_id and
* the session_id.
* @param [out] last_error >0 Trustlet has terminated itself with this value,
* <0 Trustlet is dead because of an error within the MobiCore
* (e.g. Kernel exception).
* See also MCI definition.
*
* @return MC_DRV_OK if operation has been successfully completed.
* @return MC_DRV_INVALID_PARAMETER if a parameter is invalid.
* @return MC_DRV_ERR_UNKNOWN_SESSION when session id is invalid.
* @return MC_DRV_ERR_UNKNOWN_DEVICE when device id of session is invalid.
*/
__MC_CLIENT_LIB_API enum mc_result mc_get_session_error_code(
struct mc_session_handle *session,
int32_t *last_error
);
#endif /** MCDRIVER_H_ */
/** @} */

View file

@ -1,289 +0,0 @@
/** @addtogroup MCD_MCDIMPL_DAEMON
* @{
* @file
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 MCDAEMON_H_
#define MCDAEMON_H_
#include "mcuuid.h"
enum mc_drv_cmd_t {
MC_DRV_CMD_PING = 0,
MC_DRV_CMD_GET_INFO = 1,
MC_DRV_CMD_OPEN_DEVICE = 2,
MC_DRV_CMD_CLOSE_DEVICE = 3,
MC_DRV_CMD_NQ_CONNECT = 4,
MC_DRV_CMD_OPEN_SESSION = 5,
MC_DRV_CMD_CLOSE_SESSION = 6,
MC_DRV_CMD_NOTIFY = 7,
MC_DRV_CMD_MAP_BULK_BUF = 8,
MC_DRV_CMD_UNMAP_BULK_BUF = 9
};
enum mc_drv_rsp_t {
MC_DRV_RSP_OK = 0,
MC_DRV_RSP_FAILED = 1,
MC_DRV_RSP_DEVICE_NOT_OPENED = 2,
MC_DRV_RSP_DEVICE_ALREADY_OPENED = 3,
MC_DRV_RSP_COMMAND_NOT_ALLOWED = 4,
MC_DRV_INVALID_DEVICE_NAME = 5,
MC_DRV_RSP_MAP_BULK_ERRO = 6,
MC_DRV_RSP_TRUSTLET_NOT_FOUND = 7,
MC_DRV_RSP_PAYLOAD_LENGTH_ERROR = 8,
};
struct mc_drv_command_header_t {
uint32_t command_id;
};
struct mc_drv_response_header_t {
uint32_t response_id;
};
#define MC_DEVICE_ID_DEFAULT 0 /**< The default device ID */
/*****************************************************************************/
struct mc_drv_cmd_open_device_payload_t {
uint32_t device_id;
};
struct mc_drv_cmd_open_device_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_open_device_payload_t payload;
};
struct mc_drv_rsp_open_device_payload_t {
/* empty */
};
struct mc_drv_rsp_open_device_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_open_device_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_close_device_t {
struct mc_drv_command_header_t header;
/* no payload here because close has none.
If we use an empty struct, C++ will count it as 4 bytes.
This will write too much into the socket at write(cmd,sizeof(cmd)) */
};
struct mc_drv_rsp_close_device_payload_t {
/* empty */
};
struct mc_drv_rsp_close_device_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_close_device_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_open_session_payload_t {
uint32_t device_id;
struct mc_uuid_t uuid;
uint32_t tci;
uint32_t len;
};
struct mc_drv_cmd_open_session_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_open_session_payload_t payload;
};
struct mc_drv_rsp_open_session_payload_t {
uint32_t device_id;
uint32_t session_id;
uint32_t device_session_id;
uint32_t mc_result;
uint32_t session_magic;
};
struct mc_drv_rsp_open_session_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_open_session_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_close_session_payload_t {
uint32_t session_id;
};
struct mc_drv_cmd_close_session_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_close_session_payload_t payload;
};
struct mc_drv_rsp_close_session_payload_t {
/* empty */
};
struct mc_drv_rsp_close_session_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_close_session_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_notify_payload_t {
uint32_t session_id;
};
struct mc_drv_cmd_notify_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_notify_payload_t payload;
};
struct mc_drv_rsp_notify_payload_t {
/* empty */
};
struct mc_drv_rsp_notify_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_notify_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_map_bulk_mem_payload_t {
uint32_t session_id;
uint32_t phys_addr_l2;
uint32_t offset_payload;
uint32_t len_bulk_mem;
};
struct mc_drv_cmd_map_bulk_mem_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_map_bulk_mem_payload_t payload;
};
struct mc_drv_rsp_map_bulk_mem_payload_t {
uint32_t session_id;
uint32_t secure_virtual_adr;
uint32_t mc_result;
};
struct mc_drv_rsp_map_bulk_mem_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_map_bulk_mem_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_unmap_bulk_mem_payload_t {
uint32_t session_id;
uint32_t secure_virtual_adr;
uint32_t len_bulk_mem;
};
struct mc_drv_cmd_unmap_bulk_mem_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_unmap_bulk_mem_payload_t payload;
};
struct mc_drv_rsp_unmap_bulk_mem_payload_t {
uint32_t response_id;
uint32_t session_id;
uint32_t mc_result;
};
struct mc_drv_rsp_unmap_bulk_mem_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_unmap_bulk_mem_payload_t payload;
};
/*****************************************************************************/
struct mc_drv_cmd_nqconnect_payload_t {
uint32_t device_id;
uint32_t session_id;
uint32_t device_session_id;
uint32_t session_magic; /* Random data */
};
struct mc_drv_cmd_nqconnect_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_nqconnect_payload_t payload;
};
struct mc_drv_rsp_nqconnect_payload_t {
/* empty; */
};
struct mc_drv_rsp_nqconnect_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_nqconnect_payload_t payload;
};
/*****************************************************************************/
union mc_drv_command_t {
struct mc_drv_command_header_t header;
struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device;
struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device;
struct mc_drv_cmd_open_session_t mc_drv_cmd_open_session;
struct mc_drv_cmd_close_session_t mc_drv_cmd_close_session;
struct mc_drv_cmd_nqconnect_t mc_drv_cmd_nqconnect;
struct mc_drv_cmd_notify_t mc_drv_cmd_notify;
struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem;
struct mc_drv_cmd_unmap_bulk_mem_t mc_drv_cmd_unmap_bulk_mem;
};
union mc_drv_response_t {
struct mc_drv_response_header_t header;
struct mc_drv_rsp_open_device_t mc_drv_rsp_open_device;
struct mc_drv_rsp_close_device_t mc_drv_rsp_close_device;
struct mc_drv_rsp_open_session_t mc_drv_rsp_open_session;
struct mc_drv_rsp_close_session_t mc_drv_rsp_close_session;
struct mc_drv_rsp_nqconnect_t mc_drv_rsp_nqconnect;
struct mc_drv_rsp_notify_t mc_drv_rsp_notify;
struct mc_drv_rsp_map_bulk_mem_t mc_drv_rsp_map_bulk_mem;
struct mc_drv_rsp_unmap_bulk_mem_t mc_drv_rsp_unmap_bulk_mem;
};
#endif /* MCDAEMON_H_ */
/** @} */

View file

@ -1,202 +0,0 @@
/** @addtogroup MCD_IMPL_LIB
* @{
* @file
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#include <linux/types.h>
#include <linux/slab.h>
#include "mc_kernel_api.h"
#include "public/mobicore_driver_api.h"
#include "session.h"
/*****************************************************************************/
struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
void *virt_addr,
uint32_t len,
uint32_t handle,
void *phys_addr_wsm_l2
) {
struct bulk_buffer_descriptor *desc =
kzalloc(sizeof(struct bulk_buffer_descriptor), GFP_KERNEL);
desc->virt_addr = virt_addr;
desc->len = len;
desc->handle = handle;
desc->phys_addr_wsm_l2 = phys_addr_wsm_l2;
return desc;
}
/*****************************************************************************/
struct session *session_create(
uint32_t session_id,
void *instance,
struct connection *connection
) {
struct session *session =
kzalloc(sizeof(struct session), GFP_KERNEL);
session->session_id = session_id;
session->instance = instance;
session->notification_connection = connection;
session->session_info.last_error = SESSION_ERR_NO;
session->session_info.state = SESSION_STATE_INITIAL;
INIT_LIST_HEAD(&(session->bulk_buffer_descriptors));
return session;
}
/*****************************************************************************/
void session_cleanup(
struct session *session
) {
struct bulk_buffer_descriptor *bulk_buf_descr;
struct list_head *pos, *q;
/* Unmap still mapped buffers */
list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
bulk_buf_descr =
list_entry(pos, struct bulk_buffer_descriptor, list);
MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
"handle= %d",
(unsigned int)bulk_buf_descr->phys_addr_wsm_l2,
bulk_buf_descr->handle);
/* ignore any error, as we cannot do anything in this case. */
int ret = mobicore_unmap_vmem(session->instance,
bulk_buf_descr->handle);
if (ret != 0)
MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
list_del(pos);
kfree(bulk_buf_descr);
}
/* Finally delete notification connection */
connection_cleanup(session->notification_connection);
kfree(session);
}
/*****************************************************************************/
void session_set_error_info(
struct session *session,
int32_t err
) {
session->session_info.last_error = err;
}
/*****************************************************************************/
int32_t session_get_last_err(
struct session *session
) {
return session->session_info.last_error;
}
/*****************************************************************************/
struct bulk_buffer_descriptor *session_add_bulk_buf(
struct session *session,
void *buf,
uint32_t len
) {
struct bulk_buffer_descriptor *bulk_buf_descr = NULL;
struct bulk_buffer_descriptor *tmp;
struct list_head *pos;
/* Search bulk buffer descriptors for existing vAddr
At the moment a virtual address can only be added one time */
list_for_each(pos, &session->bulk_buffer_descriptors) {
tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
if (tmp->virt_addr == buf)
return NULL;
}
do {
/* Prepare the interface structure for memory registration in
Kernel Module */
void *l2_table_phys;
uint32_t handle;
int ret = mobicore_map_vmem(session->instance,
buf,
len,
&handle,
&l2_table_phys);
if (ret != 0) {
MCDRV_DBG_ERROR("mobicore_map_vmem failed, ret=%d",
ret);
break;
}
MCDRV_DBG_VERBOSE("Physical Address of L2 Table = 0x%X, "
"handle=%d",
(unsigned int)l2_table_phys,
handle);
/* Create new descriptor */
bulk_buf_descr = bulk_buffer_descriptor_create(
buf,
len,
handle,
l2_table_phys);
/* Add to vector of descriptors */
list_add_tail(&(bulk_buf_descr->list),
&(session->bulk_buffer_descriptors));
} while (0);
return bulk_buf_descr;
}
/*****************************************************************************/
bool session_remove_bulk_buf(
struct session *session,
void *virt_addr
) {
bool ret = true;
struct bulk_buffer_descriptor *bulk_buf_descr = NULL;
struct bulk_buffer_descriptor *tmp;
struct list_head *pos, *q;
MCDRV_DBG_VERBOSE("Virtual Address = 0x%X", (unsigned int) virt_addr);
/* Search and remove bulk buffer descriptor */
list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
if (tmp->virt_addr == virt_addr) {
bulk_buf_descr = tmp;
list_del(pos);
break;
}
}
if (bulk_buf_descr == NULL) {
MCDRV_DBG_ERROR("Virtual Address not found");
ret = false;
} else {
MCDRV_DBG_VERBOSE("WsmL2 phys=0x%X, handle=%d",
(unsigned int)bulk_buf_descr->phys_addr_wsm_l2,
bulk_buf_descr->handle);
/* ignore any error, as we cannot do anything */
int ret = mobicore_unmap_vmem(session->instance,
bulk_buf_descr->handle);
if (ret != 0)
MCDRV_DBG_ERROR("mobicore_unmap_vmem failed: %d", ret);
kfree(bulk_buf_descr);
}
return ret;
}
/** @} */

View file

@ -1,136 +0,0 @@
/** @addtogroup MCD_IMPL_LIB
* @{
* @file
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#ifndef SESSION_H_
#define SESSION_H_
#include "common.h"
#include <linux/list.h>
#include "connection.h"
struct bulk_buffer_descriptor {
void *virt_addr;/**< The virtual address of the Bulk buffer*/
uint32_t len; /**< Length of the Bulk buffer*/
uint32_t handle;
void *phys_addr_wsm_l2; /**< The physical address of the
L2 table of the Bulk buffer*/
struct list_head list; /**< The list param for using the kernel lists*/
};
struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
void *virt_addr,
uint32_t len,
uint32_t handle,
void *phys_addr_wsm_l2
);
/** Session states.
* At the moment not used !!.
*/
enum session_state {
SESSION_STATE_INITIAL,
SESSION_STATE_OPEN,
SESSION_STATE_TRUSTLET_DEAD
};
#define SESSION_ERR_NO 0 /**< No session error */
/** Session information structure.
* The information structure is used to hold the state of the session, which
* will limit further actions for the session.
* Also the last error code will be stored till it's read.
*/
struct session_information {
enum session_state state; /**< Session state */
int32_t last_error; /**< Last error of session */
};
struct session {
struct mc_instance *instance;
/**< Descriptors of additional bulk buffer of a session */
struct list_head bulk_buffer_descriptors;
/**< Informations about session */
struct session_information session_info;
uint32_t session_id;
struct connection *notification_connection;
/**< The list param for using the kernel lists*/
struct list_head list;
};
struct session *session_create(
uint32_t session_id,
void *instance,
struct connection *connection
);
void session_cleanup(
struct session *session
);
/**
* Add address information of additional bulk buffer memory to session and
* register virtual memory in kernel module.
*
* @attention The virtual address can only be added one time. If the virtual
* address already exist, NULL is returned.
*
* @param buf The virtual address of bulk buffer.
* @param len Length of bulk buffer.
*
* @return On success the actual Bulk buffer descriptor with all address
* information is retured, NULL if an error occurs.
*/
struct bulk_buffer_descriptor *session_add_bulk_buf(
struct session *session,
void *buf,
uint32_t len
);
/**
* Remove address information of additional bulk buffer memory from session and
* unregister virtual memory in kernel module
*
* @param buf The virtual address of the bulk buffer.
*
* @return true on success.
*/
bool session_remove_bulk_buf(
struct session *session,
void *buf
);
/**
* Set additional error information of the last error that occured.
*
* @param errorCode The actual error.
*/
void session_set_error_info(
struct session *session,
int32_t err
);
/**
* Get additional error information of the last error that occured.
*
* @attention After request the information is set to SESSION_ERR_NO.
*
* @return Last stored error code or SESSION_ERR_NO.
*/
int32_t session_get_last_err(
struct session *session
);
#endif /* SESSION_H_ */
/** @} */

View file

@ -1,35 +0,0 @@
/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
* @{
* @file
*
* World shared memory definitions.
*
* <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
*
* 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.
*/
#ifndef WSM_H_
#define WSM_H_
#include "common.h"
#include <linux/list.h>
struct wsm {
void *virt_addr;
uint32_t len;
uint32_t handle;
void *phys_addr;
struct list_head list;
};
struct wsm *wsm_create(
void *virt_addr,
uint32_t len,
uint32_t handle,
void *phys_addr /*= NULL this may be unknown, so is can be omitted.*/
);
#endif /* WSM_H_ */
/** @} */