* [PATCH v2 1/3] ARM: start: save end of memory passed to start.
2019-02-27 13:22 [PATCH v2 0/3] VideoCore FDT interop for Raspberry Pi Tomaz Solc
@ 2019-02-27 13:22 ` Tomaz Solc
2019-02-27 13:22 ` [PATCH v2 2/3] ARM: rpi: save fdt that was passed from VideoCore Tomaz Solc
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Tomaz Solc @ 2019-02-27 13:22 UTC (permalink / raw)
To: barebox
Knowing the address of the end of the memory area used by Barebox is
useful if PBL stores some extra data after it, so that board init code
can later retrieve it from there.
---
arch/arm/cpu/start.c | 8 ++++++++
arch/arm/include/asm/barebox-arm.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 768fa9e1b..6573c2ef7 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -38,6 +38,7 @@
unsigned long arm_stack_top;
static unsigned long arm_barebox_size;
+static unsigned long arm_endmem;
static void *barebox_boarddata;
static unsigned long barebox_boarddata_size;
@@ -131,6 +132,12 @@ unsigned long arm_mem_ramoops_get(void)
}
EXPORT_SYMBOL_GPL(arm_mem_ramoops_get);
+unsigned long arm_mem_endmem_get(void)
+{
+ return arm_endmem;
+}
+EXPORT_SYMBOL_GPL(arm_mem_endmem_get);
+
static int barebox_memory_areas_init(void)
{
if(barebox_boarddata)
@@ -163,6 +170,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
+ arm_endmem = endmem;
arm_stack_top = arm_mem_stack_top(membase, endmem);
arm_barebox_size = barebox_size;
malloc_end = barebox_base;
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index e065b479e..a11d34923 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -86,6 +86,7 @@ static inline void boarddata_create(void *adr, u32 machine)
u32 barebox_arm_machine(void);
unsigned long arm_mem_ramoops_get(void);
+unsigned long arm_mem_endmem_get(void);
struct barebox_arm_boarddata_compressed_dtb {
#define BAREBOX_ARM_BOARDDATA_COMPRESSED_DTB_MAGIC 0x7b66bcbd
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] ARM: rpi: save fdt that was passed from VideoCore
2019-02-27 13:22 [PATCH v2 0/3] VideoCore FDT interop for Raspberry Pi Tomaz Solc
2019-02-27 13:22 ` [PATCH v2 1/3] ARM: start: save end of memory passed to start Tomaz Solc
@ 2019-02-27 13:22 ` Tomaz Solc
2019-02-27 13:22 ` [PATCH v2 3/3] ARM: rpi: save bootargs from VC FDT to vc.bootargs Tomaz Solc
2019-03-04 7:48 ` [PATCH v2 0/3] VideoCore FDT interop for Raspberry Pi Sascha Hauer
3 siblings, 0 replies; 5+ messages in thread
From: Tomaz Solc @ 2019-02-27 13:22 UTC (permalink / raw)
To: barebox
On Raspberry Pi, VideoCore firmware creates a device tree that contains
information about peripherals that were initialized by VideoCore based
on settings in config.txt. Normally this device tree is passed to the
Linux kernel via a pointer in the r2 register. A bootloader needs to
pass this device tree to the kernel, or some peripherals will not work
correctly.
Since the VideoCore device tree is not compatible with barebox, we can't
just pass it to barebox_arm_entry() as the internal barebox device tree.
This commit makes the prebootloader code copy the device tree from
VideoCore into a scrap RAM area just above the area reserved for the
bootloader. Board initialization code in the bootloader proper then
copies it into a file /vc.dtb. The bootloader environment is then free
to pass this file to the kernel at boot (e.g. via bootm -o).
---
Documentation/boards/bcm2835.rst | 4 ++
arch/arm/boards/raspberry-pi/lowlevel.c | 68 ++++++++++++++++++++++---------
arch/arm/boards/raspberry-pi/lowlevel.h | 9 ++++
arch/arm/boards/raspberry-pi/rpi-common.c | 34 ++++++++++++++++
4 files changed, 96 insertions(+), 19 deletions(-)
create mode 100644 arch/arm/boards/raspberry-pi/lowlevel.h
diff --git a/Documentation/boards/bcm2835.rst b/Documentation/boards/bcm2835.rst
index ea80d5834..95e910896 100644
--- a/Documentation/boards/bcm2835.rst
+++ b/Documentation/boards/bcm2835.rst
@@ -30,5 +30,9 @@ Raspberry Pi
6. Turn board's power on.
+VideoCore firmware creates a device tree based on the entries in ``config.txt``. This file is available to the Barebox environment in the file ``/vc.dtb``. For example, to boot a kernel shipped with Raspbian::
+
+ bootm -o /vc.dtb /boot/kernel7.img
+
.. _Raspberry Pi firmware: https://codeload.github.com/raspberrypi/firmware/zip/80e1fbeb78f9df06701d28c0ed3a3060a3f557ef
.. _documentation for config.txt: https://www.raspberrypi.org/documentation/configuration/config-txt/
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c
index 1a3d39421..4b64f5d1d 100644
--- a/arch/arm/boards/raspberry-pi/lowlevel.c
+++ b/arch/arm/boards/raspberry-pi/lowlevel.c
@@ -3,43 +3,73 @@
#include <common.h>
#include <linux/sizes.h>
#include <mach/platform.h>
+#include <of.h>
-extern char __dtb_bcm2835_rpi_start[];
-ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2)
+#include "lowlevel.h"
+
+static void copy_vc_fdt(void *dest, void *src, unsigned long max_size)
{
- void *fdt = __dtb_bcm2835_rpi_start + get_runtime_offset();
+ struct fdt_header *oftree_src = src;
+ struct fdt_header *oftree_dest = dest;
- arm_cpu_lowlevel_init();
+ unsigned long size = be32_to_cpu(oftree_src->totalsize);
+ if (size > max_size) {
+ oftree_dest->magic = cpu_to_be32(VIDEOCORE_FDT_ERROR);
+ /* Save an error code after the magic value for easier
+ * debugging. We can't print out anything this early */
+ oftree_dest->totalsize = cpu_to_be32(ENOMEM);
+ return;
+ }
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_128M, fdt);
+ memmove(dest, src, size);
}
-extern char __dtb_bcm2836_rpi_2_start[];
-ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2)
+/* Must be inline since stack isn't setup yet. */
+static inline void start_raspberry_pi(unsigned long memsize, void *fdt,
+ void *vc_fdt)
{
- void *fdt = __dtb_bcm2836_rpi_2_start + get_runtime_offset();
+ void *saved_vc_fdt;
+ unsigned long membase = BCM2835_SDRAM_BASE;
+
+ /* A pointer to the FDT created by VideoCore was passed to us in r2. We
+ * reserve some memory just above the region used for Basebox and copy
+ * this FDT there. We fetch it from there later in rpi_devices_init().*/
+ memsize -= VIDEOCORE_FDT_SZ;
arm_cpu_lowlevel_init();
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt);
+ /* Copied from barebox_arm_entry(). We need stack here early
+ * for normal function calls to work. */
+ arm_setup_stack(arm_mem_stack_top(membase, membase + memsize) - 16);
+
+ fdt += get_runtime_offset();
+
+ saved_vc_fdt = (void *)(membase + memsize);
+ copy_vc_fdt(saved_vc_fdt, vc_fdt, VIDEOCORE_FDT_SZ);
+
+ barebox_arm_entry(membase, memsize, fdt);
}
-extern char __dtb_bcm2837_rpi_3_start[];
-ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2)
+extern char __dtb_bcm2835_rpi_start[];
+ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2)
{
- void *fdt = __dtb_bcm2837_rpi_3_start + get_runtime_offset();
+ start_raspberry_pi(SZ_128M, __dtb_bcm2835_rpi_start, (void *)r2);
+}
- arm_cpu_lowlevel_init();
+extern char __dtb_bcm2836_rpi_2_start[];
+ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2)
+{
+ start_raspberry_pi(SZ_512M, __dtb_bcm2836_rpi_2_start, (void *)r2);
+}
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt);
+extern char __dtb_bcm2837_rpi_3_start[];
+ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2)
+{
+ start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_3_start, (void *)r2);
}
extern char __dtb_bcm2837_rpi_cm3_start[];
ENTRY_FUNCTION(start_raspberry_pi_cm3, r0, r1, r2)
{
- void *fdt = __dtb_bcm2837_rpi_cm3_start + get_runtime_offset();
-
- arm_cpu_lowlevel_init();
-
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt);
+ start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_cm3_start, (void *)r2);
}
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.h b/arch/arm/boards/raspberry-pi/lowlevel.h
new file mode 100644
index 000000000..9ef9135b2
--- /dev/null
+++ b/arch/arm/boards/raspberry-pi/lowlevel.h
@@ -0,0 +1,9 @@
+#ifndef __ARCH_ARM_BOARDS_LOWLEVEL_H__
+#define __ARCH_ARM_BOARDS_LOWLEVEL_H__
+
+#include <linux/sizes.h>
+
+#define VIDEOCORE_FDT_SZ SZ_1M
+#define VIDEOCORE_FDT_ERROR 0xdeadfeed
+
+#endif /* __ARCH_ARM_BOARDS_LOWLEVEL_H__ */
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c
index b5d16a15c..fffa882a7 100644
--- a/arch/arm/boards/raspberry-pi/rpi-common.c
+++ b/arch/arm/boards/raspberry-pi/rpi-common.c
@@ -16,21 +16,26 @@
#include <common.h>
#include <init.h>
#include <fs.h>
+#include <of.h>
#include <linux/stat.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <envfs.h>
#include <malloc.h>
+#include <libfile.h>
#include <gpio.h>
#include <net.h>
#include <led.h>
#include <asm/armlinux.h>
+#include <asm/barebox-arm.h>
#include <generated/mach-types.h>
+#include <linux/sizes.h>
#include <mach/core.h>
#include <mach/mbox.h>
#include "rpi.h"
+#include "lowlevel.h"
struct msg_get_arm_mem {
struct bcm2835_mbox_hdr hdr;
@@ -370,12 +375,41 @@ static int rpi_env_init(void)
return 0;
}
+static void rpi_vc_fdt(void)
+{
+ void *saved_vc_fdt;
+ struct fdt_header *oftree;
+ unsigned long magic, size;
+
+ /* VideoCore FDT was copied in PBL just above Barebox memory */
+ saved_vc_fdt = (void *)(arm_mem_endmem_get());
+
+ oftree = saved_vc_fdt;
+ magic = be32_to_cpu(oftree->magic);
+ if (magic != FDT_MAGIC) {
+ pr_err("videocore fdt saved in pbl has invalid magic\n");
+
+ if (magic == VIDEOCORE_FDT_ERROR) {
+ pr_err("there was an error copying fdt in pbl: %d\n",
+ be32_to_cpu(oftree->totalsize));
+ }
+ return;
+ }
+
+ size = be32_to_cpu(oftree->totalsize);
+ if (write_file("/vc.dtb", saved_vc_fdt, size)) {
+ pr_err("failed to save videocore fdt to a file\n");
+ return;
+ }
+}
+
static int rpi_devices_init(void)
{
rpi_model_init();
bcm2835_register_fb();
armlinux_set_architecture(MACH_TYPE_BCM2708);
rpi_env_init();
+ rpi_vc_fdt();
return 0;
}
late_initcall(rpi_devices_init);
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] ARM: rpi: save bootargs from VC FDT to vc.bootargs
2019-02-27 13:22 [PATCH v2 0/3] VideoCore FDT interop for Raspberry Pi Tomaz Solc
2019-02-27 13:22 ` [PATCH v2 1/3] ARM: start: save end of memory passed to start Tomaz Solc
2019-02-27 13:22 ` [PATCH v2 2/3] ARM: rpi: save fdt that was passed from VideoCore Tomaz Solc
@ 2019-02-27 13:22 ` Tomaz Solc
2019-03-04 7:48 ` [PATCH v2 0/3] VideoCore FDT interop for Raspberry Pi Sascha Hauer
3 siblings, 0 replies; 5+ messages in thread
From: Tomaz Solc @ 2019-02-27 13:22 UTC (permalink / raw)
To: barebox
When booting a Raspberry Pi, it is useful to extract bootargs from the
device tree that was created by the VideoCore firmware. These bootargs
contain for example settings for the framebuffer that the kernel needs
to properly set the video output.
This commit extracts the bootargs in the board initialization code and
saves them to the vc.bootargs global variable.
For example, a bootloader environment can then add the contents of this
variable to linux.bootargs.vc, which then gets included into the final
bootargs for the kernel using CONFIG_FLEXIBLE_BOOTARGS.
---
Documentation/boards/bcm2835.rst | 6 ++++
arch/arm/boards/raspberry-pi/rpi-common.c | 47 +++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/Documentation/boards/bcm2835.rst b/Documentation/boards/bcm2835.rst
index 95e910896..e9ad1d4d5 100644
--- a/Documentation/boards/bcm2835.rst
+++ b/Documentation/boards/bcm2835.rst
@@ -34,5 +34,11 @@ VideoCore firmware creates a device tree based on the entries in ``config.txt``.
bootm -o /vc.dtb /boot/kernel7.img
+VideoCore device tree also contains the kernel command-line that is constructed from ``cmdline.txt`` and other parameters internally determined by the VideoCore firmware. Normally in Barebox this command-line gets overwritten on boot by the Linux bootargs (see :ref:`booting_linux`).
+
+The original command-line from VideoCore device tree is available to the Barebox environment in the ``vc.bootargs`` global variable. For example, to append it to the Linux bootargs::
+
+ global linux.bootargs.vc="$global.vc.bootargs"
+
.. _Raspberry Pi firmware: https://codeload.github.com/raspberrypi/firmware/zip/80e1fbeb78f9df06701d28c0ed3a3060a3f557ef
.. _documentation for config.txt: https://www.raspberrypi.org/documentation/configuration/config-txt/
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c
index fffa882a7..9d334cde1 100644
--- a/arch/arm/boards/raspberry-pi/rpi-common.c
+++ b/arch/arm/boards/raspberry-pi/rpi-common.c
@@ -30,6 +30,7 @@
#include <asm/barebox-arm.h>
#include <generated/mach-types.h>
#include <linux/sizes.h>
+#include <globalvar.h>
#include <mach/core.h>
#include <mach/mbox.h>
@@ -375,11 +376,50 @@ static int rpi_env_init(void)
return 0;
}
+/* Extract /chosen/bootargs from the VideoCore FDT into vc.bootargs
+ * global variable. */
+static int rpi_vc_fdt_bootargs(void *fdt)
+{
+ int ret = 0;
+ struct device_node *root = NULL, *node;
+ const char *cmdline;
+
+ root = of_unflatten_dtb(fdt);
+ if (IS_ERR(root)) {
+ ret = PTR_ERR(root);
+ root = NULL;
+ goto out;
+ }
+
+ node = of_find_node_by_path_from(root, "/chosen");
+ if (!node) {
+ pr_err("no /chosen node\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ cmdline = of_get_property(node, "bootargs", NULL);
+ if (!cmdline) {
+ pr_err("no bootargs property in the /chosen node\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ globalvar_add_simple("vc.bootargs", cmdline);
+
+out:
+ if (root)
+ of_delete_node(root);
+
+ return ret;
+}
+
static void rpi_vc_fdt(void)
{
void *saved_vc_fdt;
struct fdt_header *oftree;
unsigned long magic, size;
+ int ret;
/* VideoCore FDT was copied in PBL just above Barebox memory */
saved_vc_fdt = (void *)(arm_mem_endmem_get());
@@ -401,6 +441,13 @@ static void rpi_vc_fdt(void)
pr_err("failed to save videocore fdt to a file\n");
return;
}
+
+ ret = rpi_vc_fdt_bootargs(saved_vc_fdt);
+ if (ret) {
+ pr_err("failed to extract bootargs from videocore fdt: %d\n",
+ ret);
+ return;
+ }
}
static int rpi_devices_init(void)
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread