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(¬ification); 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