mirror of https://github.com/acidanthera/audk.git
411 lines
12 KiB
C
411 lines
12 KiB
C
|
/** @file
|
||
|
|
||
|
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||
|
|
||
|
All rights reserved. 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>
|
||
|
#include <unistd.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", gOutputImageFile);
|
||
|
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;
|
||
|
unsigned int NewImageFileSize;
|
||
|
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;
|
||
|
|
||
|
//Calculate new file size
|
||
|
NewImageFileSize = InputImageFileSize - 520;
|
||
|
|
||
|
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(&NewImageFileSize, 1, 4, OutputFile);
|
||
|
fwrite(&gImageExecutionAddress, 1, 4, OutputFile);
|
||
|
|
||
|
//Skip first 0x207 bytes
|
||
|
fseek(InputFile, 520, SEEK_SET);
|
||
|
|
||
|
//Copy input image to the output file.
|
||
|
for (i = 0; i < NewImageFileSize; 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;
|
||
|
|
||
|
if (argc == 1) {
|
||
|
PrintUsage ();
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
while ((Ch = getopt(argc, argv, "D:E:I:O:")) != -1) {
|
||
|
switch (Ch) {
|
||
|
case 'E': /* Image execution address */
|
||
|
gImageExecutionAddress = strtoul (optarg, (char **)&ptr, 16);
|
||
|
break;
|
||
|
|
||
|
case 'I': /* Input image file */
|
||
|
gInputImageFile = optarg;
|
||
|
break;
|
||
|
|
||
|
case 'O': /* Output image file */
|
||
|
gOutputImageFile = optarg;
|
||
|
break;
|
||
|
|
||
|
case 'D': /* Data file */
|
||
|
gDataFile = optarg;
|
||
|
break;
|
||
|
|
||
|
case '?':
|
||
|
if ((optopt == 'E') || (optopt == 'I') || (optopt == 'O')) {
|
||
|
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
|
||
|
} else if (isprint (optopt)) {
|
||
|
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
||
|
} else {
|
||
|
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
|
||
|
}
|
||
|
return 1;
|
||
|
|
||
|
default:
|
||
|
abort ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Prepare configuration header
|
||
|
PrepareConfigurationHeader ();
|
||
|
|
||
|
//Build image with configuration header + image header + image
|
||
|
ConstructImage ();
|
||
|
|
||
|
return 0;
|
||
|
}
|