1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-07-03 06:53:18 +02:00

erasure_layout: Add an option to sacrifice unchanged blocks for speed

The patch adds command line option to handle the following situation:

There is a region which is requested to be erased (or written, because
the write operation uses erase too). Some of the areas inside this
region don't need to be erased, because the bytes already have expected
value. Such areas can be skipped.

The logic selects eraseblocks that can cover the areas which need to be
erased. Suppose there is a region which is partially covered by
eraseblocks of size S (partially because remaining areas don't need to
be erased). Now suppose we can cover the whole region with eraseblock
of larger size, S+1, and erase it all at once. This will run faster:
erase opcode will only be sent once instead of many smaller opcodes.
However, this will run erase over some areas of the chip memory that
didn't need to be erased. Which means, the chip, as a hardware, will
wear faster.

New command line option sets the maximum % memory that is allowed for
redundant erase. Default is 0, S+1 size block only selected if all the
area needs to be erased in full. 50 means that if more than a half of
the area needs to be erased, a S+1 size block can be selected to cover
all area with one block.

The tradeoff is the speed of programming operation VS the longevity of
the chip. Default is longevity.

Change-Id: I154e8a713f626c37dbbe118db700055b96d24803
Co-developed-by: persmule <persmule@hardenedlinux.org
Co-developed-by: Anastasia Klimchuk <aklm@flashrom.org>
Signed-off-by: persmule <persmule@hardenedlinux.org>
Signed-off-by: Anastasia Klimchuk <aklm@flashrom.org>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/84721
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Peter Marheine <pmarheine@chromium.org>
This commit is contained in:
persmule
2024-10-11 11:04:04 +08:00
committed by Anastasia Klimchuk
parent 32e5aca1a9
commit 9ff3d4cf75
6 changed files with 152 additions and 6 deletions

View File

@ -45,6 +45,7 @@ enum {
OPTION_WP_DISABLE,
OPTION_WP_LIST,
OPTION_PROGRESS,
OPTION_SACRIFICE_RATIO,
};
struct cli_options {
@ -73,6 +74,7 @@ struct cli_options {
char *logfile;
char *referencefile;
const char *chip_to_probe;
int sacrifice_ratio;
};
static void cli_classic_usage(const char *name)
@ -119,6 +121,14 @@ static void cli_classic_usage(const char *name)
" --flash-contents <ref-file> assume flash contents to be <ref-file>\n"
" -L | --list-supported print supported devices\n"
" --progress show progress percentage on the standard output\n"
" --sacrifice-ratio <ratio> Fraction (as a percentage, 0-50) of an erase block\n"
" that may be erased even if unmodified. Larger values\n"
" may complete programming faster, but may also hurt\n"
" chip longevity by erasing cells unnecessarily.\n"
" Default is 0, tradeoff is the speed of programming\n"
" operation VS the longevity of the chip. Default is\n"
" longevity.\n"
" DANGEROUS! It wears your chip faster!\n"
" -p | --programmer <name>[:<param>] specify the programmer device. One of\n");
list_programmers_linebreak(4, 80, 0);
printf(".\n\nYou can specify one of -h, -R, -L, "
@ -810,6 +820,10 @@ static void parse_options(int argc, char **argv, const char *optstring,
case OPTION_PROGRESS:
options->show_progress = true;
break;
case OPTION_SACRIFICE_RATIO:
/* It is okay to convert invalid input to 0. */
options->sacrifice_ratio = atoi(optarg);
break;
default:
cli_classic_abort_usage(NULL);
break;
@ -879,6 +893,7 @@ int main(int argc, char *argv[])
{"version", 0, NULL, 'R'},
{"output", 1, NULL, 'o'},
{"progress", 0, NULL, OPTION_PROGRESS},
{"sacrifice-ratio", 1, NULL, OPTION_SACRIFICE_RATIO},
{NULL, 0, NULL, 0},
};
@ -1125,6 +1140,14 @@ int main(int argc, char *argv[])
goto out_shutdown;
}
if (options.sacrifice_ratio) {
if (options.sacrifice_ratio < 0 || options.sacrifice_ratio > 50) {
msg_ginfo("Invalid input of sacrifice ratio, valid 0-50. Fallback to default value 0.\n");
options.sacrifice_ratio = 0;
}
fill_flash->sacrifice_ratio = options.sacrifice_ratio;
}
if (options.ifd && (flashrom_layout_read_from_ifd(&options.layout, fill_flash, NULL, 0) ||
process_include_args(options.layout, options.include_args))) {
ret = 1;