From 7bdb5bcddb0db589f9246ff74ffbab9b35796fae Mon Sep 17 00:00:00 2001 From: xSmurf Date: Wed, 23 Sep 2015 19:20:25 +0000 Subject: [PATCH] Added flashrom ifd patch --- .../patches/flashrom/02-read-ifd.patch | 381 ++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 board/coreboot/patches/flashrom/02-read-ifd.patch diff --git a/board/coreboot/patches/flashrom/02-read-ifd.patch b/board/coreboot/patches/flashrom/02-read-ifd.patch new file mode 100644 index 0000000..abec232 --- /dev/null +++ b/board/coreboot/patches/flashrom/02-read-ifd.patch @@ -0,0 +1,381 @@ +diff --git a/Makefile b/Makefile +index 805290c..5e77a48 100644 +--- a/Makefile ++++ b/Makefile +@@ -306,7 +306,7 @@ CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \ + ############################################################################### + # Library code. + +-LIB_OBJS = layout.o flashrom.o udelay.o programmer.o ++LIB_OBJS = layout.o ifd.o flashrom.o udelay.o programmer.o + + ############################################################################### + # Frontend related stuff. +diff --git a/cli_classic.c b/cli_classic.c +index 14fb825..b3cc826 100644 +--- a/cli_classic.c ++++ b/cli_classic.c +@@ -41,7 +41,7 @@ static void cli_classic_usage(const char *name) + "-z|" + #endif + "-p [:] [-c ]\n" +- "[-E|(-r|-w|-v) ] [-l [-i ]...] [-n] [-f]]\n" ++ "[-E|(-r|-w|-v) ] [(-l |-d) [-i ]...] [-n] [-f]]\n" + "[-V[V[V]]] [-o ]\n\n", name); + + printf(" -h | --help print this help text\n" +@@ -55,6 +55,7 @@ static void cli_classic_usage(const char *name) + " -f | --force force specific operations (see man page)\n" + " -n | --noverify don't auto-verify\n" + " -l | --layout read ROM layout from \n" ++ " -d | --ifd read layout from an Intel Firmware Descriptor\n" + " -i | --image only flash image from flash layout\n" + " -o | --output log output to \n" + " -L | --list-supported print supported devices\n" +@@ -98,7 +99,7 @@ int main(int argc, char *argv[]) + struct flashctx *fill_flash; + const char *name; + int namelen, opt, i, j; +- int startchip = -1, chipcount = 0, option_index = 0, force = 0; ++ int startchip = -1, chipcount = 0, option_index = 0, force = 0, ifd = 0; + #if CONFIG_PRINT_WIKI == 1 + int list_supported_wiki = 0; + #endif +@@ -107,7 +108,7 @@ int main(int argc, char *argv[]) + enum programmer prog = PROGRAMMER_INVALID; + int ret = 0; + +- static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:"; ++ static const char optstring[] = "r:Rw:v:nVEfc:l:di:p:Lzho:"; + static const struct option long_options[] = { + {"read", 1, NULL, 'r'}, + {"write", 1, NULL, 'w'}, +@@ -118,6 +119,7 @@ int main(int argc, char *argv[]) + {"verbose", 0, NULL, 'V'}, + {"force", 0, NULL, 'f'}, + {"layout", 1, NULL, 'l'}, ++ {"ifd", 0, NULL, 'd'}, + {"image", 1, NULL, 'i'}, + {"list-supported", 0, NULL, 'L'}, + {"list-supported-wiki", 0, NULL, 'z'}, +@@ -215,8 +217,20 @@ int main(int argc, char *argv[]) + "more than once. Aborting.\n"); + cli_classic_abort_usage(); + } ++ if (ifd) { ++ fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n"); ++ cli_classic_abort_usage(); ++ } + layoutfile = strdup(optarg); + break; ++ case 'd': ++ if (layoutfile) { ++ fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n"); ++ cli_classic_abort_usage(); ++ } ++ layout_use_ifd(); ++ ifd = 1; ++ break; + case 'i': + tempstr = strdup(optarg); + if (register_include_arg(tempstr)) { +@@ -374,7 +388,7 @@ int main(int argc, char *argv[]) + ret = 1; + goto out; + } +- if (process_include_args()) { ++ if (!ifd && process_include_args()) { + ret = 1; + goto out; + } +diff --git a/flash.h b/flash.h +index 1857cc0..36b1e0d 100644 +--- a/flash.h ++++ b/flash.h +@@ -306,11 +306,21 @@ int print(enum msglevel level, const char *fmt, ...) __attribute__((format(print + #define msg_cspew(...) print(MSG_SPEW, __VA_ARGS__) /* chip debug spew */ + + /* layout.c */ ++typedef struct { ++ unsigned int start; ++ unsigned int end; ++ unsigned int included; ++ char name[256]; ++} romlayout_t; ++void layout_use_ifd(void); + int register_include_arg(char *name); + int process_include_args(void); + int read_romlayout(char *name); + int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents); + ++/* ifd.c */ ++int ifd_read_romlayout(const uint8_t *oldcontents, const uint8_t *newcontents, unsigned flash_size, romlayout_t *entries, int *n_entries); ++ + /* spi.c */ + struct spi_command { + unsigned int writecnt; +diff --git a/flashrom.8 b/flashrom.8 +index 4e6ab55..82afb10 100644 +--- a/flashrom.8 ++++ b/flashrom.8 +@@ -6,7 +6,7 @@ flashrom \- detect, read, write, verify and erase flash chips + \fB\-p\fR [:] + [\fB\-E\fR|\fB\-r\fR |\fB\-w\fR |\fB\-v\fR ] \ + [\fB\-c\fR ] +- [\fB\-l\fR [\fB\-i\fR ]] [\fB\-n\fR] [\fB\-f\fR]] ++ [(\fB\-l\fR |\fB\-d\fR) [\fB\-i\fR ]] [\fB\-n\fR] [\fB\-f\fR]] + [\fB\-V\fR[\fBV\fR[\fBV\fR]]] [\fB-o\fR ] + .SH DESCRIPTION + .B flashrom +@@ -137,6 +137,22 @@ To update only the images named + .sp + Overlapping sections are not supported. + .TP ++.B "\-d, \-\-ifd" ++Read ROM layout from Intel Firmware Descriptor. ++.sp ++flashrom supports ROM layouts given by an Intel Firmware Descriptor ++(IFD). Both, the current flash ROM chips contents and the file's ++contents which are to be flashed, must contain an IFD with the same ROM ++regions. ++.sp ++The following ROM images may be present in an IFD: ++.sp ++ Flash_Descriptor the IFD itself ++ BIOS the host firmware aka. BIOS ++ Intel_ME Intel Management Engine firmware ++ GbE Gigabit Ethernet firmware ++ Platform_Data platform specific data ++.TP + .B "\-i, \-\-image " + Only flash region/image + .B +diff --git a/flashrom.c b/flashrom.c +index c11f723..bf690dc 100644 +--- a/flashrom.c ++++ b/flashrom.c +@@ -1958,7 +1958,10 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, + + // This should be moved into each flash part's code to do it + // cleanly. This does the job. +- handle_romentries(flash, oldcontents, newcontents); ++ if (handle_romentries(flash, oldcontents, newcontents)) { ++ ret = 1; ++ goto out; ++ } + + // //////////////////////////////////////////////////////////// + +diff --git a/ifd.c b/ifd.c +new file mode 100644 +index 0000000..fd31f4f +--- /dev/null ++++ b/ifd.c +@@ -0,0 +1,155 @@ ++/* ++ * This file is part of the flashrom project. ++ * ++ * Copyright (C) 2013 secunet Security Networks AG ++ * ++ * ifd reading code borrowed from coreboot's ifdtool: ++ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include ++#include ++#include "flash.h" ++ ++/* flash descriptor */ ++typedef struct { ++ uint32_t flvalsig; ++ uint32_t flmap0; ++ uint32_t flmap1; ++ uint32_t flmap2; ++ uint8_t reserved[0xefc - 0x20]; ++ uint32_t flumap1; ++} __attribute__((packed)) fdbar_t; ++ ++/* regions */ ++typedef struct { ++ uint32_t flreg0; ++ uint32_t flreg1; ++ uint32_t flreg2; ++ uint32_t flreg3; ++ uint32_t flreg4; ++} __attribute__((packed)) frba_t; ++ ++typedef struct { ++ int base, limit, size; ++} region_t; ++ ++static fdbar_t *find_fd(const uint8_t *image, int size) ++{ ++ int i, found = 0; ++ ++ /* Scan for FD signature */ ++ for (i = 0; i <= (size - sizeof(fdbar_t)); i += 4) { ++ if (*(uint32_t *) (image + i) == 0x0FF0A55A) { ++ found = 1; ++ break; // signature found. ++ } ++ } ++ ++ if (!found) ++ return NULL; ++ ++ msg_ginfo("Found Flash Descriptor signature at 0x%08x\n", i); ++ ++ return (fdbar_t *) (image + i); ++} ++ ++static region_t get_region(const frba_t *frba, int region_type) ++{ ++ region_t region; ++ region.base = 0, region.limit = 0, region.size = 0; ++ ++ switch (region_type) { ++ case 0: ++ region.base = (frba->flreg0 & 0x00000fff) << 12; ++ region.limit = ((frba->flreg0 & 0x0fff0000) >> 4) | 0xfff; ++ break; ++ case 1: ++ region.base = (frba->flreg1 & 0x00000fff) << 12; ++ region.limit = ((frba->flreg1 & 0x0fff0000) >> 4) | 0xfff; ++ break; ++ case 2: ++ region.base = (frba->flreg2 & 0x00000fff) << 12; ++ region.limit = ((frba->flreg2 & 0x0fff0000) >> 4) | 0xfff; ++ break; ++ case 3: ++ region.base = (frba->flreg3 & 0x00000fff) << 12; ++ region.limit = ((frba->flreg3 & 0x0fff0000) >> 4) | 0xfff; ++ break; ++ case 4: ++ region.base = (frba->flreg4 & 0x00000fff) << 12; ++ region.limit = ((frba->flreg4 & 0x0fff0000) >> 4) | 0xfff; ++ break; ++ default: ++ break; ++ } ++ ++ region.size = region.limit - region.base + 1; ++ ++ return region; ++} ++ ++int ifd_read_romlayout(const uint8_t *const oldcontents, const uint8_t *const newcontents, ++ const unsigned flash_size, romlayout_t *const entries, int *const n_entries) ++{ ++ static const char *regions[5] = { ++ "Flash_Descriptor", ++ "BIOS", ++ "Intel_ME", ++ "GbE", ++ "Platform_Data" ++ }; ++ ++ const int max_entries = *n_entries; ++ *n_entries = 0; ++ ++ const fdbar_t *const fdb_old = find_fd(oldcontents, flash_size); ++ if (!fdb_old) { ++ msg_gerr("No IFD found in old flash contents.\n"); ++ return 1; ++ } ++ const fdbar_t *const fdb_new = find_fd(newcontents, flash_size); ++ if (!fdb_old) { ++ msg_gerr("No IFD found in new flash contents.\n"); ++ return 1; ++ } ++ ++ const frba_t *const fr_old = (frba_t *)(oldcontents + (((fdb_old->flmap0 >> 16) & 0xff) << 4)); ++ const frba_t *const fr_new = (frba_t *)(newcontents + (((fdb_new->flmap0 >> 16) & 0xff) << 4)); ++ int i; ++ for (i = 0; i < 5; ++i) { ++ const region_t reg_old = get_region(fr_old, i); ++ const region_t reg_new = get_region(fr_new, i); ++ if (reg_old.base != reg_new.base || reg_old.limit != reg_new.limit) { ++ msg_gerr("Image '%s' doesn't match in old and new IFD, won't flash.\n", regions[i]); ++ return 1; ++ } ++ if (reg_old.size <= 0) ++ continue; ++ ++ if (*n_entries >= max_entries) { ++ msg_gerr("Maximum number of ROM images (%i) in layout reached.\n", max_entries); ++ return 1; ++ } ++ entries[*n_entries].start = reg_old.base; ++ entries[*n_entries].end = reg_old.limit; ++ snprintf(entries[*n_entries].name, sizeof(entries[*n_entries].name), "%s", regions[i]); ++ msg_ginfo("Found flash region [%08x:%08x] %s\n", ++ entries[*n_entries].start, entries[*n_entries].end, entries[*n_entries].name); ++ ++*n_entries; ++ } ++ return 0; ++} +diff --git a/layout.c b/layout.c +index 1bd3152..81058f3 100644 +--- a/layout.c ++++ b/layout.c +@@ -26,16 +26,10 @@ + #include "programmer.h" + + static int romimages = 0; ++static int use_ifd = 0; + + #define MAX_ROMLAYOUT 32 + +-typedef struct { +- unsigned int start; +- unsigned int end; +- unsigned int included; +- char name[256]; +-} romlayout_t; +- + /* include_args lists arguments specified at the command line with -i. They + * must be processed at some point so that desired regions are marked as + * "included" in the rom_entries list. +@@ -44,6 +38,11 @@ static char *include_args[MAX_ROMLAYOUT]; + static int num_include_args = 0; /* the number of valid entries. */ + static romlayout_t rom_entries[MAX_ROMLAYOUT]; + ++void layout_use_ifd(void) ++{ ++ use_ifd = 1; ++} ++ + #ifndef __LIBPAYLOAD__ + int read_romlayout(char *name) + { +@@ -223,6 +222,16 @@ int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_ + romlayout_t *entry; + unsigned int size = flash->chip->total_size * 1024; + ++ if (use_ifd) { ++ romimages = MAX_ROMLAYOUT; ++ if (ifd_read_romlayout(oldcontents, newcontents, size, rom_entries, &romimages)) ++ return 1; ++ /* Call process_include_args() late, as we only ++ just got to know the names of available images. */ ++ if (process_include_args()) ++ return 1; ++ } ++ + /* If no regions were specified for inclusion, assume + * that the user wants to write the complete new image. + */ +--