ifdtool: Update to support Skylake+ descriptor format
The descriptor format has changed with Skylake and some fields have moved or been expanded. This includes new SPI frequencies and chip densities, though unfortunately 30MHz in the new format conflicts with 50MHz in the old format... There are also new regions with a few reserved regions inserted before a new embedded controller region. Unfortunately there does not seem to be a documented version field so there does not seem to be an official way to determine if a specific descriptor is new or old. To work around this ifdtool checks the hardcoded "SPI Read Frequency" to see if it set for 20MHz (old descriptor) or 17MHz (new descriptor). BUG=chrome-os-partner:40635 BUG=chrome-os-partner:43461 BRANCH=none TEST=run ifdtool on skylake and broadwell images Original-Change-Id: I0561b3c65fcb3e77c0a24be58b01db9b3a36e5a9 Original-Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/281001 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Commit-Queue: Aaron Durbin <adurbin@chromium.org> Change-Id: I9a08c26432e13c4000afc50de9d8473e6f911805 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/293240 Reviewed-on: http://review.coreboot.org/11228 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
e0334e8296
commit
1f7fd720c8
|
@ -31,14 +31,18 @@
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NUM_REGIONS 5
|
static int ifd_version;
|
||||||
|
|
||||||
static const struct region_name region_names[NUM_REGIONS] = {
|
static const struct region_name region_names[MAX_REGIONS] = {
|
||||||
{ "Flash Descriptor", "fd" },
|
{ "Flash Descriptor", "fd" },
|
||||||
{ "BIOS", "bios" },
|
{ "BIOS", "bios" },
|
||||||
{ "Intel ME", "me" },
|
{ "Intel ME", "me" },
|
||||||
{ "GbE", "gbe" },
|
{ "GbE", "gbe" },
|
||||||
{ "Platform Data", "pd" }
|
{ "Platform Data", "pd" },
|
||||||
|
{ "Reserved", "res1" },
|
||||||
|
{ "Reserved", "res2" },
|
||||||
|
{ "Reserved", "res3" },
|
||||||
|
{ "EC" "ec" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static fdbar_t *find_fd(char *image, int size)
|
static fdbar_t *find_fd(char *image, int size)
|
||||||
|
@ -58,11 +62,43 @@ static fdbar_t *find_fd(char *image, int size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Found Flash Descriptor signature at 0x%08x\n", i);
|
|
||||||
|
|
||||||
return (fdbar_t *) (image + i);
|
return (fdbar_t *) (image + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is no version field in the descriptor so to determine
|
||||||
|
* if this is a new descriptor format we check the hardcoded SPI
|
||||||
|
* read frequency to see if it is fixed at 20MHz or 17MHz.
|
||||||
|
*/
|
||||||
|
static void check_ifd_version(char *image, int size)
|
||||||
|
{
|
||||||
|
fdbar_t *fdb = find_fd(image, size);
|
||||||
|
fcba_t *fcba;
|
||||||
|
int read_freq;
|
||||||
|
|
||||||
|
if (!fdb)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
fcba = (fcba_t *) (image + (((fdb->flmap0) & 0xff) << 4));
|
||||||
|
if (!fcba)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
read_freq = (fcba->flcomp >> 17) & 7;
|
||||||
|
|
||||||
|
switch (read_freq) {
|
||||||
|
case SPI_FREQUENCY_20MHZ:
|
||||||
|
ifd_version = IFD_VERSION_1;
|
||||||
|
break;
|
||||||
|
case SPI_FREQUENCY_17MHZ:
|
||||||
|
ifd_version = IFD_VERSION_2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown descriptor version: %d\n",
|
||||||
|
read_freq);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static region_t get_region(frba_t *frba, int region_type)
|
static region_t get_region(frba_t *frba, int region_type)
|
||||||
{
|
{
|
||||||
region_t region;
|
region_t region;
|
||||||
|
@ -89,8 +125,24 @@ static region_t get_region(frba_t *frba, int region_type)
|
||||||
region.base = (frba->flreg4 & 0x00000fff) << 12;
|
region.base = (frba->flreg4 & 0x00000fff) << 12;
|
||||||
region.limit = ((frba->flreg4 & 0x0fff0000) >> 4) | 0xfff;
|
region.limit = ((frba->flreg4 & 0x0fff0000) >> 4) | 0xfff;
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
region.base = (frba->flreg5 & 0x00000fff) << 12;
|
||||||
|
region.limit = ((frba->flreg5 & 0x0fff0000) >> 4) | 0xfff;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
region.base = (frba->flreg6 & 0x00000fff) << 12;
|
||||||
|
region.limit = ((frba->flreg6 & 0x0fff0000) >> 4) | 0xfff;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
region.base = (frba->flreg7 & 0x00000fff) << 12;
|
||||||
|
region.limit = ((frba->flreg7 & 0x0fff0000) >> 4) | 0xfff;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
region.base = (frba->flreg8 & 0x00000fff) << 12;
|
||||||
|
region.limit = ((frba->flreg8 & 0x0fff0000) >> 4) | 0xfff;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Invalid region type.\n");
|
fprintf(stderr, "Invalid region type %d.\n", region_type);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +184,7 @@ static void set_region(frba_t *frba, int region_type, region_t region)
|
||||||
|
|
||||||
static const char *region_name(int region_type)
|
static const char *region_name(int region_type)
|
||||||
{
|
{
|
||||||
if (region_type < 0 || region_type >= NUM_REGIONS) {
|
if (region_type < 0 || region_type >= MAX_REGIONS) {
|
||||||
fprintf(stderr, "Invalid region type.\n");
|
fprintf(stderr, "Invalid region type.\n");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +194,7 @@ static const char *region_name(int region_type)
|
||||||
|
|
||||||
static const char *region_name_short(int region_type)
|
static const char *region_name_short(int region_type)
|
||||||
{
|
{
|
||||||
if (region_type < 0 || region_type >= NUM_REGIONS) {
|
if (region_type < 0 || region_type >= MAX_REGIONS) {
|
||||||
fprintf(stderr, "Invalid region type.\n");
|
fprintf(stderr, "Invalid region type.\n");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +206,7 @@ static int region_num(const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
for (i = 0; i < MAX_REGIONS; i++) {
|
||||||
if (strcasecmp(name, region_names[i].pretty) == 0)
|
if (strcasecmp(name, region_names[i].pretty) == 0)
|
||||||
return i;
|
return i;
|
||||||
if (strcasecmp(name, region_names[i].terse) == 0)
|
if (strcasecmp(name, region_names[i].terse) == 0)
|
||||||
|
@ -166,16 +218,20 @@ static int region_num(const char *name)
|
||||||
|
|
||||||
static const char *region_filename(int region_type)
|
static const char *region_filename(int region_type)
|
||||||
{
|
{
|
||||||
static const char *region_filenames[NUM_REGIONS] = {
|
static const char *region_filenames[MAX_REGIONS] = {
|
||||||
"flashregion_0_flashdescriptor.bin",
|
"flashregion_0_flashdescriptor.bin",
|
||||||
"flashregion_1_bios.bin",
|
"flashregion_1_bios.bin",
|
||||||
"flashregion_2_intel_me.bin",
|
"flashregion_2_intel_me.bin",
|
||||||
"flashregion_3_gbe.bin",
|
"flashregion_3_gbe.bin",
|
||||||
"flashregion_4_platform_data.bin"
|
"flashregion_4_platform_data.bin",
|
||||||
|
"flashregion_5_reserved.bin",
|
||||||
|
"flashregion_6_reserved.bin",
|
||||||
|
"flashregion_7_reserved.bin",
|
||||||
|
"flashregion_8_ec.bin",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (region_type < 0 || region_type >= NUM_REGIONS) {
|
if (region_type < 0 || region_type >= MAX_REGIONS) {
|
||||||
fprintf(stderr, "Invalid region type.\n");
|
fprintf(stderr, "Invalid region type %d.\n", region_type);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +266,17 @@ static void dump_frba(frba_t * frba)
|
||||||
dump_region(3, frba);
|
dump_region(3, frba);
|
||||||
printf("FLREG4: 0x%08x\n", frba->flreg4);
|
printf("FLREG4: 0x%08x\n", frba->flreg4);
|
||||||
dump_region(4, frba);
|
dump_region(4, frba);
|
||||||
|
|
||||||
|
if (ifd_version >= IFD_VERSION_2) {
|
||||||
|
printf("FLREG5: 0x%08x\n", frba->flreg5);
|
||||||
|
dump_region(5, frba);
|
||||||
|
printf("FLREG6: 0x%08x\n", frba->flreg6);
|
||||||
|
dump_region(6, frba);
|
||||||
|
printf("FLREG7: 0x%08x\n", frba->flreg7);
|
||||||
|
dump_region(7, frba);
|
||||||
|
printf("FLREG8: 0x%08x\n", frba->flreg8);
|
||||||
|
dump_region(8, frba);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_frba_layout(frba_t * frba, char *layout_fname)
|
static void dump_frba_layout(frba_t * frba, char *layout_fname)
|
||||||
|
@ -225,7 +292,7 @@ static void dump_frba_layout(frba_t * frba, char *layout_fname)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
for (i = 0; i < MAX_REGIONS; i++) {
|
||||||
dump_region_layout(buf, bufsize, i, frba);
|
dump_region_layout(buf, bufsize, i, frba);
|
||||||
if (write(layout_fd, buf, strlen(buf)) < 0) {
|
if (write(layout_fd, buf, strlen(buf)) < 0) {
|
||||||
perror("Could not write to file");
|
perror("Could not write to file");
|
||||||
|
@ -245,8 +312,21 @@ static void decode_spi_frequency(unsigned int freq)
|
||||||
case SPI_FREQUENCY_33MHZ:
|
case SPI_FREQUENCY_33MHZ:
|
||||||
printf("33MHz");
|
printf("33MHz");
|
||||||
break;
|
break;
|
||||||
case SPI_FREQUENCY_50MHZ:
|
case SPI_FREQUENCY_48MHZ:
|
||||||
printf("50MHz");
|
printf("48MHz");
|
||||||
|
break;
|
||||||
|
case SPI_FREQUENCY_50MHZ_30MHZ:
|
||||||
|
switch (ifd_version) {
|
||||||
|
case IFD_VERSION_1:
|
||||||
|
printf("50MHz");
|
||||||
|
break;
|
||||||
|
case IFD_VERSION_2:
|
||||||
|
printf("30MHz");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPI_FREQUENCY_17MHZ:
|
||||||
|
printf("17MHz");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown<%x>MHz", freq);
|
printf("unknown<%x>MHz", freq);
|
||||||
|
@ -274,6 +354,15 @@ static void decode_component_density(unsigned int density)
|
||||||
case COMPONENT_DENSITY_16MB:
|
case COMPONENT_DENSITY_16MB:
|
||||||
printf("16MB");
|
printf("16MB");
|
||||||
break;
|
break;
|
||||||
|
case COMPONENT_DENSITY_32MB:
|
||||||
|
printf("32MB");
|
||||||
|
break;
|
||||||
|
case COMPONENT_DENSITY_64MB:
|
||||||
|
printf("64MB");
|
||||||
|
break;
|
||||||
|
case COMPONENT_DENSITY_UNUSED:
|
||||||
|
printf("UNUSED");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown<%x>MB", density);
|
printf("unknown<%x>MB", density);
|
||||||
}
|
}
|
||||||
|
@ -295,10 +384,22 @@ static void dump_fcba(fcba_t * fcba)
|
||||||
(fcba->flcomp & (1 << 20))?"":"not ");
|
(fcba->flcomp & (1 << 20))?"":"not ");
|
||||||
printf("\n Read Clock Frequency: ");
|
printf("\n Read Clock Frequency: ");
|
||||||
decode_spi_frequency((fcba->flcomp >> 17) & 7);
|
decode_spi_frequency((fcba->flcomp >> 17) & 7);
|
||||||
printf("\n Component 2 Density: ");
|
|
||||||
decode_component_density((fcba->flcomp >> 3) & 7);
|
switch (ifd_version) {
|
||||||
printf("\n Component 1 Density: ");
|
case IFD_VERSION_1:
|
||||||
decode_component_density(fcba->flcomp & 7);
|
printf("\n Component 2 Density: ");
|
||||||
|
decode_component_density((fcba->flcomp >> 3) & 7);
|
||||||
|
printf("\n Component 1 Density: ");
|
||||||
|
decode_component_density(fcba->flcomp & 7);
|
||||||
|
break;
|
||||||
|
case IFD_VERSION_2:
|
||||||
|
printf("\n Component 2 Density: ");
|
||||||
|
decode_component_density((fcba->flcomp >> 4) & 0xf);
|
||||||
|
printf("\n Component 1 Density: ");
|
||||||
|
decode_component_density(fcba->flcomp & 0xf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("FLILL 0x%08x\n", fcba->flill);
|
printf("FLILL 0x%08x\n", fcba->flill);
|
||||||
printf(" Invalid Instruction 3: 0x%02x\n",
|
printf(" Invalid Instruction 3: 0x%02x\n",
|
||||||
|
@ -339,6 +440,9 @@ static void dump_fpsba(fpsba_t * fpsba)
|
||||||
|
|
||||||
static void decode_flmstr(uint32_t flmstr)
|
static void decode_flmstr(uint32_t flmstr)
|
||||||
{
|
{
|
||||||
|
if (ifd_version >= IFD_VERSION_2)
|
||||||
|
printf(" EC Region Write Access: %s\n",
|
||||||
|
(flmstr & (1 << 29)) ? "enabled" : "disabled");
|
||||||
printf(" Platform Data Region Write Access: %s\n",
|
printf(" Platform Data Region Write Access: %s\n",
|
||||||
(flmstr & (1 << 28)) ? "enabled" : "disabled");
|
(flmstr & (1 << 28)) ? "enabled" : "disabled");
|
||||||
printf(" GbE Region Write Access: %s\n",
|
printf(" GbE Region Write Access: %s\n",
|
||||||
|
@ -350,6 +454,9 @@ static void decode_flmstr(uint32_t flmstr)
|
||||||
printf(" Flash Descriptor Write Access: %s\n",
|
printf(" Flash Descriptor Write Access: %s\n",
|
||||||
(flmstr & (1 << 24)) ? "enabled" : "disabled");
|
(flmstr & (1 << 24)) ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
if (ifd_version >= IFD_VERSION_2)
|
||||||
|
printf(" EC Region Read Access: %s\n",
|
||||||
|
(flmstr & (1 << 21)) ? "enabled" : "disabled");
|
||||||
printf(" Platform Data Region Read Access: %s\n",
|
printf(" Platform Data Region Read Access: %s\n",
|
||||||
(flmstr & (1 << 20)) ? "enabled" : "disabled");
|
(flmstr & (1 << 20)) ? "enabled" : "disabled");
|
||||||
printf(" GbE Region Read Access: %s\n",
|
printf(" GbE Region Read Access: %s\n",
|
||||||
|
@ -374,6 +481,10 @@ static void dump_fmba(fmba_t * fmba)
|
||||||
decode_flmstr(fmba->flmstr2);
|
decode_flmstr(fmba->flmstr2);
|
||||||
printf("FLMSTR3: 0x%08x (GbE)\n", fmba->flmstr3);
|
printf("FLMSTR3: 0x%08x (GbE)\n", fmba->flmstr3);
|
||||||
decode_flmstr(fmba->flmstr3);
|
decode_flmstr(fmba->flmstr3);
|
||||||
|
if (ifd_version >= IFD_VERSION_2) {
|
||||||
|
printf("FLMSTR5: 0x%08x (EC)\n", fmba->flmstr5);
|
||||||
|
decode_flmstr(fmba->flmstr5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_fmsba(fmsba_t * fmsba)
|
static void dump_fmsba(fmsba_t * fmsba)
|
||||||
|
@ -528,6 +639,7 @@ static void dump_layout(char *image, int size, char *layout_fname)
|
||||||
static void write_regions(char *image, int size)
|
static void write_regions(char *image, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int max_regions = MAX_REGIONS;
|
||||||
|
|
||||||
fdbar_t *fdb = find_fd(image, size);
|
fdbar_t *fdb = find_fd(image, size);
|
||||||
if (!fdb)
|
if (!fdb)
|
||||||
|
@ -536,7 +648,11 @@ static void write_regions(char *image, int size)
|
||||||
frba_t *frba =
|
frba_t *frba =
|
||||||
(frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
(frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
||||||
|
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
/* Older descriptor images have fewer regions */
|
||||||
|
if (ifd_version < IFD_VERSION_2)
|
||||||
|
max_regions = MAX_REGIONS_OLD;
|
||||||
|
|
||||||
|
for (i = 0; i < max_regions; i++) {
|
||||||
region_t region = get_region(frba, i);
|
region_t region = get_region(frba, i);
|
||||||
dump_region(i, frba);
|
dump_region(i, frba);
|
||||||
if (region.size > 0) {
|
if (region.size > 0) {
|
||||||
|
@ -601,9 +717,19 @@ static void set_em100_mode(char *filename, char *image, int size)
|
||||||
{
|
{
|
||||||
fdbar_t *fdb = find_fd(image, size);
|
fdbar_t *fdb = find_fd(image, size);
|
||||||
fcba_t *fcba = (fcba_t *) (image + (((fdb->flmap0) & 0xff) << 4));
|
fcba_t *fcba = (fcba_t *) (image + (((fdb->flmap0) & 0xff) << 4));
|
||||||
|
int freq;
|
||||||
|
|
||||||
|
switch (ifd_version) {
|
||||||
|
case IFD_VERSION_1:
|
||||||
|
freq = SPI_FREQUENCY_20MHZ;
|
||||||
|
break;
|
||||||
|
case IFD_VERSION_2:
|
||||||
|
freq = SPI_FREQUENCY_17MHZ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
fcba->flcomp &= ~(1 << 30);
|
fcba->flcomp &= ~(1 << 30);
|
||||||
set_spi_frequency(filename, image, size, SPI_FREQUENCY_20MHZ);
|
set_spi_frequency(filename, image, size, freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lock_descriptor(char *filename, char *image, int size)
|
static void lock_descriptor(char *filename, char *image, int size)
|
||||||
|
@ -736,8 +862,8 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
char layout_region_name[256];
|
char layout_region_name[256];
|
||||||
int i, j;
|
int i, j;
|
||||||
int region_number;
|
int region_number;
|
||||||
region_t current_regions[NUM_REGIONS];
|
region_t current_regions[MAX_REGIONS];
|
||||||
region_t new_regions[NUM_REGIONS];
|
region_t new_regions[MAX_REGIONS];
|
||||||
int new_extent = 0;
|
int new_extent = 0;
|
||||||
char *new_image;
|
char *new_image;
|
||||||
|
|
||||||
|
@ -749,7 +875,7 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
frba_t *frba =
|
frba_t *frba =
|
||||||
(frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
(frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
||||||
|
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
for (i = 0; i < MAX_REGIONS; i++) {
|
||||||
current_regions[i] = get_region(frba, i);
|
current_regions[i] = get_region(frba, i);
|
||||||
new_regions[i] = get_region(frba, i);
|
new_regions[i] = get_region(frba, i);
|
||||||
}
|
}
|
||||||
|
@ -793,7 +919,7 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
fclose(romlayout);
|
fclose(romlayout);
|
||||||
|
|
||||||
/* check new layout */
|
/* check new layout */
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
for (i = 0; i < MAX_REGIONS; i++) {
|
||||||
if (new_regions[i].size == 0)
|
if (new_regions[i].size == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -804,7 +930,7 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
printf(" This may result in an unusable image.\n");
|
printf(" This may result in an unusable image.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = i + 1; j < NUM_REGIONS; j++) {
|
for (j = i + 1; j < MAX_REGIONS; j++) {
|
||||||
if (regions_collide(new_regions[i], new_regions[j])) {
|
if (regions_collide(new_regions[i], new_regions[j])) {
|
||||||
fprintf(stderr, "Regions would overlap.\n");
|
fprintf(stderr, "Regions would overlap.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -826,7 +952,7 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
/* copy regions to a new image */
|
/* copy regions to a new image */
|
||||||
new_image = malloc(new_extent);
|
new_image = malloc(new_extent);
|
||||||
memset(new_image, 0xff, new_extent);
|
memset(new_image, 0xff, new_extent);
|
||||||
for (i = 0; i < NUM_REGIONS; i++) {
|
for (i = 0; i < MAX_REGIONS; i++) {
|
||||||
int copy_size = new_regions[i].size;
|
int copy_size = new_regions[i].size;
|
||||||
int offset_current = 0, offset_new = 0;
|
int offset_current = 0, offset_new = 0;
|
||||||
region_t current = current_regions[i];
|
region_t current = current_regions[i];
|
||||||
|
@ -864,7 +990,7 @@ void new_layout(char *filename, char *image, int size, char *layout_fname)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
frba = (frba_t *) (new_image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
frba = (frba_t *) (new_image + (((fdb->flmap0 >> 16) & 0xff) << 4));
|
||||||
for (i = 1; i < NUM_REGIONS; i++) {
|
for (i = 1; i < MAX_REGIONS; i++) {
|
||||||
set_region(frba, i, new_regions[i]);
|
set_region(frba, i, new_regions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,18 +1018,18 @@ static void print_usage(const char *name)
|
||||||
{
|
{
|
||||||
printf("usage: %s [-vhdix?] <filename>\n", name);
|
printf("usage: %s [-vhdix?] <filename>\n", name);
|
||||||
printf("\n"
|
printf("\n"
|
||||||
" -d | --dump: dump intel firmware descriptor\n"
|
" -d | --dump: dump intel firmware descriptor\n"
|
||||||
" -f | --layout <filename> dump regions into a flashrom layout file\n"
|
" -f | --layout <filename> dump regions into a flashrom layout file\n"
|
||||||
" -x | --extract: extract intel fd modules\n"
|
" -x | --extract: extract intel fd modules\n"
|
||||||
" -i | --inject <region>:<module> inject file <module> into region <region>\n"
|
" -i | --inject <region>:<module> inject file <module> into region <region>\n"
|
||||||
" -n | --newlayout <filename> update regions using a flashrom layout file\n"
|
" -n | --newlayout <filename> update regions using a flashrom layout file\n"
|
||||||
" -s | --spifreq <20|33|50> set the SPI frequency\n"
|
" -s | --spifreq <17|20|30|33|48|50> set the SPI frequency\n"
|
||||||
" -e | --em100 set SPI frequency to 20MHz and disable\n"
|
" -e | --em100 set SPI frequency to 20MHz and disable\n"
|
||||||
" Dual Output Fast Read Support\n"
|
" Dual Output Fast Read Support\n"
|
||||||
" -l | --lock Lock firmware descriptor and ME region\n"
|
" -l | --lock Lock firmware descriptor and ME region\n"
|
||||||
" -u | --unlock Unlock firmware descriptor and ME region\n"
|
" -u | --unlock Unlock firmware descriptor and ME region\n"
|
||||||
" -v | --version: print the version\n"
|
" -v | --version: print the version\n"
|
||||||
" -h | --help: print this help\n\n"
|
" -h | --help: print this help\n\n"
|
||||||
"<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
|
"<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
@ -973,6 +1099,8 @@ int main(int argc, char *argv[])
|
||||||
region_type = 3;
|
region_type = 3;
|
||||||
else if (!strcasecmp("Platform", region_type_string))
|
else if (!strcasecmp("Platform", region_type_string))
|
||||||
region_type = 4;
|
region_type = 4;
|
||||||
|
else if (!strcasecmp("EC", region_type_string))
|
||||||
|
region_type = 8;
|
||||||
if (region_type == -1) {
|
if (region_type == -1) {
|
||||||
fprintf(stderr, "No such region type: '%s'\n\n",
|
fprintf(stderr, "No such region type: '%s'\n\n",
|
||||||
region_type_string);
|
region_type_string);
|
||||||
|
@ -994,14 +1122,23 @@ int main(int argc, char *argv[])
|
||||||
// Parse the requested SPI frequency
|
// Parse the requested SPI frequency
|
||||||
inputfreq = strtol(optarg, NULL, 0);
|
inputfreq = strtol(optarg, NULL, 0);
|
||||||
switch (inputfreq) {
|
switch (inputfreq) {
|
||||||
|
case 17:
|
||||||
|
spifreq = SPI_FREQUENCY_17MHZ;
|
||||||
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
spifreq = SPI_FREQUENCY_20MHZ;
|
spifreq = SPI_FREQUENCY_20MHZ;
|
||||||
break;
|
break;
|
||||||
|
case 30:
|
||||||
|
spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
|
||||||
|
break;
|
||||||
case 33:
|
case 33:
|
||||||
spifreq = SPI_FREQUENCY_33MHZ;
|
spifreq = SPI_FREQUENCY_33MHZ;
|
||||||
break;
|
break;
|
||||||
|
case 48:
|
||||||
|
spifreq = SPI_FREQUENCY_48MHZ;
|
||||||
|
break;
|
||||||
case 50:
|
case 50:
|
||||||
spifreq = SPI_FREQUENCY_50MHZ;
|
spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Invalid SPI Frequency: %d\n",
|
fprintf(stderr, "Invalid SPI Frequency: %d\n",
|
||||||
|
@ -1091,6 +1228,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
close(bios_fd);
|
close(bios_fd);
|
||||||
|
|
||||||
|
check_ifd_version(image, size);
|
||||||
|
|
||||||
if (mode_dump)
|
if (mode_dump)
|
||||||
dump_fd(image, size);
|
dump_fd(image, size);
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define IFDTOOL_VERSION "1.1"
|
#define IFDTOOL_VERSION "1.2"
|
||||||
|
|
||||||
|
enum ifd_version {
|
||||||
|
IFD_VERSION_1,
|
||||||
|
IFD_VERSION_2,
|
||||||
|
};
|
||||||
|
|
||||||
#define LAYOUT_LINELEN 80
|
#define LAYOUT_LINELEN 80
|
||||||
|
|
||||||
enum spi_frequency {
|
enum spi_frequency {
|
||||||
SPI_FREQUENCY_20MHZ = 0,
|
SPI_FREQUENCY_20MHZ = 0,
|
||||||
SPI_FREQUENCY_33MHZ = 1,
|
SPI_FREQUENCY_33MHZ = 1,
|
||||||
SPI_FREQUENCY_50MHZ = 4,
|
SPI_FREQUENCY_48MHZ = 2,
|
||||||
|
SPI_FREQUENCY_50MHZ_30MHZ = 4,
|
||||||
|
SPI_FREQUENCY_17MHZ = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum component_density {
|
enum component_density {
|
||||||
|
@ -35,6 +42,9 @@ enum component_density {
|
||||||
COMPONENT_DENSITY_4MB = 3,
|
COMPONENT_DENSITY_4MB = 3,
|
||||||
COMPONENT_DENSITY_8MB = 4,
|
COMPONENT_DENSITY_8MB = 4,
|
||||||
COMPONENT_DENSITY_16MB = 5,
|
COMPONENT_DENSITY_16MB = 5,
|
||||||
|
COMPONENT_DENSITY_32MB = 6,
|
||||||
|
COMPONENT_DENSITY_64MB = 7,
|
||||||
|
COMPONENT_DENSITY_UNUSED = 0xf
|
||||||
};
|
};
|
||||||
|
|
||||||
// flash descriptor
|
// flash descriptor
|
||||||
|
@ -48,12 +58,18 @@ typedef struct {
|
||||||
} __attribute__((packed)) fdbar_t;
|
} __attribute__((packed)) fdbar_t;
|
||||||
|
|
||||||
// regions
|
// regions
|
||||||
|
#define MAX_REGIONS 9
|
||||||
|
#define MAX_REGIONS_OLD 5
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t flreg0;
|
uint32_t flreg0;
|
||||||
uint32_t flreg1;
|
uint32_t flreg1;
|
||||||
uint32_t flreg2;
|
uint32_t flreg2;
|
||||||
uint32_t flreg3;
|
uint32_t flreg3;
|
||||||
uint32_t flreg4;
|
uint32_t flreg4;
|
||||||
|
uint32_t flreg5;
|
||||||
|
uint32_t flreg6;
|
||||||
|
uint32_t flreg7;
|
||||||
|
uint32_t flreg8;
|
||||||
} __attribute__((packed)) frba_t;
|
} __attribute__((packed)) frba_t;
|
||||||
|
|
||||||
// component section
|
// component section
|
||||||
|
@ -90,6 +106,8 @@ typedef struct {
|
||||||
uint32_t flmstr1;
|
uint32_t flmstr1;
|
||||||
uint32_t flmstr2;
|
uint32_t flmstr2;
|
||||||
uint32_t flmstr3;
|
uint32_t flmstr3;
|
||||||
|
uint32_t flmstr4;
|
||||||
|
uint32_t flmstr5;
|
||||||
} __attribute__((packed)) fmba_t;
|
} __attribute__((packed)) fmba_t;
|
||||||
|
|
||||||
// processor strap
|
// processor strap
|
||||||
|
|
Loading…
Reference in New Issue