1 /** @addtogroup MCD_MCDIMPL_DAEMON_DEV 2 * @{ 3 * @file 4 * 5 * MobiCore device. 6 * The MobiCore device class handles the MCP processing within the driver. 7 * Concrete devices implementing the communication behavior for the platforms have to be derived 8 * from this. 9 * 10 * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 --> 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. The name of the author may not be used to endorse or promote 21 * products derived from this software without specific prior 22 * written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 25 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 30 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 #ifndef MOBICOREDEVICE_H_ 37 #define MOBICOREDEVICE_H_ 38 39 #include <stdint.h> 40 #include <vector> 41 42 #include "McTypes.h" 43 #include "MobiCoreDriverApi.h" 44 45 #include "Mci/mcimcp.h" 46 #include "mcLoadFormat.h" 47 #include "MobiCoreDriverCmd.h" 48 49 #include "Connection.h" 50 #include "CWsm.h" 51 52 #include "ExcDevice.h" 53 #include "DeviceScheduler.h" 54 #include "DeviceIrqHandler.h" 55 #include "NotificationQueue.h" 56 #include "TrustletSession.h" 57 #include "mcVersionInfo.h" 58 59 60 class MobiCoreDevice; 61 62 typedef struct { 63 addr_t baseAddr; /**< Physical address of the data to load. */ 64 uint32_t offs; /**< Offset to the data. */ 65 uint32_t len; /**< Length of the data to load. */ 66 mclfHeader_ptr tlHeader; /**< Pointer to trustlet header. */ 67 } loadDataOpenSession_t, *loadDataOpenSession_ptr; 68 69 /** 70 * Factory method to return the platform specific MobiCore device. 71 * Implemented in the platform specific *Device.cpp 72 */ 73 extern MobiCoreDevice *getDeviceInstance(void); 74 75 class MobiCoreDevice : public DeviceScheduler, public DeviceIrqHandler 76 { 77 78 protected: 79 80 NotificationQueue *nq; /**< Pointer to the notification queue within the MCI buffer */ 81 mcFlags_t *mcFlags; /**< Pointer to the MC flags within the MCI buffer */ 82 mcpMessage_t *mcpMessage; /**< Pointer to the MCP message structure within the MCI buffer */ 83 CSemaphore mcpSessionNotification; /**< Semaphore to synchronize incoming notifications for the MCP session */ 84 85 trustletSessionList_t trustletSessions; /**< Available Trustlet Sessions */ 86 mcVersionInfo_t *mcVersionInfo; /**< MobiCore version info. */ 87 bool mcFault; /**< Signal RTM fault */ 88 bool mciReused; /**< Signal restart of Daemon. */ 89 90 /* In a special case a Trustlet can create a race condition in the daemon. 91 * If at Trustlet start it detects an error of some sort and calls the 92 * exit function before waiting for any notifications from NWD then the daemon 93 * will receive the openSession notification from RTM and the error notification 94 * from the Trustlet at the same time but because the internal objects in 95 * the daemon are not yet completely setup then the error notification will 96 * never be sent to the TLC! 97 * 98 * This queue holds notifications received between the time the daemon 99 * puts the MCP command for open session until the internal session objects 100 * are setup correctly. 101 */ 102 std::queue<notification_t> notifications; /**< Notifications queue for open session notification */ 103 104 MobiCoreDevice(); 105 106 void signalMcpNotification(void); 107 108 bool waitMcpNotification(void); 109 110 private: 111 virtual bool yield(void) = 0; 112 113 virtual bool nsiq(void) = 0; 114 115 virtual bool waitSsiq(void) = 0; 116 117 public: 118 virtual ~MobiCoreDevice(); 119 120 TrustletSession *getTrustletSession(uint32_t sessionId); 121 122 void cleanSessionBuffers(TrustletSession *session); 123 void removeTrustletSession(uint32_t sessionId); 124 125 Connection *getSessionConnection(uint32_t sessionId, notification_t *notification); 126 127 bool open(Connection *connection); 128 129 void close(Connection *connection); 130 131 mcResult_t openSession(Connection *deviceConnection, 132 loadDataOpenSession_ptr pLoadDataOpenSession, 133 MC_DRV_CMD_OPEN_SESSION_struct *cmdOpenSession, 134 mcDrvRspOpenSessionPayload_ptr pRspOpenSessionPayload); 135 136 TrustletSession *registerTrustletConnection( Connection *connection, 137 MC_DRV_CMD_NQ_CONNECT_struct *cmdNqConnect); 138 139 // Internal function 140 mcResult_t closeSession(uint32_t sessionId); 141 142 // Do more checks 143 mcResult_t closeSession(Connection *deviceConnection, uint32_t sessionId); 144 145 virtual void notify(uint32_t sessionId) = 0; 146 147 mcResult_t mapBulk(uint32_t sessionId, uint32_t handle, uint32_t pAddrL2, uint32_t offsetPayload, 148 uint32_t lenBulkMem, uint32_t *secureVirtualAdr); 149 150 mcResult_t unmapBulk(uint32_t sessionId, uint32_t handle, uint32_t secureVirtualAdr, uint32_t lenBulkMem); 151 152 void start(); 153 154 void donateRam(const uint32_t donationSize); 155 156 mcResult_t getMobiCoreVersion(mcDrvRspGetMobiCoreVersionPayload_ptr pRspGetMobiCoreVersionPayload); 157 getMcFault()158 bool getMcFault() { 159 return mcFault; 160 } 161 162 void queueUnknownNotification(notification_t notification); 163 164 virtual void dumpMobicoreStatus(void) = 0; 165 166 virtual uint32_t getMobicoreStatus(void) = 0; 167 168 virtual bool schedulerAvailable(void) = 0; 169 170 virtual void schedule(void) = 0; 171 172 virtual void handleIrq(void) = 0; 173 174 //virtual bool freeWsm(CWsm_ptr pWsm) = 0; 175 176 /** 177 * Initialize MobiCore. 178 * 179 * @param devFile the device node to speak to. 180 * @param loadMobiCore 181 * @param mobicoreImage 182 * @param enableScheduler 183 * 184 * @returns true if MobiCore is already initialized. 185 * */ 186 virtual bool initDevice( 187 const char *devFile, 188 bool loadMobiCore, 189 const char *mobicoreImage, 190 bool enableScheduler 191 ) = 0; 192 193 virtual void initDeviceStep2(void) = 0; 194 195 virtual bool getMciInstance(uint32_t len, CWsm_ptr *mci, bool *reused) = 0; 196 197 virtual CWsm_ptr registerWsmL2(addr_t buffer, uint32_t len, uint32_t pid) = 0; 198 199 virtual bool unregisterWsmL2(CWsm_ptr pWsm) = 0; 200 201 virtual bool lockWsmL2(uint32_t handle) = 0; 202 203 virtual bool unlockWsmL2(uint32_t handle) = 0; 204 205 virtual addr_t findWsmL2(uint32_t handle) = 0; 206 207 virtual bool findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len) = 0; 208 209 /** 210 * Cleanup all orphaned bulk buffers. 211 */ 212 virtual bool cleanupWsmL2(void) = 0; 213 214 /** 215 * Allocates persistent WSM memory for TL (won't be released when TLC exits). 216 */ 217 virtual CWsm_ptr allocateContiguousPersistentWsm(uint32_t len) = 0; 218 mobicoreAlreadyRunning(void)219 bool mobicoreAlreadyRunning(void) { 220 return mciReused; 221 } 222 }; 223 224 #endif /* MOBICOREDEVICE_H_ */ 225 226 /** @} */ 227