xref: /openbmc/linux/include/linux/bootconfig.h (revision e46d3be7)
176db5a27SMasami Hiramatsu /* SPDX-License-Identifier: GPL-2.0 */
276db5a27SMasami Hiramatsu #ifndef _LINUX_XBC_H
376db5a27SMasami Hiramatsu #define _LINUX_XBC_H
476db5a27SMasami Hiramatsu /*
576db5a27SMasami Hiramatsu  * Extra Boot Config
676db5a27SMasami Hiramatsu  * Copyright (C) 2019 Linaro Ltd.
776db5a27SMasami Hiramatsu  * Author: Masami Hiramatsu <mhiramat@kernel.org>
876db5a27SMasami Hiramatsu  */
976db5a27SMasami Hiramatsu 
104ee1b4caSMasami Hiramatsu #ifdef __KERNEL__
1176db5a27SMasami Hiramatsu #include <linux/kernel.h>
1276db5a27SMasami Hiramatsu #include <linux/types.h>
134ee1b4caSMasami Hiramatsu #else /* !__KERNEL__ */
144ee1b4caSMasami Hiramatsu /*
154ee1b4caSMasami Hiramatsu  * NOTE: This is only for tools/bootconfig, because tools/bootconfig will
164ee1b4caSMasami Hiramatsu  * run the parser sanity test.
174ee1b4caSMasami Hiramatsu  * This does NOT mean linux/bootconfig.h is available in the user space.
184ee1b4caSMasami Hiramatsu  * However, if you change this file, please make sure the tools/bootconfig
194ee1b4caSMasami Hiramatsu  * has no issue on building and running.
204ee1b4caSMasami Hiramatsu  */
214ee1b4caSMasami Hiramatsu #endif
2276db5a27SMasami Hiramatsu 
2385c46b78SMasami Hiramatsu #define BOOTCONFIG_MAGIC	"#BOOTCONFIG\n"
2485c46b78SMasami Hiramatsu #define BOOTCONFIG_MAGIC_LEN	12
25e1cef2d4SMasami Hiramatsu #define BOOTCONFIG_ALIGN_SHIFT	2
26e1cef2d4SMasami Hiramatsu #define BOOTCONFIG_ALIGN	(1 << BOOTCONFIG_ALIGN_SHIFT)
27e1cef2d4SMasami Hiramatsu #define BOOTCONFIG_ALIGN_MASK	(BOOTCONFIG_ALIGN - 1)
2885c46b78SMasami Hiramatsu 
2999f4f5d6SMasami Hiramatsu /**
3099f4f5d6SMasami Hiramatsu  * xbc_calc_checksum() - Calculate checksum of bootconfig
3199f4f5d6SMasami Hiramatsu  * @data: Bootconfig data.
3299f4f5d6SMasami Hiramatsu  * @size: The size of the bootconfig data.
3399f4f5d6SMasami Hiramatsu  *
3499f4f5d6SMasami Hiramatsu  * Calculate the checksum value of the bootconfig data.
3599f4f5d6SMasami Hiramatsu  * The checksum will be used with the BOOTCONFIG_MAGIC and the size for
3699f4f5d6SMasami Hiramatsu  * embedding the bootconfig in the initrd image.
3799f4f5d6SMasami Hiramatsu  */
384f292c48SMasami Hiramatsu static inline __init uint32_t xbc_calc_checksum(void *data, uint32_t size)
3999f4f5d6SMasami Hiramatsu {
4099f4f5d6SMasami Hiramatsu 	unsigned char *p = data;
414f292c48SMasami Hiramatsu 	uint32_t ret = 0;
4299f4f5d6SMasami Hiramatsu 
4399f4f5d6SMasami Hiramatsu 	while (size--)
4499f4f5d6SMasami Hiramatsu 		ret += *p++;
4599f4f5d6SMasami Hiramatsu 
4699f4f5d6SMasami Hiramatsu 	return ret;
4799f4f5d6SMasami Hiramatsu }
4899f4f5d6SMasami Hiramatsu 
4976db5a27SMasami Hiramatsu /* XBC tree node */
5076db5a27SMasami Hiramatsu struct xbc_node {
514f292c48SMasami Hiramatsu 	uint16_t next;
524f292c48SMasami Hiramatsu 	uint16_t child;
534f292c48SMasami Hiramatsu 	uint16_t parent;
544f292c48SMasami Hiramatsu 	uint16_t data;
5576db5a27SMasami Hiramatsu } __attribute__ ((__packed__));
5676db5a27SMasami Hiramatsu 
5776db5a27SMasami Hiramatsu #define XBC_KEY		0
5876db5a27SMasami Hiramatsu #define XBC_VALUE	(1 << 15)
5976db5a27SMasami Hiramatsu /* Maximum size of boot config is 32KB - 1 */
6076db5a27SMasami Hiramatsu #define XBC_DATA_MAX	(XBC_VALUE - 1)
6176db5a27SMasami Hiramatsu 
626c406249SSouradeep Chowdhury #define XBC_NODE_MAX	8192
6376db5a27SMasami Hiramatsu #define XBC_KEYLEN_MAX	256
6476db5a27SMasami Hiramatsu #define XBC_DEPTH_MAX	16
6576db5a27SMasami Hiramatsu 
6676db5a27SMasami Hiramatsu /* Node tree access raw APIs */
6776db5a27SMasami Hiramatsu struct xbc_node * __init xbc_root_node(void);
6876db5a27SMasami Hiramatsu int __init xbc_node_index(struct xbc_node *node);
6976db5a27SMasami Hiramatsu struct xbc_node * __init xbc_node_get_parent(struct xbc_node *node);
7076db5a27SMasami Hiramatsu struct xbc_node * __init xbc_node_get_child(struct xbc_node *node);
7176db5a27SMasami Hiramatsu struct xbc_node * __init xbc_node_get_next(struct xbc_node *node);
7276db5a27SMasami Hiramatsu const char * __init xbc_node_get_data(struct xbc_node *node);
7376db5a27SMasami Hiramatsu 
7476db5a27SMasami Hiramatsu /**
7576db5a27SMasami Hiramatsu  * xbc_node_is_value() - Test the node is a value node
7676db5a27SMasami Hiramatsu  * @node: An XBC node.
7776db5a27SMasami Hiramatsu  *
7876db5a27SMasami Hiramatsu  * Test the @node is a value node and return true if a value node, false if not.
7976db5a27SMasami Hiramatsu  */
8076db5a27SMasami Hiramatsu static inline __init bool xbc_node_is_value(struct xbc_node *node)
8176db5a27SMasami Hiramatsu {
8276db5a27SMasami Hiramatsu 	return node->data & XBC_VALUE;
8376db5a27SMasami Hiramatsu }
8476db5a27SMasami Hiramatsu 
8576db5a27SMasami Hiramatsu /**
8676db5a27SMasami Hiramatsu  * xbc_node_is_key() - Test the node is a key node
8776db5a27SMasami Hiramatsu  * @node: An XBC node.
8876db5a27SMasami Hiramatsu  *
8976db5a27SMasami Hiramatsu  * Test the @node is a key node and return true if a key node, false if not.
9076db5a27SMasami Hiramatsu  */
9176db5a27SMasami Hiramatsu static inline __init bool xbc_node_is_key(struct xbc_node *node)
9276db5a27SMasami Hiramatsu {
9376db5a27SMasami Hiramatsu 	return !xbc_node_is_value(node);
9476db5a27SMasami Hiramatsu }
9576db5a27SMasami Hiramatsu 
9676db5a27SMasami Hiramatsu /**
9776db5a27SMasami Hiramatsu  * xbc_node_is_array() - Test the node is an arraied value node
9876db5a27SMasami Hiramatsu  * @node: An XBC node.
9976db5a27SMasami Hiramatsu  *
10076db5a27SMasami Hiramatsu  * Test the @node is an arraied value node.
10176db5a27SMasami Hiramatsu  */
10276db5a27SMasami Hiramatsu static inline __init bool xbc_node_is_array(struct xbc_node *node)
10376db5a27SMasami Hiramatsu {
104ca24306dSMasami Hiramatsu 	return xbc_node_is_value(node) && node->child != 0;
10576db5a27SMasami Hiramatsu }
10676db5a27SMasami Hiramatsu 
10776db5a27SMasami Hiramatsu /**
10876db5a27SMasami Hiramatsu  * xbc_node_is_leaf() - Test the node is a leaf key node
10976db5a27SMasami Hiramatsu  * @node: An XBC node.
11076db5a27SMasami Hiramatsu  *
11176db5a27SMasami Hiramatsu  * Test the @node is a leaf key node which is a key node and has a value node
11276db5a27SMasami Hiramatsu  * or no child. Returns true if it is a leaf node, or false if not.
113e5efaeb8SMasami Hiramatsu  * Note that the leaf node can have subkey nodes in addition to the
114e5efaeb8SMasami Hiramatsu  * value node.
11576db5a27SMasami Hiramatsu  */
11676db5a27SMasami Hiramatsu static inline __init bool xbc_node_is_leaf(struct xbc_node *node)
11776db5a27SMasami Hiramatsu {
11876db5a27SMasami Hiramatsu 	return xbc_node_is_key(node) &&
11976db5a27SMasami Hiramatsu 		(!node->child || xbc_node_is_value(xbc_node_get_child(node)));
12076db5a27SMasami Hiramatsu }
12176db5a27SMasami Hiramatsu 
12276db5a27SMasami Hiramatsu /* Tree-based key-value access APIs */
1235dfe50b0SMasami Hiramatsu struct xbc_node * __init xbc_node_find_subkey(struct xbc_node *parent,
12476db5a27SMasami Hiramatsu 					     const char *key);
12576db5a27SMasami Hiramatsu 
12676db5a27SMasami Hiramatsu const char * __init xbc_node_find_value(struct xbc_node *parent,
12776db5a27SMasami Hiramatsu 					const char *key,
12876db5a27SMasami Hiramatsu 					struct xbc_node **vnode);
12976db5a27SMasami Hiramatsu 
13076db5a27SMasami Hiramatsu struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
13176db5a27SMasami Hiramatsu 						 struct xbc_node *leaf);
13276db5a27SMasami Hiramatsu 
13376db5a27SMasami Hiramatsu const char * __init xbc_node_find_next_key_value(struct xbc_node *root,
13476db5a27SMasami Hiramatsu 						 struct xbc_node **leaf);
13576db5a27SMasami Hiramatsu 
13676db5a27SMasami Hiramatsu /**
13776db5a27SMasami Hiramatsu  * xbc_find_value() - Find a value which matches the key
13876db5a27SMasami Hiramatsu  * @key: Search key
13976db5a27SMasami Hiramatsu  * @vnode: A container pointer of XBC value node.
14076db5a27SMasami Hiramatsu  *
14176db5a27SMasami Hiramatsu  * Search a value whose key matches @key from whole of XBC tree and return
14276db5a27SMasami Hiramatsu  * the value if found. Found value node is stored in *@vnode.
14376db5a27SMasami Hiramatsu  * Note that this can return 0-length string and store NULL in *@vnode for
14476db5a27SMasami Hiramatsu  * key-only (non-value) entry.
14576db5a27SMasami Hiramatsu  */
14676db5a27SMasami Hiramatsu static inline const char * __init
14776db5a27SMasami Hiramatsu xbc_find_value(const char *key, struct xbc_node **vnode)
14876db5a27SMasami Hiramatsu {
14976db5a27SMasami Hiramatsu 	return xbc_node_find_value(NULL, key, vnode);
15076db5a27SMasami Hiramatsu }
15176db5a27SMasami Hiramatsu 
15276db5a27SMasami Hiramatsu /**
15376db5a27SMasami Hiramatsu  * xbc_find_node() - Find a node which matches the key
15476db5a27SMasami Hiramatsu  * @key: Search key
15576db5a27SMasami Hiramatsu  *
15676db5a27SMasami Hiramatsu  * Search a (key) node whose key matches @key from whole of XBC tree and
15776db5a27SMasami Hiramatsu  * return the node if found. If not found, returns NULL.
15876db5a27SMasami Hiramatsu  */
15976db5a27SMasami Hiramatsu static inline struct xbc_node * __init xbc_find_node(const char *key)
16076db5a27SMasami Hiramatsu {
1615dfe50b0SMasami Hiramatsu 	return xbc_node_find_subkey(NULL, key);
16276db5a27SMasami Hiramatsu }
16376db5a27SMasami Hiramatsu 
16476db5a27SMasami Hiramatsu /**
165e5efaeb8SMasami Hiramatsu  * xbc_node_get_subkey() - Return the first subkey node if exists
166e5efaeb8SMasami Hiramatsu  * @node: Parent node
167e5efaeb8SMasami Hiramatsu  *
168e5efaeb8SMasami Hiramatsu  * Return the first subkey node of the @node. If the @node has no child
169e5efaeb8SMasami Hiramatsu  * or only value node, this will return NULL.
170e5efaeb8SMasami Hiramatsu  */
171e5efaeb8SMasami Hiramatsu static inline struct xbc_node * __init xbc_node_get_subkey(struct xbc_node *node)
172e5efaeb8SMasami Hiramatsu {
173e5efaeb8SMasami Hiramatsu 	struct xbc_node *child = xbc_node_get_child(node);
174e5efaeb8SMasami Hiramatsu 
175e5efaeb8SMasami Hiramatsu 	if (child && xbc_node_is_value(child))
176e5efaeb8SMasami Hiramatsu 		return xbc_node_get_next(child);
177e5efaeb8SMasami Hiramatsu 	else
178e5efaeb8SMasami Hiramatsu 		return child;
179e5efaeb8SMasami Hiramatsu }
180e5efaeb8SMasami Hiramatsu 
181e5efaeb8SMasami Hiramatsu /**
18276db5a27SMasami Hiramatsu  * xbc_array_for_each_value() - Iterate value nodes on an array
18376db5a27SMasami Hiramatsu  * @anode: An XBC arraied value node
18476db5a27SMasami Hiramatsu  * @value: A value
18576db5a27SMasami Hiramatsu  *
18676db5a27SMasami Hiramatsu  * Iterate array value nodes and values starts from @anode. This is expected to
18776db5a27SMasami Hiramatsu  * be used with xbc_find_value() and xbc_node_find_value(), so that user can
18876db5a27SMasami Hiramatsu  * process each array entry node.
18976db5a27SMasami Hiramatsu  */
19076db5a27SMasami Hiramatsu #define xbc_array_for_each_value(anode, value)				\
19176db5a27SMasami Hiramatsu 	for (value = xbc_node_get_data(anode); anode != NULL ;		\
192ca24306dSMasami Hiramatsu 	     anode = xbc_node_get_child(anode),				\
19376db5a27SMasami Hiramatsu 	     value = anode ? xbc_node_get_data(anode) : NULL)
19476db5a27SMasami Hiramatsu 
19576db5a27SMasami Hiramatsu /**
19676db5a27SMasami Hiramatsu  * xbc_node_for_each_child() - Iterate child nodes
19776db5a27SMasami Hiramatsu  * @parent: An XBC node.
19876db5a27SMasami Hiramatsu  * @child: Iterated XBC node.
19976db5a27SMasami Hiramatsu  *
20076db5a27SMasami Hiramatsu  * Iterate child nodes of @parent. Each child nodes are stored to @child.
201e5efaeb8SMasami Hiramatsu  * The @child can be mixture of a value node and subkey nodes.
20276db5a27SMasami Hiramatsu  */
20376db5a27SMasami Hiramatsu #define xbc_node_for_each_child(parent, child)				\
20476db5a27SMasami Hiramatsu 	for (child = xbc_node_get_child(parent); child != NULL ;	\
20576db5a27SMasami Hiramatsu 	     child = xbc_node_get_next(child))
20676db5a27SMasami Hiramatsu 
20776db5a27SMasami Hiramatsu /**
208e5efaeb8SMasami Hiramatsu  * xbc_node_for_each_subkey() - Iterate child subkey nodes
209e5efaeb8SMasami Hiramatsu  * @parent: An XBC node.
210e5efaeb8SMasami Hiramatsu  * @child: Iterated XBC node.
211e5efaeb8SMasami Hiramatsu  *
212e5efaeb8SMasami Hiramatsu  * Iterate subkey nodes of @parent. Each child nodes are stored to @child.
213e5efaeb8SMasami Hiramatsu  * The @child is only the subkey node.
214e5efaeb8SMasami Hiramatsu  */
215e5efaeb8SMasami Hiramatsu #define xbc_node_for_each_subkey(parent, child)				\
216e5efaeb8SMasami Hiramatsu 	for (child = xbc_node_get_subkey(parent); child != NULL ;	\
217e5efaeb8SMasami Hiramatsu 	     child = xbc_node_get_next(child))
218e5efaeb8SMasami Hiramatsu 
219e5efaeb8SMasami Hiramatsu /**
22076db5a27SMasami Hiramatsu  * xbc_node_for_each_array_value() - Iterate array entries of geven key
22176db5a27SMasami Hiramatsu  * @node: An XBC node.
22276db5a27SMasami Hiramatsu  * @key: A key string searched under @node
22376db5a27SMasami Hiramatsu  * @anode: Iterated XBC node of array entry.
22476db5a27SMasami Hiramatsu  * @value: Iterated value of array entry.
22576db5a27SMasami Hiramatsu  *
22676db5a27SMasami Hiramatsu  * Iterate array entries of given @key under @node. Each array entry node
227c23c8082SZhen Lei  * is stored to @anode and @value. If the @node doesn't have @key node,
22876db5a27SMasami Hiramatsu  * it does nothing.
22976db5a27SMasami Hiramatsu  * Note that even if the found key node has only one value (not array)
230c23c8082SZhen Lei  * this executes block once. However, if the found key node has no value
23176db5a27SMasami Hiramatsu  * (key-only node), this does nothing. So don't use this for testing the
23276db5a27SMasami Hiramatsu  * key-value pair existence.
23376db5a27SMasami Hiramatsu  */
23476db5a27SMasami Hiramatsu #define xbc_node_for_each_array_value(node, key, anode, value)		\
23576db5a27SMasami Hiramatsu 	for (value = xbc_node_find_value(node, key, &anode); value != NULL; \
236ca24306dSMasami Hiramatsu 	     anode = xbc_node_get_child(anode),				\
23776db5a27SMasami Hiramatsu 	     value = anode ? xbc_node_get_data(anode) : NULL)
23876db5a27SMasami Hiramatsu 
23976db5a27SMasami Hiramatsu /**
24076db5a27SMasami Hiramatsu  * xbc_node_for_each_key_value() - Iterate key-value pairs under a node
24176db5a27SMasami Hiramatsu  * @node: An XBC node.
24276db5a27SMasami Hiramatsu  * @knode: Iterated key node
24376db5a27SMasami Hiramatsu  * @value: Iterated value string
24476db5a27SMasami Hiramatsu  *
24576db5a27SMasami Hiramatsu  * Iterate key-value pairs under @node. Each key node and value string are
24676db5a27SMasami Hiramatsu  * stored in @knode and @value respectively.
24776db5a27SMasami Hiramatsu  */
24876db5a27SMasami Hiramatsu #define xbc_node_for_each_key_value(node, knode, value)			\
24976db5a27SMasami Hiramatsu 	for (knode = NULL, value = xbc_node_find_next_key_value(node, &knode);\
25076db5a27SMasami Hiramatsu 	     knode != NULL; value = xbc_node_find_next_key_value(node, &knode))
25176db5a27SMasami Hiramatsu 
25276db5a27SMasami Hiramatsu /**
25376db5a27SMasami Hiramatsu  * xbc_for_each_key_value() - Iterate key-value pairs
25476db5a27SMasami Hiramatsu  * @knode: Iterated key node
25576db5a27SMasami Hiramatsu  * @value: Iterated value string
25676db5a27SMasami Hiramatsu  *
25776db5a27SMasami Hiramatsu  * Iterate key-value pairs in whole XBC tree. Each key node and value string
25876db5a27SMasami Hiramatsu  * are stored in @knode and @value respectively.
25976db5a27SMasami Hiramatsu  */
26076db5a27SMasami Hiramatsu #define xbc_for_each_key_value(knode, value)				\
26176db5a27SMasami Hiramatsu 	xbc_node_for_each_key_value(NULL, knode, value)
26276db5a27SMasami Hiramatsu 
26376db5a27SMasami Hiramatsu /* Compose partial key */
26476db5a27SMasami Hiramatsu int __init xbc_node_compose_key_after(struct xbc_node *root,
26576db5a27SMasami Hiramatsu 			struct xbc_node *node, char *buf, size_t size);
26676db5a27SMasami Hiramatsu 
26776db5a27SMasami Hiramatsu /**
26876db5a27SMasami Hiramatsu  * xbc_node_compose_key() - Compose full key string of the XBC node
26976db5a27SMasami Hiramatsu  * @node: An XBC node.
27076db5a27SMasami Hiramatsu  * @buf: A buffer to store the key.
27176db5a27SMasami Hiramatsu  * @size: The size of the @buf.
27276db5a27SMasami Hiramatsu  *
27376db5a27SMasami Hiramatsu  * Compose the full-length key of the @node into @buf. Returns the total
27476db5a27SMasami Hiramatsu  * length of the key stored in @buf. Or returns -EINVAL if @node is NULL,
27576db5a27SMasami Hiramatsu  * and -ERANGE if the key depth is deeper than max depth.
27676db5a27SMasami Hiramatsu  */
27776db5a27SMasami Hiramatsu static inline int __init xbc_node_compose_key(struct xbc_node *node,
27876db5a27SMasami Hiramatsu 					      char *buf, size_t size)
27976db5a27SMasami Hiramatsu {
28076db5a27SMasami Hiramatsu 	return xbc_node_compose_key_after(NULL, node, buf, size);
28176db5a27SMasami Hiramatsu }
28276db5a27SMasami Hiramatsu 
28376db5a27SMasami Hiramatsu /* XBC node initializer */
284bdac5c2bSMasami Hiramatsu int __init xbc_init(const char *buf, size_t size, const char **emsg, int *epos);
28589b74cacSMasami Hiramatsu 
286e306220cSMasami Hiramatsu /* XBC node and size information */
287e306220cSMasami Hiramatsu int __init xbc_get_info(int *node_size, size_t *data_size);
28876db5a27SMasami Hiramatsu 
28976db5a27SMasami Hiramatsu /* XBC cleanup data structures */
290e46d3be7SQiang Zhang void __init _xbc_exit(bool early);
291e46d3be7SQiang Zhang 
292e46d3be7SQiang Zhang static inline void xbc_exit(void)
293e46d3be7SQiang Zhang {
294e46d3be7SQiang Zhang 	_xbc_exit(false);
295e46d3be7SQiang Zhang }
29676db5a27SMasami Hiramatsu 
297a2a9d67aSMasami Hiramatsu /* XBC embedded bootconfig data in kernel */
298a2a9d67aSMasami Hiramatsu #ifdef CONFIG_BOOT_CONFIG_EMBED
299a2a9d67aSMasami Hiramatsu const char * __init xbc_get_embedded_bootconfig(size_t *size);
300a2a9d67aSMasami Hiramatsu #else
301a2a9d67aSMasami Hiramatsu static inline const char *xbc_get_embedded_bootconfig(size_t *size)
302a2a9d67aSMasami Hiramatsu {
303a2a9d67aSMasami Hiramatsu 	return NULL;
304a2a9d67aSMasami Hiramatsu }
305a2a9d67aSMasami Hiramatsu #endif
306a2a9d67aSMasami Hiramatsu 
30776db5a27SMasami Hiramatsu #endif
308