Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33300
Change subject: [RFC and WIP]Add an option to align FMAP regions ......................................................................
[RFC and WIP]Add an option to align FMAP regions
This eases writing FMD files when there are alignment requirement on some regions (e.g. MRC_VAR_CACHE).
Some questions: - Do we want to error out on options that have a base defined but that does not follow its alignment or do we want to fix the alignment if such configuration presents itself - '~' is used. Is that the 'best' symbol
Change-Id: If6e01112f0c98f45876bcc7012f195f5aa693efd Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M util/cbfstool/fmd.c M util/cbfstool/fmd.h M util/cbfstool/fmd_parser.y M util/cbfstool/fmd_scanner.l 4 files changed, 22 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/00/33300/1
diff --git a/util/cbfstool/fmd.c b/util/cbfstool/fmd.c index 7a289d7..d39ec20 100644 --- a/util/cbfstool/fmd.c +++ b/util/cbfstool/fmd.c @@ -248,6 +248,10 @@ } else if (!first_incomplete_it) { watermark = cur_section->offset + cur_section->size; } + if (cur_section->alignment_known) { + cur_section->offset = (cur_section->offset + cur_section->alignment - 1) + & ~(cur_section->alignment); + } }
if (first_incomplete_it && diff --git a/util/cbfstool/fmd.h b/util/cbfstool/fmd.h index 90e6d6e..91ae2fd 100644 --- a/util/cbfstool/fmd.h +++ b/util/cbfstool/fmd.h @@ -53,6 +53,8 @@ bool size_known; /** It is an error to read this field unless size_known is set. */ unsigned size; + bool alignment_known; + unsigned alignment; size_t list_len; union flashmap_flags flags; /** It is an error to dereference this array if list_len is 0. */ diff --git a/util/cbfstool/fmd_parser.y b/util/cbfstool/fmd_parser.y index 3ba710c..e7e1caf 100644 --- a/util/cbfstool/fmd_parser.y +++ b/util/cbfstool/fmd_parser.y @@ -52,7 +52,8 @@
struct flashmap_descriptor *parse_descriptor( char *name, union flashmap_flags flags, struct unsigned_option offset, - struct unsigned_option size, struct descriptor_list children); + struct unsigned_option size, struct unsigned_option alignment, + struct descriptor_list children); void yyerror(const char *s); }
@@ -71,6 +72,8 @@ %type <maybe_intval> region_offset %type <maybe_intval> region_size_opt %type <maybe_intval> region_size +%type <maybe_intval> region_alignment_opt +%type <maybe_intval> region_alignment %type <region_listhdr> region_list_opt %type <region_listhdr> region_list %type <region_listhdr> region_list_entries @@ -80,13 +83,14 @@ flash_chip: region_name region_offset_opt region_size region_list { union flashmap_flags flags = { .v=0 }; - if (!(res = parse_descriptor($1, flags, $2, $3, $4))) + struct unsigned_option alignment = { .val_known = false }; + if (!(res = parse_descriptor($1, flags, $2, $3, alignment, $4))) YYABORT; }; flash_region: region_name region_flags_opt region_offset_opt region_size_opt - region_list_opt + region_alignment_opt region_list_opt { - struct flashmap_descriptor *node = parse_descriptor($1, $2, $3, $4, $5); + struct flashmap_descriptor *node = parse_descriptor($1, $2, $3, $4, $5, $6); if (!node) YYABORT;
@@ -115,6 +119,9 @@ region_size_opt: { $$ = (struct unsigned_option){false, 0}; } | region_size; region_size: INTEGER { $$ = (struct unsigned_option){true, $1}; }; +region_alignment_opt: { $$ = (struct unsigned_option){false, 0}; } + | region_alignment; +region_alignment: '~' INTEGER { $$ = (struct unsigned_option){true, $2}; }; region_list_opt: { $$ = (struct descriptor_list) @@ -152,7 +159,8 @@
struct flashmap_descriptor *parse_descriptor( char *name, union flashmap_flags flags, struct unsigned_option offset, - struct unsigned_option size, struct descriptor_list children) + struct unsigned_option size, struct unsigned_option alignment, + struct descriptor_list children) { struct flashmap_descriptor *region = malloc(sizeof(*region)); if (!region) { @@ -165,6 +173,8 @@ region->offset = offset.val; region->size_known = size.val_known; region->size = size.val; + region->alignment_known = alignment.val_known; + region->alignment = alignment.val; region->list_len = children.len; if (region->list_len) { region->list = malloc(region->list_len * sizeof(*region->list)); diff --git a/util/cbfstool/fmd_scanner.l b/util/cbfstool/fmd_scanner.l index be9a5de..4c7d322 100644 --- a/util/cbfstool/fmd_scanner.l +++ b/util/cbfstool/fmd_scanner.l @@ -39,7 +39,7 @@ [1-9][0-9]*{MULTIPLIER}? return parse_integer(yytext, 10); 0[0-9]+{MULTIPLIER}? return OCTAL; 0[xX][0-9a-fA-F]+{MULTIPLIER}? return parse_integer(yytext + 2, 16); -[^#@{}()[:space:]]* return copy_string(yytext); +[^#@~{}()[:space:]]* return copy_string(yytext); . return *yytext;
%%