Hello, There were still a few things missing for real support for the ZynqMP ZCU104 in Barebox. This series adds support for reset source detection, Barebox environment, barebox_update and soft reset (via PSCI) for the ZynqMP ZCU104 board. It extends the zynqmp_defconfig to enable more features that you would probably want by default on a ZynqMP board. I also added some introductory information how to build and use Barebox on the ZynqMP. Michael Michael Tretter (7): ARM: zynqmp: set reset source clk: zynqmp: do not enable already enabled clocks dts: zcu104: add Barebox environment ARM: zynqmp: add update handler ARM: zynqmp: zcu104: register update handler ARM: zynqmp: defconfig: enable more features Documentation: zynqmp: add some documentation Documentation/boards/zynqmp.rst | 40 ++++++++++ arch/arm/boards/xilinx-zcu104/Makefile | 1 + arch/arm/boards/xilinx-zcu104/board.c | 18 +++++ arch/arm/configs/zynqmp_defconfig | 23 ++++++ arch/arm/dts/zynqmp-zcu104-revA.dts | 10 +++ arch/arm/mach-zynqmp/Makefile | 2 + .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++ arch/arm/mach-zynqmp/include/mach/zynqmp.h | 6 ++ arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 ++++++++++++ arch/arm/mach-zynqmp/zynqmp.c | 74 +++++++++++++++++++ drivers/clk/zynqmp/clk-gate-zynqmp.c | 3 + 11 files changed, 246 insertions(+) create mode 100644 Documentation/boards/zynqmp.rst create mode 100644 arch/arm/boards/xilinx-zcu104/board.c create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp.h create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c create mode 100644 arch/arm/mach-zynqmp/zynqmp.c -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
The reset reason is available in the APB register set on the ZynqMP. Read the reset reason and set the reset source accordingly. There might be multiple bits set in the APB register. Use the MSB for determining the actual reset source. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- arch/arm/mach-zynqmp/Makefile | 1 + arch/arm/mach-zynqmp/include/mach/zynqmp.h | 6 ++ arch/arm/mach-zynqmp/zynqmp.c | 74 ++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp.h create mode 100644 arch/arm/mach-zynqmp/zynqmp.c diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index 021efc94afaf..14b8a4e46b87 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-or-later obj-y += firmware-zynqmp.o +obj-y += zynqmp.o diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp.h b/arch/arm/mach-zynqmp/include/mach/zynqmp.h new file mode 100644 index 000000000000..f6c05f35a470 --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp.h @@ -0,0 +1,6 @@ +#ifndef __MACH_ZYNQMP_H +#define __MACH_ZYNQMP_H + +int zynqmp_soc_revision(void); + +#endif /* __MACH_ZYNQMP_H */ diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c new file mode 100644 index 000000000000..2b3bd8406ce9 --- /dev/null +++ b/arch/arm/mach-zynqmp/zynqmp.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> + */ + +#include <common.h> +#include <init.h> +#include <linux/types.h> +#include <reset_source.h> + +#include <mach/zynqmp.h> + +#define ZYNQMP_CRL_APB_BASE 0xff5e0000 +#define ZYNQMP_CRL_APB_RESET_REASON (ZYNQMP_CRL_APB_BASE + 0x220) + +/* External POR: The PS_POR_B reset signal pin was asserted. */ +#define ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL BIT(0) +/* Internal POR: A system error triggered a POR reset. */ +#define ZYNQMP_CRL_APB_RESET_REASON_INTERNAL BIT(1) +/* Internal system reset; A system error triggered a system reset. */ +#define ZYNQMP_CRL_APB_RESET_REASON_PMU BIT(2) +/* PS-only reset: Write to PMU_GLOBAL.GLOBAL_RESET [PS_ONLY_RST]. */ +#define ZYNQMP_CRL_APB_RESET_REASON_PSONLY BIT(3) +/* External system reset: The PS_SRST_B reset signal pin was asserted. */ +#define ZYNQMP_CRL_APB_RESET_REASON_SRST BIT(4) +/* Software system reset: Write to RESET_CTRL [soft_reset]. */ +#define ZYNQMP_CRL_APB_RESET_REASON_SOFT BIT(5) +/* Software debugger reset: Write to BLOCKONLY_RST [debug_only]. */ +#define ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS BIT(6) + +struct zynqmp_reset_reason { + u32 mask; + enum reset_src_type type; +}; + +static const struct zynqmp_reset_reason reset_reasons[] = { + { ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS, RESET_UKWN }, + { ZYNQMP_CRL_APB_RESET_REASON_SOFT, RESET_RST }, + { ZYNQMP_CRL_APB_RESET_REASON_SRST, RESET_POR }, + { ZYNQMP_CRL_APB_RESET_REASON_PSONLY, RESET_POR }, + { ZYNQMP_CRL_APB_RESET_REASON_PMU, RESET_POR }, + { ZYNQMP_CRL_APB_RESET_REASON_INTERNAL, RESET_POR }, + { ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL, RESET_POR }, + { /* sentinel */ } +}; + +static enum reset_src_type zynqmp_get_reset_src(void) +{ + enum reset_src_type type = RESET_UKWN; + unsigned int i; + u32 val; + + val = readl(ZYNQMP_CRL_APB_RESET_REASON); + + for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) { + if (val & reset_reasons[i].mask) { + type = reset_reasons[i].type; + break; + } + } + + pr_info("ZynqMP reset reason %s (ZYNQMP_CRL_APB_RESET_REASON: 0x%08x)\n", + reset_source_to_string(type), val); + + return type; +} + +static int zynqmp_init(void) +{ + reset_source_set(zynqmp_get_reset_src()); + + return 0; +} +postcore_initcall(zynqmp_init); -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
The pmu fw manages the permissions who can enable/disable the clocks. There are a few clocks (TOPSW_LSBUS and LSBUS) which are exposed to Barebox and Barebox assumes that is has to enable the clocks. However, the pmu fw considers the clocks under its control and returns a permission denied for the clock enable request. Assume that clocks that are already enabled don't need to be enable by Barebox to avoid the permission denied errors. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- drivers/clk/zynqmp/clk-gate-zynqmp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c index a3b9ee21e506..493c1dfeaaa3 100644 --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c @@ -28,6 +28,9 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw) { struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); + if (clk_hw_is_enabled(hw)) + return 0; + return gate->ops->clock_enable(gate->clk_id); } -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Use the same partition on the SD-card that is used by the ROM loader to find the BOOT.BIN (which contains the FSBL and Barebox) to store the Barebox environment. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- arch/arm/dts/zynqmp-zcu104-revA.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 8c467ee97045..95b60a6b1d69 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -8,3 +8,13 @@ */ #include <arm64/xilinx/zynqmp-zcu104-revA.dts> + +/ { + chosen { + environment { + compatible = "barebox,environment"; + device-path = &sdhci1, "partname:0"; + file-path = "barebox.env"; + }; + }; +}; -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
The ZynqMP boots from an SDHCI device by reading a boot.bin file from the FAT16/32 partition, which is the first partition in the MBR. The update handler copies a boot.bin image to this partition, which might be board specific. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- arch/arm/mach-zynqmp/Makefile | 1 + .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++++ arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index 14b8a4e46b87..e24a43c0d59f 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-or-later obj-y += firmware-zynqmp.o obj-y += zynqmp.o +obj-$(CONFIG_BAREBOX_UPDATE) += zynqmp-bbu.o diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h new file mode 100644 index 000000000000..8502791ee0f7 --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> + */ +#ifndef __MACH_ZYNQMP_BBU_H +#define __MACH_ZYNQMP_BBU_H + +#include <bbu.h> + +#ifdef CONFIG_BAREBOX_UPDATE +int zynqmp_bbu_register_handler(const char *name, char *devicefile, + unsigned long flags); +#else +static int zynqmp_bbu_register_handler(const char *name, char *devicefile, + unsigned long flags) +{ + return 0; +}; +#endif + +#endif /* __MACH_ZYNQMP_BBU_H */ diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c new file mode 100644 index 000000000000..d1197c01dc41 --- /dev/null +++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> + */ + +#include <common.h> +#include <libfile.h> +#include <mach/zynqmp-bbu.h> + +static int zynqmp_bbu_handler(struct bbu_handler *handler, + struct bbu_data *data) +{ + int ret = 0; + + ret = bbu_confirm(data); + if (ret) + return ret; + + ret = copy_file(data->imagefile, data->devicefile, 1); + if (ret < 0) { + pr_err("update failed: %s", strerror(-ret)); + return ret; + } + + return ret; +} + +int zynqmp_bbu_register_handler(const char *name, char *devicefile, + unsigned long flags) +{ + struct bbu_handler *handler; + int ret = 0; + + if (!name || !devicefile) + return -EINVAL; + + handler = xzalloc(sizeof(*handler)); + handler->name = name; + handler->devicefile = devicefile; + handler->flags = flags; + handler->handler = zynqmp_bbu_handler; + + ret = bbu_register_handler(handler); + if (ret) + free(handler); + + return ret; +} -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
As the zcu104 stores the environment in the same partition as the barebox image, the partition is already mounted in ENV_MNT_DIR ("/boot"). Therefore, the update handler has to use the already existing mount point for the update. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- arch/arm/boards/xilinx-zcu104/Makefile | 1 + arch/arm/boards/xilinx-zcu104/board.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 arch/arm/boards/xilinx-zcu104/board.c diff --git a/arch/arm/boards/xilinx-zcu104/Makefile b/arch/arm/boards/xilinx-zcu104/Makefile index 884d6e63b019..297f77d57ab1 100644 --- a/arch/arm/boards/xilinx-zcu104/Makefile +++ b/arch/arm/boards/xilinx-zcu104/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-or-later +obj-y += board.o lwl-y += lowlevel.o lowlevel_init.o diff --git a/arch/arm/boards/xilinx-zcu104/board.c b/arch/arm/boards/xilinx-zcu104/board.c new file mode 100644 index 000000000000..7654d2bfac90 --- /dev/null +++ b/arch/arm/boards/xilinx-zcu104/board.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> + */ + +#include <common.h> +#include <init.h> +#include <mach/zynqmp-bbu.h> + +static int zcu104_register_update_handler(void) +{ + if (!of_machine_is_compatible("xlnx,zynqmp-zcu104")) + return 0; + + return zynqmp_bbu_register_handler("SD", "/boot/BOOT.BIN", + BBU_HANDLER_FLAG_DEFAULT); +} +device_initcall(zcu104_register_update_handler); -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Enable network, file system, and PSCI support in the defconfig to get a Barebox with a useful feature set when building the ZynqMP defconfig. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- arch/arm/configs/zynqmp_defconfig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm/configs/zynqmp_defconfig b/arch/arm/configs/zynqmp_defconfig index 6f5612fa92a0..2cd878133223 100644 --- a/arch/arm/configs/zynqmp_defconfig +++ b/arch/arm/configs/zynqmp_defconfig @@ -1,5 +1,6 @@ CONFIG_ARCH_ZYNQMP=y CONFIG_MACH_XILINX_ZCU104=y +CONFIG_ARM_PSCI_CLIENT=y CONFIG_MMU=y CONFIG_MALLOC_SIZE=0x0 CONFIG_MALLOC_TLSF=y @@ -12,32 +13,54 @@ CONFIG_BOOTM_SHOW_TYPE=y CONFIG_BOOTM_VERBOSE=y CONFIG_BOOTM_INITRD=y CONFIG_BOOTM_OFTREE=y +CONFIG_BLSPEC=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_RESET_SOURCE=y CONFIG_LONGHELP=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_GO=y CONFIG_CMD_RESET=y CONFIG_CMD_PARTITION=y CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_MAGICVAR=y CONFIG_CMD_MAGICVAR_HELP=y CONFIG_CMD_SAVEENV=y CONFIG_CMD_LN=y CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y +CONFIG_CMD_TFTP=y CONFIG_CMD_EDIT=y CONFIG_CMD_MENU=y CONFIG_CMD_MENU_MANAGEMENT=y CONFIG_CMD_READLINE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_BAREBOX_UPDATE=y +CONFIG_CMD_FIRMWARELOAD=y +CONFIG_CMD_OF_OVERLAY=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_OF_BAREBOX_ENV_IN_FS=y +CONFIG_OF_OVERLAY_LIVE=y CONFIG_DRIVER_SERIAL_CADENCE=y CONFIG_DRIVER_NET_MACB=y +CONFIG_DP83867_PHY=y # CONFIG_SPI is not set CONFIG_MCI=y CONFIG_MCI_ARASAN=y CONFIG_FIRMWARE_ZYNQMP_FPGA=y +# CONFIG_VIRTIO_MENU is not set +CONFIG_FS_EXT4=y +CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y CONFIG_DIGEST=y -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Add at least some information how Barebox can be used on the ZynqMP and what is required to create a bootable image. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- Documentation/boards/zynqmp.rst | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/boards/zynqmp.rst diff --git a/Documentation/boards/zynqmp.rst b/Documentation/boards/zynqmp.rst new file mode 100644 index 000000000000..05d41c401dc2 --- /dev/null +++ b/Documentation/boards/zynqmp.rst @@ -0,0 +1,40 @@ +Xilinx ZynqMP Ultrascale+ +========================= + +Barebox has support as a second stage boot loader for the Xilinx ZynqMP +Ultrascale+. + +Image creation +-------------- + +Currently, Barebox only supports booting as a second stage boot loader from an +SD-card. It relies on the FSBL_ to initialize the base system including sdram +setup and pin muxing. + +The ZynqMP defconfig supports the ZCU104 reference board. Use it to build the +Barebox image:: + + make ARCH=arm64 zynqmp_defconfig + make ARCH=arm64 + +.. note:: The resulting image ``images/barebox-zynqmp-zcu104.img`` is **not** an image + that can directly be booted on the ZynqMP. + +For a bootable BOOT.BIN image, you also need to build the FSBL_ and a ZynqMP +TF-A. Prepare these separately using the respective instructions. + +Use bootgen_ or ``mkimage -T zynqmpbif`` from the U-boot tools to build the +final BOOT.BIN image that can be loaded by the ROM code. Check the +instructions for these tools how to prepare the BOOT.BIN image. + +Create a FAT partition as the first partition of the SD card and copy the +produced BOOT.BIN into this partition. + +.. _FSBL: `https://github.com/Xilinx/embeddedsw/` +.. _bootgen: `https://github.com/Xilinx/bootgen` + +Booting Barebox +--------------- + +The FSBL loads the TF-A and Barebox, jumps to the TF-A, which will then return +to Barebox. Afterwards, you can use Barebox as usual. -- 2.29.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On 24.06.21 12:23, Michael Tretter wrote: > The reset reason is available in the APB register set on the ZynqMP. > Read the reset reason and set the reset source accordingly. > > There might be multiple bits set in the APB register. Use the MSB for > determining the actual reset source. APB is usually the AMBA Advanced Peripheral Bus. Perhaps CRL is the actual name of the register and APB just tells that it's mapped there? > > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> > --- > arch/arm/mach-zynqmp/Makefile | 1 + > arch/arm/mach-zynqmp/include/mach/zynqmp.h | 6 ++ > arch/arm/mach-zynqmp/zynqmp.c | 74 ++++++++++++++++++++++ > 3 files changed, 81 insertions(+) > create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp.h > create mode 100644 arch/arm/mach-zynqmp/zynqmp.c > > diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile > index 021efc94afaf..14b8a4e46b87 100644 > --- a/arch/arm/mach-zynqmp/Makefile > +++ b/arch/arm/mach-zynqmp/Makefile > @@ -1,2 +1,3 @@ > # SPDX-License-Identifier: GPL-2.0-or-later > obj-y += firmware-zynqmp.o > +obj-y += zynqmp.o > diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp.h b/arch/arm/mach-zynqmp/include/mach/zynqmp.h > new file mode 100644 > index 000000000000..f6c05f35a470 > --- /dev/null > +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp.h Nitpick: revision.h sounds more self-describing. > @@ -0,0 +1,6 @@ > +#ifndef __MACH_ZYNQMP_H > +#define __MACH_ZYNQMP_H > + > +int zynqmp_soc_revision(void); > + > +#endif /* __MACH_ZYNQMP_H */ > diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c > new file mode 100644 > index 000000000000..2b3bd8406ce9 > --- /dev/null > +++ b/arch/arm/mach-zynqmp/zynqmp.c > @@ -0,0 +1,74 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > + */ > + > +#include <common.h> > +#include <init.h> > +#include <linux/types.h> > +#include <reset_source.h> > + > +#include <mach/zynqmp.h> > + > +#define ZYNQMP_CRL_APB_BASE 0xff5e0000 > +#define ZYNQMP_CRL_APB_RESET_REASON (ZYNQMP_CRL_APB_BASE + 0x220) > + > +/* External POR: The PS_POR_B reset signal pin was asserted. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL BIT(0) > +/* Internal POR: A system error triggered a POR reset. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_INTERNAL BIT(1) > +/* Internal system reset; A system error triggered a system reset. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_PMU BIT(2) > +/* PS-only reset: Write to PMU_GLOBAL.GLOBAL_RESET [PS_ONLY_RST]. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_PSONLY BIT(3) > +/* External system reset: The PS_SRST_B reset signal pin was asserted. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_SRST BIT(4) > +/* Software system reset: Write to RESET_CTRL [soft_reset]. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_SOFT BIT(5) > +/* Software debugger reset: Write to BLOCKONLY_RST [debug_only]. */ > +#define ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS BIT(6) > + > +struct zynqmp_reset_reason { > + u32 mask; > + enum reset_src_type type; > +}; > + > +static const struct zynqmp_reset_reason reset_reasons[] = { > + { ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS, RESET_UKWN }, RESET_JTAG? > + { ZYNQMP_CRL_APB_RESET_REASON_SOFT, RESET_RST }, > + { ZYNQMP_CRL_APB_RESET_REASON_SRST, RESET_POR }, > + { ZYNQMP_CRL_APB_RESET_REASON_PSONLY, RESET_POR }, > + { ZYNQMP_CRL_APB_RESET_REASON_PMU, RESET_POR }, > + { ZYNQMP_CRL_APB_RESET_REASON_INTERNAL, RESET_POR }, > + { ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL, RESET_POR }, RESET_EXT? > + { /* sentinel */ } > +}; > + > +static enum reset_src_type zynqmp_get_reset_src(void) > +{ > + enum reset_src_type type = RESET_UKWN; > + unsigned int i; > + u32 val; > + > + val = readl(ZYNQMP_CRL_APB_RESET_REASON); > + > + for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) { > + if (val & reset_reasons[i].mask) { > + type = reset_reasons[i].type; > + break; > + } > + } > + > + pr_info("ZynqMP reset reason %s (ZYNQMP_CRL_APB_RESET_REASON: 0x%08x)\n", > + reset_source_to_string(type), val); > + > + return type; > +} > + > +static int zynqmp_init(void) > +{ > + reset_source_set(zynqmp_get_reset_src()); > + > + return 0; > +} > +postcore_initcall(zynqmp_init); > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Hi, On 24.06.21 12:23, Michael Tretter wrote: > The ZynqMP boots from an SDHCI device by reading a boot.bin file from > the FAT16/32 partition, which is the first partition in the MBR. > > The update handler copies a boot.bin image to this partition, which > might be board specific. Is barebox the boot.bin or is that a separate first stage bootloader? > > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> > --- > arch/arm/mach-zynqmp/Makefile | 1 + > .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++++ > arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 +++++++++++++++++++ > 3 files changed, 70 insertions(+) > create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c > > diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile > index 14b8a4e46b87..e24a43c0d59f 100644 > --- a/arch/arm/mach-zynqmp/Makefile > +++ b/arch/arm/mach-zynqmp/Makefile > @@ -1,3 +1,4 @@ > # SPDX-License-Identifier: GPL-2.0-or-later > obj-y += firmware-zynqmp.o > obj-y += zynqmp.o > +obj-$(CONFIG_BAREBOX_UPDATE) += zynqmp-bbu.o > diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > new file mode 100644 > index 000000000000..8502791ee0f7 > --- /dev/null > +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > @@ -0,0 +1,21 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > + */ > +#ifndef __MACH_ZYNQMP_BBU_H > +#define __MACH_ZYNQMP_BBU_H > + > +#include <bbu.h> > + > +#ifdef CONFIG_BAREBOX_UPDATE > +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > + unsigned long flags); > +#else > +static int zynqmp_bbu_register_handler(const char *name, char *devicefile, > + unsigned long flags) > +{ > + return 0; > +}; > +#endif > + > +#endif /* __MACH_ZYNQMP_BBU_H */ > diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c > new file mode 100644 > index 000000000000..d1197c01dc41 > --- /dev/null > +++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c > @@ -0,0 +1,48 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > + */ > + > +#include <common.h> > +#include <libfile.h> > +#include <mach/zynqmp-bbu.h> > + > +static int zynqmp_bbu_handler(struct bbu_handler *handler, > + struct bbu_data *data) > +{ > + int ret = 0; > + > + ret = bbu_confirm(data); > + if (ret) > + return ret; > + > + ret = copy_file(data->imagefile, data->devicefile, 1); > + if (ret < 0) { > + pr_err("update failed: %s", strerror(-ret)); > + return ret; > + } > + > + return ret; > +} > + > +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > + unsigned long flags) > +{ > + struct bbu_handler *handler; > + int ret = 0; > + > + if (!name || !devicefile) > + return -EINVAL; > + > + handler = xzalloc(sizeof(*handler)); > + handler->name = name; > + handler->devicefile = devicefile; > + handler->flags = flags; > + handler->handler = zynqmp_bbu_handler; > + > + ret = bbu_register_handler(handler); > + if (ret) > + free(handler); > + > + return ret; > +} > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On Thu, 24 Jun 2021 12:48:44 +0200, Ahmad Fatoum wrote: > On 24.06.21 12:23, Michael Tretter wrote: > > The reset reason is available in the APB register set on the ZynqMP. > > Read the reset reason and set the reset source accordingly. > > > > There might be multiple bits set in the APB register. Use the MSB for > > determining the actual reset source. > > APB is usually the AMBA Advanced Peripheral Bus. Perhaps CRL is the > actual name of the register and APB just tells that it's mapped there? Ack. The data sheet calls it "Clock and Reset control registers for LPD." I will fix it in v2. > > > > > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> > > --- > > arch/arm/mach-zynqmp/Makefile | 1 + > > arch/arm/mach-zynqmp/include/mach/zynqmp.h | 6 ++ > > arch/arm/mach-zynqmp/zynqmp.c | 74 ++++++++++++++++++++++ > > 3 files changed, 81 insertions(+) > > create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp.h > > create mode 100644 arch/arm/mach-zynqmp/zynqmp.c > > > > diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile > > index 021efc94afaf..14b8a4e46b87 100644 > > --- a/arch/arm/mach-zynqmp/Makefile > > +++ b/arch/arm/mach-zynqmp/Makefile > > @@ -1,2 +1,3 @@ > > # SPDX-License-Identifier: GPL-2.0-or-later > > obj-y += firmware-zynqmp.o > > +obj-y += zynqmp.o > > diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp.h b/arch/arm/mach-zynqmp/include/mach/zynqmp.h > > new file mode 100644 > > index 000000000000..f6c05f35a470 > > --- /dev/null > > +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp.h > > Nitpick: revision.h sounds more self-describing. Ok. I thought there might be some more soc specific function instead of revision specific functions here, but revision.h is fine for me as well. > > > @@ -0,0 +1,6 @@ > > +#ifndef __MACH_ZYNQMP_H > > +#define __MACH_ZYNQMP_H > > + > > +int zynqmp_soc_revision(void); > > + > > +#endif /* __MACH_ZYNQMP_H */ > > diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c > > new file mode 100644 > > index 000000000000..2b3bd8406ce9 > > --- /dev/null > > +++ b/arch/arm/mach-zynqmp/zynqmp.c > > @@ -0,0 +1,74 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > > + */ > > + > > +#include <common.h> > > +#include <init.h> > > +#include <linux/types.h> > > +#include <reset_source.h> > > + > > +#include <mach/zynqmp.h> > > + > > +#define ZYNQMP_CRL_APB_BASE 0xff5e0000 > > +#define ZYNQMP_CRL_APB_RESET_REASON (ZYNQMP_CRL_APB_BASE + 0x220) > > + > > +/* External POR: The PS_POR_B reset signal pin was asserted. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL BIT(0) > > +/* Internal POR: A system error triggered a POR reset. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_INTERNAL BIT(1) > > +/* Internal system reset; A system error triggered a system reset. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_PMU BIT(2) > > +/* PS-only reset: Write to PMU_GLOBAL.GLOBAL_RESET [PS_ONLY_RST]. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_PSONLY BIT(3) > > +/* External system reset: The PS_SRST_B reset signal pin was asserted. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_SRST BIT(4) > > +/* Software system reset: Write to RESET_CTRL [soft_reset]. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_SOFT BIT(5) > > +/* Software debugger reset: Write to BLOCKONLY_RST [debug_only]. */ > > +#define ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS BIT(6) > > + > > +struct zynqmp_reset_reason { > > + u32 mask; > > + enum reset_src_type type; > > +}; > > + > > +static const struct zynqmp_reset_reason reset_reasons[] = { > > + { ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS, RESET_UKWN }, > > RESET_JTAG? I am not sure, if I understand RESET_JTAG correctly. The reference manual says that it is like a soft reset while preserving the debug logic and originates in the DAP controller. Is this RESET_JTAG? > > > + { ZYNQMP_CRL_APB_RESET_REASON_SOFT, RESET_RST }, > > + { ZYNQMP_CRL_APB_RESET_REASON_SRST, RESET_POR }, > > + { ZYNQMP_CRL_APB_RESET_REASON_PSONLY, RESET_POR }, > > + { ZYNQMP_CRL_APB_RESET_REASON_PMU, RESET_POR }, > > + { ZYNQMP_CRL_APB_RESET_REASON_INTERNAL, RESET_POR }, > > + { ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL, RESET_POR }, > > RESET_EXT? This bit is set for a normal POR, too. > > > + { /* sentinel */ } > > +}; > > + > > +static enum reset_src_type zynqmp_get_reset_src(void) > > +{ > > + enum reset_src_type type = RESET_UKWN; > > + unsigned int i; > > + u32 val; > > + > > + val = readl(ZYNQMP_CRL_APB_RESET_REASON); > > + > > + for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) { > > + if (val & reset_reasons[i].mask) { > > + type = reset_reasons[i].type; > > + break; > > + } > > + } > > + > > + pr_info("ZynqMP reset reason %s (ZYNQMP_CRL_APB_RESET_REASON: 0x%08x)\n", > > + reset_source_to_string(type), val); > > + > > + return type; > > +} > > + > > +static int zynqmp_init(void) > > +{ > > + reset_source_set(zynqmp_get_reset_src()); > > + > > + return 0; > > +} > > +postcore_initcall(zynqmp_init); > > _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On Thu, 24 Jun 2021 12:52:58 +0200, Ahmad Fatoum wrote: > On 24.06.21 12:23, Michael Tretter wrote: > > The ZynqMP boots from an SDHCI device by reading a boot.bin file from > > the FAT16/32 partition, which is the first partition in the MBR. > > > > The update handler copies a boot.bin image to this partition, which > > might be board specific. > > Is barebox the boot.bin or is that a separate first stage bootloader? Both. The boot.bin contains at least the first stage bootloader, TF-A, and Barebox. You cannot boot a "standalone" Barebox image on the ZynqMP. I also documented this in the zynqmp documentation as part of this patch series. Michael > > > > > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> > > --- > > arch/arm/mach-zynqmp/Makefile | 1 + > > .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++++ > > arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 +++++++++++++++++++ > > 3 files changed, 70 insertions(+) > > create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > > create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c > > > > diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile > > index 14b8a4e46b87..e24a43c0d59f 100644 > > --- a/arch/arm/mach-zynqmp/Makefile > > +++ b/arch/arm/mach-zynqmp/Makefile > > @@ -1,3 +1,4 @@ > > # SPDX-License-Identifier: GPL-2.0-or-later > > obj-y += firmware-zynqmp.o > > obj-y += zynqmp.o > > +obj-$(CONFIG_BAREBOX_UPDATE) += zynqmp-bbu.o > > diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > > new file mode 100644 > > index 000000000000..8502791ee0f7 > > --- /dev/null > > +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > > @@ -0,0 +1,21 @@ > > +/* SPDX-License-Identifier: GPL-2.0-only */ > > +/* > > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > > + */ > > +#ifndef __MACH_ZYNQMP_BBU_H > > +#define __MACH_ZYNQMP_BBU_H > > + > > +#include <bbu.h> > > + > > +#ifdef CONFIG_BAREBOX_UPDATE > > +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > > + unsigned long flags); > > +#else > > +static int zynqmp_bbu_register_handler(const char *name, char *devicefile, > > + unsigned long flags) > > +{ > > + return 0; > > +}; > > +#endif > > + > > +#endif /* __MACH_ZYNQMP_BBU_H */ > > diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c > > new file mode 100644 > > index 000000000000..d1197c01dc41 > > --- /dev/null > > +++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c > > @@ -0,0 +1,48 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > > + */ > > + > > +#include <common.h> > > +#include <libfile.h> > > +#include <mach/zynqmp-bbu.h> > > + > > +static int zynqmp_bbu_handler(struct bbu_handler *handler, > > + struct bbu_data *data) > > +{ > > + int ret = 0; > > + > > + ret = bbu_confirm(data); > > + if (ret) > > + return ret; > > + > > + ret = copy_file(data->imagefile, data->devicefile, 1); > > + if (ret < 0) { > > + pr_err("update failed: %s", strerror(-ret)); > > + return ret; > > + } > > + > > + return ret; > > +} > > + > > +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > > + unsigned long flags) > > +{ > > + struct bbu_handler *handler; > > + int ret = 0; > > + > > + if (!name || !devicefile) > > + return -EINVAL; > > + > > + handler = xzalloc(sizeof(*handler)); > > + handler->name = name; > > + handler->devicefile = devicefile; > > + handler->flags = flags; > > + handler->handler = zynqmp_bbu_handler; > > + > > + ret = bbu_register_handler(handler); > > + if (ret) > > + free(handler); > > + > > + return ret; > > +} > > _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On 24.06.21 15:20, Michael Tretter wrote: > On Thu, 24 Jun 2021 12:48:44 +0200, Ahmad Fatoum wrote: >> On 24.06.21 12:23, Michael Tretter wrote: >>> The reset reason is available in the APB register set on the ZynqMP. >>> Read the reset reason and set the reset source accordingly. >>> >>> There might be multiple bits set in the APB register. Use the MSB for >>> determining the actual reset source. >> >> APB is usually the AMBA Advanced Peripheral Bus. Perhaps CRL is the >> actual name of the register and APB just tells that it's mapped there? > > Ack. The data sheet calls it "Clock and Reset control registers for LPD." I > will fix it in v2. > >> >>> >>> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> >>> --- >>> arch/arm/mach-zynqmp/Makefile | 1 + >>> arch/arm/mach-zynqmp/include/mach/zynqmp.h | 6 ++ >>> arch/arm/mach-zynqmp/zynqmp.c | 74 ++++++++++++++++++++++ >>> 3 files changed, 81 insertions(+) >>> create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp.h >>> create mode 100644 arch/arm/mach-zynqmp/zynqmp.c >>> >>> diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile >>> index 021efc94afaf..14b8a4e46b87 100644 >>> --- a/arch/arm/mach-zynqmp/Makefile >>> +++ b/arch/arm/mach-zynqmp/Makefile >>> @@ -1,2 +1,3 @@ >>> # SPDX-License-Identifier: GPL-2.0-or-later >>> obj-y += firmware-zynqmp.o >>> +obj-y += zynqmp.o >>> diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp.h b/arch/arm/mach-zynqmp/include/mach/zynqmp.h >>> new file mode 100644 >>> index 000000000000..f6c05f35a470 >>> --- /dev/null >>> +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp.h >> >> Nitpick: revision.h sounds more self-describing. > > Ok. I thought there might be some more soc specific function instead of > revision specific functions here, but revision.h is fine for me as well. > >> >>> @@ -0,0 +1,6 @@ >>> +#ifndef __MACH_ZYNQMP_H >>> +#define __MACH_ZYNQMP_H >>> + >>> +int zynqmp_soc_revision(void); >>> + >>> +#endif /* __MACH_ZYNQMP_H */ >>> diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c >>> new file mode 100644 >>> index 000000000000..2b3bd8406ce9 >>> --- /dev/null >>> +++ b/arch/arm/mach-zynqmp/zynqmp.c >>> @@ -0,0 +1,74 @@ >>> +// SPDX-License-Identifier: GPL-2.0-only >>> +/* >>> + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> >>> + */ >>> + >>> +#include <common.h> >>> +#include <init.h> >>> +#include <linux/types.h> >>> +#include <reset_source.h> >>> + >>> +#include <mach/zynqmp.h> >>> + >>> +#define ZYNQMP_CRL_APB_BASE 0xff5e0000 >>> +#define ZYNQMP_CRL_APB_RESET_REASON (ZYNQMP_CRL_APB_BASE + 0x220) >>> + >>> +/* External POR: The PS_POR_B reset signal pin was asserted. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL BIT(0) >>> +/* Internal POR: A system error triggered a POR reset. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_INTERNAL BIT(1) >>> +/* Internal system reset; A system error triggered a system reset. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_PMU BIT(2) >>> +/* PS-only reset: Write to PMU_GLOBAL.GLOBAL_RESET [PS_ONLY_RST]. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_PSONLY BIT(3) >>> +/* External system reset: The PS_SRST_B reset signal pin was asserted. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_SRST BIT(4) >>> +/* Software system reset: Write to RESET_CTRL [soft_reset]. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_SOFT BIT(5) >>> +/* Software debugger reset: Write to BLOCKONLY_RST [debug_only]. */ >>> +#define ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS BIT(6) >>> + >>> +struct zynqmp_reset_reason { >>> + u32 mask; >>> + enum reset_src_type type; >>> +}; >>> + >>> +static const struct zynqmp_reset_reason reset_reasons[] = { >>> + { ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS, RESET_UKWN }, >> >> RESET_JTAG? > > I am not sure, if I understand RESET_JTAG correctly. The reference manual says > that it is like a soft reset while preserving the debug logic and originates > in the DAP controller. Is this RESET_JTAG? Yes. DAP may be used with SWD as well, but as far as barebox reset reasons are concerned, every debugger related reset should be RESET_JTAG. > >> >>> + { ZYNQMP_CRL_APB_RESET_REASON_SOFT, RESET_RST }, >>> + { ZYNQMP_CRL_APB_RESET_REASON_SRST, RESET_POR }, >>> + { ZYNQMP_CRL_APB_RESET_REASON_PSONLY, RESET_POR }, >>> + { ZYNQMP_CRL_APB_RESET_REASON_PMU, RESET_POR }, >>> + { ZYNQMP_CRL_APB_RESET_REASON_INTERNAL, RESET_POR }, >>> + { ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL, RESET_POR }, >> >> RESET_EXT? > > This bit is set for a normal POR, too. > >> >>> + { /* sentinel */ } >>> +}; >>> + >>> +static enum reset_src_type zynqmp_get_reset_src(void) >>> +{ >>> + enum reset_src_type type = RESET_UKWN; >>> + unsigned int i; >>> + u32 val; >>> + >>> + val = readl(ZYNQMP_CRL_APB_RESET_REASON); >>> + >>> + for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) { >>> + if (val & reset_reasons[i].mask) { >>> + type = reset_reasons[i].type; >>> + break; >>> + } >>> + } >>> + >>> + pr_info("ZynqMP reset reason %s (ZYNQMP_CRL_APB_RESET_REASON: 0x%08x)\n", >>> + reset_source_to_string(type), val); >>> + >>> + return type; >>> +} >>> + >>> +static int zynqmp_init(void) >>> +{ >>> + reset_source_set(zynqmp_get_reset_src()); >>> + >>> + return 0; >>> +} >>> +postcore_initcall(zynqmp_init); >>> > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On 24.06.21 15:24, Michael Tretter wrote: > On Thu, 24 Jun 2021 12:52:58 +0200, Ahmad Fatoum wrote: >> On 24.06.21 12:23, Michael Tretter wrote: >>> The ZynqMP boots from an SDHCI device by reading a boot.bin file from >>> the FAT16/32 partition, which is the first partition in the MBR. >>> >>> The update handler copies a boot.bin image to this partition, which >>> might be board specific. >> >> Is barebox the boot.bin or is that a separate first stage bootloader? > > Both. The boot.bin contains at least the first stage bootloader, TF-A, and > Barebox. You cannot boot a "standalone" Barebox image on the ZynqMP. > > I also documented this in the zynqmp documentation as part of this patch > series. I saw that after writing the mail here. Thanks for clarifying. > > Michael > >> >>> >>> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> >>> --- >>> arch/arm/mach-zynqmp/Makefile | 1 + >>> .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++++ >>> arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 +++++++++++++++++++ >>> 3 files changed, 70 insertions(+) >>> create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h >>> create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c >>> >>> diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile >>> index 14b8a4e46b87..e24a43c0d59f 100644 >>> --- a/arch/arm/mach-zynqmp/Makefile >>> +++ b/arch/arm/mach-zynqmp/Makefile >>> @@ -1,3 +1,4 @@ >>> # SPDX-License-Identifier: GPL-2.0-or-later >>> obj-y += firmware-zynqmp.o >>> obj-y += zynqmp.o >>> +obj-$(CONFIG_BAREBOX_UPDATE) += zynqmp-bbu.o >>> diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h >>> new file mode 100644 >>> index 000000000000..8502791ee0f7 >>> --- /dev/null >>> +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h >>> @@ -0,0 +1,21 @@ >>> +/* SPDX-License-Identifier: GPL-2.0-only */ >>> +/* >>> + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> >>> + */ >>> +#ifndef __MACH_ZYNQMP_BBU_H >>> +#define __MACH_ZYNQMP_BBU_H >>> + >>> +#include <bbu.h> >>> + >>> +#ifdef CONFIG_BAREBOX_UPDATE >>> +int zynqmp_bbu_register_handler(const char *name, char *devicefile, >>> + unsigned long flags); >>> +#else >>> +static int zynqmp_bbu_register_handler(const char *name, char *devicefile, >>> + unsigned long flags) >>> +{ >>> + return 0; >>> +}; >>> +#endif >>> + >>> +#endif /* __MACH_ZYNQMP_BBU_H */ >>> diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c >>> new file mode 100644 >>> index 000000000000..d1197c01dc41 >>> --- /dev/null >>> +++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c >>> @@ -0,0 +1,48 @@ >>> +// SPDX-License-Identifier: GPL-2.0-only >>> +/* >>> + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> >>> + */ >>> + >>> +#include <common.h> >>> +#include <libfile.h> >>> +#include <mach/zynqmp-bbu.h> >>> + >>> +static int zynqmp_bbu_handler(struct bbu_handler *handler, >>> + struct bbu_data *data) >>> +{ >>> + int ret = 0; >>> + >>> + ret = bbu_confirm(data); >>> + if (ret) >>> + return ret; >>> + >>> + ret = copy_file(data->imagefile, data->devicefile, 1); >>> + if (ret < 0) { >>> + pr_err("update failed: %s", strerror(-ret)); >>> + return ret; >>> + } EFI also registers an barebox update handler for a file: /boot/EFI/BOOT/BOOTx64.EFI, but there apparently bbu_register_std_file_update suffices. Did you check if that would work for you as well? It's still a good idea to have a zynqmp specific wrapper for bbu_register_std_file_update, but I am not sure you need to duplicate the copy_file stuff. Also, this seems SD-specific. I assume eMMC would boot from boot partitions? If so, zynqmp_bbu_register_sd_handler may be a more apt name. >>> + >>> + return ret; >>> +} >>> + >>> +int zynqmp_bbu_register_handler(const char *name, char *devicefile, >>> + unsigned long flags) >>> +{ >>> + struct bbu_handler *handler; >>> + int ret = 0; >>> + >>> + if (!name || !devicefile) >>> + return -EINVAL; >>> + >>> + handler = xzalloc(sizeof(*handler)); >>> + handler->name = name; >>> + handler->devicefile = devicefile; >>> + handler->flags = flags; >>> + handler->handler = zynqmp_bbu_handler; >>> + >>> + ret = bbu_register_handler(handler); >>> + if (ret) >>> + free(handler); >>> + >>> + return ret; >>> +} >>> > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
On Thu, 24 Jun 2021 15:34:33 +0200, Ahmad Fatoum wrote: > On 24.06.21 15:24, Michael Tretter wrote: > > On Thu, 24 Jun 2021 12:52:58 +0200, Ahmad Fatoum wrote: > >> On 24.06.21 12:23, Michael Tretter wrote: > >>> The ZynqMP boots from an SDHCI device by reading a boot.bin file from > >>> the FAT16/32 partition, which is the first partition in the MBR. > >>> > >>> The update handler copies a boot.bin image to this partition, which > >>> might be board specific. > >> > >> Is barebox the boot.bin or is that a separate first stage bootloader? > > > > Both. The boot.bin contains at least the first stage bootloader, TF-A, and > > Barebox. You cannot boot a "standalone" Barebox image on the ZynqMP. > > > > I also documented this in the zynqmp documentation as part of this patch > > series. > > I saw that after writing the mail here. Thanks for clarifying. > > > > > Michael > > > >> > >>> > >>> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> > >>> --- > >>> arch/arm/mach-zynqmp/Makefile | 1 + > >>> .../arm/mach-zynqmp/include/mach/zynqmp-bbu.h | 21 ++++++++ > >>> arch/arm/mach-zynqmp/zynqmp-bbu.c | 48 +++++++++++++++++++ > >>> 3 files changed, 70 insertions(+) > >>> create mode 100644 arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > >>> create mode 100644 arch/arm/mach-zynqmp/zynqmp-bbu.c > >>> > >>> diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile > >>> index 14b8a4e46b87..e24a43c0d59f 100644 > >>> --- a/arch/arm/mach-zynqmp/Makefile > >>> +++ b/arch/arm/mach-zynqmp/Makefile > >>> @@ -1,3 +1,4 @@ > >>> # SPDX-License-Identifier: GPL-2.0-or-later > >>> obj-y += firmware-zynqmp.o > >>> obj-y += zynqmp.o > >>> +obj-$(CONFIG_BAREBOX_UPDATE) += zynqmp-bbu.o > >>> diff --git a/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > >>> new file mode 100644 > >>> index 000000000000..8502791ee0f7 > >>> --- /dev/null > >>> +++ b/arch/arm/mach-zynqmp/include/mach/zynqmp-bbu.h > >>> @@ -0,0 +1,21 @@ > >>> +/* SPDX-License-Identifier: GPL-2.0-only */ > >>> +/* > >>> + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > >>> + */ > >>> +#ifndef __MACH_ZYNQMP_BBU_H > >>> +#define __MACH_ZYNQMP_BBU_H > >>> + > >>> +#include <bbu.h> > >>> + > >>> +#ifdef CONFIG_BAREBOX_UPDATE > >>> +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > >>> + unsigned long flags); > >>> +#else > >>> +static int zynqmp_bbu_register_handler(const char *name, char *devicefile, > >>> + unsigned long flags) > >>> +{ > >>> + return 0; > >>> +}; > >>> +#endif > >>> + > >>> +#endif /* __MACH_ZYNQMP_BBU_H */ > >>> diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c > >>> new file mode 100644 > >>> index 000000000000..d1197c01dc41 > >>> --- /dev/null > >>> +++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c > >>> @@ -0,0 +1,48 @@ > >>> +// SPDX-License-Identifier: GPL-2.0-only > >>> +/* > >>> + * Copyright (C) 2020 Michael Tretter <m.tretter@pengutronix.de> > >>> + */ > >>> + > >>> +#include <common.h> > >>> +#include <libfile.h> > >>> +#include <mach/zynqmp-bbu.h> > >>> + > >>> +static int zynqmp_bbu_handler(struct bbu_handler *handler, > >>> + struct bbu_data *data) > >>> +{ > >>> + int ret = 0; > >>> + > >>> + ret = bbu_confirm(data); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret = copy_file(data->imagefile, data->devicefile, 1); > >>> + if (ret < 0) { > >>> + pr_err("update failed: %s", strerror(-ret)); > >>> + return ret; > >>> + } > > EFI also registers an barebox update handler for a file: /boot/EFI/BOOT/BOOTx64.EFI, > but there apparently bbu_register_std_file_update suffices. > > Did you check if that would work for you as well? > > It's still a good idea to have a zynqmp specific wrapper for bbu_register_std_file_update, > but I am not sure you need to duplicate the copy_file stuff. I didn't know about the handler and haven't checked this. If this can work, I'll sent another patch to replace the copy_file stuff with use of the existing functions. > > Also, this seems SD-specific. I assume eMMC would boot from boot partitions? > If so, zynqmp_bbu_register_sd_handler may be a more apt name. No, eMMC boot partitions are not supported by the ROM code. The handler is the same for SD and eMMC. Michael > > > >>> + > >>> + return ret; > >>> +} > >>> + > >>> +int zynqmp_bbu_register_handler(const char *name, char *devicefile, > >>> + unsigned long flags) > >>> +{ > >>> + struct bbu_handler *handler; > >>> + int ret = 0; > >>> + > >>> + if (!name || !devicefile) > >>> + return -EINVAL; > >>> + > >>> + handler = xzalloc(sizeof(*handler)); > >>> + handler->name = name; > >>> + handler->devicefile = devicefile; > >>> + handler->flags = flags; > >>> + handler->handler = zynqmp_bbu_handler; > >>> + > >>> + ret = bbu_register_handler(handler); > >>> + if (ret) > >>> + free(handler); > >>> + > >>> + return ret; > >>> +} _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox