summaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-08-12 12:51:14 -0400
committerTom Rini <trini@konsulko.com>2022-08-12 12:51:14 -0400
commit6fc212779c990ff27a430e370bfb8fac01ddde7f (patch)
tree32ecaafa1d653e275683cfacac41dd2bb57efca1 /drivers/core
parentf5003e0791dbe796bf7b41515d67ae5527679ec9 (diff)
parent5fe76d460d857b00d582d7cd6cea9ac740ea912b (diff)
Merge branch '2022-08-11-verified-boot-for-embedded-initial-support'
To quote Simon: This adds the concept of a VBE method to U-Boot, along with an implementation of the 'VBE simple' method, basically a simple way of updating firmware in MMC from userspace and monitoring it from U-Boot. VBE simple is implemented in fwupd. U-Boot's role is to set up the device tree with the required firmware-update properties and provide the developer with information about the current VBE state. To that end this series includes a new 'vbe' command that allows VBE methods to be listed and examined. As part of this work, support for doing FDT fixups via the event interface is provided, along with the ability to write to the device tree via the ofnode interface. Another (significant) change is that bootmeths now have a 'global' flag, to allow the implementation of EFI bootmgr (and VBE) to be cleaned up. The 'system' bootdev is no-longer needed and these bootmeths are scanned first. Further work is needed to pull everything together, but this is a step along the way.
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/of_access.c57
-rw-r--r--drivers/core/ofnode.c81
2 files changed, 86 insertions, 52 deletions
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index c20b19cb50f..a52f5a6b18b 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -343,24 +343,30 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent,
#define for_each_property_of_node(dn, pp) \
for (pp = dn->properties; pp != NULL; pp = pp->next)
-struct device_node *of_find_node_opts_by_path(const char *path,
+struct device_node *of_find_node_opts_by_path(struct device_node *root,
+ const char *path,
const char **opts)
{
struct device_node *np = NULL;
struct property *pp;
const char *separator = strchr(path, ':');
+ if (!root)
+ root = gd->of_root;
if (opts)
*opts = separator ? separator + 1 : NULL;
if (strcmp(path, "/") == 0)
- return of_node_get(gd->of_root);
+ return of_node_get(root);
/* The path could begin with an alias */
if (*path != '/') {
int len;
const char *p = separator;
+ /* Only allow alias processing on the control FDT */
+ if (root != gd->of_root)
+ return NULL;
if (!p)
p = strchrnul(path, '/');
len = p - path;
@@ -383,7 +389,7 @@ struct device_node *of_find_node_opts_by_path(const char *path,
/* Step down the tree matching path components */
if (!np)
- np = of_node_get(gd->of_root);
+ np = of_node_get(root);
while (np && *path == '/') {
struct device_node *tmp = np;
@@ -791,7 +797,7 @@ int of_alias_scan(void)
name = of_get_property(of_chosen, "stdout-path", NULL);
if (name)
- of_stdout = of_find_node_opts_by_path(name,
+ of_stdout = of_find_node_opts_by_path(NULL, name,
&of_stdout_options);
}
@@ -881,3 +887,46 @@ struct device_node *of_get_stdout(void)
{
return of_stdout;
}
+
+int of_write_prop(struct device_node *np, const char *propname, int len,
+ const void *value)
+{
+ struct property *pp;
+ struct property *pp_last = NULL;
+ struct property *new;
+
+ if (!np)
+ return -EINVAL;
+
+ for (pp = np->properties; pp; pp = pp->next) {
+ if (strcmp(pp->name, propname) == 0) {
+ /* Property exists -> change value */
+ pp->value = (void *)value;
+ pp->length = len;
+ return 0;
+ }
+ pp_last = pp;
+ }
+
+ if (!pp_last)
+ return -ENOENT;
+
+ /* Property does not exist -> append new property */
+ new = malloc(sizeof(struct property));
+ if (!new)
+ return -ENOMEM;
+
+ new->name = strdup(propname);
+ if (!new->name) {
+ free(new);
+ return -ENOMEM;
+ }
+
+ new->value = (void *)value;
+ new->length = len;
+ new->next = NULL;
+
+ pp_last->next = new;
+
+ return 0;
+}
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index a59832ebbfb..45ea84e9fb8 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -552,6 +552,17 @@ ofnode ofnode_path(const char *path)
return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path));
}
+ofnode ofnode_path_root(oftree tree, const char *path)
+{
+ if (of_live_active())
+ return np_to_ofnode(of_find_node_opts_by_path(tree.np, path,
+ NULL));
+ else if (*path != '/' && tree.fdt != gd->fdt_blob)
+ return ofnode_null(); /* Aliases only on control FDT */
+ else
+ return offset_to_ofnode(fdt_path_offset(tree.fdt, path));
+}
+
const void *ofnode_read_chosen_prop(const char *propname, int *sizep)
{
ofnode chosen_node;
@@ -1094,70 +1105,44 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname,
}
}
-int ofnode_write_prop(ofnode node, const char *propname, int len,
- const void *value)
+int ofnode_write_prop(ofnode node, const char *propname, const void *value,
+ int len)
{
- const struct device_node *np = ofnode_to_np(node);
- struct property *pp;
- struct property *pp_last = NULL;
- struct property *new;
-
- if (!of_live_active())
- return -ENOSYS;
-
- if (!np)
- return -EINVAL;
-
- for (pp = np->properties; pp; pp = pp->next) {
- if (strcmp(pp->name, propname) == 0) {
- /* Property exists -> change value */
- pp->value = (void *)value;
- pp->length = len;
- return 0;
- }
- pp_last = pp;
- }
-
- if (!pp_last)
- return -ENOENT;
-
- /* Property does not exist -> append new property */
- new = malloc(sizeof(struct property));
- if (!new)
- return -ENOMEM;
+ if (of_live_active())
+ return of_write_prop(ofnode_to_npw(node), propname, len, value);
+ else
+ return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node),
+ propname, value, len);
- new->name = strdup(propname);
- if (!new->name) {
- free(new);
- return -ENOMEM;
- }
+ return 0;
+}
- new->value = (void *)value;
- new->length = len;
- new->next = NULL;
+int ofnode_write_string(ofnode node, const char *propname, const char *value)
+{
+ assert(ofnode_valid(node));
- pp_last->next = new;
+ debug("%s: %s = %s", __func__, propname, value);
- return 0;
+ return ofnode_write_prop(node, propname, value, strlen(value) + 1);
}
-int ofnode_write_string(ofnode node, const char *propname, const char *value)
+int ofnode_write_u32(ofnode node, const char *propname, u32 value)
{
- if (!of_live_active())
- return -ENOSYS;
+ fdt32_t *val;
assert(ofnode_valid(node));
- debug("%s: %s = %s", __func__, propname, value);
+ log_debug("%s = %x", propname, value);
+ val = malloc(sizeof(*val));
+ if (!val)
+ return -ENOMEM;
+ *val = cpu_to_fdt32(value);
- return ofnode_write_prop(node, propname, strlen(value) + 1, value);
+ return ofnode_write_prop(node, propname, val, sizeof(value));
}
int ofnode_set_enabled(ofnode node, bool value)
{
- if (!of_live_active())
- return -ENOSYS;
-
assert(ofnode_valid(node));
if (value)