mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/6] bootm: split bootm_load_devicetree into two functions
@ 2018-06-06  7:11 Sascha Hauer
  2018-06-06  7:11 ` [PATCH 1/6] ARM: bootm: drop usage of data->oftree Sascha Hauer
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

This splits bootm_load_devicetree into two functions to be able to load
the devicetree to an allocated address without having to specify a SDRAM
region, which is sometimes enough.

The rest of the series deals with getting rid of data->oftree as it's
not really clear who owns this field. If we are using
bootm_load_devicetree then this is just a reference to the SDRAM region,
which gets released by generic code, but sometimes it points to
allocated memory instead which is forgotten to be freed. So we get rid
of this field altogether.

Sascha

Sascha Hauer (6):
  ARM: bootm: drop usage of data->oftree
  ppc: bootm: rename variables
  ppc: bootm: remove unnecessary parameter
  ppc: bootm: Drop usage of data->oftree
  bootm: Drop data->oftree
  bootm: Split bootm_load_devicetree into two functions

 arch/arm/lib32/bootm.c    | 50 ++++++++++++++++-----------
 arch/arm/lib64/armlinux.c | 12 ++++++-
 arch/ppc/lib/ppclinux.c   | 52 ++++++++++++++--------------
 common/bootm.c            | 72 ++++++++++++++++++++++-----------------
 include/bootm.h           |  5 +--
 5 files changed, 111 insertions(+), 80 deletions(-)

-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] ARM: bootm: drop usage of data->oftree
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  2018-06-06  7:11 ` [PATCH 2/6] ppc: bootm: rename variables Sascha Hauer
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

data->oftree can be replaced with a variable local to the arm code, so
drop usage of data->oftree.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/lib32/bootm.c | 43 +++++++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index c8bf72f0e0..7817e1bdc1 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -130,11 +130,13 @@ static int get_kernel_addresses(size_t image_size,
 	return 0;
 }
 
-static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap)
+static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
+			    int swap, void *fdt)
 {
 	unsigned long kernel;
 	unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
 	enum arm_security_state state = bootm_arm_security_state();
+	void *fdt_load_address = NULL;
 	int ret;
 
 	kernel = data->os_res->start + data->os_entry;
@@ -163,16 +165,21 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
 		free_mem = PAGE_ALIGN(initrd_end + 1);
 	}
 
-	ret = bootm_load_devicetree(data, free_mem);
-	if (ret)
-		return ret;
+	if (fdt) {
+		fdt_load_address = fdt;
+	} else {
+		fdt_load_address = (void *)free_mem;
+		ret = bootm_load_devicetree(data, free_mem);
+		if (ret)
+			return ret;
+	}
 
 	if (bootm_verbose(data)) {
 		printf("\nStarting kernel at 0x%08lx", kernel);
 		if (initrd_size)
 			printf(", initrd at 0x%08lx", initrd_start);
-		if (data->oftree)
-			printf(", oftree at 0x%p", data->oftree);
+		if (fdt_load_address)
+			printf(", oftree at 0x%p", fdt_load_address);
 		printf("...\n");
 	}
 
@@ -188,8 +195,8 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
 	if (data->dryrun)
 		return 0;
 
-	start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree,
-		    state);
+	start_linux((void *)kernel, swap, initrd_start, initrd_size,
+		    fdt_load_address, state);
 
 	restart_machine();
 
@@ -212,7 +219,7 @@ static int do_bootm_linux(struct image_data *data)
 	if (ret)
 		return ret;
 
-	return __do_bootm_linux(data, mem_free, 0);
+	return __do_bootm_linux(data, mem_free, 0, NULL);
 }
 
 static struct image_handler uimage_handler = {
@@ -237,7 +244,7 @@ struct zimage_header {
 
 #define ZIMAGE_MAGIC 0x016F2818
 
-static int do_bootz_linux_fdt(int fd, struct image_data *data)
+static int do_bootz_linux_fdt(int fd, struct image_data *data, void **outfdt)
 {
 	struct fdt_header __header, *header;
 	void *oftree;
@@ -245,9 +252,6 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
 
 	u32 end;
 
-	if (data->oftree)
-		return -ENXIO;
-
 	header = &__header;
 	ret = read(fd, header, sizeof(*header));
 	if (ret < 0)
@@ -287,8 +291,8 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
 			pr_err("unable to unflatten devicetree\n");
 			goto err_free;
 		}
-		data->oftree = of_get_fixed_tree(root);
-		if (!data->oftree) {
+		*outfdt = of_get_fixed_tree(root);
+		if (!*outfdt) {
 			pr_err("Unable to get fixed tree\n");
 			ret = -EINVAL;
 			goto err_free;
@@ -296,7 +300,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
 
 		free(oftree);
 	} else {
-		data->oftree = oftree;
+		*outfdt = oftree;
 	}
 
 	pr_info("zImage: concatenated oftree detected\n");
@@ -318,6 +322,7 @@ static int do_bootz_linux(struct image_data *data)
 	size_t image_size;
 	unsigned long load_address = data->os_address;
 	unsigned long mem_free;
+	void *fdt;
 
 	fd = open(data->os_file, O_RDONLY);
 	if (fd < 0) {
@@ -388,13 +393,13 @@ static int do_bootz_linux(struct image_data *data)
 			*(u32 *)ptr = swab32(*(u32 *)ptr);
 	}
 
-	ret = do_bootz_linux_fdt(fd, data);
+	ret = do_bootz_linux_fdt(fd, data, &fdt);
 	if (ret && ret != -ENXIO)
 		goto err_out;
 
 	close(fd);
 
-	return __do_bootm_linux(data, mem_free, swap);
+	return __do_bootm_linux(data, mem_free, swap, fdt);
 
 err_out:
 	close(fd);
@@ -559,7 +564,7 @@ static int do_bootm_aimage(struct image_data *data)
 	else
 		mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M);
 
-	return __do_bootm_linux(data, mem_free, 0);
+	return __do_bootm_linux(data, mem_free, 0, NULL);
 
 err_out:
 	linux_bootargs_overwrite(NULL);
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/6] ppc: bootm: rename variables
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
  2018-06-06  7:11 ` [PATCH 1/6] ARM: bootm: drop usage of data->oftree Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  2018-06-06  7:11 ` [PATCH 3/6] ppc: bootm: remove unnecessary parameter Sascha Hauer
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

In bootm_relocate_fdt 'addr' is used for two different purposes, once for the
os address and once for the new fdt. Make the code more readable by
using two variables describing their meaning, 'os' and 'newfdt'.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/ppc/lib/ppclinux.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 3fca6b2720..ed2f769c25 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -14,34 +14,36 @@
 #include <restart.h>
 #include <fs.h>
 
-static int bootm_relocate_fdt(void *addr, struct image_data *data)
+static int bootm_relocate_fdt(void *os, struct image_data *data)
 {
-	if (addr < LINUX_TLB1_MAX_ADDR) {
+	void *newfdt;
+
+	if (os < LINUX_TLB1_MAX_ADDR) {
 		/* The kernel is within  the boot TLB mapping.
 		 * Put the DTB above if there is no space
 		 * below.
 		 */
-		if (addr < (void *)data->oftree->totalsize) {
-			addr = (void *)PAGE_ALIGN((phys_addr_t)addr +
+		if (os < (void *)data->oftree->totalsize) {
+			os = (void *)PAGE_ALIGN((phys_addr_t)os +
 					data->os->header.ih_size);
-			addr += data->oftree->totalsize;
-			if (addr < LINUX_TLB1_MAX_ADDR)
-				addr = LINUX_TLB1_MAX_ADDR;
+			os += data->oftree->totalsize;
+			if (os < LINUX_TLB1_MAX_ADDR)
+				os = LINUX_TLB1_MAX_ADDR;
 		}
 	}
 
-	if (addr > LINUX_TLB1_MAX_ADDR) {
+	if (os > LINUX_TLB1_MAX_ADDR) {
 		pr_crit("Unable to relocate DTB to Linux TLB\n");
 		return 1;
 	}
 
-	addr = (void *)PAGE_ALIGN_DOWN((phys_addr_t)addr -
+	newfdt = (void *)PAGE_ALIGN_DOWN((phys_addr_t)os -
 			data->oftree->totalsize);
-	memcpy(addr, data->oftree, data->oftree->totalsize);
+	memcpy(newfdt, data->oftree, data->oftree->totalsize);
 	free(data->oftree);
-	data->oftree = addr;
+	data->oftree = newfdt;
 
-	pr_info("Relocating device tree to 0x%p\n", addr);
+	pr_info("Relocating device tree to 0x%p\n", newfdt);
 	return 0;
 }
 
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/6] ppc: bootm: remove unnecessary parameter
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
  2018-06-06  7:11 ` [PATCH 1/6] ARM: bootm: drop usage of data->oftree Sascha Hauer
  2018-06-06  7:11 ` [PATCH 2/6] ppc: bootm: rename variables Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  2018-06-06  7:11 ` [PATCH 4/6] ppc: bootm: Drop usage of data->oftree Sascha Hauer
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

bootm_relocate_fdt takes the os address as parameter, but this can be
extracted from struct image_data, so drop the parameter.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/ppc/lib/ppclinux.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index ed2f769c25..67649f3b46 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -14,8 +14,9 @@
 #include <restart.h>
 #include <fs.h>
 
-static int bootm_relocate_fdt(void *os, struct image_data *data)
+static int bootm_relocate_fdt(struct image_data *data)
 {
+	void *os = (void *)data->os_address;
 	void *newfdt;
 
 	if (os < LINUX_TLB1_MAX_ADDR) {
@@ -73,9 +74,7 @@ static int do_bootm_linux(struct image_data *data)
 		void *addr = data->oftree;
 
 		if ((addr + data->oftree->totalsize) > LINUX_TLB1_MAX_ADDR) {
-			addr = (void *)data->os_address;
-
-			if (bootm_relocate_fdt(addr, data))
+			if (bootm_relocate_fdt(data))
 				goto error;
 		}
 	}
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/6] ppc: bootm: Drop usage of data->oftree
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
                   ` (2 preceding siblings ...)
  2018-06-06  7:11 ` [PATCH 3/6] ppc: bootm: remove unnecessary parameter Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  2018-06-06  7:11 ` [PATCH 5/6] bootm: Drop data->oftree Sascha Hauer
  2018-06-06  7:11 ` [PATCH 6/6] bootm: Split bootm_load_devicetree into two functions Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

The ppc bootm code uses data->oftree to store its private data pointers.
Drop this and use a local variable instead.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/ppc/lib/ppclinux.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 67649f3b46..05c29be7da 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -14,7 +14,8 @@
 #include <restart.h>
 #include <fs.h>
 
-static int bootm_relocate_fdt(struct image_data *data)
+static struct fdt_header *bootm_relocate_fdt(struct image_data *data,
+					     struct fdt_header *fdt)
 {
 	void *os = (void *)data->os_address;
 	void *newfdt;
@@ -24,10 +25,10 @@ static int bootm_relocate_fdt(struct image_data *data)
 		 * Put the DTB above if there is no space
 		 * below.
 		 */
-		if (os < (void *)data->oftree->totalsize) {
+		if (os < (void *)fdt->totalsize) {
 			os = (void *)PAGE_ALIGN((phys_addr_t)os +
 					data->os->header.ih_size);
-			os += data->oftree->totalsize;
+			os += fdt->totalsize;
 			if (os < LINUX_TLB1_MAX_ADDR)
 				os = LINUX_TLB1_MAX_ADDR;
 		}
@@ -35,17 +36,15 @@ static int bootm_relocate_fdt(struct image_data *data)
 
 	if (os > LINUX_TLB1_MAX_ADDR) {
 		pr_crit("Unable to relocate DTB to Linux TLB\n");
-		return 1;
+		return NULL;
 	}
 
-	newfdt = (void *)PAGE_ALIGN_DOWN((phys_addr_t)os -
-			data->oftree->totalsize);
-	memcpy(newfdt, data->oftree, data->oftree->totalsize);
-	free(data->oftree);
-	data->oftree = newfdt;
+	newfdt = (void *)PAGE_ALIGN_DOWN((phys_addr_t)os - fdt->totalsize);
+	memcpy(newfdt, fdt, fdt->totalsize);
+	free(fdt);
 
 	pr_info("Relocating device tree to 0x%p\n", newfdt);
-	return 0;
+	return newfdt;
 }
 
 static int do_bootm_linux(struct image_data *data)
@@ -53,13 +52,14 @@ static int do_bootm_linux(struct image_data *data)
 	void	(*kernel)(void *, void *, unsigned long,
 			unsigned long, unsigned long);
 	int ret;
+	struct fdt_header *fdt;
 
 	ret = bootm_load_os(data, data->os_address);
 	if (ret)
 		return ret;
 
-	data->oftree = of_get_fixed_tree(data->of_root_node);
-	if (!data->oftree) {
+	fdt = of_get_fixed_tree(data->of_root_node);
+	if (!fdt) {
 		pr_err("bootm: No devicetree given.\n");
 		return -EINVAL;
 	}
@@ -71,15 +71,14 @@ static int do_bootm_linux(struct image_data *data)
 	 * Linux mapped TLB.
 	 */
 	if (IS_ENABLED(CONFIG_MPC85xx)) {
-		void *addr = data->oftree;
-
-		if ((addr + data->oftree->totalsize) > LINUX_TLB1_MAX_ADDR) {
-			if (bootm_relocate_fdt(data))
+		if (((void *)fdt + fdt->totalsize) > LINUX_TLB1_MAX_ADDR) {
+			fdt = bootm_relocate_fdt(data, fdt);
+			if (!fdt)
 				goto error;
 		}
 	}
 
-	fdt_add_reserve_map(data->oftree);
+	fdt_add_reserve_map(fdt);
 
 	kernel = (void *)(data->os_address + data->os_entry);
 
@@ -91,7 +90,7 @@ static int do_bootm_linux(struct image_data *data)
 	 *   r6: NULL
 	 *   r7: NULL
 	 */
-	kernel(data->oftree, kernel, 0, 0, 0);
+	kernel(fdt, kernel, 0, 0, 0);
 
 	restart_machine();
 
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/6] bootm: Drop data->oftree
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
                   ` (3 preceding siblings ...)
  2018-06-06  7:11 ` [PATCH 4/6] ppc: bootm: Drop usage of data->oftree Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  2018-06-06  7:11 ` [PATCH 6/6] bootm: Split bootm_load_devicetree into two functions Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

It's no longer necessary to store the devicetree pointer in struct
image_data, it can be replaced with a local variable.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/bootm.c  | 6 ------
 include/bootm.h | 1 -
 2 files changed, 7 deletions(-)

diff --git a/common/bootm.c b/common/bootm.c
index 5ff6683fe7..8167c3a603 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -337,9 +337,6 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 	struct fdt_header *oftree;
 	int ret;
 
-	if (data->oftree)
-		return 0;
-
 	if (!IS_ENABLED(CONFIG_OFTREE))
 		return 0;
 
@@ -431,8 +428,6 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 	if (bootm_verbose(data) > 1)
 		of_print_nodes(data->of_root_node, 0);
 
-	data->oftree = oftree;
-
 	return 0;
 }
 
@@ -576,7 +571,6 @@ int bootm_boot(struct bootm_data *bootm_data)
 		 * When we only allow booting signed images make sure everything
 		 * we boot is in the OS image and not given separately.
 		 */
-		data->oftree = NULL;
 		data->oftree_file = NULL;
 		data->initrd_file = NULL;
 		if (os_type != filetype_oftree) {
diff --git a/include/bootm.h b/include/bootm.h
index 62951d6058..03779772c4 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -78,7 +78,6 @@ struct image_data {
 	void *fit_config;
 
 	struct device_node *of_root_node;
-	struct fdt_header *oftree;
 	struct resource *oftree_res;
 
 	/*
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 6/6] bootm: Split bootm_load_devicetree into two functions
  2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
                   ` (4 preceding siblings ...)
  2018-06-06  7:11 ` [PATCH 5/6] bootm: Drop data->oftree Sascha Hauer
@ 2018-06-06  7:11 ` Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-06-06  7:11 UTC (permalink / raw)
  To: Barebox List

It is not always desired to get the devicetree from image data and load
it to a SDRAM region at the same time. Sometimes it's enough to just
load it to an allocated address (in case the user has no constraints
where the devicetree should be placed.

This patch splits bootm_load_devicetree into bootm_get_devicetree which
returns a pointer to the allocated devicetree and bootm_load_devicetree
which loads the devicetree to a specified region.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/lib32/bootm.c    | 13 ++++++--
 arch/arm/lib64/armlinux.c | 12 ++++++-
 common/bootm.c            | 66 ++++++++++++++++++++++++---------------
 include/bootm.h           |  4 ++-
 4 files changed, 64 insertions(+), 31 deletions(-)

diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index 7817e1bdc1..a205228b43 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -165,11 +165,18 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
 		free_mem = PAGE_ALIGN(initrd_end + 1);
 	}
 
+	if (!fdt) {
+		fdt = bootm_get_devicetree(data);
+		if (IS_ERR(fdt))
+			return PTR_ERR(fdt);
+	}
+
 	if (fdt) {
-		fdt_load_address = fdt;
-	} else {
 		fdt_load_address = (void *)free_mem;
-		ret = bootm_load_devicetree(data, free_mem);
+		ret = bootm_load_devicetree(data, fdt, free_mem);
+
+		free(fdt);
+
 		if (ret)
 			return ret;
 	}
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 238e8b67a4..afa56792fb 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -38,6 +38,7 @@ static int do_bootm_linux(struct image_data *data)
 	resource_size_t start, end;
 	unsigned long text_offset, image_size, devicetree, kernel;
 	int ret;
+	void *fdt;
 
 	text_offset = le64_to_cpup(data->os_header + 8);
 	image_size = le64_to_cpup(data->os_header + 16);
@@ -54,7 +55,16 @@ static int do_bootm_linux(struct image_data *data)
 
 	devicetree = ALIGN(kernel + image_size, PAGE_SIZE);
 
-	ret = bootm_load_devicetree(data, devicetree);
+	fdt = bootm_get_devicetree(data);
+	if (IS_ERR(fdt)) {
+		ret = PTR_ERR(fdt);
+		goto out;
+	}
+
+	ret = bootm_load_devicetree(data, fdt, devicetree);
+
+	free(fdt);
+
 	if (ret)
 		goto out;
 
diff --git a/common/bootm.c b/common/bootm.c
index 8167c3a603..b95bca4984 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -320,25 +320,24 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
 }
 
 /*
- * bootm_load_devicetree() - load devicetree
+ * bootm_get_devicetree() - get devicetree
  *
  * @data:		image data context
- * @load_address:	The address where the devicetree should be loaded to
  *
- * This loads the devicetree to a RAM location. load_address must be a valid
- * address. The resulting devicetree will be found at data->oftree.
+ * This gets the fixed devicetree from the various image sources or the internal
+ * devicetree. It returns a pointer to the allocated devicetree which must be
+ * freed after use.
  *
- * Return: 0 on success, negative error code otherwise
+ * Return: pointer to the fixed devicetree or a ERR_PTR() on failure.
  */
-int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
+void *bootm_get_devicetree(struct image_data *data)
 {
 	enum filetype type;
-	int fdt_size;
 	struct fdt_header *oftree;
 	int ret;
 
 	if (!IS_ENABLED(CONFIG_OFTREE))
-		return 0;
+		return ERR_PTR(-ENOSYS);
 
 	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
 	    fit_has_image(data->os_fit, data->fit_config, "fdt")) {
@@ -348,7 +347,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 		ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
 				     &of_tree, &of_size);
 		if (ret)
-			return ret;
+			return ERR_PTR(ret);
 
 		data->of_root_node = of_unflatten_dtb(of_tree);
 	} else if (data->oftree_file) {
@@ -359,7 +358,7 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 		if ((int)type < 0) {
 			printf("could not open %s: %s\n", data->oftree_file,
 					strerror(-type));
-			return (int)type;
+			return ERR_PTR((int)type);
 		}
 
 		switch (type) {
@@ -372,11 +371,11 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 					  FILESIZE_MAX);
 			break;
 		default:
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 		}
 
 		if (ret)
-			return ret;
+			return ERR_PTR(ret);
 
 		data->of_root_node = of_unflatten_dtb(oftree);
 
@@ -385,13 +384,13 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 		if (IS_ERR(data->of_root_node)) {
 			data->of_root_node = NULL;
 			pr_err("unable to unflatten devicetree\n");
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 		}
 
 	} else {
 		data->of_root_node = of_get_root_node();
 		if (!data->of_root_node)
-			return 0;
+			return NULL;
 
 		if (bootm_verbose(data) > 1 && data->of_root_node)
 			printf("using internal devicetree\n");
@@ -405,24 +404,39 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 
 	oftree = of_get_fixed_tree(data->of_root_node);
 	if (!oftree)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
-	fdt_size = be32_to_cpu(oftree->totalsize);
+	fdt_add_reserve_map(oftree);
 
-	data->oftree_res = request_sdram_region("oftree", load_address,
-			fdt_size);
-	if (!data->oftree_res) {
-		free(oftree);
-		return -ENOMEM;
-	}
+	return oftree;
+}
 
-	memcpy((void *)data->oftree_res->start, oftree, fdt_size);
+/*
+ * bootm_load_devicetree() - load devicetree
+ *
+ * @data:		image data context
+ * @fdt:		The flat device tree to load
+ * @load_address:	The address where the devicetree should be loaded to
+ *
+ * This loads the devicetree to a RAM location. load_address must be a valid
+ * address which is requested with request_sdram_region. The associated region
+ * is released automatically in the bootm error path.
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+int bootm_load_devicetree(struct image_data *data, void *fdt,
+			    unsigned long load_address)
+{
+	int fdt_size;
 
-	free(oftree);
+	fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
 
-	oftree = (void *)data->oftree_res->start;
+	data->oftree_res = request_sdram_region("oftree", load_address,
+			fdt_size);
+	if (!data->oftree_res)
+		return -ENOMEM;
 
-	fdt_add_reserve_map(oftree);
+	memcpy((void *)data->oftree_res->start, fdt, fdt_size);
 
 	of_print_cmdline(data->of_root_node);
 	if (bootm_verbose(data) > 1)
diff --git a/include/bootm.h b/include/bootm.h
index 03779772c4..fdc73f711a 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -125,7 +125,9 @@ int bootm_load_os(struct image_data *data, unsigned long load_address);
 bool bootm_has_initrd(struct image_data *data);
 int bootm_load_initrd(struct image_data *data, unsigned long load_address);
 
-int bootm_load_devicetree(struct image_data *data, unsigned long load_address);
+void *bootm_get_devicetree(struct image_data *data);
+int bootm_load_devicetree(struct image_data *data, void *fdt,
+			  unsigned long load_address);
 int bootm_get_os_size(struct image_data *data);
 
 enum bootm_verify bootm_get_verify_mode(void);
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-06-06  7:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-06  7:11 [PATCH 0/6] bootm: split bootm_load_devicetree into two functions Sascha Hauer
2018-06-06  7:11 ` [PATCH 1/6] ARM: bootm: drop usage of data->oftree Sascha Hauer
2018-06-06  7:11 ` [PATCH 2/6] ppc: bootm: rename variables Sascha Hauer
2018-06-06  7:11 ` [PATCH 3/6] ppc: bootm: remove unnecessary parameter Sascha Hauer
2018-06-06  7:11 ` [PATCH 4/6] ppc: bootm: Drop usage of data->oftree Sascha Hauer
2018-06-06  7:11 ` [PATCH 5/6] bootm: Drop data->oftree Sascha Hauer
2018-06-06  7:11 ` [PATCH 6/6] bootm: Split bootm_load_devicetree into two functions Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox