1 /* parser generator for flashmap descriptor language */
2 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include "fmd_scanner.h"
10 struct flashmap_descriptor
*res
= NULL
;
16 struct unsigned_option maybe_intval
;
17 struct flashmap_descriptor
*region_ptr
;
18 union flashmap_flags flags
;
19 struct descriptor_list region_listhdr
;
28 struct descriptor_node
{
29 struct flashmap_descriptor
*val
;
30 struct descriptor_node
*next
;
33 struct descriptor_list
{
35 struct descriptor_node
*head
;
36 struct descriptor_node
*tail
;
39 extern
struct flashmap_descriptor
*res
;
41 struct flashmap_descriptor
*parse_descriptor
(
42 char *name
, union flashmap_flags flags
, struct unsigned_option offset
,
43 struct unsigned_option size
, struct descriptor_list children
);
44 void yyerror(const char *s
);
47 %token
<intval
> INTEGER
49 %token
<strval
> STRING
53 %type
<region_ptr
> flash_region
54 %type
<strval
> region_name
55 %type
<flags
> region_flags_opt
56 %type
<flags
> region_flags
57 %type
<flags
> region_flag
58 %type
<maybe_intval
> region_offset_opt
59 %type
<maybe_intval
> region_offset
60 %type
<maybe_intval
> region_size_opt
61 %type
<maybe_intval
> region_size
62 %type
<region_listhdr
> region_list_opt
63 %type
<region_listhdr
> region_list
64 %type
<region_listhdr
> region_list_entries
68 flash_chip: region_name region_offset_opt region_size region_list
70 union flashmap_flags flags
= { .v
=0 };
71 if
(!(res
= parse_descriptor
($1, flags
, $2, $3, $4)))
74 flash_region: region_name region_flags_opt region_offset_opt region_size_opt
77 struct flashmap_descriptor
*node
= parse_descriptor
($1, $2, $3, $4, $5);
81 if
(node
->flags.f.cbfs
&& !fmd_process_flag_cbfs
(node
)) {
82 ERROR
("Section '%s' cannot have flag 'CBFS''\n", node
->name
);
91 perror
("E: While allocating section name");
95 region_flags_opt: { $$
= (union flashmap_flags
){ .v
=0 }; }
96 |
'(' region_flags
')' { $$
= $2; };
97 region_flags: region_flag | region_flag region_flags
{ $$.v
= $1.v |
$2.v
; };
98 region_flag: FLAG_CBFS
{ $$.v
= 0; $$.f.cbfs
= 1; };
99 region_flag: FLAG_PRESERVE
{ $$.v
= 0; $$.f.preserve
= 1; };
100 region_offset_opt: { $$
= (struct unsigned_option
){false
, 0}; }
102 region_offset: '@' INTEGER
{ $$
= (struct unsigned_option
){true
, $2}; };
103 region_size_opt: { $$
= (struct unsigned_option
){false
, 0}; }
105 region_size: INTEGER
{ $$
= (struct unsigned_option
){true
, $1}; };
108 $$
= (struct descriptor_list
)
109 {.len
= 0, .head
= NULL
, .tail
= NULL
};
112 region_list: '{' region_list_entries
'}' { $$
= $2; };
113 region_list_entries: flash_region
115 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
117 perror
("E: While allocating linked list node");
122 $$
= (struct descriptor_list
){.len
= 1, .head
= node
, .tail
= node
};
124 | region_list_entries flash_region
126 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
128 perror
("E: While allocating linked list node");
134 $1.tail
->next
= node
;
135 $$
= (struct descriptor_list
)
136 {.len
= $1.len
+ 1, .head
= $1.head
, .tail
= node
};
141 struct flashmap_descriptor
*parse_descriptor
(
142 char *name
, union flashmap_flags flags
, struct unsigned_option offset
,
143 struct unsigned_option size
, struct descriptor_list children
)
145 struct flashmap_descriptor
*region
= malloc
(sizeof
(*region
));
147 perror
("E: While allocating descriptor section");
151 region
->flags
= flags
;
152 region
->offset_known
= offset.val_known
;
153 region
->offset
= offset.val
;
154 region
->size_known
= size.val_known
;
155 region
->size
= size.val
;
156 region
->list_len
= children.len
;
157 if
(region
->list_len
) {
158 region
->list
= malloc
(region
->list_len
* sizeof
(*region
->list
));
160 perror
("E: While allocating node children array");
163 struct descriptor_node
*cur_node
= children.head
;
164 for
(unsigned idx
= 0; idx
< region
->list_len
; ++idx
) {
165 region
->list
[idx
] = cur_node
->val
;
167 struct descriptor_node
*next_node
= cur_node
->next
;
169 cur_node
= next_node
;
177 void yyerror(const char *s
)
179 fprintf
(stderr
, "%s\n", s
);