mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-28 07:23:43 +02:00
Add option to read ROM layout from IFD
Add an option --ifd to read the ROM layout from an Intel Firmware Descriptor (IFD). Works the same as the -l option, if given, -i specifies the images to update. v2: o Rebased on libflashrom, use libflashrom interface. o Use functions from ich_descriptors.c. v3: o Move ich_descriptors.o to LIB_OBJS, thus build it independent of arch and programmers. o Bail out if we aren't compiled for little endian. o Update flashrom.8.tmpl. v4: o Incorporated David's comments. o Removed single-character `-d` option. v5: Changed region names to match the output of `ifdtool --layout ...` Change-Id: Ifafff2bf6d5c5e62283416b3269723f81fdc0fa3 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/17953 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
ad18631b59
commit
305f417ea5
4
Makefile
4
Makefile
@ -519,7 +519,7 @@ CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# Library code.
|
# Library code.
|
||||||
|
|
||||||
LIB_OBJS = libflashrom.o layout.o flashrom.o udelay.o programmer.o helpers.o
|
LIB_OBJS = libflashrom.o layout.o flashrom.o udelay.o programmer.o helpers.o ich_descriptors.o
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Frontend related stuff.
|
# Frontend related stuff.
|
||||||
@ -731,7 +731,7 @@ FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1'
|
|||||||
PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o internal.o
|
PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o internal.o
|
||||||
ifeq ($(ARCH), x86)
|
ifeq ($(ARCH), x86)
|
||||||
PROGRAMMER_OBJS += it87spi.o it85spi.o sb600spi.o amd_imc.o wbsio_spi.o mcp6x_spi.o
|
PROGRAMMER_OBJS += it87spi.o it85spi.o sb600spi.o amd_imc.o wbsio_spi.o mcp6x_spi.o
|
||||||
PROGRAMMER_OBJS += ichspi.o ich_descriptors.o dmi.o
|
PROGRAMMER_OBJS += ichspi.o dmi.o
|
||||||
ifeq ($(CONFIG_INTERNAL_DMI), yes)
|
ifeq ($(CONFIG_INTERNAL_DMI), yes)
|
||||||
FEATURE_CFLAGS += -D'CONFIG_INTERNAL_DMI=1'
|
FEATURE_CFLAGS += -D'CONFIG_INTERNAL_DMI=1'
|
||||||
endif
|
endif
|
||||||
|
@ -42,7 +42,7 @@ static void cli_classic_usage(const char *name)
|
|||||||
"-z|"
|
"-z|"
|
||||||
#endif
|
#endif
|
||||||
"-p <programmername>[:<parameters>] [-c <chipname>]\n"
|
"-p <programmername>[:<parameters>] [-c <chipname>]\n"
|
||||||
"[-E|(-r|-w|-v) <file>] [-l <layoutfile> [-i <imagename>]...] [-n] [-N] [-f]]\n"
|
"[-E|(-r|-w|-v) <file>] [(-l <layoutfile>|--ifd) [-i <imagename>]...] [-n] [-N] [-f]]\n"
|
||||||
"[-V[V[V]]] [-o <logfile>]\n\n", name);
|
"[-V[V[V]]] [-o <logfile>]\n\n", name);
|
||||||
|
|
||||||
printf(" -h | --help print this help text\n"
|
printf(" -h | --help print this help text\n"
|
||||||
@ -57,6 +57,7 @@ static void cli_classic_usage(const char *name)
|
|||||||
" -n | --noverify don't auto-verify\n"
|
" -n | --noverify don't auto-verify\n"
|
||||||
" -N | --noverify-all verify included regions only (cf. -i)\n"
|
" -N | --noverify-all verify included regions only (cf. -i)\n"
|
||||||
" -l | --layout <layoutfile> read ROM layout from <layoutfile>\n"
|
" -l | --layout <layoutfile> read ROM layout from <layoutfile>\n"
|
||||||
|
" --ifd read layout from an Intel Firmware Descriptor\n"
|
||||||
" -i | --image <name> only flash image <name> from flash layout\n"
|
" -i | --image <name> only flash image <name> from flash layout\n"
|
||||||
" -o | --output <logfile> log output to <logfile>\n"
|
" -o | --output <logfile> log output to <logfile>\n"
|
||||||
" -L | --list-supported print supported devices\n"
|
" -L | --list-supported print supported devices\n"
|
||||||
@ -99,12 +100,13 @@ int main(int argc, char *argv[])
|
|||||||
struct flashctx *fill_flash;
|
struct flashctx *fill_flash;
|
||||||
const char *name;
|
const char *name;
|
||||||
int namelen, opt, i, j;
|
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
|
#if CONFIG_PRINT_WIKI == 1
|
||||||
int list_supported_wiki = 0;
|
int list_supported_wiki = 0;
|
||||||
#endif
|
#endif
|
||||||
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
|
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
|
||||||
int dont_verify_it = 0, dont_verify_all = 0, list_supported = 0, operation_specified = 0;
|
int dont_verify_it = 0, dont_verify_all = 0, list_supported = 0, operation_specified = 0;
|
||||||
|
struct flashrom_layout *layout = NULL;
|
||||||
enum programmer prog = PROGRAMMER_INVALID;
|
enum programmer prog = PROGRAMMER_INVALID;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -120,6 +122,7 @@ int main(int argc, char *argv[])
|
|||||||
{"verbose", 0, NULL, 'V'},
|
{"verbose", 0, NULL, 'V'},
|
||||||
{"force", 0, NULL, 'f'},
|
{"force", 0, NULL, 'f'},
|
||||||
{"layout", 1, NULL, 'l'},
|
{"layout", 1, NULL, 'l'},
|
||||||
|
{"ifd", 0, NULL, 0x0100},
|
||||||
{"image", 1, NULL, 'i'},
|
{"image", 1, NULL, 'i'},
|
||||||
{"list-supported", 0, NULL, 'L'},
|
{"list-supported", 0, NULL, 'L'},
|
||||||
{"list-supported-wiki", 0, NULL, 'z'},
|
{"list-supported-wiki", 0, NULL, 'z'},
|
||||||
@ -220,8 +223,19 @@ int main(int argc, char *argv[])
|
|||||||
"more than once. Aborting.\n");
|
"more than once. Aborting.\n");
|
||||||
cli_classic_abort_usage();
|
cli_classic_abort_usage();
|
||||||
}
|
}
|
||||||
|
if (ifd) {
|
||||||
|
fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n");
|
||||||
|
cli_classic_abort_usage();
|
||||||
|
}
|
||||||
layoutfile = strdup(optarg);
|
layoutfile = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 0x0100:
|
||||||
|
if (layoutfile) {
|
||||||
|
fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n");
|
||||||
|
cli_classic_abort_usage();
|
||||||
|
}
|
||||||
|
ifd = 1;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
tempstr = strdup(optarg);
|
tempstr = strdup(optarg);
|
||||||
if (register_include_arg(tempstr)) {
|
if (register_include_arg(tempstr)) {
|
||||||
@ -376,7 +390,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (process_include_args()) {
|
if (!ifd && process_include_args(get_global_layout())) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -529,9 +543,15 @@ int main(int argc, char *argv[])
|
|||||||
goto out_shutdown;
|
goto out_shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layoutfile)
|
if (layoutfile) {
|
||||||
flashrom_layout_set(fill_flash, get_global_layout());
|
layout = get_global_layout();
|
||||||
|
} else if (ifd && (flashrom_layout_read_from_ifd(&layout, fill_flash, NULL, 0) ||
|
||||||
|
process_include_args(layout))) {
|
||||||
|
ret = 1;
|
||||||
|
goto out_shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
flashrom_layout_set(fill_flash, layout);
|
||||||
flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE, !!force);
|
flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE, !!force);
|
||||||
flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE_BOARDMISMATCH, !!force_boardmismatch);
|
flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE_BOARDMISMATCH, !!force_boardmismatch);
|
||||||
flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_AFTER_WRITE, !dont_verify_it);
|
flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_AFTER_WRITE, !dont_verify_it);
|
||||||
@ -551,6 +571,8 @@ int main(int argc, char *argv[])
|
|||||||
else if (verify_it)
|
else if (verify_it)
|
||||||
ret = do_verify(fill_flash, filename);
|
ret = do_verify(fill_flash, filename);
|
||||||
|
|
||||||
|
flashrom_layout_release(layout);
|
||||||
|
|
||||||
out_shutdown:
|
out_shutdown:
|
||||||
programmer_shutdown();
|
programmer_shutdown();
|
||||||
out:
|
out:
|
||||||
|
3
flash.h
3
flash.h
@ -287,6 +287,8 @@ void list_programmers_linebreak(int startcol, int cols, int paren);
|
|||||||
int selfcheck(void);
|
int selfcheck(void);
|
||||||
int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename);
|
int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename);
|
||||||
int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename);
|
int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename);
|
||||||
|
int prepare_flash_access(struct flashctx *, bool read_it, bool write_it, bool erase_it, bool verify_it);
|
||||||
|
void finalize_flash_access(struct flashctx *);
|
||||||
int do_read(struct flashctx *, const char *filename);
|
int do_read(struct flashctx *, const char *filename);
|
||||||
int do_erase(struct flashctx *);
|
int do_erase(struct flashctx *);
|
||||||
int do_write(struct flashctx *, const char *const filename);
|
int do_write(struct flashctx *, const char *const filename);
|
||||||
@ -354,7 +356,6 @@ __attribute__((format(printf, 2, 3)));
|
|||||||
|
|
||||||
/* layout.c */
|
/* layout.c */
|
||||||
int register_include_arg(char *name);
|
int register_include_arg(char *name);
|
||||||
int process_include_args(void);
|
|
||||||
int read_romlayout(const char *name);
|
int read_romlayout(const char *name);
|
||||||
int normalize_romentries(const struct flashctx *flash);
|
int normalize_romentries(const struct flashctx *flash);
|
||||||
void layout_cleanup(void);
|
void layout_cleanup(void);
|
||||||
|
@ -48,8 +48,8 @@ flashrom \- detect, read, write, verify and erase flash chips
|
|||||||
\fB\-p\fR <programmername>[:<parameters>]
|
\fB\-p\fR <programmername>[:<parameters>]
|
||||||
[\fB\-E\fR|\fB\-r\fR <file>|\fB\-w\fR <file>|\fB\-v\fR <file>] \
|
[\fB\-E\fR|\fB\-r\fR <file>|\fB\-w\fR <file>|\fB\-v\fR <file>] \
|
||||||
[\fB\-c\fR <chipname>]
|
[\fB\-c\fR <chipname>]
|
||||||
[\fB\-l\fR <file> [\fB\-i\fR <image>]] [\fB\-n\fR] [\fB\-N\fR] \
|
[(\fB\-l\fR <file>|\fB\-\-ifd\fR) [\fB\-i\fR <image>]] \
|
||||||
[\fB\-f\fR]]
|
[\fB\-n\fR] [\fB\-N\fR] [\fB\-f\fR]]
|
||||||
[\fB\-V\fR[\fBV\fR[\fBV\fR]]] [\fB-o\fR <logfile>]
|
[\fB\-V\fR[\fBV\fR[\fBV\fR]]] [\fB-o\fR <logfile>]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B flashrom
|
.B flashrom
|
||||||
@ -195,6 +195,22 @@ To update only the images named
|
|||||||
.sp
|
.sp
|
||||||
Overlapping sections are not supported.
|
Overlapping sections are not supported.
|
||||||
.TP
|
.TP
|
||||||
|
.B "\-\-ifd"
|
||||||
|
Read ROM layout from Intel Firmware Descriptor.
|
||||||
|
.sp
|
||||||
|
flashrom supports ROM layouts given by an Intel Firmware Descriptor
|
||||||
|
(IFD). The on-chip descriptor will be read and used to generate the
|
||||||
|
layout. If you need to change the layout, you have to update the IFD
|
||||||
|
only first.
|
||||||
|
.sp
|
||||||
|
The following ROM images may be present in an IFD:
|
||||||
|
.sp
|
||||||
|
fd the IFD itself
|
||||||
|
bios the host firmware aka. BIOS
|
||||||
|
me Intel Management Engine firmware
|
||||||
|
gbe gigabit ethernet firmware
|
||||||
|
pd platform specific data
|
||||||
|
.TP
|
||||||
.B "\-i, \-\-image <imagename>"
|
.B "\-i, \-\-image <imagename>"
|
||||||
Only flash region/image
|
Only flash region/image
|
||||||
.B <imagename>
|
.B <imagename>
|
||||||
|
@ -2168,7 +2168,7 @@ int chip_safety_check(const struct flashctx *flash, int force, int read_it, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepare_flash_access(struct flashctx *const flash,
|
int prepare_flash_access(struct flashctx *const flash,
|
||||||
const bool read_it, const bool write_it,
|
const bool read_it, const bool write_it,
|
||||||
const bool erase_it, const bool verify_it)
|
const bool erase_it, const bool verify_it)
|
||||||
{
|
{
|
||||||
@ -2193,7 +2193,7 @@ static int prepare_flash_access(struct flashctx *const flash,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finalize_flash_access(struct flashctx *const flash)
|
void finalize_flash_access(struct flashctx *const flash)
|
||||||
{
|
{
|
||||||
unmap_flash(flash);
|
unmap_flash(flash);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
|
#ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#define print(t, ...) printf(__VA_ARGS__)
|
#define print(t, ...) printf(__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -38,7 +39,7 @@
|
|||||||
#include "programmer.h"
|
#include "programmer.h"
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(a, b) (a < b) ? a : b
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl)
|
void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl)
|
||||||
@ -916,4 +917,42 @@ int read_ich_descriptors_via_fdo(void *spibar, struct ich_descriptors *desc)
|
|||||||
msg_pdbg2(" done.\n");
|
msg_pdbg2(" done.\n");
|
||||||
return ICH_RET_OK;
|
return ICH_RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a layout from the dump of an Intel ICH descriptor.
|
||||||
|
*
|
||||||
|
* @param layout Pointer where to store the layout.
|
||||||
|
* @param dump The descriptor dump to read from.
|
||||||
|
* @param len The length of the descriptor dump.
|
||||||
|
*
|
||||||
|
* @return 0 on success,
|
||||||
|
* 1 if the descriptor couldn't be parsed.
|
||||||
|
*/
|
||||||
|
int layout_from_ich_descriptors(struct ich_layout *const layout, const void *const dump, const size_t len)
|
||||||
|
{
|
||||||
|
static const char *regions[] = { "fd", "bios", "me", "gbe", "pd" };
|
||||||
|
|
||||||
|
struct ich_descriptors desc;
|
||||||
|
if (read_ich_descriptors_from_dump(dump, len, &desc))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
memset(layout, 0x00, sizeof(*layout));
|
||||||
|
|
||||||
|
size_t i, j;
|
||||||
|
for (i = 0, j = 0; i < min(desc.content.NR + 1, ARRAY_SIZE(regions)); ++i) {
|
||||||
|
const chipoff_t base = ICH_FREG_BASE(desc.region.FLREGs[i]);
|
||||||
|
const chipoff_t limit = ICH_FREG_LIMIT(desc.region.FLREGs[i]) + 0xfff;
|
||||||
|
if (limit <= base)
|
||||||
|
continue;
|
||||||
|
layout->entries[j].start = base;
|
||||||
|
layout->entries[j].end = limit;
|
||||||
|
layout->entries[j].included = false;
|
||||||
|
snprintf(layout->entries[j].name, sizeof(layout->entries[j].name), "%s", regions[i]);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
layout->base.entries = layout->entries;
|
||||||
|
layout->base.num_entries = j;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */
|
#endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */
|
||||||
|
@ -584,4 +584,6 @@ int read_ich_descriptors_from_dump(const uint32_t *dump, unsigned int len, struc
|
|||||||
int read_ich_descriptors_via_fdo(void *spibar, struct ich_descriptors *desc);
|
int read_ich_descriptors_via_fdo(void *spibar, struct ich_descriptors *desc);
|
||||||
int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx);
|
int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx);
|
||||||
|
|
||||||
|
int layout_from_ich_descriptors(struct ich_layout *, const void *dump, size_t len);
|
||||||
|
|
||||||
#endif /* __ICH_DESCRIPTORS_H__ */
|
#endif /* __ICH_DESCRIPTORS_H__ */
|
||||||
|
18
layout.c
18
layout.c
@ -35,7 +35,7 @@ static struct flashrom_layout layout = { entries, 0 };
|
|||||||
static char *include_args[MAX_ROMLAYOUT];
|
static char *include_args[MAX_ROMLAYOUT];
|
||||||
static int num_include_args = 0; /* the number of valid include_args. */
|
static int num_include_args = 0; /* the number of valid include_args. */
|
||||||
|
|
||||||
const struct flashrom_layout *get_global_layout(void)
|
struct flashrom_layout *get_global_layout(void)
|
||||||
{
|
{
|
||||||
return &layout;
|
return &layout;
|
||||||
}
|
}
|
||||||
@ -132,17 +132,17 @@ int register_include_arg(char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns the index of the entry (or a negative value if it is not found) */
|
/* returns the index of the entry (or a negative value if it is not found) */
|
||||||
static int find_romentry(char *name)
|
static int find_romentry(struct flashrom_layout *const l, char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (layout.num_entries == 0)
|
if (l->num_entries == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
msg_gspew("Looking for region \"%s\"... ", name);
|
msg_gspew("Looking for region \"%s\"... ", name);
|
||||||
for (i = 0; i < layout.num_entries; i++) {
|
for (i = 0; i < l->num_entries; i++) {
|
||||||
if (!strcmp(layout.entries[i].name, name)) {
|
if (!strcmp(l->entries[i].name, name)) {
|
||||||
layout.entries[i].included = 1;
|
l->entries[i].included = 1;
|
||||||
msg_gspew("found.\n");
|
msg_gspew("found.\n");
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ static int find_romentry(char *name)
|
|||||||
/* process -i arguments
|
/* process -i arguments
|
||||||
* returns 0 to indicate success, >0 to indicate failure
|
* returns 0 to indicate success, >0 to indicate failure
|
||||||
*/
|
*/
|
||||||
int process_include_args(void)
|
int process_include_args(struct flashrom_layout *const l)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned int found = 0;
|
unsigned int found = 0;
|
||||||
@ -163,7 +163,7 @@ int process_include_args(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* User has specified an area, but no layout file is loaded. */
|
/* User has specified an area, but no layout file is loaded. */
|
||||||
if (layout.num_entries == 0) {
|
if (l->num_entries == 0) {
|
||||||
msg_gerr("Region requested (with -i \"%s\"), "
|
msg_gerr("Region requested (with -i \"%s\"), "
|
||||||
"but no layout data is available.\n",
|
"but no layout data is available.\n",
|
||||||
include_args[0]);
|
include_args[0]);
|
||||||
@ -171,7 +171,7 @@ int process_include_args(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_include_args; i++) {
|
for (i = 0; i < num_include_args; i++) {
|
||||||
if (find_romentry(include_args[i]) < 0) {
|
if (find_romentry(l, include_args[i]) < 0) {
|
||||||
msg_gerr("Invalid region specified: \"%s\".\n",
|
msg_gerr("Invalid region specified: \"%s\".\n",
|
||||||
include_args[i]);
|
include_args[i]);
|
||||||
return 1;
|
return 1;
|
||||||
|
9
layout.h
9
layout.h
@ -57,6 +57,13 @@ struct single_layout {
|
|||||||
struct romentry entry;
|
struct romentry entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct flashrom_layout *get_global_layout(void);
|
struct ich_layout {
|
||||||
|
struct flashrom_layout base;
|
||||||
|
struct romentry entries[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct flashrom_layout *get_global_layout(void);
|
||||||
|
|
||||||
|
int process_include_args(struct flashrom_layout *);
|
||||||
|
|
||||||
#endif /* !__LAYOUT_H__ */
|
#endif /* !__LAYOUT_H__ */
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "programmer.h"
|
#include "programmer.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "hwaccess.h"
|
||||||
|
#include "ich_descriptors.h"
|
||||||
#include "libflashrom.h"
|
#include "libflashrom.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,6 +306,86 @@ int flashrom_layout_include_region(struct flashrom_layout *const layout, const c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a layout from the Intel ICH descriptor in the flash.
|
||||||
|
*
|
||||||
|
* Optionally verify that the layout matches the one in the given
|
||||||
|
* descriptor dump.
|
||||||
|
*
|
||||||
|
* @param[out] layout Points to a struct flashrom_layout pointer that
|
||||||
|
* gets set if the descriptor is read and parsed
|
||||||
|
* successfully.
|
||||||
|
* @param[in] flashctx Flash context to read the descriptor from flash.
|
||||||
|
* @param[in] dump The descriptor dump to compare to or NULL.
|
||||||
|
* @param[in] len The length of the descriptor dump.
|
||||||
|
*
|
||||||
|
* @return 0 on success,
|
||||||
|
* 6 if descriptor parsing isn't implemented for the host,
|
||||||
|
* 5 if the descriptors don't match,
|
||||||
|
* 4 if the descriptor dump couldn't be parsed,
|
||||||
|
* 3 if the descriptor on flash couldn't be parsed,
|
||||||
|
* 2 if the descriptor on flash couldn't be read,
|
||||||
|
* 1 on any other error.
|
||||||
|
*/
|
||||||
|
int flashrom_layout_read_from_ifd(struct flashrom_layout **const layout, struct flashctx *const flashctx,
|
||||||
|
const void *const dump, const size_t len)
|
||||||
|
{
|
||||||
|
#ifndef __FLASHROM_LITTLE_ENDIAN__
|
||||||
|
return 6;
|
||||||
|
#else
|
||||||
|
struct ich_layout dump_layout;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
void *const desc = malloc(0x1000);
|
||||||
|
struct ich_layout *const chip_layout = malloc(sizeof(*chip_layout));
|
||||||
|
if (!desc || !chip_layout) {
|
||||||
|
msg_gerr("Out of memory!\n");
|
||||||
|
goto _free_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prepare_flash_access(flashctx, true, false, false, false))
|
||||||
|
goto _free_ret;
|
||||||
|
|
||||||
|
msg_cinfo("Reading ich descriptor... ");
|
||||||
|
if (flashctx->chip->read(flashctx, desc, 0, 0x1000)) {
|
||||||
|
msg_cerr("Read operation failed!\n");
|
||||||
|
msg_cinfo("FAILED.\n");
|
||||||
|
ret = 2;
|
||||||
|
goto _finalize_ret;
|
||||||
|
}
|
||||||
|
msg_cinfo("done.\n");
|
||||||
|
|
||||||
|
if (layout_from_ich_descriptors(chip_layout, desc, 0x1000)) {
|
||||||
|
ret = 3;
|
||||||
|
goto _finalize_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump) {
|
||||||
|
if (layout_from_ich_descriptors(&dump_layout, dump, len)) {
|
||||||
|
ret = 4;
|
||||||
|
goto _finalize_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chip_layout->base.num_entries != dump_layout.base.num_entries ||
|
||||||
|
memcmp(chip_layout->entries, dump_layout.entries, sizeof(dump_layout.entries))) {
|
||||||
|
ret = 5;
|
||||||
|
goto _finalize_ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*layout = (struct flashrom_layout *)chip_layout;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
_finalize_ret:
|
||||||
|
finalize_flash_access(flashctx);
|
||||||
|
_free_ret:
|
||||||
|
if (ret)
|
||||||
|
free(chip_layout);
|
||||||
|
free(desc);
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free a layout.
|
* @brief Free a layout.
|
||||||
*
|
*
|
||||||
|
@ -63,6 +63,7 @@ int flashrom_image_write(struct flashrom_flashctx *, const void *buffer, size_t
|
|||||||
int flashrom_image_verify(struct flashrom_flashctx *, const void *buffer, size_t buffer_len);
|
int flashrom_image_verify(struct flashrom_flashctx *, const void *buffer, size_t buffer_len);
|
||||||
|
|
||||||
struct flashrom_layout;
|
struct flashrom_layout;
|
||||||
|
int flashrom_layout_read_from_ifd(struct flashrom_layout **, struct flashrom_flashctx *, const void *dump, size_t len);
|
||||||
int flashrom_layout_include_region(struct flashrom_layout *, const char *name);
|
int flashrom_layout_include_region(struct flashrom_layout *, const char *name);
|
||||||
void flashrom_layout_release(struct flashrom_layout *);
|
void flashrom_layout_release(struct flashrom_layout *);
|
||||||
void flashrom_layout_set(struct flashrom_flashctx *, const struct flashrom_layout *);
|
void flashrom_layout_set(struct flashrom_flashctx *, const struct flashrom_layout *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user