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 
readLocalFile(const char * pFileName,uint32_t * pnBufferSize,bool bIsString)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 
smcPAStart(const char * pPAFileName,const char * pConfFileName)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 
smcPAStop(void)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