aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gud/MobiCoreDriver/mcDrvModuleFc.h')
-rw-r--r--drivers/gud/MobiCoreDriver/mcDrvModuleFc.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h b/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h
new file mode 100644
index 0000000..6bfdd6b
--- /dev/null
+++ b/drivers/gud/MobiCoreDriver/mcDrvModuleFc.h
@@ -0,0 +1,227 @@
+/**
+ * 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 "mcDrvModule.h"
+
+/**
+ * MobiCore SMCs
+ */
+enum mcSmcCodes {
+ 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 mcFastCallCodes {
+ 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 mcFastCallsResult {
+ 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 fcGeneric {
+ struct {
+ uint32_t cmd;
+ uint32_t param[3];
+ } asIn;
+ struct {
+ uint32_t resp;
+ uint32_t ret;
+ uint32_t param[2];
+ } asOut;
+};
+
+
+/** fast call init */
+union mcFcInit {
+ union fcGeneric asGeneric;
+ struct {
+ uint32_t cmd;
+ uint32_t base;
+ uint32_t nqInfo;
+ uint32_t mcpInfo;
+ } asIn;
+ struct {
+ uint32_t resp;
+ uint32_t ret;
+ uint32_t rfu[2];
+ } asOut;
+};
+
+
+/** fast call info parameters */
+union mcFcInfo {
+ union fcGeneric asGeneric;
+ struct {
+ uint32_t cmd;
+ uint32_t extInfoId;
+ uint32_t rfu[2];
+ } asIn;
+ struct {
+ uint32_t resp;
+ uint32_t ret;
+ uint32_t state;
+ uint32_t extInfo;
+ } asOut;
+};
+
+
+/** fast call S-Yield parameters */
+union mcFcSYield {
+ union fcGeneric asGeneric;
+ struct {
+ uint32_t cmd;
+ uint32_t rfu[3];
+ } asIn;
+ struct {
+ uint32_t resp;
+ uint32_t ret;
+ uint32_t rfu[2];
+ } asOut;
+};
+
+
+/** fast call N-SIQ parameters */
+union mcFcNSIQ {
+ union fcGeneric asGeneric;
+ struct {
+ uint32_t cmd;
+ uint32_t rfu[3];
+ } asIn;
+ struct {
+ uint32_t resp;
+ uint32_t ret;
+ uint32_t rfu[2];
+ } asOut;
+};
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * fast call to MobiCore
+ *
+ * @param pFcGeneric pointer to fast call data
+ */
+static inline void mcFastCall(
+ union fcGeneric *pFcGeneric
+)
+{
+ MCDRV_ASSERT(pFcGeneric != NULL);
+ /* We only expect to make smc calls on CPU0 otherwise something wrong
+ * will happen */
+ MCDRV_ASSERT(raw_smp_processor_id() == 0);
+ dsb();
+#ifdef MC_SMC_FASTCALL
+ {
+ int ret = 0;
+ MCDRV_DBG("Going into SCM()");
+ ret = smc_fastcall((void *)pFcGeneric, sizeof(*pFcGeneric));
+ MCDRV_DBG("Coming from SCM, scm_call=%i, resp=%d/0x%x\n",
+ ret,
+ pFcGeneric->asOut.resp, pFcGeneric->asOut.resp);
+ }
+#else
+ {
+ /* SVC expect values in r0-r3 */
+ register u32 reg0 __asm__("r0") = pFcGeneric->asIn.cmd;
+ register u32 reg1 __asm__("r1") = pFcGeneric->asIn.param[0];
+ register u32 reg2 __asm__("r2") = pFcGeneric->asIn.param[1];
+ register u32 reg3 __asm__("r3") = pFcGeneric->asIn.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 */
+ pFcGeneric->asOut.resp = reg0;
+ pFcGeneric->asOut.ret = reg1;
+ pFcGeneric->asOut.param[0] = reg2;
+ pFcGeneric->asOut.param[1] = reg3;
+ }
+#endif
+}
+
+
+/*----------------------------------------------------------------------------*/
+/**
+ * convert fast call return code to linux driver module error code
+ *
+ */
+static inline int convertFcRet(
+ 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_ */
+/** @} */