1 /* parser frontend and utility functions for flashmap descriptor language */ 2 /* SPDX-License-Identifier: GPL-2.0-only */ 3 4 #ifndef FMD_H_ 5 #define FMD_H_ 6 7 #include <limits.h> 8 #include <stdbool.h> 9 #include <stddef.h> 10 #include <stdio.h> 11 12 #define FMD_NOTFOUND UINT_MAX 13 14 /** 15 * Flags used by flashmap_descriptor. 16 * These flags can be set by adding (NAME) after description name. 17 * For example, declaring a CBFS section named as COREBOOT for 16k: 18 * COREBOOT(CBFS) 16k 19 */ 20 union flashmap_flags { 21 struct { 22 unsigned int cbfs: 1; /* The section contains a CBFS area. */ 23 unsigned int preserve: 1; /* Preserve the section before update. */ 24 } f; 25 int v; 26 }; 27 28 struct flashmap_descriptor { 29 char *name; 30 bool offset_known; 31 /** 32 * Offset relative to that of the parent node. 33 * Exception: for the root node in the descriptor tree, it is optional. 34 * In this case, if absent, it indicates that the flash chip will not be 35 * memory mapped at runtime; otherwise, its value indicates the base 36 * address of the flash chip in the virtual address space rather than 37 * representing an offset into the flash image itself. 38 * It is an error to read this field unless offset_known is set. 39 */ 40 unsigned offset; 41 bool size_known; 42 /** It is an error to read this field unless size_known is set. */ 43 unsigned size; 44 size_t list_len; 45 union flashmap_flags flags; 46 /** It is an error to dereference this array if list_len is 0. */ 47 struct flashmap_descriptor **list; 48 }; 49 50 /** 51 * **Client-defined** callback for flag "CBFS". 52 * This call is used to notify client code that the user has requested the given 53 * section node to be flagged with "CBFS". Implementations of this function 54 * should use their return type to tell the compiler whether the flag can be 55 * applied and can perform whatever actions are necessary. 56 * It's worth reiterating that this is only called on section nodes, and will 57 * never be called with the final, complete flashmap_descriptor because 58 * it is impossible to set flags for the image as a whole. 59 * 60 * @param flashmap_descriptor The section node with flag set 61 * @return Whether this flag can be applied 62 */ 63 bool fmd_process_flag_cbfs(const struct flashmap_descriptor *node); 64 65 /** 66 * Parse and validate a flashmap descriptor from the specified stream. 67 * As part of this process, any fields that were omitted in the input are 68 * inferred from whatever information is known, if possible. The result is a 69 * tree with all its offset and size fields filled, except possibly the former 70 * part of the root node in the case of non--memory mapped flash. If a syntax 71 * error causes the parser to fail, or if there is not enough information given 72 * in the input file to determine any single missing value, the specific error 73 * is reported to standard error and this function returns NULL. 74 * 75 * @param stream File from which to read the (partial) flashmap descriptor 76 * @return Populated flashmap descriptor tree, or NULL on failure 77 */ 78 struct flashmap_descriptor *fmd_create(FILE *stream); 79 80 /** @param victim Valid descriptor tree to be cleaned up, or NULL for no-op */ 81 void fmd_cleanup(struct flashmap_descriptor *victim); 82 83 /** 84 * @param tree Must be non-NULL 85 * @return The number of nodes in the tree, including the root 86 */ 87 size_t fmd_count_nodes(const struct flashmap_descriptor *tree); 88 89 /** 90 * @param root The flashmap descriptor to search 91 * @param name The name of the sought-after section 92 * @return The desired section node, or NULL if none was found 93 */ 94 const struct flashmap_descriptor *fmd_find_node( 95 const struct flashmap_descriptor *root, const char *name); 96 97 /** 98 * @param root Parent node to whose start the "absolute" offset will be relative 99 * @param name The name of the node whose offset to determine 100 * @return The "absolute" offset, or FMD_NOTFOUND if the node wasn't found 101 */ 102 unsigned fmd_calc_absolute_offset(const struct flashmap_descriptor *root, 103 const char *name); 104 105 /** @param tree Must be non-NULL */ 106 void fmd_print(const struct flashmap_descriptor *tree); 107 108 typedef struct flashmap_descriptor **flashmap_descriptor_iterator_t; 109 110 /* 111 * Run the subsequent statement once on each descendant of the specified node. 112 * 113 * @param iterator A flashmap_descriptor_iterator_t (automatically declared) 114 * @param parent The parent node of those over which the loop should iterate 115 */ 116 #define fmd_foreach_child_iterator(iterator, parent) \ 117 for (flashmap_descriptor_iterator_t iterator = parent->list; \ 118 iterator < parent->list + parent->list_len; ++iterator) 119 120 /* 121 * Run the subsequent statement once on each descendant of the specified node. 122 * 123 * @param child A struct flashmap_descriptor * (automatically declared) 124 * @param parent The parent node of those over which the loop should iterate 125 */ 126 #define fmd_foreach_child(child, parent) \ 127 for (struct flashmap_descriptor **fmd_foreach_child_iterator_ = \ 128 parent->list, *child = NULL; \ 129 fmd_foreach_child_iterator_ < \ 130 parent->list + parent->list_len && \ 131 (child = *fmd_foreach_child_iterator_); \ 132 ++fmd_foreach_child_iterator_) 133 134 #endif 135