diff options
author | Sol Boucher <solb@chromium.org> | 2015-02-26 11:47:19 -0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-05-08 19:55:42 +0200 |
commit | 69b88bf1276d2cb0309e2fc96df9d33a893138e3 (patch) | |
tree | 2dc297765cb1f858e5f2f6865481eeafdad8e897 /util/cbfstool/fmd_parser.y | |
parent | 5f7e4f019e258a49fff78e90509d1fda280fc147 (diff) | |
download | coreboot-69b88bf1276d2cb0309e2fc96df9d33a893138e3.tar.xz |
fmaptool: Introduce the fmd ("flashmap descriptor") language and compiler
This adds a compiler for a language whose textual representation of flashmap
regions will be used to describe the layout of flash chips that contain more
than just a single CBFS. Direct integration with cbfstool (via a new
command-line switch for the create action) is forthcoming but will be added
separately.
BUG=chromium:461875
TEST=Use Chromium OS's cros_bundle_firmware script on the fmap.dts file for
panther. Using the latter file as a reference, write a corresponding
fmap.fmd file and feed it through fmaptool. Run both binary output files
though the flashmap project's own flashmap_decode utility. Observe only
the expected differences.
BRANCH=None
Change-Id: I06b32d138dbef0a4e5ed43c81bd31c796fd5d669
Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Commit-Id: 005ab67eb594e21489cf31036aedaea87e0c7142
Original-Change-Id: Ia08f28688efdbbfc70c255916b8eb7eb0eb07fb2
Original-Signed-off-by: Sol Boucher <solb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/255031
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Reviewed-on: http://review.coreboot.org/9942
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'util/cbfstool/fmd_parser.y')
-rw-r--r-- | util/cbfstool/fmd_parser.y | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/util/cbfstool/fmd_parser.y b/util/cbfstool/fmd_parser.y new file mode 100644 index 0000000000..292fba3d8a --- /dev/null +++ b/util/cbfstool/fmd_parser.y @@ -0,0 +1,190 @@ +/* + * fmd_parser.y, parser generator for flashmap descriptor language + * + * Copyright (C) 2015 Google, Inc. + * + * 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 "fmd_scanner.h" + +#include <stdlib.h> + +struct flashmap_descriptor *res = NULL; +%} + +%union { + unsigned intval; + char *strval; + struct unsigned_option maybe_intval; + struct flashmap_descriptor *region_ptr; + struct descriptor_list region_listhdr; +} + +%code requires { +#include "fmd.h" +#include "option.h" + +#include <stdbool.h> + +struct descriptor_node { + struct flashmap_descriptor *val; + struct descriptor_node *next; +}; + +struct descriptor_list { + size_t len; + struct descriptor_node *head; + struct descriptor_node *tail; +}; + +extern struct flashmap_descriptor *res; + +struct flashmap_descriptor *parse_descriptor(char *name, + struct unsigned_option offset, struct unsigned_option size, + struct descriptor_list children); +void yyerror(const char *s); +} + +%token <intval> INTEGER +%token OCTAL +%token <strval> STRING + +%type <region_ptr> flash_region +%type <strval> region_name +%type <strval> region_annotation_opt +%type <strval> region_annotation +%type <maybe_intval> region_offset_opt +%type <maybe_intval> region_offset +%type <maybe_intval> region_size_opt +%type <maybe_intval> region_size +%type <region_listhdr> region_list_opt +%type <region_listhdr> region_list +%type <region_listhdr> region_list_entries + +%% + +flash_chip: region_name region_offset_opt region_size region_list +{ + if (!(res = parse_descriptor($1, $2, $3, $4))) + YYABORT; +}; +flash_region: region_name region_annotation_opt region_offset_opt + region_size_opt region_list_opt +{ + struct flashmap_descriptor *node = parse_descriptor($1, $3, $4, $5); + if (!node) + YYABORT; + + char *annotation = $2; + if (annotation && !fmd_process_annotation_impl(node, annotation)) { + fprintf(stderr, "ERROR: Section '%s' has unexpected annotation '(%s)'\n", + node->name, annotation); + YYABORT; + } + free(annotation); + + $$ = node; +}; +region_name: STRING +{ + if (!$1) { + perror("ERROR: While allocating section name"); + YYABORT; + } +}; +region_annotation_opt: { $$ = NULL; } + | region_annotation; +region_annotation: '(' STRING ')' { $$ = $2; }; +region_offset_opt: { $$ = (struct unsigned_option){false, 0}; } + | region_offset; +region_offset: '@' INTEGER { $$ = (struct unsigned_option){true, $2}; }; +region_size_opt: { $$ = (struct unsigned_option){false, 0}; } + | region_size; +region_size: INTEGER { $$ = (struct unsigned_option){true, $1}; }; +region_list_opt: +{ + $$ = (struct descriptor_list) + {.len = 0, .head = NULL, .tail = NULL}; +} + | region_list; +region_list: '{' region_list_entries '}' { $$ = $2; }; +region_list_entries: flash_region +{ + struct descriptor_node *node = malloc(sizeof(*node)); + if (!node) { + perror("ERROR: While allocating linked list node"); + YYABORT; + } + node->val = $1; + node->next = NULL; + $$ = (struct descriptor_list){.len = 1, .head = node, .tail = node}; +} + | region_list_entries flash_region +{ + struct descriptor_node *node = malloc(sizeof(*node)); + if (!node) { + perror("ERROR: While allocating linked list node"); + YYABORT; + } + node->val = $2; + node->next = NULL; + + $1.tail->next = node; + $$ = (struct descriptor_list) + {.len = $1.len + 1, .head = $1.head, .tail = node}; +}; + +%% + +struct flashmap_descriptor *parse_descriptor(char *name, + struct unsigned_option offset, struct unsigned_option size, + struct descriptor_list children) +{ + struct flashmap_descriptor *region = malloc(sizeof(*region)); + if (!region) { + perror("ERROR: While allocating descriptor section"); + return NULL; + } + region->name = name; + region->offset_known = offset.val_known; + region->offset = offset.val; + region->size_known = size.val_known; + region->size = size.val; + region->list_len = children.len; + if (region->list_len) { + region->list = malloc(region->list_len * sizeof(*region->list)); + if (!region->list) { + perror("ERROR: While allocating node children array"); + return NULL; + } + struct descriptor_node *cur_node = children.head; + for (unsigned idx = 0; idx < region->list_len; ++idx) { + region->list[idx] = cur_node->val; + + struct descriptor_node *next_node = cur_node->next; + free(cur_node); + cur_node = next_node; + } + } else { + region->list = NULL; + } + return region; +} + +void yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} |