1 /** @file 2 The data structures in this code come from: 3 OMAP35x Applications Processor Technical Reference Manual chapter 25 4 OMAP34xx Multimedia Device Technical Reference Manual chapter 26.4.8. 5 6 You should use the OMAP35x manual when possible. Some things, like SectionKey, 7 are not defined in the OMAP35x manual and you have to use the OMAP34xx manual 8 to find the data. 9 10 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> 11 12 This program and the accompanying materials 13 are licensed and made available under the terms and conditions of the BSD License 14 which accompanies this distribution. The full text of the license may be found at 15 http://opensource.org/licenses/bsd-license.php 16 17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 20 **/ 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <errno.h> 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 28 29 30 //TOC structure as defined by OMAP35XX TRM. 31 typedef struct { 32 unsigned int Start; 33 unsigned int Size; 34 unsigned int Reserved1; 35 unsigned int Reserved2; 36 unsigned int Reserved3; 37 unsigned char Filename[12]; 38 } TOC_DATA; 39 40 //NOTE: OMAP3430 TRM has CHSETTINGS and CHRAM structures. 41 typedef struct { 42 unsigned int SectionKey; 43 unsigned char Valid; 44 unsigned char Version; 45 unsigned short Reserved; 46 unsigned int Flags; 47 unsigned int PRM_CLKSRC_CTRL; 48 unsigned int PRM_CLKSEL; 49 unsigned int CM_CLKSEL1_EMU; 50 unsigned int CM_CLKSEL_CORE; 51 unsigned int CM_CLKSEL_WKUP; 52 unsigned int CM_CLKEN_PLL_DPLL3; 53 unsigned int CM_AUTOIDLE_PLL_DPLL3; 54 unsigned int CM_CLKSEL1_PLL; 55 unsigned int CM_CLKEN_PLL_DPLL4; 56 unsigned int CM_AUTOIDLE_PLL_DPLL4; 57 unsigned int CM_CLKSEL2_PLL; 58 unsigned int CM_CLKSEL3_PLL; 59 unsigned int CM_CLKEN_PLL_MPU; 60 unsigned int CM_AUTOIDLE_PLL_MPU; 61 unsigned int CM_CLKSEL1_PLL_MPU; 62 unsigned int CM_CLKSEL2_PLL_MPU; 63 unsigned int CM_CLKSTCTRL_MPU; 64 } CHSETTINGS_DATA; 65 66 typedef struct { 67 unsigned int SectionKey; 68 unsigned char Valid; 69 unsigned char Reserved1; 70 unsigned char Reserved2; 71 unsigned char Reserved3; 72 unsigned short SDRC_SYSCONFIG_LSB; 73 unsigned short SDRC_CS_CFG_LSB; 74 unsigned short SDRC_SHARING_LSB; 75 unsigned short SDRC_ERR_TYPE_LSB; 76 unsigned int SDRC_DLLA_CTRL; 77 unsigned short Reserved4; 78 unsigned short Reserved5; 79 unsigned int SDRC_POWER; 80 unsigned short MEMORY_TYPE_CS0; 81 unsigned short Reserved6; 82 unsigned int SDRC_MCFG_0; 83 unsigned short SDRC_MR_0_LSB; 84 unsigned short SDRC_EMR1_0_LSB; 85 unsigned short SDRC_EMR2_0_LSB; 86 unsigned short SDRC_EMR3_0_LSB; 87 unsigned int SDRC_ACTIM_CTRLA_0; 88 unsigned int SDRC_ACTIM_CTRLB_0; 89 unsigned int SDRC_RFRCTRL_0; 90 unsigned short MEMORY_TYPE_CS1; 91 unsigned short Reserved7; 92 unsigned int SDRC_MCFG_1; 93 unsigned short SDRC_MR_1_LSB; 94 unsigned short SDRC_EMR1_1_LSB; 95 unsigned short SDRC_EMR2_1_LSB; 96 unsigned short SDRC_EMR3_1_LSB; 97 unsigned int SDRC_ACTIM_CTRLA_1; 98 unsigned int SDRC_ACTIM_CTRLB_1; 99 unsigned int SDRC_RFRCTRL_1; 100 unsigned int Reserved8; 101 unsigned short Flags; 102 unsigned short Reserved9; 103 } CHRAM_DATA; 104 105 #define CHSETTINGS_START 0xA0 106 #define CHSETTINGS_SIZE 0x50 107 #define CHRAM_START 0xF0 108 #define CHRAM_SIZE 0x5C 109 #define CLOSING_TOC_ITEM_SIZE 4 110 111 unsigned char gConfigurationHeader[512]; 112 unsigned int gImageExecutionAddress; 113 char *gInputImageFile = NULL; 114 char *gOutputImageFile = NULL; 115 char *gDataFile = NULL; 116 117 static 118 void 119 PrintUsage ( 120 void 121 ) 122 { 123 printf("Usage..\n"); 124 } 125 126 static 127 void 128 PopulateCHSETTINGSData ( 129 FILE *DataFile, 130 CHSETTINGS_DATA *CHSETTINGSData 131 ) 132 { 133 unsigned int Value; 134 135 CHSETTINGSData->SectionKey = 0xC0C0C0C1; 136 CHSETTINGSData->Valid = 0x1; 137 CHSETTINGSData->Version = 0x1; 138 CHSETTINGSData->Reserved = 0x00; 139 CHSETTINGSData->Flags = 0x050001FD; 140 141 //General clock settings. 142 fscanf(DataFile, "PRM_CLKSRC_CTRL=0x%08x\n", &Value); 143 CHSETTINGSData->PRM_CLKSRC_CTRL = Value; 144 fscanf(DataFile, "PRM_CLKSEL=0x%08x\n", &Value); 145 CHSETTINGSData->PRM_CLKSEL = Value; 146 fscanf(DataFile, "CM_CLKSEL1_EMU=0x%08x\n", &Value); 147 CHSETTINGSData->CM_CLKSEL1_EMU = Value; 148 149 //Clock configuration 150 fscanf(DataFile, "CM_CLKSEL_CORE=0x%08x\n", &Value); 151 CHSETTINGSData->CM_CLKSEL_CORE = Value; 152 fscanf(DataFile, "CM_CLKSEL_WKUP=0x%08x\n", &Value); 153 CHSETTINGSData->CM_CLKSEL_WKUP = Value; 154 155 //DPLL3 (Core) settings 156 fscanf(DataFile, "CM_CLKEN_PLL_DPLL3=0x%08x\n", &Value); 157 CHSETTINGSData->CM_CLKEN_PLL_DPLL3 = Value; 158 fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL3=0x%08x\n", &Value); 159 CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL3 = Value; 160 fscanf(DataFile, "CM_CLKSEL1_PLL=0x%08x\n", &Value); 161 CHSETTINGSData->CM_CLKSEL1_PLL = Value; 162 163 //DPLL4 (Peripheral) settings 164 fscanf(DataFile, "CM_CLKEN_PLL_DPLL4=0x%08x\n", &Value); 165 CHSETTINGSData->CM_CLKEN_PLL_DPLL4 = Value; 166 fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL4=0x%08x\n", &Value); 167 CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL4 = Value; 168 fscanf(DataFile, "CM_CLKSEL2_PLL=0x%08x\n", &Value); 169 CHSETTINGSData->CM_CLKSEL2_PLL = Value; 170 fscanf(DataFile, "CM_CLKSEL3_PLL=0x%08x\n", &Value); 171 CHSETTINGSData->CM_CLKSEL3_PLL = Value; 172 173 //DPLL1 (MPU) settings 174 fscanf(DataFile, "CM_CLKEN_PLL_MPU=0x%08x\n", &Value); 175 CHSETTINGSData->CM_CLKEN_PLL_MPU = Value; 176 fscanf(DataFile, "CM_AUTOIDLE_PLL_MPU=0x%08x\n", &Value); 177 CHSETTINGSData->CM_AUTOIDLE_PLL_MPU = Value; 178 fscanf(DataFile, "CM_CLKSEL1_PLL_MPU=0x%08x\n", &Value); 179 CHSETTINGSData->CM_CLKSEL1_PLL_MPU = Value; 180 fscanf(DataFile, "CM_CLKSEL2_PLL_MPU=0x%08x\n", &Value); 181 CHSETTINGSData->CM_CLKSEL2_PLL_MPU = Value; 182 fscanf(DataFile, "CM_CLKSTCTRL_MPU=0x%08x\n", &Value); 183 CHSETTINGSData->CM_CLKSTCTRL_MPU = Value; 184 } 185 186 static 187 void 188 PopulateCHRAMData ( 189 FILE *DataFile, 190 CHRAM_DATA *CHRAMData 191 ) 192 { 193 unsigned int Value; 194 195 CHRAMData->SectionKey = 0xC0C0C0C2; 196 CHRAMData->Valid = 0x1; 197 198 fscanf(DataFile, "SDRC_SYSCONFIG_LSB=0x%04x\n", &Value); 199 CHRAMData->SDRC_SYSCONFIG_LSB = Value; 200 fscanf(DataFile, "SDRC_CS_CFG_LSB=0x%04x\n", &Value); 201 CHRAMData->SDRC_CS_CFG_LSB = Value; 202 fscanf(DataFile, "SDRC_SHARING_LSB=0x%04x\n", &Value); 203 CHRAMData->SDRC_SHARING_LSB = Value; 204 fscanf(DataFile, "SDRC_ERR_TYPE_LSB=0x%04x\n", &Value); 205 CHRAMData->SDRC_ERR_TYPE_LSB = Value; 206 fscanf(DataFile, "SDRC_DLLA_CTRL=0x%08x\n", &Value); 207 CHRAMData->SDRC_DLLA_CTRL = Value; 208 fscanf(DataFile, "SDRC_POWER=0x%08x\n", &Value); 209 CHRAMData->SDRC_POWER = Value; 210 fscanf(DataFile, "MEMORY_TYPE_CS0=0x%04x\n", &Value); 211 CHRAMData->MEMORY_TYPE_CS0 = Value; 212 fscanf(DataFile, "SDRC_MCFG_0=0x%08x\n", &Value); 213 CHRAMData->SDRC_MCFG_0 = Value; 214 fscanf(DataFile, "SDRC_MR_0_LSB=0x%04x\n", &Value); 215 CHRAMData->SDRC_MR_0_LSB = Value; 216 fscanf(DataFile, "SDRC_EMR1_0_LSB=0x%04x\n", &Value); 217 CHRAMData->SDRC_EMR1_0_LSB = Value; 218 fscanf(DataFile, "SDRC_EMR2_0_LSB=0x%04x\n", &Value); 219 CHRAMData->SDRC_EMR2_0_LSB = Value; 220 fscanf(DataFile, "SDRC_EMR3_0_LSB=0x%04x\n", &Value); 221 CHRAMData->SDRC_EMR3_0_LSB = Value; 222 fscanf(DataFile, "SDRC_ACTIM_CTRLA_0=0x%08x\n", &Value); 223 CHRAMData->SDRC_ACTIM_CTRLA_0 = Value; 224 fscanf(DataFile, "SDRC_ACTIM_CTRLB_0=0x%08x\n", &Value); 225 CHRAMData->SDRC_ACTIM_CTRLB_0 = Value; 226 fscanf(DataFile, "SDRC_RFRCTRL_0=0x%08x\n", &Value); 227 CHRAMData->SDRC_RFRCTRL_0 = Value; 228 fscanf(DataFile, "MEMORY_TYPE_CS1=0x%04x\n", &Value); 229 CHRAMData->MEMORY_TYPE_CS1 = Value; 230 fscanf(DataFile, "SDRC_MCFG_1=0x%08x\n", &Value); 231 CHRAMData->SDRC_MCFG_1 = Value; 232 fscanf(DataFile, "SDRC_MR_1_LSB=0x%04x\n", &Value); 233 CHRAMData->SDRC_MR_1_LSB = Value; 234 fscanf(DataFile, "SDRC_EMR1_1_LSB=0x%04x\n", &Value); 235 CHRAMData->SDRC_EMR1_1_LSB = Value; 236 fscanf(DataFile, "SDRC_EMR2_1_LSB=0x%04x\n", &Value); 237 CHRAMData->SDRC_EMR2_1_LSB = Value; 238 fscanf(DataFile, "SDRC_EMR3_1_LSB=0x%04x\n", &Value); 239 CHRAMData->SDRC_EMR3_1_LSB = Value; 240 fscanf(DataFile, "SDRC_ACTIM_CTRLA_1=0x%08x\n", &Value); 241 CHRAMData->SDRC_ACTIM_CTRLA_1 = Value; 242 fscanf(DataFile, "SDRC_ACTIM_CTRLB_1=0x%08x\n", &Value); 243 CHRAMData->SDRC_ACTIM_CTRLB_1 = Value; 244 fscanf(DataFile, "SDRC_RFRCTRL_1=0x%08x\n", &Value); 245 CHRAMData->SDRC_RFRCTRL_1 = Value; 246 247 CHRAMData->Flags = 0x0003; 248 } 249 250 static 251 void 252 PrepareConfigurationHeader ( 253 void 254 ) 255 { 256 TOC_DATA Toc; 257 CHSETTINGS_DATA CHSETTINGSData; 258 CHRAM_DATA CHRAMData; 259 unsigned int ConfigurationHdrOffset = 0; 260 FILE *DataFile; 261 262 // Open data file 263 DataFile = fopen(gDataFile, "rb"); 264 if (DataFile == NULL) { 265 fprintf(stderr, "Can't open data file %s.\n", gDataFile); 266 exit(1); 267 } 268 269 //Initialize configuration header. 270 memset(gConfigurationHeader, 0x00, sizeof(gConfigurationHeader)); 271 272 //CHSETTINGS TOC 273 memset(&Toc, 0x00, sizeof(TOC_DATA)); 274 Toc.Start = CHSETTINGS_START; 275 Toc.Size = CHSETTINGS_SIZE; 276 strcpy((char *)Toc.Filename, (const char *)"CHSETTINGS"); 277 memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA)); 278 279 //Populate CHSETTINGS Data 280 memset(&CHSETTINGSData, 0x00, sizeof(CHSETTINGS_DATA)); 281 PopulateCHSETTINGSData(DataFile, &CHSETTINGSData); 282 memcpy(gConfigurationHeader + Toc.Start, &CHSETTINGSData, Toc.Size); 283 284 //Adjust ConfigurationHdrOffset to point to next TOC 285 ConfigurationHdrOffset += sizeof(TOC_DATA); 286 287 //CHRAM TOC 288 memset(&Toc, 0x00, sizeof(TOC_DATA)); 289 Toc.Start = CHRAM_START; 290 Toc.Size = CHRAM_SIZE; 291 strcpy((char *)Toc.Filename, (const char *)"CHRAM"); 292 memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA)); 293 294 //Populate CHRAM Data 295 memset(&CHRAMData, 0x00, sizeof(CHRAM_DATA)); 296 PopulateCHRAMData(DataFile, &CHRAMData); 297 memcpy(gConfigurationHeader + Toc.Start, &CHRAMData, Toc.Size); 298 299 //Adjust ConfigurationHdrOffset to point to next TOC 300 ConfigurationHdrOffset += sizeof(TOC_DATA); 301 302 //Closing TOC item 303 memset(gConfigurationHeader + ConfigurationHdrOffset, 0xFF, CLOSING_TOC_ITEM_SIZE); 304 ConfigurationHdrOffset += CLOSING_TOC_ITEM_SIZE; 305 306 // Close data file 307 fclose(DataFile); 308 } 309 310 static 311 void 312 ConstructImage ( 313 void 314 ) 315 { 316 FILE *InputFile; 317 FILE *OutputFile; 318 unsigned int InputImageFileSize; 319 struct stat FileStat; 320 char Ch; 321 unsigned int i; 322 323 InputFile = fopen(gInputImageFile, "rb"); 324 if (InputFile == NULL) { 325 fprintf(stderr, "Can't open input file.\n"); 326 exit(0); 327 } 328 329 // Get the size of the input image. 330 fstat(fileno(InputFile), &FileStat); 331 InputImageFileSize = FileStat.st_size; 332 333 OutputFile = fopen(gOutputImageFile, "wb"); 334 if (OutputFile == NULL) { 335 fprintf(stderr, "Can't open output file %s.\n", gOutputImageFile); 336 exit(0); 337 } 338 339 // Write Configuration header 340 fwrite(gConfigurationHeader, 1, sizeof(gConfigurationHeader), OutputFile); 341 342 // Write image header (Input image size, execution address) 343 fwrite(&InputImageFileSize, 1, 4, OutputFile); 344 fwrite(&gImageExecutionAddress, 1, 4, OutputFile); 345 346 // Copy input image to the output file. 347 for (i = 0; i < InputImageFileSize; i++) { 348 fread(&Ch, 1, 1, InputFile); 349 fwrite(&Ch, 1, 1, OutputFile); 350 } 351 352 fclose(InputFile); 353 fclose(OutputFile); 354 } 355 356 357 int 358 main ( 359 int argc, 360 char** argv 361 ) 362 { 363 char Ch; 364 unsigned char *ptr; 365 int i; 366 int TwoArg; 367 368 if (argc == 1) { 369 PrintUsage (); 370 exit(1); 371 } 372 373 for (i=1; i < argc; i++) { 374 if (argv[i][0] == '-') { 375 // TwoArg TRUE -E 0x123, FALSE -E0x1234 376 TwoArg = (argv[i][2] != ' '); 377 switch (argv[i][1]) { 378 case 'E': /* Image execution address */ 379 gImageExecutionAddress = strtoul (TwoArg ? argv[i+1] : &argv[i][2], (char **)&ptr, 16); 380 break; 381 382 case 'I': /* Input image file */ 383 gInputImageFile = TwoArg ? argv[i+1] : &argv[i][2]; 384 break; 385 386 case 'O': /* Output image file */ 387 gOutputImageFile = TwoArg ? argv[i+1] : &argv[i][2]; 388 break; 389 390 case 'D': /* Data file */ 391 gDataFile = TwoArg ? argv[i+1] : &argv[i][2]; 392 break; 393 394 default: 395 abort (); 396 } 397 } 398 } 399 400 401 //Prepare configuration header 402 PrepareConfigurationHeader (); 403 404 //Build image with configuration header + image header + image 405 ConstructImage (); 406 407 return 0; 408 } 409