[U-Boot] [PATCH 0/3] Zynq: Add support for UEFI booted Z-Turn

I got myself an amazing new toy: A MYIR Z-Turn board.
Since the only sane way to boot distributions on such a device is obviously U-Boot with grub and openSUSE, I stumbled over a few shortcomings in the current upstream state of affairs.
This patch set fixes most of them. With this set applied, we can boot UEFI binaries just fine even on 32bit zynq systems. We can also boot on the Z-Turn, albeit only without USB and Ethernet (fixes to come).
Alexander Graf (3): zynq: Add EFI runtime sections to linker script zynq: Enable distro boot zynq: Add Z-Turn board
arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-zturn-myir.dts | 161 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-zynq/u-boot.lds | 29 +++++++ configs/zynq_z_turn_defconfig | 58 ++++++++++++++ include/configs/zynq-common.h | 55 ++++++++++++- 5 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 arch/arm/dts/zynq-zturn-myir.dts create mode 100644 configs/zynq_z_turn_defconfig

When using EFI_LOADER, we add a few special sections for runtime code and data which get relocated on demand when executing a target OS.
These runtime structures need to get annotated properly in the linker script. While we do that properly in the generic one, we missed out on the zynq specific linker script.
This patch adds the EFI runtime section annotations into the zynq linker script so that the efi loader code actually works on that platform.
Signed-off-by: Alexander Graf agraf@suse.de --- arch/arm/mach-zynq/u-boot.lds | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds index 4dc9bb0..86559cb 100644 --- a/arch/arm/mach-zynq/u-boot.lds +++ b/arch/arm/mach-zynq/u-boot.lds @@ -42,6 +42,35 @@ SECTIONS
. = ALIGN(4);
+ .__efi_runtime_start : { + *(.__efi_runtime_start) + } + + .efi_runtime : { + *(efi_runtime_text) + *(efi_runtime_data) + } + + .__efi_runtime_stop : { + *(.__efi_runtime_stop) + } + + .efi_runtime_rel_start : + { + *(.__efi_runtime_rel_start) + } + + .efi_runtime_rel : { + *(.relefi_runtime_text) + *(.relefi_runtime_data) + } + + .efi_runtime_rel_stop : + { + *(.__efi_runtime_rel_stop) + } + + . = ALIGN(4); .image_copy_end : { *(.__image_copy_end)

Distro boot allows devices to boot using standardized boot methods by default. This can be very handy for distributions that want to run on different platforms.
This patch moves the zynq platform to use its old, zynq specific boot method first and then fall back to distro boot. That way supporting Linux distributions like openSUSE is much easier.
Signed-off-by: Alexander Graf agraf@suse.de --- include/configs/zynq-common.h | 55 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 4b6b088..4615327 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -176,6 +176,50 @@ /* enable preboot to be loaded before CONFIG_BOOTDELAY */ #define CONFIG_PREBOOT
+/* Boot configuration */ +#define CONFIG_BOOTCOMMAND "run $modeboot || run distro_bootcmd" +#define CONFIG_SYS_LOAD_ADDR 0 /* default? */ + +/* Distro boot enablement */ + +#ifdef CONFIG_SPL_BUILD +#define BOOTENV +#else +#include <config_distro_defaults.h> + +#ifdef CONFIG_CMD_MMC +#define BOOT_TARGET_DEVICES_MMC(func) func(MMC, mmc, 0) +#else +#define BOOT_TARGET_DEVICES_MMC(func) +#endif + +#ifdef CONFIG_CMD_USB +#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0) +#else +#define BOOT_TARGET_DEVICES_USB(func) +#endif + +#if defined(CONFIG_CMD_PXE) +#define BOOT_TARGET_DEVICES_PXE(func) func(PXE, pxe, na) +#else +#define BOOT_TARGET_DEVICES_PXE(func) +#endif + +#if defined(CONFIG_CMD_DHCP) +#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na) +#else +#define BOOT_TARGET_DEVICES_DHCP(func) +#endif + +#define BOOT_TARGET_DEVICES(func) \ + BOOT_TARGET_DEVICES_MMC(func) \ + BOOT_TARGET_DEVICES_USB(func) \ + BOOT_TARGET_DEVICES_PXE(func) \ + BOOT_TARGET_DEVICES_DHCP(func) + +#include <config_distro_bootcmd.h> +#endif /* CONFIG_SPL_BUILD */ + /* Default environment */ #ifndef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -187,6 +231,11 @@ "fdt_high=0x20000000\0" \ "initrd_high=0x20000000\0" \ "loadbootenv_addr=0x2000000\0" \ + "fdt_addr_r=0x1f00000\0" \ + "pxefile_addr_r=0x2000000\0" \ + "kernel_addr_r=0x2000000\0" \ + "scriptaddr=0x3000000\0" \ + "ramdisk_addr_r=0x3100000\0" \ "bootenv=uEnv.txt\0" \ "bootenv_dev=mmc\0" \ "loadbootenv=load ${bootenv_dev} 0 ${loadbootenv_addr} ${bootenv}\0" \ @@ -222,12 +271,10 @@ "echo Copying FIT from USB to RAM... && " \ "load usb 0 ${load_addr} ${fit_image} && " \ "bootm ${load_addr}; fi\0" \ - DFU_ALT_INFO + DFU_ALT_INFO \ + BOOTENV #endif
-#define CONFIG_BOOTCOMMAND "run $modeboot" -#define CONFIG_SYS_LOAD_ADDR 0 /* default? */ - /* Miscellaneous configurable options */
#define CONFIG_CMDLINE_EDITING

The Z-Turn board is a low cost development board based on the Xilinx Zynq SoC. While it's powerful and quite versatile, it so far lacked upstream support.
This patch adds basic support for the Z-Turn. It does however for now miss enablement for MIO51 reset which means that USB and ethernet don't work. For that either FSBL or SPL need to be adjusted. The SPL part will follow later.
Signed-off-by: Alexander Graf agraf@suse.de --- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-zturn-myir.dts | 161 +++++++++++++++++++++++++++++++++++++++ configs/zynq_z_turn_defconfig | 58 ++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 arch/arm/dts/zynq-zturn-myir.dts create mode 100644 configs/zynq_z_turn_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9cc5c1e..567d10a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -131,6 +131,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \ zynq-topic-miami.dtb \ zynq-topic-miamilite.dtb \ zynq-topic-miamiplus.dtb \ + zynq-zturn-myir.dtb \ zynq-zc770-xm010.dtb \ zynq-zc770-xm011.dtb \ zynq-zc770-xm012.dtb \ diff --git a/arch/arm/dts/zynq-zturn-myir.dts b/arch/arm/dts/zynq-zturn-myir.dts new file mode 100644 index 0000000..a5ecfcc --- /dev/null +++ b/arch/arm/dts/zynq-zturn-myir.dts @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015 Andrea Merello adnrea.merello@gmail.com + * Copyright (C) 2017 Alexander Graf agraf@suse.de + * + * Based on zynq-zed.dts which is: + * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2012 National Instruments Corp. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +/dts-v1/; +/include/ "zynq-7000.dtsi" + +/ { + model = "Zynq Z-Turn MYIR Board"; + compatible = "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + serial1 = &uart0; + spi0 = &qspi; + mmc0 = &sdhci0; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + led_r { + label = "led_r"; + gpios = <&gpio0 0x72 0x1>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + led_g { + label = "led_g"; + gpios = <&gpio0 0x73 0x1>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + led_b { + label = "led_b"; + gpios = <&gpio0 0x74 0x1>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + usr_led1 { + label = "usr_led1"; + gpios = <&gpio0 0x0 0x1>; + default-state = "off"; + linux,default-trigger = "none"; + }; + + usr_led2 { + label = "usr_led2"; + gpios = <&gpio0 0x9 0x1>; + default-state = "off"; + linux,default-trigger = "none"; + }; + }; + + gpio-beep { + compatible = "gpio-beeper"; + label = "pl-beep"; + gpios = <&gpio0 0x75 0x0>; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <0x1>; + #size-cells = <0x0>; + autorepeat; + K1 { + label = "K1"; + gpios = <&gpio0 0x32 0x1>; + linux,code = <0x66>; + gpio-key,wakeup; + autorepeat; + }; + }; +}; + +&clkc { + ps-clk-frequency = <33333333>; + fclk-enable = <0xf>; +}; + +&qspi { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy>; + + ethernet_phy: ethernet-phy@0 { + reg = <0x0>; + }; +}; + +&sdhci0 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&uart0 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&uart1 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&can0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + stlm75@49 { + status = "okay"; + compatible = "lm75"; + reg = <0x49>; + }; + + adxl345@53 { + compatible = "adi,adxl34x", "adxl34x"; + reg = <0x53>; + interrupt-parent = <&intc>; + interrupts = <0x0 0x1e 0x4>; + }; +}; diff --git a/configs/zynq_z_turn_defconfig b/configs/zynq_z_turn_defconfig new file mode 100644 index 0000000..3fd8317 --- /dev/null +++ b/configs/zynq_z_turn_defconfig @@ -0,0 +1,58 @@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y +CONFIG_SYS_TEXT_BASE=0x4000000 +CONFIG_DEFAULT_DEVICE_TREE="zynq-zturn-myir" +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_FIT_VERBOSE=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL=y +CONFIG_SPL_OS_BOOT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="Zynq> " +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_USB=y +CONFIG_CMD_DFU=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_ZYNQ_GEM=y +CONFIG_ZYNQ_QSPI=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_CI_UDC=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_G_DNL_MANUFACTURER="Xilinx" +CONFIG_G_DNL_VENDOR_NUM=0x03FD +CONFIG_G_DNL_PRODUCT_NUM=0x0300 +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_ZYNQ=y +CONFIG_DEBUG_UART_BASE=0xe0001000 +CONFIG_DEBUG_UART_CLOCK=50000000

On 3.7.2017 13:41, Alexander Graf wrote:
I got myself an amazing new toy: A MYIR Z-Turn board.
Since the only sane way to boot distributions on such a device is obviously U-Boot with grub and openSUSE, I stumbled over a few shortcomings in the current upstream state of affairs.
This patch set fixes most of them. With this set applied, we can boot UEFI binaries just fine even on 32bit zynq systems. We can also boot on the Z-Turn, albeit only without USB and Ethernet (fixes to come).
Alexander Graf (3): zynq: Add EFI runtime sections to linker script zynq: Enable distro boot zynq: Add Z-Turn board
arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-zturn-myir.dts | 161 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-zynq/u-boot.lds | 29 +++++++ configs/zynq_z_turn_defconfig | 58 ++++++++++++++ include/configs/zynq-common.h | 55 ++++++++++++- 5 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 arch/arm/dts/zynq-zturn-myir.dts create mode 100644 configs/zynq_z_turn_defconfig
All looks good. I have tested that distro command wiring and behavior is correct that we don't break existing users which is great.
Applied all.
Thanks, Michal
participants (2)
-
Alexander Graf
-
Michal Simek