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