Discussion:
[PATCH v2 7/9] blspec: skip all devicetree tests if entry doesn't specify one
Steffen Trumtrar
2017-07-10 10:33:53 UTC
Permalink
If the blspec entry does not specify a devicetree to test against,
it doesn't make any sense to check the compatible of the machine or
find the root node.

Instead of first testing the barebox devicetree check if the entry
specifies one.

Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
common/blspec.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/common/blspec.c b/common/blspec.c
index 8132d141ab5c..b258e6600bbe 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -361,6 +361,14 @@ static bool entry_is_of_compatible(struct blspec_entry *entry)
const char *compat;
char *filename;

+ /* If the entry doesn't specifiy a devicetree we are compatible */
+ devicetree = blspec_entry_var_get(entry, "devicetree");
+ if (!devicetree)
+ return true;
+
+ if (!strcmp(devicetree, "none"))
+ return true;
+
/* If we don't have a root node every entry is compatible */
barebox_root = of_get_root_node();
if (!barebox_root)
@@ -375,14 +383,6 @@ static bool entry_is_of_compatible(struct blspec_entry *entry)
else
abspath = "";

- /* If the entry doesn't specifiy a devicetree we are compatible */
- devicetree = blspec_entry_var_get(entry, "devicetree");
- if (!devicetree)
- return true;
-
- if (!strcmp(devicetree, "none"))
- return true;
-
filename = basprintf("%s/%s", abspath, devicetree);

fdt = read_file(filename, &size);
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:48 UTC
Permalink
Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
common/efi/efi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/common/efi/efi.c b/common/efi/efi.c
index 05c58250f4a7..f924385958e1 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -266,8 +266,7 @@ static int efi_console_init(void)

add_generic_device("efi-stdio", DEVICE_ID_SINGLE, NULL, 0 , 0, 0, NULL);

- if (IS_ENABLED(CONFIG_ARCH_EFI_REGISTER_COM1))
- add_ns16550_device(0, 0x3f8, 0x10, IORESOURCE_IO | IORESOURCE_MEM_8BIT,
+ add_ns16550_device(0, 0x3f8, 0x10, IORESOURCE_IO | IORESOURCE_MEM_8BIT,
&ns16550_plat);

return 0;
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:54 UTC
Permalink
Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
common/efi/efi.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/common/efi/efi.c b/common/efi/efi.c
index cc3051dedae9..2c3ad33976c4 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -42,6 +42,7 @@
#include <efi/efi-device.h>
#include <libfile.h>
#include <state.h>
+#include <bbu.h>

efi_runtime_services_t *RT;
efi_boot_services_t *BS;
@@ -382,6 +383,9 @@ static int efi_postcore_init(void)
free(uuid16);
}

+ bbu_register_std_file_update("fat", 0, "/boot/EFI/BOOT/BOOTx64.EFI",
+ filetype_exe);
+
return 0;
}
postcore_initcall(efi_postcore_init);
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:55 UTC
Permalink
Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
arch/x86/configs/efi_defconfig | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/configs/efi_defconfig b/arch/x86/configs/efi_defconfig
index 0d9a44a4d23e..3e83fd92d9ea 100644
--- a/arch/x86/configs/efi_defconfig
+++ b/arch/x86/configs/efi_defconfig
@@ -15,12 +15,12 @@ CONFIG_CONSOLE_ACTIVATE_ALL=y
CONFIG_PARTITION_DISK_EFI=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_POLLER=y
+CONFIG_STATE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LL=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_MEMINFO=y
-# CONFIG_CMD_LINUX16 is not set
CONFIG_CMD_GO=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_RESET=y
@@ -61,6 +61,7 @@ CONFIG_CMD_OF_NODE=y
CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OFTREE=y
CONFIG_CMD_TIME=y
+CONFIG_CMD_STATE=y
CONFIG_NET=y
CONFIG_NET_NFS=y
CONFIG_NET_NETCONSOLE=y
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:49 UTC
Permalink
Instead of erroring out when a file is not present, just return ENOENT if the
file does not exist and let the fs-layer handle the situation correctly.

Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
fs/efi.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/fs/efi.c b/fs/efi.c
index 0c0f52e87c47..85ff914291ed 100644
--- a/fs/efi.c
+++ b/fs/efi.c
@@ -407,9 +407,7 @@ static int efifs_stat(struct device_d *dev, const char *filename, struct stat *s

efiret = priv->root_dir->open(priv->root_dir, &entry, efi_path, EFI_FILE_MODE_READ, 0ULL);
if (EFI_ERROR(efiret)) {
- pr_err("%s: unable to Open %s: %s\n", __func__, filename,
- efi_strerror(efiret));
- ret = -efi_errno(efiret);
+ ret = -ENOENT;
goto out_free;
}
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:50 UTC
Permalink
Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
fs/devfs-core.c | 14 ++++++++++++++
include/driver.h | 1 +
2 files changed, 15 insertions(+)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 3368d3ed68bd..be56edd18d80 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -95,6 +95,20 @@ struct cdev *cdev_by_device_node(struct device_node *node)
return NULL;
}

+struct cdev *cdev_by_partuuid(const char *partuuid)
+{
+ struct cdev *cdev;
+
+ if (!partuuid)
+ return NULL;
+
+ list_for_each_entry(cdev, &cdev_list, list) {
+ if (!strcmp(cdev->partuuid, partuuid))
+ return cdev;
+ }
+ return NULL;
+}
+
/**
* device_find_partition - find a partition belonging to a physical device
*
diff --git a/include/driver.h b/include/driver.h
index 3d701f24398a..8617872053d8 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -472,6 +472,7 @@ struct cdev *cdev_by_name(const char *filename);
struct cdev *lcdev_by_name(const char *filename);
struct cdev *cdev_readlink(struct cdev *cdev);
struct cdev *cdev_by_device_node(struct device_node *node);
+struct cdev *cdev_by_partuuid(const char *partuuid);
struct cdev *cdev_open(const char *name, unsigned long flags);
struct cdev *cdev_create_loop(const char *path, ulong flags);
void cdev_remove_loop(struct cdev *cdev);
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:51 UTC
Permalink
When a node is compatible to a fixed-partitions, support searching the
corresponding device via the partuuid, if it specified in the device tree.

Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
Changes since v1:
- add documentation

Documentation/devicetree/bindings/mtd/partition.txt | 21 +++++++++++++++++++++
drivers/of/of_path.c | 17 ++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mtd/partition.txt

diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt
new file mode 100644
index 000000000000..ab21ff25bb11
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/partition.txt
@@ -0,0 +1,21 @@
+Representing flash partitions in devicetree
+
+In addition to the upstream binding, another property is added:
+
+Optional properties:
+- partuuid : The partition UUID for this partition.
+
+
+Examples:
+
+***@0 {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ state_part: state {
+ partuuid = "16367da7-c518-499f-9aad-e1f366692365";
+ };
+ };
+};
diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
index 334eab841a01..e53041b0a16c 100644
--- a/drivers/of/of_path.c
+++ b/drivers/of/of_path.c
@@ -56,11 +56,26 @@ static int __of_find_path(struct device_node *node, const char *part, char **out

dev = of_find_device_by_node_path(node->full_name);
if (!dev) {
+ int ret;
+ const char *uuid;
struct device_node *devnode = node->parent;

- if (of_device_is_compatible(devnode, "fixed-partitions"))
+ if (of_device_is_compatible(devnode, "fixed-partitions")) {
devnode = devnode->parent;

+ /* when partuuid is specified short-circuit the search for the cdev */
+ ret = of_property_read_string(node, "partuuid", &uuid);
+ if (!ret) {
+ cdev = cdev_by_partuuid(uuid);
+ if (!cdev)
+ return -ENODEV;
+
+ *outpath = basprintf("/dev/%s", cdev->name);
+
+ return 0;
+ }
+ }
+
dev = of_find_device_by_node_path(devnode->full_name);
if (!dev)
return -ENODEV;
--
2.11.0
Steffen Trumtrar
2017-07-10 10:33:52 UTC
Permalink
Signed-off-by: Steffen Trumtrar <***@pengutronix.de>
---
Changes since v1:
- add documentation

Documentation/boards/efi.rst | 4 ++++
common/efi/efi.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)

diff --git a/Documentation/boards/efi.rst b/Documentation/boards/efi.rst
index ecadb3ebba57..8f78a800ef74 100644
--- a/Documentation/boards/efi.rst
+++ b/Documentation/boards/efi.rst
@@ -42,6 +42,10 @@ architectures. Switching to USB boot in the BIOS should then be enough to
start barebox via USB. Some BIOSes allow to specify a path to a binary to
be executed, others have a "start UEFI shell" entry which executes
EFI/Shellx64.efi on the :term:`ESP`. This can be a barebox binary aswell.
+To use the :ref:`state_framework`, the describing devicetree file ``state.dtb``
+has to be put into the ``EFI/barebox/`` directory.
+Supported backends for EFI are raw partitions that can be discovered via a
+partition UUID.

Running EFI barebox on qemu
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/common/efi/efi.c b/common/efi/efi.c
index f924385958e1..cc3051dedae9 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -40,6 +40,8 @@
#include <efi.h>
#include <efi/efi.h>
#include <efi/efi-device.h>
+#include <libfile.h>
+#include <state.h>

efi_runtime_services_t *RT;
efi_boot_services_t *BS;
@@ -384,6 +386,60 @@ static int efi_postcore_init(void)
}
postcore_initcall(efi_postcore_init);

+static int efi_late_init(void)
+{
+ char *state_desc;
+ int ret;
+
+ state_desc = xasprintf("/boot/EFI/barebox/state.dtb");
+
+ if (state_desc) {
+ void *fdt;
+ size_t size;
+ struct device_node *root = NULL;
+ struct device_node *np = NULL;
+ struct state *state;
+
+ fdt = read_file(state_desc, &size);
+ if (!fdt) {
+ pr_err("unable to read %s: %s\n", state_desc,
+ strerror(errno));
+ return -errno;
+ }
+
+ if (file_detect_type(fdt, size) != filetype_oftree) {
+ pr_err("%s is not an oftree file.\n", state_desc);
+ free(fdt);
+ return -EINVAL;
+ }
+
+ root = of_unflatten_dtb(fdt);
+
+ free(fdt);
+
+ if (IS_ERR(root))
+ return PTR_ERR(root);
+
+ of_set_root_node(root);
+
+ np = of_find_node_by_alias(root, "state");
+
+ state = state_new_from_node(np, NULL, 0, 0, false);
+ if (IS_ERR(state))
+ return PTR_ERR(state);
+
+ ret = state_load(state);
+ if (ret)
+ pr_warn("Failed to load persistent state, continuing with defaults, %d\n",
+ ret);
+
+ return 0;
+ }
+
+ return 0;
+}
+late_initcall(efi_late_init);
+
static int do_efiexit(int argc, char *argv[])
{
return BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
--
2.11.0
Lucas Stach
2017-07-10 13:49:07 UTC
Permalink
This commit breaks compilation of the efi_defconfig with:
barebox/common/efi/efi.c:427: undefined reference to `state_new_from_node'
barebox/common/efi/efi.c:431: undefined reference to `state_load'

You probably don't want to compile in this initcall when !CONFIG_STATE.

Regards,
Lucas
Post by Steffen Trumtrar
---
- add documentation
Documentation/boards/efi.rst | 4 ++++
common/efi/efi.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/Documentation/boards/efi.rst b/Documentation/boards/efi.rst
index ecadb3ebba57..8f78a800ef74 100644
--- a/Documentation/boards/efi.rst
+++ b/Documentation/boards/efi.rst
@@ -42,6 +42,10 @@ architectures. Switching to USB boot in the BIOS should then be enough to
start barebox via USB. Some BIOSes allow to specify a path to a binary to
be executed, others have a "start UEFI shell" entry which executes
EFI/Shellx64.efi on the :term:`ESP`. This can be a barebox binary aswell.
+To use the :ref:`state_framework`, the describing devicetree file ``state.dtb``
+has to be put into the ``EFI/barebox/`` directory.
+Supported backends for EFI are raw partitions that can be discovered via a
+partition UUID.
Running EFI barebox on qemu
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/common/efi/efi.c b/common/efi/efi.c
index f924385958e1..cc3051dedae9 100644
--- a/common/efi/efi.c
+++ b/common/efi/efi.c
@@ -40,6 +40,8 @@
#include <efi.h>
#include <efi/efi.h>
#include <efi/efi-device.h>
+#include <libfile.h>
+#include <state.h>
efi_runtime_services_t *RT;
efi_boot_services_t *BS;
@@ -384,6 +386,60 @@ static int efi_postcore_init(void)
}
postcore_initcall(efi_postcore_init);
+static int efi_late_init(void)
+{
+ char *state_desc;
+ int ret;
+
+ state_desc = xasprintf("/boot/EFI/barebox/state.dtb");
+
+ if (state_desc) {
+ void *fdt;
+ size_t size;
+ struct device_node *root = NULL;
+ struct device_node *np = NULL;
+ struct state *state;
+
+ fdt = read_file(state_desc, &size);
+ if (!fdt) {
+ pr_err("unable to read %s: %s\n", state_desc,
+ strerror(errno));
+ return -errno;
+ }
+
+ if (file_detect_type(fdt, size) != filetype_oftree) {
+ pr_err("%s is not an oftree file.\n", state_desc);
+ free(fdt);
+ return -EINVAL;
+ }
+
+ root = of_unflatten_dtb(fdt);
+
+ free(fdt);
+
+ if (IS_ERR(root))
+ return PTR_ERR(root);
+
+ of_set_root_node(root);
+
+ np = of_find_node_by_alias(root, "state");
+
+ state = state_new_from_node(np, NULL, 0, 0, false);
+ if (IS_ERR(state))
+ return PTR_ERR(state);
+
+ ret = state_load(state);
+ if (ret)
+ pr_warn("Failed to load persistent state, continuing with defaults, %d\n",
+ ret);
+
+ return 0;
+ }
+
+ return 0;
+}
+late_initcall(efi_late_init);
+
static int do_efiexit(int argc, char *argv[])
{
return BS->exit(efi_parent_image, EFI_SUCCESS, 0, NULL);
Lucas Stach
2017-07-11 15:00:16 UTC
Permalink
Post by Lucas Stach
barebox/common/efi/efi.c:427: undefined reference to `state_new_from_node'
barebox/common/efi/efi.c:431: undefined reference to `state_load'
You probably don't want to compile in this initcall when !CONFIG_STATE.
I've added a fix for this while applying.

Regards,
Lucas

Loading...