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
60class MobiCoreDevice;
61
62typedef 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 */
73extern MobiCoreDevice *getDeviceInstance(void);
74
75class MobiCoreDevice : public DeviceScheduler, public DeviceIrqHandler
76{
77
78protected:
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
110private:
111    virtual bool yield(void) = 0;
112
113    virtual bool nsiq(void) = 0;
114
115    virtual bool waitSsiq(void) = 0;
116
117public:
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
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
219    bool mobicoreAlreadyRunning(void) {
220        return mciReused;
221    }
222};
223
224#endif /* MOBICOREDEVICE_H_ */
225
226/** @} */
227