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