Home | History | Annotate | Download | only in smc_pa_ctrl
      1 /**
      2  * Copyright(c) 2011 Trusted Logic.   All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *  * Neither the name Trusted Logic nor the names of its
     15  *    contributors may be used to endorse or promote products derived
     16  *    from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include <stdlib.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #ifndef WIN32
     37 #include <sys/ioctl.h>
     38 #include <unistd.h>
     39 #endif
     40 #include <fcntl.h>
     41 #include <errno.h>
     42 
     43 #include "smc_pa_ctrl_os.h"
     44 #include "s_type.h"
     45 
     46 #ifndef BOOT_TIME_PA
     47 #define SMC_DRIVER_NAME    "/dev/tf_ctrl"
     48 #else
     49 #define SMC_DRIVER_NAME    "/dev/supervisor"
     50 #endif
     51 
     52 #define IOCTL_SCX_SMC_PA_CTRL \
     53          _IOWR('z', 0xFF, SCX_SMC_PA_CTRL)
     54 
     55 
     56 typedef struct
     57 {
     58    uint32_t nPACommand;       /* SCX_PA_CTRL_xxx */
     59 
     60    /* For the SCX_SMC_PA_CTRL_START command only                           */
     61    uint32_t nPASize;          /* PA buffer size                            */
     62    uint8_t* pPABuffer;        /* PA buffer                                 */
     63    uint32_t nConfSize;        /* Configuration buffer size, including the  */
     64                               /* zero-terminating character (may be zero)  */
     65    uint8_t* pConfBuffer;      /* Configuration buffer, zero-terminated     */
     66                               /* string (may be NULL)                      */
     67 } SCX_SMC_PA_CTRL;
     68 
     69 static uint8_t* readLocalFile(const char* pFileName, uint32_t* pnBufferSize, bool bIsString)
     70 {
     71    uint8_t* pBuffer = NULL;
     72    FILE*    pFile = NULL;
     73    uint32_t nBytesToAllocate;
     74    int      nBytesRead;
     75    int      nResult;
     76 
     77    struct stat statFile;
     78 
     79    *pnBufferSize = 0;
     80 
     81    if (stat(pFileName, &statFile) != 0)
     82    {
     83       printf("Cannot read '%s' !\n", pFileName);
     84       goto error;
     85    }
     86 
     87    nBytesToAllocate = statFile.st_size;
     88 
     89    if (bIsString)
     90    {
     91       /* Allocate enough room for the zero-terminated string */
     92       nBytesToAllocate ++;
     93    }
     94 
     95    pBuffer = (uint8_t*)malloc(nBytesToAllocate);
     96    if (pBuffer == NULL)
     97    {
     98       printf("Out of memory for the buffer [%u bytes] !\n", nBytesToAllocate);
     99       goto error;
    100    }
    101 
    102    pFile = fopen(pFileName, "rb");
    103    if (pFile == NULL)
    104    {
    105       printf("Cannot open '%s' !\n", pFileName);
    106       goto error;
    107    }
    108 
    109    nBytesRead = fread(pBuffer, 1, statFile.st_size, pFile);
    110 
    111    if (nBytesRead != statFile.st_size)
    112    {
    113       printf("Cannot read bytes from '%s' [%i] !\n", pFileName, nBytesRead);
    114       goto error;
    115    }
    116 
    117    nResult = fclose(pFile);
    118 
    119    pFile = NULL;
    120 
    121    if (nResult != 0)
    122    {
    123       printf("Cannot close '%s' !\n", pFileName);
    124       goto error;
    125    }
    126 
    127    if (bIsString)
    128    {
    129       /* Set the zero-terminated string */
    130       pBuffer[nBytesRead] = 0;
    131    }
    132 
    133    *pnBufferSize = nBytesToAllocate;
    134 
    135    return pBuffer;
    136 
    137    /*
    138     * Error handling.
    139     */
    140 
    141 error:
    142    free(pBuffer);
    143    if (pFile != NULL)
    144    {
    145       fclose(pFile);
    146    }
    147 
    148    return NULL;
    149 }
    150 
    151 
    152 
    153 
    154 int smcPAStart(const char* pPAFileName, const char* pConfFileName)
    155 {
    156    int fd = 0;
    157    int nStatus = 0;
    158    SCX_SMC_PA_CTRL paCtrl;
    159 
    160    memset(&paCtrl, 0, sizeof(SCX_SMC_PA_CTRL));
    161    paCtrl.nPACommand = SCX_SMC_PA_CTRL_START;
    162 
    163 #ifdef BOOT_TIME_PA
    164    printf("Starting the SMC BOOT PA '%s'. Driver name : %s", pPAFileName, SMC_DRIVER_NAME);
    165 #else
    166    printf("Starting the SMC PA '%s'", pPAFileName);
    167 #endif
    168    if (pConfFileName != NULL)
    169    {
    170       printf(" with the Configuration file '%s'", pConfFileName);
    171    }
    172    else
    173    {
    174       printf("Configuration file is mandatory\n");
    175       nStatus  = -1;
    176       goto end;
    177    }
    178    printf("...\n");
    179 
    180    paCtrl.pPABuffer = readLocalFile(pPAFileName, &paCtrl.nPASize, false);
    181    if (paCtrl.pPABuffer == NULL)
    182    {
    183       nStatus  = -2;
    184       goto end;
    185    }
    186 
    187    paCtrl.pConfBuffer = readLocalFile(pConfFileName, &paCtrl.nConfSize, false);
    188    if (paCtrl.pConfBuffer == NULL)
    189    {
    190       nStatus  = -4;
    191       goto end;
    192    }
    193 
    194    #ifndef WIN32
    195    fd = open(SMC_DRIVER_NAME, O_RDWR, 0);
    196    #endif
    197    if (fd == -1)
    198    {
    199       nStatus = errno;
    200 #ifdef BOOT_TIME_PA
    201       printf("Boot time driver open failed [%d] !\n", nStatus);
    202 #else
    203       printf("SMC driver open failed [%d] !\n", nStatus);
    204 #endif
    205       goto end;
    206    }
    207 
    208    #ifndef WIN32
    209    nStatus = ioctl(fd, IOCTL_SCX_SMC_PA_CTRL, &paCtrl);
    210    #endif
    211    if (nStatus != 0)
    212    {
    213       nStatus = errno;
    214 #ifdef BOOT_TIME_PA
    215       printf("Starting the BOOT TIME PA failed [%d] !\n", nStatus);
    216 #else
    217       printf("Starting the SMC PA failed [%d] !\n", nStatus);
    218 #endif
    219       goto end;
    220    }
    221 
    222 #ifdef BOOT_TIME_PA
    223    printf("Boot time PA '%s' has been launched successfully.\n", pPAFileName);
    224 #else
    225    printf("Starting the SMC PA '%s': Done\n", pPAFileName);
    226 #endif
    227 
    228 end:
    229    if (fd != 0)
    230    {
    231       #ifndef WIN32
    232       close(fd);
    233       #endif
    234    }
    235 
    236    free(paCtrl.pPABuffer);
    237    free(paCtrl.pConfBuffer);
    238 
    239    return nStatus;
    240 }
    241 
    242 int smcPAStop(void)
    243 {
    244    int fd = 0;
    245    int nStatus = 0;
    246    SCX_SMC_PA_CTRL paCtrl;
    247 
    248    memset(&paCtrl, 0, sizeof(SCX_SMC_PA_CTRL));
    249    paCtrl.nPACommand = SCX_SMC_PA_CTRL_STOP;
    250 
    251    printf("Stopping the SMC PA...\n");
    252 
    253    #ifndef WIN32
    254    fd = open(SMC_DRIVER_NAME, O_RDWR, 0);
    255    #endif
    256    if (fd == 0)
    257    {
    258       nStatus = errno;
    259       printf("SMC driver open failed [%d] !\n", nStatus);
    260       goto end;
    261    }
    262 
    263    #ifndef WIN32
    264    nStatus = ioctl(fd, IOCTL_SCX_SMC_PA_CTRL, &paCtrl);
    265    #endif
    266    if (nStatus != 0)
    267    {
    268       printf("Stopping the SMC PA failed [%d] !\n", nStatus);
    269       goto end;
    270    }
    271 
    272    printf("Stopping the SMC PA: Done\n");
    273 
    274 end:
    275 
    276    if (fd != 0)
    277    {
    278       #ifndef WIN32
    279       close(fd);
    280       #endif
    281    }
    282 
    283    return nStatus;
    284 }
    285