14e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @addtogroup MCD_MCDIMPL_DAEMON_DEV
24e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @{
34e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @file
44e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
54e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
64e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
79081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim *
84e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Redistribution and use in source and binary forms, with or without
94e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * modification, are permitted provided that the following conditions
104e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * are met:
114e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 1. Redistributions of source code must retain the above copyright
124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    notice, this list of conditions and the following disclaimer.
134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 2. Redistributions in binary form must reproduce the above copyright
144e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    notice, this list of conditions and the following disclaimer in the
154e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    documentation and/or other materials provided with the distribution.
164e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 3. The name of the author may not be used to endorse or promote
174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    products derived from this software without specific prior
184e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    written permission.
194e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
204e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
214e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
224e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
304e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
314e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park */
324e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
334e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <cstdlib>
349081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim#include <stdio.h>
354e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <inttypes.h>
364e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <list>
374e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
389081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim#include "mc_linux.h"
394e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "McTypes.h"
404e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "Mci/mci.h"
414e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "mcVersionHelper.h"
424e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
434e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "CSemaphore.h"
444e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "CMcKMod.h"
454e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
464e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "MobiCoreDevice.h"
474e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "TrustZoneDevice.h"
484e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "NotificationQueue.h"
494e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
504e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "log.h"
514e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
524e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
534e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#define NQ_NUM_ELEMS      (16)
544e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#define NQ_BUFFER_SIZE    (2 * (sizeof(notificationQueueHeader_t)+  NQ_NUM_ELEMS * sizeof(notification_t)))
554e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#define MCP_BUFFER_SIZE   (sizeof(mcpBuffer_t))
564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#define MCI_BUFFER_SIZE   (NQ_BUFFER_SIZE + MCP_BUFFER_SIZE)
574e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
584e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
597b143edf281bed18c8ebd0733465f3af5af327ebJungtae KimMC_CHECK_VERSION(MCI, 0, 2);
604e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
614e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim__attribute__ ((weak)) MobiCoreDevice *getDeviceInstance(
637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    void
647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return new TrustZoneDevice();
674e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
684e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
694e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
704e9e8c9c0169b40318386436d762c3d73cf4c328DongJin ParkTrustZoneDevice::TrustZoneDevice(
714e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    void
727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
744e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    // nothing to do
754e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
764e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
774e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
784e9e8c9c0169b40318386436d762c3d73cf4c328DongJin ParkTrustZoneDevice::~TrustZoneDevice(
794e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    void
807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
824e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    delete pMcKMod;
837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    delete pWsmMcp;
844e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    delete nq;
854e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
864e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
874e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
884e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim/**
907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim * Set up MCI and wait till MC is initialized
917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim * @return true if mobicore is already initialized
927b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim */
937b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::initDevice(
947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    const char  *devFile,
957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    bool        loadMobiCore,
967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    const char  *mobicoreImage,
977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    bool        enableScheduler)
987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    notificationQueue_t *nqStartOut;
1007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    notificationQueue_t *nqStartIn;
1017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t mciBuffer;
1027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pMcKMod = new CMcKMod();
1047b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mcResult_t ret = pMcKMod->open(devFile);
1057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != MC_DRV_OK) {
1067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_W(" Opening kernel module device failed");
1077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
1087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
1097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!pMcKMod->checkVersion()) {
1107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("kernel module version mismatch");
1117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
1127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
1134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    this->schedulerEnabled = enableScheduler;
1154e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Init MC with NQ and MCP buffer addresses
1174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Set up MCI buffer
1197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!getMciInstance(MCI_BUFFER_SIZE, &pWsmMcp, &mciReused)) {
1207b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
1217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
1227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mciBuffer = pWsmMcp->virtAddr;
1237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1247b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!checkMciVersion()) {
1257b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
1267b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
1277b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1287b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Only do a fastcall if MCI has not been reused (MC already initialized)
1297b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!mciReused) {
1307b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Wipe memory before first usage
1317b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        bzero(mciBuffer, MCI_BUFFER_SIZE);
1327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Init MC with NQ and MCP buffer addresses
1347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        int ret = pMcKMod->fcInit(0, NQ_BUFFER_SIZE, NQ_BUFFER_SIZE, MCP_BUFFER_SIZE);
1357b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        if (ret != 0) {
1367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            LOG_E("pMcKMod->fcInit() failed");
1377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            return false;
1384e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        }
1394e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // First empty N-SIQ which results in set up of the MCI structure
1417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        if (!nsiq()) {
1427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            return false;
1434e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        }
1444e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Wait until MobiCore state switches to MC_STATUS_INITIALIZED
1467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // It is assumed that MobiCore always switches state at a certain point in time.
1477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        while (1) {
1487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            uint32_t status = getMobicoreStatus();
1497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            if (MC_STATUS_INITIALIZED == status) {
1517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                break;
1527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            } else if (MC_STATUS_NOT_INITIALIZED == status) {
1537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // Switch to MobiCore to give it more CPU time.
1547b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                if (!yield())
1557b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    return false;
1567b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim		::sleep(1);
1577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            } else if (MC_STATUS_HALT == status) {
1587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                dumpMobicoreStatus();
1597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                LOG_E("MobiCore halted during init !!!, state is 0x%x", status);
1607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                return false;
1617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            } else { // MC_STATUS_BAD_INIT or anything else
1627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                LOG_E("MCI buffer init failed, state is 0x%x", status);
1637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                return false;
1647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            }
1657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        }
1667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
1674e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    nqStartOut = (notificationQueue_t *) mciBuffer;
1697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    nqStartIn = (notificationQueue_t *) ((uint8_t *) nqStartOut
1707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                                         + sizeof(notificationQueueHeader_t) + NQ_NUM_ELEMS
1717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                                         * sizeof(notification_t));
1724e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Set up the NWd NQ
1747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    nq = new NotificationQueue(nqStartIn, nqStartOut, NQ_NUM_ELEMS);
1754e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mcpBuffer_t *mcpBuf = (mcpBuffer_t *) ((uint8_t *) mciBuffer + NQ_BUFFER_SIZE);
1774e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Set up the MC flags
1797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mcFlags = &(mcpBuf->mcFlags);
1804e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Set up the MCP message
1827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mcpMessage = &(mcpBuf->mcpMessage);
1837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
1847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // convert virtual address of mapping to physical address for the init.
1857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("MCI established, at %p, phys=%p, reused=%s",
1867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim          pWsmMcp->virtAddr,
1877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim          pWsmMcp->physAddr,
1887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim          mciReused ? "true" : "false");
1897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
1904e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
1914e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1924e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1934e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
1944e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid TrustZoneDevice::initDeviceStep2(
1954e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    void
1967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
1977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
1987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // not needed
1994e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
2004e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2014e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2024e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
2034e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkbool TrustZoneDevice::yield(
2044e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    void
2057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
2067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
2074e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    int32_t ret = pMcKMod->fcYield();
2084e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    if (ret != 0) {
2094e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        LOG_E("pMcKMod->fcYield() failed: %d", ret);
2104e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    }
2114e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    return ret == 0;
2124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
2134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2144e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2154e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
2164e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkbool TrustZoneDevice::nsiq(
2174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    void
2187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
2197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
2209081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim    // There is no need to set the NON-IDLE flag here. Sending an N-SIQ will
2219081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim    // make the MobiCore run until it could set itself to a state where it
2229081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim    // set the flag itself. IRQs and FIQs are disbaled for this period, so
2239081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim    // there is no way the NWd can interrupt here.
2244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    // not needed: mcFlags->schedule = MC_FLAG_SCHEDULE_NON_IDLE;
2264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    int32_t ret = pMcKMod->fcNSIQ();
2284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    if (ret != 0) {
2294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        LOG_E("pMcKMod->fcNSIQ() failed : %d", ret);
2304e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        return false;
2314e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    }
2324e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    // now we have to wake the scheduler, so MobiCore gets CPU time.
2334e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    schedSync.signal();
2344e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    return true;
2354e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
2364e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2374e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2384e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
2394e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid TrustZoneDevice::notify(
2404e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    uint32_t sessionId
2417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
2427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
2437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Check if it is MCP session - handle openSession() command
2447b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (sessionId != SID_MCP) {
2457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Check if session ID exists to avoid flooding of nq by clients
2467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        TrustletSession *ts = getTrustletSession(sessionId);
2477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        if (ts == NULL) {
2487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            LOG_E("no session with id=%d", sessionId);
2497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            return;
2507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        }
2517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
2527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_I(" Sending notification for session %d to MobiCore", sessionId);
2537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    } else {
2549081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim        LOG_I(" Sending MCP notification to MobiCore");
2557b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
2564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Notify MobiCore about new data
2584e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2592928ff10f58e86cd9c10ad09cbcd879fdf080ae7synergy dev    notification_t notification = {
2602928ff10f58e86cd9c10ad09cbcd879fdf080ae7synergy dev        .sessionId = sessionId,
2612928ff10f58e86cd9c10ad09cbcd879fdf080ae7synergy dev        .payload = 0
2622928ff10f58e86cd9c10ad09cbcd879fdf080ae7synergy dev    };
2634e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    nq->putNotification(&notification);
2657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    //IMPROVEMENT-2012-03-07-maneaval What happens when/if nsiq fails?
2667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    //In the old days an exception would be thrown but it was uncertain
2677b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    //where it was handled, some server(sock or Netlink). In that case
2687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    //the server would just die but never actually signaled to the client
2697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    //any error condition
2707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    nsiq();
2714e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
2724e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2734e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
2749081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimuint32_t TrustZoneDevice::getMobicoreStatus(void)
2759081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
2767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t status;
2772821a826dbd3097b27801e02a2d7bc412a02e76cDongJin Park
2782821a826dbd3097b27801e02a2d7bc412a02e76cDongJin Park    pMcKMod->fcInfo(1, &status, NULL);
2799081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim
2807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return status;
2814e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
2824e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
2834e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
2849081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimbool TrustZoneDevice::checkMciVersion(void)
2859081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
2867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t version = 0;
2877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret;
2887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    char *errmsg;
2897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
2907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(MC_EXT_INFO_ID_MCI_VERSION, NULL, &version);
2917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != 0) {
2927b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->fcInfo() failed with %d", ret);
2937b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
2947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
2957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
2967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Run-time check.
2977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!checkVersionOkMCI(version, &errmsg)) {
2987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("%s", errmsg);
2997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
3007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
3017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("%s", errmsg);
3027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
3034e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
3044e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3054e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
3064e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid TrustZoneDevice::dumpMobicoreStatus(
3077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    void
3087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
3097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
3107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret;
3117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t status, info;
3127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // read additional info about exception-point and print
3137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_E("MobiCore halted !!!");
3147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(1, &status, &info);
3157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: flags               : 0x%8x", info);
3167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(2, &status, &info);
3177b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: haltCode            : 0x%8x", info);
3187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(3, &status, &info);
3197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: haltIp              : 0x%8x", info);
3207b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(4, &status, &info);
3217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.cnt        : 0x%8x", info);
3227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(5, &status, &info);
3237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.cause      : 0x%8x", info);
3247b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(6, &status, &info);
3257b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.meta       : 0x%8x", info);
3267b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(7, &status, &info);
3277b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.thread     : 0x%8x", info);
3287b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(8, &status, &info);
3297b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.ip         : 0x%8x", info);
3307b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(9, &status, &info);
3317b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.sp         : 0x%8x", info);
3327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(10, &status, &info);
3337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.dfsr  : 0x%8x", info);
3347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(11, &status, &info);
3357b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.adfsr : 0x%8x", info);
3367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(12, &status, &info);
3377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.dfar  : 0x%8x", info);
3387b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(13, &status, &info);
3397b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.ifsr  : 0x%8x", info);
3407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(14, &status, &info);
3417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.aifsr : 0x%8x", info);
3427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(15, &status, &info);
3437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: faultRec.arch.ifar  : 0x%8x", info);
3447b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(16, &status, &info);
3457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: mcData.flags        : 0x%8x", info);
3467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(19, &status, &info);
3477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: mcExcep.partner     : 0x%8x", info);
3487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(20, &status, &info);
3497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: mcExcep.peer        : 0x%8x", info);
3507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(21, &status, &info);
3517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: mcExcep.message     : 0x%8x", info);
3527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    ret = pMcKMod->fcInfo(22, &status, &info);
3537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_W("MC_HALT: mcExcep.data        : 0x%8x", info);
3544e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
3554e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
3579081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimbool TrustZoneDevice::waitSsiq(void)
3589081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
3597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t cnt;
3607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!pMcKMod->waitSSIQ(&cnt)) {
3617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->SSIQ() failed");
3627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
3637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
3647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I(" Received SSIQ interrupt from MobiCore, counter=%u", cnt);
3657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
3664e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
3674e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3684e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3694e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
3709081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimbool TrustZoneDevice::getMciInstance(uint32_t len, CWsm_ptr *mci, bool *reused)
3719081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
3727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t virtAddr;
3737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t handle;
3747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t physAddr;
3757b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    bool isReused = true;
3767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (len == 0) {
3777b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("allocateWsm() length is 0");
3787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
3797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
3807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
3817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    mcResult_t ret = pMcKMod->mapMCI(len, &handle, &virtAddr, &physAddr, &isReused);
3827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != MC_DRV_OK) {
3837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->mmap() failed: %x", ret);
3847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
3857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
3867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
3877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    *mci = new CWsm(virtAddr, len, handle, physAddr);
3887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    *reused = isReused;
3897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
3904e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
3914e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3924e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
3934e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
3947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//bool TrustZoneDevice::freeWsm(CWsm_ptr pWsm)
3957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//{
3967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//  int ret = pMcKMod->free(pWsm->handle, pWsm->virtAddr, pWsm->len);
3977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//  if (ret != 0) {
3987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//      LOG_E("pMcKMod->free() failed: %d", ret);
3997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//      return false;
4007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//  }
4017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//  delete pWsm;
4027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//  return true;
4037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//}
4044e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4054e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4064e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
4079081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun KimCWsm_ptr TrustZoneDevice::registerWsmL2(addr_t buffer, uint32_t len, uint32_t pid)
4089081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
4097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t physAddr;
4107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t handle;
4117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
4127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret = pMcKMod->registerWsmL2(
4137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                  buffer,
4147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                  len,
4157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                  pid,
4167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                  &handle,
4177b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                  &physAddr);
4187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != 0) {
4197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("ipMcKMod->registerWsmL2() failed: %d", ret);
4207b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return NULL;
4217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
4227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
4237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return new CWsm(buffer, len, handle, physAddr);
4244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
4254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
4289081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun KimCWsm_ptr TrustZoneDevice::allocateContiguousPersistentWsm(uint32_t len)
4299081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
4307b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    CWsm_ptr pWsm = NULL;
4317b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Allocate shared memory
4327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t virtAddr;
4337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t handle;
4347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t physAddr;
4359081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim
4367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (len == 0 )
4377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return NULL;
4389081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim
4397b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (pMcKMod->mapWsm(len, &handle, &virtAddr, &physAddr))
4407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return NULL;
4414e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Register (vaddr,paddr) with device
4437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pWsm = new CWsm(virtAddr, len, handle, physAddr);
4444e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Return pointer to the allocated memory
4467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return pWsm;
4474e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
4484e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4494e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4504e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
4519081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimbool TrustZoneDevice::unregisterWsmL2(CWsm_ptr pWsm)
4529081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
4534e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    int ret = pMcKMod->unregisterWsmL2(pWsm->handle);
4544e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    if (ret != 0) {
4554e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        LOG_E("pMcKMod->unregisterWsmL2 failed: %d", ret);
4564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        //IMPROVEMENT-2012-03-07 maneaval Make sure we don't leak objects
4574e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park        return false;
4584e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    }
4594e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    delete pWsm;
4604e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    return true;
4614e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
4624e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//------------------------------------------------------------------------------
4647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::lockWsmL2(uint32_t handle)
4657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
4667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret = pMcKMod->lockWsmL2(handle);
4677b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != 0) {
4687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->unregisterWsmL2 failed: %d", ret);
4697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
4707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
4717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
4727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim}
4737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
4747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//------------------------------------------------------------------------------
4757b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::unlockWsmL2(uint32_t handle)
4767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
4777b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("Unlocking buffer with handle %u", handle);
4787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret = pMcKMod->unlockWsmL2(handle);
4797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != 0) {
4807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Failure here is not important
4817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_I("pMcKMod->unregisterWsmL2 failed: %d", ret);
4827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
4837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
4847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
4857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim}
4867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
4877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//------------------------------------------------------------------------------
4887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::cleanupWsmL2(void)
4897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
4907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int ret = pMcKMod->cleanupWsmL2();
4917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret != 0) {
4927b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->cleanupWsmL2 failed: %d", ret);
4937b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
4947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
4957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
4967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim}
4974e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
4984e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
4997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimaddr_t TrustZoneDevice::findWsmL2(uint32_t handle)
5007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
5017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    addr_t ret = pMcKMod->findWsmL2(handle);
5027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (ret == NULL) {
5037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->findWsmL2 failed");
5047b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return NULL;
5057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
5067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("Resolved buffer with handle %u to %p", handle, ret);
5077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return ret;
5087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim}
5097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//------------------------------------------------------------------------------
5117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::findContiguousWsm(uint32_t handle, addr_t *phys, uint32_t *len)
5127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
5137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (pMcKMod->findContiguousWsm(handle, phys, len)) {
5147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_E("pMcKMod->findContiguousWsm failed");
5157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        return false;
5167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
5177b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("Resolved buffer with handle %u to %p", handle, phys);
5187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return true;
5197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim}
5207b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim//------------------------------------------------------------------------------
5227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kimbool TrustZoneDevice::schedulerAvailable(void)
5237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
5244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park    return schedulerEnabled;
5254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
5264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
5274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
5284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//TODO Schedulerthread to be switched off if MC is idle. Will be woken up when
5294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//     driver is called again.
5309081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kimvoid TrustZoneDevice::schedule(void)
5319081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim{
5327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    uint32_t timeslice = SCHEDULING_FREQ;
5337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // loop forever
5347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    for (;;) {
5357b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Scheduling decision
5367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        if (MC_FLAG_SCHEDULE_IDLE == mcFlags->schedule) {
5377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            // MobiCore is IDLE
5387b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5397b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            // Prevent unnecessary consumption of CPU cycles -> Wait until S-SIQ received
5407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            schedSync.wait();
5417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        } else {
5437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            // MobiCore is not IDLE (anymore)
5447b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            // Check timeslice
5467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            if (timeslice == 0) {
5477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // Slice expired, so force MC internal scheduling decision
5487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                timeslice = SCHEDULING_FREQ;
5497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                if (!nsiq()) {
5507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    break;
5517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                }
5527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            } else {
5537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // Slice not used up, simply hand over control to the MC
5547b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                timeslice--;
5557b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                if (!yield()) {
5567b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    break;
5577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                }
5587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            }
5597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        }
5607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    } //for (;;)
5614e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
5624e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
5634e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid TrustZoneDevice::handleIrq(
5647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    void
5657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim)
5667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{
5677b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_I("Starting Notification Queue IRQ handler...");
5687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    for (;;) {
5697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_I(" No notifications pending");
5707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        if (!waitSsiq()) {
5717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            LOG_E("Waiting for SSIQ failed");
5727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            break;
5737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        }
5747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        LOG_V("S-SIQ received");
5757b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Save all the
5777b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        for (;;) {
5787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            notification_t *notification = nq->getNotification();
5797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            if (NULL == notification) {
5807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                break;
5817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            }
5827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            // check if the notification belongs to the MCP session
5847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            if (notification->sessionId == SID_MCP) {
5857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                LOG_I(" Found MCP notification, payload=%d",
5867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                      notification->payload);
5877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // Signal main thread of the driver to continue after MCP
5897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // command has been processed by the MC
5907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                signalMcpNotification();
5917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            } else {
5927b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                LOG_I(" Found notification for session %d, payload=%d",
5937b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                      notification->sessionId, notification->payload);
5947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
5957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                // Get the NQ connection for the session ID
5967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                Connection *connection = getSessionConnection(notification->sessionId, notification);
5977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                if (connection == NULL) {
5987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    /* Couldn't find the session for this notifications
5997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                     * In practice this only means one thing: there is
6007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                     * a race condition between RTM and the Daemon and
6017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                     * RTM won. But we shouldn't drop the notification
6027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                     * right away we should just queue it in the device
6037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                     */
6047b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    LOG_W("Notification for unknown session ID");
6057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    queueUnknownNotification(*notification);
6067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                } else {
6077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    LOG_I(" Forward notification to McClient.");
6087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    // Forward session ID and additional payload of
6097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    // notification to the TLC/Application layer
6107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                    connection->writeData((void *)notification,
6117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                                          sizeof(notification_t));
6127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim                }
6137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim            }
6147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        }
6157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
6167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        // Wake up scheduler
6177b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        schedSync.signal();
6187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
6197b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    LOG_E("S-SIQ exception");
6207b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Tell main thread that "something happened"
6217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // MSH thread MUST not block!
6227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    DeviceIrqHandler::setExiting();
6237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    signalMcpNotification();
6244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
6254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @} */
626