/** @file | |
The data structures in this code come from: | |
OMAP35x Applications Processor Technical Reference Manual chapter 25 | |
OMAP34xx Multimedia Device Technical Reference Manual chapter 26.4.8. | |
You should use the OMAP35x manual when possible. Some things, like SectionKey, | |
are not defined in the OMAP35x manual and you have to use the OMAP34xx manual | |
to find the data. | |
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
//TOC structure as defined by OMAP35XX TRM. | |
typedef struct { | |
unsigned int Start; | |
unsigned int Size; | |
unsigned int Reserved1; | |
unsigned int Reserved2; | |
unsigned int Reserved3; | |
unsigned char Filename[12]; | |
} TOC_DATA; | |
//NOTE: OMAP3430 TRM has CHSETTINGS and CHRAM structures. | |
typedef struct { | |
unsigned int SectionKey; | |
unsigned char Valid; | |
unsigned char Version; | |
unsigned short Reserved; | |
unsigned int Flags; | |
unsigned int PRM_CLKSRC_CTRL; | |
unsigned int PRM_CLKSEL; | |
unsigned int CM_CLKSEL1_EMU; | |
unsigned int CM_CLKSEL_CORE; | |
unsigned int CM_CLKSEL_WKUP; | |
unsigned int CM_CLKEN_PLL_DPLL3; | |
unsigned int CM_AUTOIDLE_PLL_DPLL3; | |
unsigned int CM_CLKSEL1_PLL; | |
unsigned int CM_CLKEN_PLL_DPLL4; | |
unsigned int CM_AUTOIDLE_PLL_DPLL4; | |
unsigned int CM_CLKSEL2_PLL; | |
unsigned int CM_CLKSEL3_PLL; | |
unsigned int CM_CLKEN_PLL_MPU; | |
unsigned int CM_AUTOIDLE_PLL_MPU; | |
unsigned int CM_CLKSEL1_PLL_MPU; | |
unsigned int CM_CLKSEL2_PLL_MPU; | |
unsigned int CM_CLKSTCTRL_MPU; | |
} CHSETTINGS_DATA; | |
typedef struct { | |
unsigned int SectionKey; | |
unsigned char Valid; | |
unsigned char Reserved1; | |
unsigned char Reserved2; | |
unsigned char Reserved3; | |
unsigned short SDRC_SYSCONFIG_LSB; | |
unsigned short SDRC_CS_CFG_LSB; | |
unsigned short SDRC_SHARING_LSB; | |
unsigned short SDRC_ERR_TYPE_LSB; | |
unsigned int SDRC_DLLA_CTRL; | |
unsigned short Reserved4; | |
unsigned short Reserved5; | |
unsigned int SDRC_POWER; | |
unsigned short MEMORY_TYPE_CS0; | |
unsigned short Reserved6; | |
unsigned int SDRC_MCFG_0; | |
unsigned short SDRC_MR_0_LSB; | |
unsigned short SDRC_EMR1_0_LSB; | |
unsigned short SDRC_EMR2_0_LSB; | |
unsigned short SDRC_EMR3_0_LSB; | |
unsigned int SDRC_ACTIM_CTRLA_0; | |
unsigned int SDRC_ACTIM_CTRLB_0; | |
unsigned int SDRC_RFRCTRL_0; | |
unsigned short MEMORY_TYPE_CS1; | |
unsigned short Reserved7; | |
unsigned int SDRC_MCFG_1; | |
unsigned short SDRC_MR_1_LSB; | |
unsigned short SDRC_EMR1_1_LSB; | |
unsigned short SDRC_EMR2_1_LSB; | |
unsigned short SDRC_EMR3_1_LSB; | |
unsigned int SDRC_ACTIM_CTRLA_1; | |
unsigned int SDRC_ACTIM_CTRLB_1; | |
unsigned int SDRC_RFRCTRL_1; | |
unsigned int Reserved8; | |
unsigned short Flags; | |
unsigned short Reserved9; | |
} CHRAM_DATA; | |
#define CHSETTINGS_START 0xA0 | |
#define CHSETTINGS_SIZE 0x50 | |
#define CHRAM_START 0xF0 | |
#define CHRAM_SIZE 0x5C | |
#define CLOSING_TOC_ITEM_SIZE 4 | |
unsigned char gConfigurationHeader[512]; | |
unsigned int gImageExecutionAddress; | |
char *gInputImageFile = NULL; | |
char *gOutputImageFile = NULL; | |
char *gDataFile = NULL; | |
static | |
void | |
PrintUsage ( | |
void | |
) | |
{ | |
printf("Usage..\n"); | |
} | |
static | |
void | |
PopulateCHSETTINGSData ( | |
FILE *DataFile, | |
CHSETTINGS_DATA *CHSETTINGSData | |
) | |
{ | |
unsigned int Value; | |
CHSETTINGSData->SectionKey = 0xC0C0C0C1; | |
CHSETTINGSData->Valid = 0x1; | |
CHSETTINGSData->Version = 0x1; | |
CHSETTINGSData->Reserved = 0x00; | |
CHSETTINGSData->Flags = 0x050001FD; | |
//General clock settings. | |
fscanf(DataFile, "PRM_CLKSRC_CTRL=0x%08x\n", &Value); | |
CHSETTINGSData->PRM_CLKSRC_CTRL = Value; | |
fscanf(DataFile, "PRM_CLKSEL=0x%08x\n", &Value); | |
CHSETTINGSData->PRM_CLKSEL = Value; | |
fscanf(DataFile, "CM_CLKSEL1_EMU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL1_EMU = Value; | |
//Clock configuration | |
fscanf(DataFile, "CM_CLKSEL_CORE=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL_CORE = Value; | |
fscanf(DataFile, "CM_CLKSEL_WKUP=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL_WKUP = Value; | |
//DPLL3 (Core) settings | |
fscanf(DataFile, "CM_CLKEN_PLL_DPLL3=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKEN_PLL_DPLL3 = Value; | |
fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL3=0x%08x\n", &Value); | |
CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL3 = Value; | |
fscanf(DataFile, "CM_CLKSEL1_PLL=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL1_PLL = Value; | |
//DPLL4 (Peripheral) settings | |
fscanf(DataFile, "CM_CLKEN_PLL_DPLL4=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKEN_PLL_DPLL4 = Value; | |
fscanf(DataFile, "CM_AUTOIDLE_PLL_DPLL4=0x%08x\n", &Value); | |
CHSETTINGSData->CM_AUTOIDLE_PLL_DPLL4 = Value; | |
fscanf(DataFile, "CM_CLKSEL2_PLL=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL2_PLL = Value; | |
fscanf(DataFile, "CM_CLKSEL3_PLL=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL3_PLL = Value; | |
//DPLL1 (MPU) settings | |
fscanf(DataFile, "CM_CLKEN_PLL_MPU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKEN_PLL_MPU = Value; | |
fscanf(DataFile, "CM_AUTOIDLE_PLL_MPU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_AUTOIDLE_PLL_MPU = Value; | |
fscanf(DataFile, "CM_CLKSEL1_PLL_MPU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL1_PLL_MPU = Value; | |
fscanf(DataFile, "CM_CLKSEL2_PLL_MPU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSEL2_PLL_MPU = Value; | |
fscanf(DataFile, "CM_CLKSTCTRL_MPU=0x%08x\n", &Value); | |
CHSETTINGSData->CM_CLKSTCTRL_MPU = Value; | |
} | |
static | |
void | |
PopulateCHRAMData ( | |
FILE *DataFile, | |
CHRAM_DATA *CHRAMData | |
) | |
{ | |
unsigned int Value; | |
CHRAMData->SectionKey = 0xC0C0C0C2; | |
CHRAMData->Valid = 0x1; | |
fscanf(DataFile, "SDRC_SYSCONFIG_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_SYSCONFIG_LSB = Value; | |
fscanf(DataFile, "SDRC_CS_CFG_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_CS_CFG_LSB = Value; | |
fscanf(DataFile, "SDRC_SHARING_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_SHARING_LSB = Value; | |
fscanf(DataFile, "SDRC_ERR_TYPE_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_ERR_TYPE_LSB = Value; | |
fscanf(DataFile, "SDRC_DLLA_CTRL=0x%08x\n", &Value); | |
CHRAMData->SDRC_DLLA_CTRL = Value; | |
fscanf(DataFile, "SDRC_POWER=0x%08x\n", &Value); | |
CHRAMData->SDRC_POWER = Value; | |
fscanf(DataFile, "MEMORY_TYPE_CS0=0x%04x\n", &Value); | |
CHRAMData->MEMORY_TYPE_CS0 = Value; | |
fscanf(DataFile, "SDRC_MCFG_0=0x%08x\n", &Value); | |
CHRAMData->SDRC_MCFG_0 = Value; | |
fscanf(DataFile, "SDRC_MR_0_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_MR_0_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR1_0_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR1_0_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR2_0_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR2_0_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR3_0_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR3_0_LSB = Value; | |
fscanf(DataFile, "SDRC_ACTIM_CTRLA_0=0x%08x\n", &Value); | |
CHRAMData->SDRC_ACTIM_CTRLA_0 = Value; | |
fscanf(DataFile, "SDRC_ACTIM_CTRLB_0=0x%08x\n", &Value); | |
CHRAMData->SDRC_ACTIM_CTRLB_0 = Value; | |
fscanf(DataFile, "SDRC_RFRCTRL_0=0x%08x\n", &Value); | |
CHRAMData->SDRC_RFRCTRL_0 = Value; | |
fscanf(DataFile, "MEMORY_TYPE_CS1=0x%04x\n", &Value); | |
CHRAMData->MEMORY_TYPE_CS1 = Value; | |
fscanf(DataFile, "SDRC_MCFG_1=0x%08x\n", &Value); | |
CHRAMData->SDRC_MCFG_1 = Value; | |
fscanf(DataFile, "SDRC_MR_1_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_MR_1_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR1_1_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR1_1_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR2_1_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR2_1_LSB = Value; | |
fscanf(DataFile, "SDRC_EMR3_1_LSB=0x%04x\n", &Value); | |
CHRAMData->SDRC_EMR3_1_LSB = Value; | |
fscanf(DataFile, "SDRC_ACTIM_CTRLA_1=0x%08x\n", &Value); | |
CHRAMData->SDRC_ACTIM_CTRLA_1 = Value; | |
fscanf(DataFile, "SDRC_ACTIM_CTRLB_1=0x%08x\n", &Value); | |
CHRAMData->SDRC_ACTIM_CTRLB_1 = Value; | |
fscanf(DataFile, "SDRC_RFRCTRL_1=0x%08x\n", &Value); | |
CHRAMData->SDRC_RFRCTRL_1 = Value; | |
CHRAMData->Flags = 0x0003; | |
} | |
static | |
void | |
PrepareConfigurationHeader ( | |
void | |
) | |
{ | |
TOC_DATA Toc; | |
CHSETTINGS_DATA CHSETTINGSData; | |
CHRAM_DATA CHRAMData; | |
unsigned int ConfigurationHdrOffset = 0; | |
FILE *DataFile; | |
// Open data file | |
DataFile = fopen(gDataFile, "rb"); | |
if (DataFile == NULL) { | |
fprintf(stderr, "Can't open data file %s.\n", gDataFile); | |
exit(1); | |
} | |
//Initialize configuration header. | |
memset(gConfigurationHeader, 0x00, sizeof(gConfigurationHeader)); | |
//CHSETTINGS TOC | |
memset(&Toc, 0x00, sizeof(TOC_DATA)); | |
Toc.Start = CHSETTINGS_START; | |
Toc.Size = CHSETTINGS_SIZE; | |
strcpy((char *)Toc.Filename, (const char *)"CHSETTINGS"); | |
memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA)); | |
//Populate CHSETTINGS Data | |
memset(&CHSETTINGSData, 0x00, sizeof(CHSETTINGS_DATA)); | |
PopulateCHSETTINGSData(DataFile, &CHSETTINGSData); | |
memcpy(gConfigurationHeader + Toc.Start, &CHSETTINGSData, Toc.Size); | |
//Adjust ConfigurationHdrOffset to point to next TOC | |
ConfigurationHdrOffset += sizeof(TOC_DATA); | |
//CHRAM TOC | |
memset(&Toc, 0x00, sizeof(TOC_DATA)); | |
Toc.Start = CHRAM_START; | |
Toc.Size = CHRAM_SIZE; | |
strcpy((char *)Toc.Filename, (const char *)"CHRAM"); | |
memcpy(gConfigurationHeader + ConfigurationHdrOffset, &Toc, sizeof(TOC_DATA)); | |
//Populate CHRAM Data | |
memset(&CHRAMData, 0x00, sizeof(CHRAM_DATA)); | |
PopulateCHRAMData(DataFile, &CHRAMData); | |
memcpy(gConfigurationHeader + Toc.Start, &CHRAMData, Toc.Size); | |
//Adjust ConfigurationHdrOffset to point to next TOC | |
ConfigurationHdrOffset += sizeof(TOC_DATA); | |
//Closing TOC item | |
memset(gConfigurationHeader + ConfigurationHdrOffset, 0xFF, CLOSING_TOC_ITEM_SIZE); | |
ConfigurationHdrOffset += CLOSING_TOC_ITEM_SIZE; | |
// Close data file | |
fclose(DataFile); | |
} | |
static | |
void | |
ConstructImage ( | |
void | |
) | |
{ | |
FILE *InputFile; | |
FILE *OutputFile; | |
unsigned int InputImageFileSize; | |
struct stat FileStat; | |
char Ch; | |
unsigned int i; | |
InputFile = fopen(gInputImageFile, "rb"); | |
if (InputFile == NULL) { | |
fprintf(stderr, "Can't open input file.\n"); | |
exit(0); | |
} | |
// Get the size of the input image. | |
fstat(fileno(InputFile), &FileStat); | |
InputImageFileSize = FileStat.st_size; | |
OutputFile = fopen(gOutputImageFile, "wb"); | |
if (OutputFile == NULL) { | |
fprintf(stderr, "Can't open output file %s.\n", gOutputImageFile); | |
exit(0); | |
} | |
// Write Configuration header | |
fwrite(gConfigurationHeader, 1, sizeof(gConfigurationHeader), OutputFile); | |
// Write image header (Input image size, execution address) | |
fwrite(&InputImageFileSize, 1, 4, OutputFile); | |
fwrite(&gImageExecutionAddress, 1, 4, OutputFile); | |
// Copy input image to the output file. | |
for (i = 0; i < InputImageFileSize; i++) { | |
fread(&Ch, 1, 1, InputFile); | |
fwrite(&Ch, 1, 1, OutputFile); | |
} | |
fclose(InputFile); | |
fclose(OutputFile); | |
} | |
int | |
main ( | |
int argc, | |
char** argv | |
) | |
{ | |
char Ch; | |
unsigned char *ptr; | |
int i; | |
int TwoArg; | |
if (argc == 1) { | |
PrintUsage (); | |
exit(1); | |
} | |
for (i=1; i < argc; i++) { | |
if (argv[i][0] == '-') { | |
// TwoArg TRUE -E 0x123, FALSE -E0x1234 | |
TwoArg = (argv[i][2] != ' '); | |
switch (argv[i][1]) { | |
case 'E': /* Image execution address */ | |
gImageExecutionAddress = strtoul (TwoArg ? argv[i+1] : &argv[i][2], (char **)&ptr, 16); | |
break; | |
case 'I': /* Input image file */ | |
gInputImageFile = TwoArg ? argv[i+1] : &argv[i][2]; | |
break; | |
case 'O': /* Output image file */ | |
gOutputImageFile = TwoArg ? argv[i+1] : &argv[i][2]; | |
break; | |
case 'D': /* Data file */ | |
gDataFile = TwoArg ? argv[i+1] : &argv[i][2]; | |
break; | |
default: | |
abort (); | |
} | |
} | |
} | |
//Prepare configuration header | |
PrepareConfigurationHeader (); | |
//Build image with configuration header + image header + image | |
ConstructImage (); | |
return 0; | |
} |