diff --git a/Documentation/boards/mvebu.rst b/Documentation/boards/mvebu.rst new file mode 100644 index 0000000..b4f8e60 --- /dev/null +++ b/Documentation/boards/mvebu.rst @@ -0,0 +1,50 @@ +Marvell Embedded Business Unit (mvebu) +====================================== + +Move of the Register Window +--------------------------- + +When an mvebu SoC comes up the internal registers are mapped at 0xd0000000 in +the address space. To make it possible to have more than 3.25 GiB of continuous +RAM in Linux this window is moved to 0xf1000000. +Unfortunately the register to configure the location of the registers is located +in this window, so there is no way to determine the location afterwards. + +RAM initialisation +------------------ + +Traditionally the RAM initialisation happens with a binary blob that have to be +extracted from the vendor U-Boot:: + + scripts/kwbimage -x -i /dev/mtdblock0 -o . + +This creates among others a file "binary.0" that has to be put into the board +directory. For license reasons this is usually not included in the barebox +repository. + +Note that in the meantime U-Boot has open source code to do the RAM +initialisation that could be taken. + +Booting second stage +-------------------- + +This is currently not possible because barebox assumes the registers are mapped +at 0xd0000000 as is the case when the boot ROM gives control to the bootloader. + +Booting from UART +----------------- + +The mvebu SoCs support booting from UART. For this there is a tool available in +barebox called kwboot. + +mvebu boards +------------ + +Not all supported boards have a description here. + +.. toctree:: + :glob: + :numbered: + :maxdepth: 1 + + mvebu/* diff --git a/Documentation/boards/mvebu/Netgear-ReadyNAS-2120.rst b/Documentation/boards/mvebu/Netgear-ReadyNAS-2120.rst new file mode 100644 index 0000000..5bee03a --- /dev/null +++ b/Documentation/boards/mvebu/Netgear-ReadyNAS-2120.rst @@ -0,0 +1,19 @@ +Netgear ReadyNAS 2120 +===================== + +This is a rack mountable 4 bay NAS using an Armada XP dual-core processor. + +UART booting +------------ + +The first UART hides behind a sticker on 4 pins. + +The machine seems to do two resets at power on which makes UART booting hard. A +trick to work around this is:: + + scripts/kwboot -d /dev/ttyUSB0; kwboot -b images/barebox-netgear-rn2120.img -t /dev/ttyUSB0 + +This way the first window in which the CPU accepts the magic string is taken by +the first invokation which blocks until the second reset happens. The second +window is then hit with the image to boot. This is not 100% reliable but works +most of the time. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 632037f..39f5f01 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -123,6 +123,7 @@ select CLKDEV_LOOKUP select GPIOLIB select HAS_DEBUG_LL + select HAVE_DEFAULT_ENVIRONMENT_NEW select HAVE_PBL_MULTI_IMAGES select HW_HAS_PCI select MVEBU_MBUS diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index da6ea0d..1a0f63f 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard/ obj-$(CONFIG_MACH_NESO) += guf-neso/ obj-$(CONFIG_MACH_NETGEAR_RN104) += netgear-rn104/ +obj-$(CONFIG_MACH_NETGEAR_RN2120) += netgear-rn2120/ obj-$(CONFIG_MACH_NOMADIK_8815NHK) += nhk8815/ obj-$(CONFIG_MACH_NVIDIA_BEAVER) += nvidia-beaver/ obj-$(CONFIG_MACH_NVIDIA_JETSON) += nvidia-jetson-tk1/ diff --git a/arch/arm/boards/netgear-rn2120/Makefile b/arch/arm/boards/netgear-rn2120/Makefile new file mode 100644 index 0000000..01c7a25 --- /dev/null +++ b/arch/arm/boards/netgear-rn2120/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/netgear-rn2120/board.c b/arch/arm/boards/netgear-rn2120/board.c new file mode 100644 index 0000000..caf106a --- /dev/null +++ b/arch/arm/boards/netgear-rn2120/board.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static int rn2120_init(void) +{ + /* + * This is the machine type that the kernel shipped by Netgear is using. + * It's wrong but a given fact. + */ + armlinux_set_architecture(MACH_TYPE_ARMADA_XP_DB); + + return 0; +} +device_initcall(rn2120_init); + +struct hdpower { + unsigned gpio_detect; + unsigned gpio_power; + unsigned gpio_led; +}; + +/* + * It would be nice to have this abstracted in the device tree, but currently + * this isn't the case. + */ +static struct hdpower rn2120_hdpower[] = { + { + /* sata 1 */ + .gpio_detect = 32, + .gpio_power = 24, + .gpio_led = 31, + }, { + /* sata 2 */ + .gpio_detect = 33, + .gpio_power = 25, + .gpio_led = 40, + }, { + /* sata 3 */ + .gpio_detect = 34, + .gpio_power = 26, + .gpio_led = 44, + }, { + /* sata 4 */ + .gpio_detect = 35, + .gpio_power = 28, + .gpio_led = 47, + }, +}; + +static int rn2120_hddetect(void) +{ + int i; + + if (!of_machine_is_compatible("netgear,readynas-2120")) + return 0; + + for (i = 0; i < ARRAY_SIZE(rn2120_hdpower); ++i) { + int ret; + ret = gpio_direction_input(rn2120_hdpower[i].gpio_detect); + if (ret) { + pr_err("Failure to detect hd%d (%d)\n", i, ret); + continue; + } + + ret = gpio_get_value(rn2120_hdpower[i].gpio_detect); + if (ret) { + /* no disk present */ + gpio_direction_output(rn2120_hdpower[i].gpio_power, 0); + } else { + pr_info("Detected presence of disk #%d\n", i + 1); + /* make a pause after powering up 2 disks */ + if (i && !(i & 1)) { + pr_info("Delay power up\n"); + mdelay(7000); + } + + gpio_direction_output(rn2120_hdpower[i].gpio_power, 1); + } + } + return 0; +} +device_initcall(rn2120_hddetect); diff --git a/arch/arm/boards/netgear-rn2120/kwbimage.cfg b/arch/arm/boards/netgear-rn2120/kwbimage.cfg new file mode 100644 index 0000000..a6f0aa6 --- /dev/null +++ b/arch/arm/boards/netgear-rn2120/kwbimage.cfg @@ -0,0 +1,7 @@ +VERSION 1 +BOOT_FROM nand +DESTADDR 00000000 +EXECADDR 00000000 +NAND_BLKSZ 00020000 +NAND_BADBLK_LOCATION 01 +BINARY binary.0 0000005b 00000068 diff --git a/arch/arm/boards/netgear-rn2120/lowlevel.c b/arch/arm/boards/netgear-rn2120/lowlevel.c new file mode 100644 index 0000000..29c8b43 --- /dev/null +++ b/arch/arm/boards/netgear-rn2120/lowlevel.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Pengutronix, Uwe Kleine-König + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, as published by the Free Software Foundation. + * + * 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. + */ + +#include +#include +#include +#include +#include + +extern char __dtb_armada_xp_rn2120_bb_start[]; + +ENTRY_FUNCTION(start_netgear_rn2120, r0, r1, r2) +{ + void *fdt; + + arm_cpu_lowlevel_init(); + + /* + * This is necessary to allow the machine to draw more power. Probably + * connected to a TI TPS65251. Without this resetting a phy makes the + * SoC reset. + * This is effectively gpio_direction_output(42, 1); + */ + writel((1 << 10) | readl((void *)0xd0018140), (void *)0xd0018140); + writel(~(1 << 10) & readl((void *)0xd0018144), (void *)0xd0018144); + + fdt = __dtb_armada_xp_rn2120_bb_start - + get_runtime_offset(); + + mvebu_barebox_entry(fdt); +} diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index bd978a9..39e7ef1 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -6,7 +6,9 @@ CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3=y CONFIG_MACH_SOLIDRUN_CUBOX=y CONFIG_MACH_GLOBALSCALE_GURUPLUG=y +CONFIG_MACH_PLATHOME_OPENBLOCKS_A6=y CONFIG_MACH_USI_TOPKICK=y +CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_TEXT_BASE=0x0 CONFIG_MALLOC_SIZE=0x0 @@ -17,7 +19,13 @@ CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y +CONFIG_BOOTM_SHOW_TYPE=y +CONFIG_BOOTM_VERBOSE=y +CONFIG_BOOTM_INITRD=y +CONFIG_BOOTM_OFTREE=y +CONFIG_BOOTM_OFTREE_UIMAGE=y CONFIG_BLSPEC=y +CONFIG_FLEXIBLE_BOOTARGS=y CONFIG_IMD_TARGET=y CONFIG_CONSOLE_ACTIVATE_NONE=y CONFIG_PARTITION_DISK_EFI=y @@ -26,13 +34,7 @@ CONFIG_CMD_IMD=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_ARM_MMUINFO=y -CONFIG_FLEXIBLE_BOOTARGS=y CONFIG_CMD_BOOT=y -CONFIG_BOOTM_SHOW_TYPE=y -CONFIG_BOOTM_VERBOSE=y -CONFIG_BOOTM_INITRD=y -CONFIG_BOOTM_OFTREE=y -CONFIG_BOOTM_OFTREE_UIMAGE=y CONFIG_CMD_GO=y CONFIG_CMD_LOADS=y CONFIG_CMD_LOADY=y @@ -90,6 +92,7 @@ CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_DRIVER_NET_MVNETA=y CONFIG_DRIVER_NET_ORION=y CONFIG_MARVELL_PHY=y CONFIG_DRIVER_SPI_GPIO=y @@ -100,6 +103,7 @@ CONFIG_MTD_M25P80=y CONFIG_NAND=y CONFIG_NAND_ORION=y +CONFIG_NAND_MRVL_NFC=y CONFIG_DISK_AHCI=y CONFIG_USB_HOST=y CONFIG_USB_EHCI=y @@ -119,6 +123,8 @@ CONFIG_PCI_MVEBU=y CONFIG_FS_CRAMFS=y CONFIG_FS_EXT4=y +CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 765cd59..671888e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -29,6 +29,7 @@ pbl-dtb-$(CONFIG_MACH_LENOVO_IX4_300D) += armada-xp-lenovo-ix4-300d-bb.dtb.o pbl-dtb-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += armada-xp-gp-bb.dtb.o pbl-dtb-$(CONFIG_MACH_NETGEAR_RN104) += armada-370-rn104-bb.dtb.o +pbl-dtb-$(CONFIG_MACH_NETGEAR_RN2120) += armada-xp-rn2120-bb.dtb.o pbl-dtb-$(CONFIG_MACH_NITROGEN6) += imx6q-nitrogen6x.dtb.o imx6dl-nitrogen6x.dtb.o imx6qp-nitrogen6_max.dtb.o pbl-dtb-$(CONFIG_MACH_NVIDIA_BEAVER) += tegra30-beaver.dtb.o pbl-dtb-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o diff --git a/arch/arm/dts/armada-xp-rn2120-bb.dts b/arch/arm/dts/armada-xp-rn2120-bb.dts new file mode 100644 index 0000000..969136b --- /dev/null +++ b/arch/arm/dts/armada-xp-rn2120-bb.dts @@ -0,0 +1,11 @@ +/* + * Barebox specific DT overlay for Netgear ReadyNAS 2120 + */ + +#include "arm/armada-xp-netgear-rn2120.dts" + +/ { + chosen { + stdout-path = "/soc/internal-regs/serial@12000"; + }; +}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 79fcc8d..148b4f6 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -55,6 +55,10 @@ bool "Marvell Armada XP GP" select ARCH_ARMADA_XP +config MACH_NETGEAR_RN2120 + bool "Netgear ReadyNAS 2120" + select ARCH_ARMADA_XP + config MACH_PLATHOME_OPENBLOCKS_AX3 bool "PlatHome OpenBlocks AX3" select ARCH_ARMADA_XP diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index 1690f3b..5c163ce 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -395,6 +395,7 @@ /* Flush transmit data */ dma_sync_single_for_device((unsigned long)data, len, DMA_TO_DEVICE); + memset(txdesc, 0, sizeof(*txdesc)); /* Fill the Tx descriptor */ txdesc->cmd_sts = MVNETA_TX_L4_CSUM_NOT | MVNETA_TXD_FLZ_DESC; txdesc->buf_ptr = (u32)data; diff --git a/drivers/pinctrl/mvebu/armada-370.c b/drivers/pinctrl/mvebu/armada-370.c index 1c79bd6..c2c1a0f 100644 --- a/drivers/pinctrl/mvebu/armada-370.c +++ b/drivers/pinctrl/mvebu/armada-370.c @@ -362,7 +362,7 @@ MPP_FUNCTION(0x5, "audio", "mclk"), MPP_FUNCTION(0x6, "uart0", "cts")), MPP_MODE(63, "mpp63", armada_370_mpp_ctrl, - MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x0, "gpio", NULL), MPP_FUNCTION(0x1, "spi0", "sck"), MPP_FUNCTION(0x2, "tclk", NULL)), MPP_MODE(64, "mpp64", armada_370_mpp_ctrl, diff --git a/drivers/pinctrl/mvebu/common.c b/drivers/pinctrl/mvebu/common.c index 5327052..ae16b39 100644 --- a/drivers/pinctrl/mvebu/common.c +++ b/drivers/pinctrl/mvebu/common.c @@ -78,7 +78,8 @@ set = mvebu_pinctrl_find_setting_by_name(pctl, mode, function); if (!set) { - dev_err(pdev->dev, "unsupported function %s on pin %s", + dev_err(pdev->dev, + "unsupported function %s on pin %s\n", function, group); continue; } diff --git a/images/Makefile.mvebu b/images/Makefile.mvebu index 195f48d..b57291c 100644 --- a/images/Makefile.mvebu +++ b/images/Makefile.mvebu @@ -6,110 +6,89 @@ # ---------------------------------------------------------------- $(obj)/%.kwbimg: $(obj)/% FORCE $(call if_changed,kwb_image) -$(obj)/%.kwbuartimg: $(obj)/% FORCE - $(call if_changed,kwb_image) KWBOPTS = -c -d 0x1000000 -e 0x1000000 # ----------------------- Armada 370 based boards --------------------------- GLOBALSCALE_MIRABOX_KWBOPTS = ${KWBOPTS} -i $(board)/globalscale-mirabox/kwbimage.cfg OPTS_start_globalscale_mirabox.pblx.kwbimg = $(GLOBALSCALE_MIRABOX_KWBOPTS) -OPTS_start_globalscale_mirabox.pblx.kwbuartimg = -m uart $(GLOBALSCALE_MIRABOX_KWBOPTS) FILE_barebox-globalscale-mirabox.img = start_globalscale_mirabox.pblx.kwbimg -FILE_barebox-globalscale-mirabox-uart.img = start_globalscale_mirabox.pblx.kwbuartimg FILE_barebox-globalscale-mirabox-2nd.img = start_globalscale_mirabox.pblx pblx-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += start_globalscale_mirabox image-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += barebox-globalscale-mirabox.img -image-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += barebox-globalscale-mirabox-uart.img image-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += barebox-globalscale-mirabox-2nd.img NETGEAR_RN104_KWBOPTS = ${KWBOPTS} -i $(board)/netgear-rn104/kwbimage.cfg OPTS_start_netgear_rn104.pblx.kwbimg = $(NETGEAR_RN104_KWBOPTS) -OPTS_start_netgear_rn104.pblx.kwbuartimg = -m uart $(NETGEAR_RN104_KWBOPTS) FILE_barebox-netgear-rn104.img = start_netgear_rn104.pblx.kwbimg -FILE_barebox-netgear-rn104-uart.img = start_netgear_rn104.pblx.kwbuartimg FILE_barebox-netgear-rn104-2nd.img = start_netgear_rn104.pblx pblx-$(CONFIG_MACH_NETGEAR_RN104) += start_netgear_rn104 image-$(CONFIG_MACH_NETGEAR_RN104) += barebox-netgear-rn104.img -image-$(CONFIG_MACH_NETGEAR_RN104) += barebox-netgear-rn104-uart.img image-$(CONFIG_MACH_NETGEAR_RN104) += barebox-netgear-rn104-2nd.img # ----------------------- Armada XP based boards --------------------------- LENOVO_IX4_300D_KWBOPTS = ${KWBOPTS} -i $(board)/lenovo-ix4-300d/kwbimage.cfg OPTS_start_lenovo_ix4_300d.pblx.kwbimg = $(LENOVO_IX4_300D_KWBOPTS) -OPTS_start_lenovo_ix4_300d.pblx.kwbuartimg = -m uart $(LENOVO_IX4_300D_KWBOPTS) FILE_barebox-lenovo-ix4-300d.img = start_lenovo_ix4_300d.pblx.kwbimg -FILE_barebox-lenovo-ix4-300d-uart.img = start_lenovo_ix4_300d.pblx.kwbuartimg FILE_barebox-lenovo-ix4-300d-2nd.img = start_lenovo_ix4_300d.pblx pblx-$(CONFIG_MACH_LENOVO_IX4_300D) += start_lenovo_ix4_300d image-$(CONFIG_MACH_LENOVO_IX4_300D) += barebox-lenovo-ix4-300d.img -image-$(CONFIG_MACH_LENOVO_IX4_300D) += barebox-lenovo-ix4-300d-uart.img image-$(CONFIG_MACH_LENOVO_IX4_300D) += barebox-lenovo-ix4-300d-2nd.img MARVELL_ARMADA_XP_GP_KWBOPTS = ${KWBOPTS} -i $(board)/marvell-armada-xp-gp/kwbimage.cfg OPTS_start_marvell_armada_xp_gp.pblx.kwbimg = $(MARVELL_ARMADA_XP_GP_KWBOPTS) -OPTS_start_marvell_armada_xp_gp.pblx.kwbuartimg = -m uart $(MARVELL_ARMADA_XP_GP_KWBOPTS) FILE_barebox-marvell-armada-xp-gp.img = start_marvell_armada_xp_gp.pblx.kwbimg -FILE_barebox-marvell-armada-xp-gp-uart.img = start_marvell_armada_xp_gp.pblx.kwbuartimg FILE_barebox-marvell-armada-xp-gp-2nd.img = start_marvell_armada_xp_gp.pblx pblx-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += start_marvell_armada_xp_gp image-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += barebox-marvell-armada-xp-gp.img -image-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += barebox-marvell-armada-xp-gp-uart.img image-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += barebox-marvell-armada-xp-gp-2nd.img +NETGEAR_RN2120_KWBOPTS = ${KWBOPTS} -i $(board)/netgear-rn2120/kwbimage.cfg +OPTS_start_netgear_rn2120.pblx.kwbimg = $(NETGEAR_RN2120_KWBOPTS) +FILE_barebox-netgear-rn2120.img = start_netgear_rn2120.pblx.kwbimg +FILE_barebox-netgear-rn2120-2nd.img = start_netgear_rn2120.pblx +pblx-$(CONFIG_MACH_NETGEAR_RN2120) += start_netgear_rn2120 +image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120.img +image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120-2nd.img + PLATHOME_OPENBLOCKS_AX3_KWBOPTS = ${KWBOPTS} -i $(board)/plathome-openblocks-ax3/kwbimage.cfg OPTS_start_plathome_openblocks_ax3.pblx.kwbimg = $(PLATHOME_OPENBLOCKS_AX3_KWBOPTS) -OPTS_start_plathome_openblocks_ax3.pblx.kwbuartimg = -m uart $(PLATHOME_OPENBLOCKS_AX3_KWBOPTS) FILE_barebox-plathome-openblocks-ax3.img = start_plathome_openblocks_ax3.pblx.kwbimg -FILE_barebox-plathome-openblocks-ax3-uart.img = start_plathome_openblocks_ax3.pblx.kwbuartimg FILE_barebox-plathome-openblocks-ax3-2nd.img = start_plathome_openblocks_ax3.pblx pblx-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += start_plathome_openblocks_ax3 image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += barebox-plathome-openblocks-ax3.img -image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += barebox-plathome-openblocks-ax3-uart.img image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += barebox-plathome-openblocks-ax3-2nd.img # ----------------------- Dove 88AP510 based boards --------------------------- SOLIDRUN_CUBOX_KWBOPTS = ${KWBOPTS} -i $(board)/solidrun-cubox/kwbimage.cfg OPTS_start_solidrun_cubox.pblx.kwbimg = $(SOLIDRUN_CUBOX_KWBOPTS) -OPTS_start_solidrun_cubox.pblx.kwbuartimg = -m uart $(SOLIDRUN_CUBOX_KWBOPTS) FILE_barebox-solidrun-cubox.img = start_solidrun_cubox.pblx.kwbimg -FILE_barebox-solidrun-cubox-uart.img = start_solidrun_cubox.pblx.kwbuartimg FILE_barebox-solidrun-cubox-2nd.img = start_solidrun_cubox.pblx pblx-$(CONFIG_MACH_SOLIDRUN_CUBOX) += start_solidrun_cubox image-$(CONFIG_MACH_SOLIDRUN_CUBOX) += barebox-solidrun-cubox.img -image-$(CONFIG_MACH_SOLIDRUN_CUBOX) += barebox-solidrun-cubox-uart.img image-$(CONFIG_MACH_SOLIDRUN_CUBOX) += barebox-solidrun-cubox-2nd.img # ----------------------- Kirkwood based boards --------------------------- GLOBALSCALE_GURUPLUG_KWBOPTS = ${KWBOPTS} -i $(board)/globalscale-guruplug/kwbimage.cfg OPTS_start_globalscale_guruplug.pblx.kwbimg = $(GLOBALSCALE_GURUPLUG_KWBOPTS) -OPTS_start_globalscale_guruplug.pblx.kwbuartimg = -m uart $(GLOBALSCALE_GURUPLUG_KWBOPTS) FILE_barebox-globalscale-guruplug.img = start_globalscale_guruplug.pblx.kwbimg -FILE_barebox-globalscale-guruplug-uart.img = start_globalscale_guruplug.pblx.kwbuartimg FILE_barebox-globalscale-guruplug-2nd.img = start_globalscale_guruplug.pblx pblx-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += start_globalscale_guruplug image-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += barebox-globalscale-guruplug.img -image-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += barebox-globalscale-guruplug-uart.img image-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += barebox-globalscale-guruplug-2nd.img PLATHOME_OPENBLOCKS_A6_KWBOPTS = ${KWBOPTS} -i $(board)/plathome-openblocks-a6/kwbimage.cfg OPTS_start_plathome_openblocks_a6.pblx.kwbimg = $(PLATHOME_OPENBLOCKS_A6_KWBOPTS) -OPTS_start_plathome_openblocks_a6.pblx.kwbuartimg = -m uart $(PLATHOME_OPENBLOCKS_A6_KWBOPTS) FILE_barebox-plathome-openblocks-a6.img = start_plathome_openblocks_a6.pblx.kwbimg -FILE_barebox-plathome-openblocks-a6-uart.img = start_plathome_openblocks_a6.pblx.kwbuartimg FILE_barebox-plathome-openblocks-a6-2nd.img = start_plathome_openblocks_a6.pblx pblx-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += start_plathome_openblocks_a6 image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += barebox-plathome-openblocks-a6.img -image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += barebox-plathome-openblocks-a6-uart.img image-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += barebox-plathome-openblocks-a6-2nd.img USI_TOPKICK_KWBOPTS = ${KWBOPTS} -i $(board)/usi-topkick/kwbimage.cfg OPTS_start_usi_topkick.pblx.kwbimg = $(USI_TOPKICK_KWBOPTS) -OPTS_start_usi_topkick.pblx.kwbuartimg = -m uart $(USI_TOPKICK_KWBOPTS) FILE_barebox-usi-topkick.img = start_usi_topkick.pblx.kwbimg -FILE_barebox-usi-topkick-uart.img = start_usi_topkick.pblx.kwbuartimg FILE_barebox-usi-topkick-2nd.img = start_usi_topkick.pblx pblx-$(CONFIG_MACH_USI_TOPKICK) += start_usi_topkick image-$(CONFIG_MACH_USI_TOPKICK) += barebox-usi-topkick.img -image-$(CONFIG_MACH_USI_TOPKICK) += barebox-usi-topkick-uart.img image-$(CONFIG_MACH_USI_TOPKICK) += barebox-usi-topkick-2nd.img diff --git a/scripts/kwboot.c b/scripts/kwboot.c index 9b0d1d0..9e4181e 100644 --- a/scripts/kwboot.c +++ b/scripts/kwboot.c @@ -9,6 +9,7 @@ * 2008. Chapter 24.2 "BootROM Firmware". */ +#include #include #include #include @@ -35,7 +36,7 @@ }; #define KWBOOT_MSG_REQ_DELAY 1000 /* ms */ -#define KWBOOT_MSG_RSP_TIMEO 1000 /* ms */ +#define KWBOOT_MSG_RSP_TIMEO 1 /* ms */ /* * Xmodem Transfers @@ -273,11 +274,11 @@ else kwboot_printv("Sending boot message. Please reboot the target..."); - do { - rc = tcflush(tty, TCIOFLUSH); - if (rc) - break; + rc = tcflush(tty, TCIOFLUSH); + if (rc) + return rc; + do { rc = kwboot_tty_send(tty, msg, 8); if (rc) { usleep(KWBOOT_MSG_REQ_DELAY * 1000); @@ -285,12 +286,20 @@ } rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO); + while (!rc && c != NAK) { + if (c == '\\') + kwboot_printv("\\\\", c); + else if (isprint(c) || c == '\r' || c == '\n') + kwboot_printv("%c", c); + else + kwboot_printv("\\x%02hhx", c); - kwboot_spinner(); + rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO); + } } while (rc || c != NAK); - kwboot_printv("\n"); + kwboot_printv("\nGot expected NAK\n"); return rc; } @@ -302,13 +311,13 @@ kwboot_printv("Sending debug message. Please reboot the target..."); + rc = tcflush(tty, TCIOFLUSH); + if (rc) + return rc; + do { char buf[16]; - rc = tcflush(tty, TCIOFLUSH); - if (rc) - break; - rc = kwboot_tty_send(tty, msg, 8); if (rc) { usleep(KWBOOT_MSG_REQ_DELAY * 1000); @@ -349,6 +358,48 @@ return n; } +#define min(a, b) ((a) < (b) ? (a) : (b)) + +static int +kwboot_xm_resync(int fd) +{ + /* + * When the SoC has a different perception of where the package boundary + * is, just resending the packet doesn't help. To resync send 0xff until + * we get another NAK. + * The BootROM code (of the Armada XP at least) doesn't interpret 0xff + * as a start of a package and sends a NAK for each 0xff when waiting + * for SOH, so it's possible to send >1 byte without the SoC starting a + * new frame. + * When there is no response after sizeof(struct kwboot_block) bytes, + * there is another problem. + */ + int rc; + char buf[sizeof(struct kwboot_block)]; + unsigned interval = 1; + unsigned len; + char *p = buf; + + memset(buf, 0xff, sizeof(buf)); + + while (interval <= sizeof(buf)) { + len = min(interval, buf + sizeof(buf) - p); + rc = kwboot_tty_send(fd, p, len); + if (rc) + return rc; + + kwboot_tty_recv(fd, p, len, KWBOOT_BLK_RSP_TIMEO); + if (*p != 0xff) + /* got at least one char, if it's a NAK we're synced. */ + return (*p == NAK); + + p += len; + interval *= 2; + } + + return 0; +} + static int kwboot_xm_sendblock(int fd, struct kwboot_block *block) { @@ -371,7 +422,9 @@ } while (c != ACK && c != NAK && c != CAN); - if (c != ACK) + if (c == NAK && kwboot_xm_resync(fd)) + kwboot_progress(-1, 'S'); + else if (c != ACK) kwboot_progress(-1, '+'); } while (c == NAK && retries-- > 0); @@ -547,7 +600,7 @@ } static int -kwboot_check_image(const unsigned char *img, size_t size) +kwboot_check_image(unsigned char *img, size_t size) { size_t i; size_t header_size, image_size; @@ -560,12 +613,20 @@ } switch (img[0x0]) { - case 0x5a: /* SPI/NOR */ case 0x69: /* UART0 */ + break; + + case 0x5a: /* SPI/NOR */ case 0x78: /* SATA */ case 0x8b: /* NAND */ case 0x9c: /* PCIe */ + /* change boot source to UART and fix checksum */ + img[0x1f] -= img[0x0]; + img[0x1f] += 0x69; + img[0x0] = 0x69; + break; + default: fprintf(stderr, "Unknown boot source: 0x%hhx\n", img[0x0]); @@ -604,9 +665,9 @@ } static void * -kwboot_mmap_image(const char *path, size_t *size, int prot) +kwboot_mmap_image(const char *path, size_t *size) { - int rc, fd, flags; + int rc, fd; struct stat st; void *img; @@ -621,9 +682,7 @@ if (rc) goto out; - flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED; - - img = mmap(NULL, st.st_size, prot, flags, fd, 0); + img = mmap(NULL, st.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0); if (img == MAP_FAILED) { img = NULL; goto out; @@ -740,7 +799,7 @@ } if (imgpath) { - img = kwboot_mmap_image(imgpath, &size, PROT_READ); + img = kwboot_mmap_image(imgpath, &size); if (!img) { perror(imgpath); goto out;