lib/bootconfig: Add override operator support
Add the value override operator (":=") support to the bootconfig. This value override operator will be useful for the bootloaders which will only update the existing bootconfig according to the bootloader boot options. Without this override operator, the bootloader needs to parse the existing bootconfig and update it. However, with this assignment, it can just append the updated (partial) bootconfig text at the tail of existing one without parsing it. (Of course, it must update the size, checksum and magic, but that will be done easily) Link: https://lkml.kernel.org/r/159482882954.126704.16209517125614438640.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
80a6e707dd
commit
a2de2f86ae
|
@ -329,22 +329,30 @@ const char * __init xbc_node_find_next_key_value(struct xbc_node *root,
|
||||||
|
|
||||||
/* XBC parse and tree build */
|
/* XBC parse and tree build */
|
||||||
|
|
||||||
|
static int __init xbc_init_node(struct xbc_node *node, char *data, u32 flag)
|
||||||
|
{
|
||||||
|
unsigned long offset = data - xbc_data;
|
||||||
|
|
||||||
|
if (WARN_ON(offset >= XBC_DATA_MAX))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
node->data = (u16)offset | flag;
|
||||||
|
node->child = 0;
|
||||||
|
node->next = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct xbc_node * __init xbc_add_node(char *data, u32 flag)
|
static struct xbc_node * __init xbc_add_node(char *data, u32 flag)
|
||||||
{
|
{
|
||||||
struct xbc_node *node;
|
struct xbc_node *node;
|
||||||
unsigned long offset;
|
|
||||||
|
|
||||||
if (xbc_node_num == XBC_NODE_MAX)
|
if (xbc_node_num == XBC_NODE_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
node = &xbc_nodes[xbc_node_num++];
|
node = &xbc_nodes[xbc_node_num++];
|
||||||
offset = data - xbc_data;
|
if (xbc_init_node(node, data, flag) < 0)
|
||||||
node->data = (u16)offset;
|
|
||||||
if (WARN_ON(offset >= XBC_DATA_MAX))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
node->data |= flag;
|
|
||||||
node->child = 0;
|
|
||||||
node->next = 0;
|
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -603,7 +611,9 @@ static int __init xbc_parse_kv(char **k, char *v, int op)
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
if (!xbc_add_sibling(v, XBC_VALUE))
|
if (op == ':' && child) {
|
||||||
|
xbc_init_node(child, v, XBC_VALUE);
|
||||||
|
} else if (!xbc_add_sibling(v, XBC_VALUE))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (c == ',') { /* Array */
|
if (c == ',') { /* Array */
|
||||||
|
@ -787,7 +797,7 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
do {
|
do {
|
||||||
q = strpbrk(p, "{}=+;\n#");
|
q = strpbrk(p, "{}=+;:\n#");
|
||||||
if (!q) {
|
if (!q) {
|
||||||
p = skip_spaces(p);
|
p = skip_spaces(p);
|
||||||
if (*p != '\0')
|
if (*p != '\0')
|
||||||
|
@ -798,9 +808,12 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
|
||||||
c = *q;
|
c = *q;
|
||||||
*q++ = '\0';
|
*q++ = '\0';
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case ':':
|
||||||
case '+':
|
case '+':
|
||||||
if (*q++ != '=') {
|
if (*q++ != '=') {
|
||||||
ret = xbc_parse_error("Wrong '+' operator",
|
ret = xbc_parse_error(c == '+' ?
|
||||||
|
"Wrong '+' operator" :
|
||||||
|
"Wrong ':' operator",
|
||||||
q - 2);
|
q - 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue