mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
@ 2013-05-09  9:52 Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni
                   ` (9 more replies)
  0 siblings, 10 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

Hello,

Here is a patch set that adds basic support for the Marvell Armada 370
and Armada XP SOCs. For now, the support is quite minimal, since only
the serial port is supported. However, a significant part of the work
has been the development of the tools that allow to extract/create
bootable images and to push a bootable image through the UART to the
hardware platform.

I expect to work on adding support for more devices (such as the
network interface) and possibly to add support for the older, but
popular, Marvell Kirkwood SoC family. Contributions are of course
welcome.

Changes since v2:

 - Use $(srctree) when accessing kwbimage.cfg from arch/arm/Makefile,
   in order to allow out-of-tree builds to work properly. Noticed by
   Grégory Clement.

 - Improve the error message displayed by kwbimage when the DDR3
   training blob cannot be found. Since it must first be extracted by
   the user, it is a good idea to guide him. Suggested by Grégory
   Clement.

 - Change the file name of the binary blobs for each board, in order
   to make it different for each board. So instead of being 'binary.0'
   it is know 'globalscale-mirabox-binary.0', etc. This allows to keep
   multiple binary blobs for different boards around at the same time.

Changes since v1:

 - Drop the patch fixing scripts/checkpatch.pl since it has been
   merged upstream.

 - Improve kwbimage to add options that allow to override the payload
   filename, the boot media, the destination address and execution
   address from the command line. Suggested by Sascha Hauer.

 - Add an integration of kwbimage to the Barebox build process. Now,
   when an ARCH_MVEBU platform is selected, a barebox.kwb file is
   automatically generated using the board kwbimage.cfg, and a
   barebox.kwbuart is generated using the board kwbimage.cfg + an
   override of the boot media to be UART.

 - Simplify the kwbimage.cfg to no longer contain the payload filename
   (it is passed by Barebox using kwbimage -p option), the destination
   and execution addresses (those are passed by Barebox using kwbimage
   -d and -e options, which allows to ensure they match
   CONFIG_TEXT_BASE).

 - Change the default boot media of the kwbimage.cfg to be the real
   boot media used on the platform, typically SPI or NAND. Since an
   image for UART is always automatically generated by overriding the
   boot media, it makes sense to have the real boot media in
   kwbimage.cfg.

 - Remove incorrect whitespace change in scripts/Makefile. Noticed by
   Sascha Hauer.

In detail, the patch set contains:

 * A kwbimage tool. This tool allows to extract existing bootloader
   images, and create new bootloader images. It is more or less
   similar in purpose to the kwbimage tool from U-Boot, but is capable
   of handling 'version 1' images used by Armada 370/XP, and not only
   allows to create images, but also extract images.

   A typical usage is to first extract an existing bootloader image:

    ./scripts/kwbimage -x -i <existing-image> -o <some-directory>

   As an output, you typically get 3 files: kwbimage.cfg (a text file
   that describes the configuration of the image in a format
   ressembling the one used by U-Boot), binary.0 (the binary blob that
   does the DDR3 training) and payload (the bootloader itself).

   Being able to extract an image is needed in order to get the DDR3
   training code, and re-use it with Barebox.

   An image is then later created with:

    ./scripts/kwbimage -c -i <path/to/kwbimage.cfg> -o <image>

   For each board, the kwbimage.cfg file is typically located in
   arch/arm/boards/<board-name>/. The DDR3 training code must however
   be extracted from an existing bootloader image of your board,
   usually the one provided by the board manufacturer.

 * A kwboot tool to push a bootloader through UART. It is directly
   taken from U-Boot source code, to which I've added some fixes:

   - Extend the timeouts, to actually make it work on Armada
     370/XP. This has originally been found by Willy Tarreau.

   - Ignore non-Xmodem characters, so that the original DDR3 training
     code can be used without modifications (Willy had to change it to
     make it output its messages on a different serial port, otherwise
     it was confusing the Xmodem implementation)

   - Output to stdout all the non-Xmodem characters so that if
     something goes wrong during the transfer, we have some
     informations. It also shows the messages output by the DDR3
     training code.

   - Remove the 'patch' feature that patches an image to have the UART
     type. This requires a knowledge of the header format, which is
     different between version 0 (kirkwood) and version 1 (armada
     370/xp). It is not really needed anyway since kwbimage can
     extract and create images.

 * The SoC-level code, which for now only consists in a minimal
   clocksource driver, a function to register an UART, a fixed-rate
   clock, and a function that determines the amount of RAM by looking
   at the SDRAM windows registers.

 * An integration of kwbimage generation. When an ARCH_MVEBU platform
   is selected, both barebox.kwb and barebox.kwbuart images are
   generated automatically.

 * The board-level code for the Armada 370 Mirabox from Globalscale,
   the Armada XP OpenBlocks AX3 from Plathome and the Armada XP GP
   from Marvell.

Best regards,

Thomas

Thomas Petazzoni (7):
  scripts: new kwbimage manipulation tool for Marvell SoC boot images
  scripts: add kwboot tool
  arm: initial support for Marvell Armada 370/XP SoCs
  arm: integrate kwbimage in the image generation
  arm: add basic support for Armada XP OpenBlocks AX3 platform
  arm: add basic support for the Armada 370 Mirabox platform
  arm: add basic support for the Armada XP GP platform

 Makefile                                           |    2 +-
 arch/arm/Kconfig                                   |    8 +
 arch/arm/Makefile                                  |   24 +
 arch/arm/boards/globalscale-mirabox/Makefile       |    2 +
 arch/arm/boards/globalscale-mirabox/config.h       |    4 +
 .../globalscale-mirabox/globalscale-mirabox.c      |   26 +
 arch/arm/boards/globalscale-mirabox/kwbimage.cfg   |    5 +
 arch/arm/boards/globalscale-mirabox/lowlevel.c     |   26 +
 arch/arm/boards/marvell-armada-xp-gp/Makefile      |    2 +
 arch/arm/boards/marvell-armada-xp-gp/config.h      |    4 +
 arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg  |    3 +
 arch/arm/boards/marvell-armada-xp-gp/lowlevel.c    |   25 +
 .../marvell-armada-xp-gp/marvell-armada-xp-gp.c    |   25 +
 arch/arm/boards/plathome-openblocks-ax3/Makefile   |    2 +
 arch/arm/boards/plathome-openblocks-ax3/config.h   |    4 +
 .../boards/plathome-openblocks-ax3/kwbimage.cfg    |    3 +
 arch/arm/boards/plathome-openblocks-ax3/lowlevel.c |   25 +
 .../plathome-openblocks-ax3.c                      |   25 +
 arch/arm/configs/globalscale_mirabox_defconfig     |    8 +
 arch/arm/configs/marvell_armada_xp_gp_defconfig    |   10 +
 arch/arm/configs/plathome_openblocks_ax3_defconfig |    9 +
 arch/arm/mach-mvebu/Kconfig                        |   54 +
 arch/arm/mach-mvebu/Makefile                       |    1 +
 arch/arm/mach-mvebu/core.c                         |  142 ++
 arch/arm/mach-mvebu/include/mach/clkdev.h          |    7 +
 arch/arm/mach-mvebu/include/mach/debug_ll.h        |   40 +
 arch/arm/mach-mvebu/include/mach/mvebu.h           |   22 +
 drivers/clocksource/Kconfig                        |    4 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/mvebu.c                        |   90 ++
 scripts/.gitignore                                 |    2 +
 scripts/Makefile                                   |    1 +
 scripts/kwbimage.c                                 | 1448 ++++++++++++++++++++
 scripts/kwboot.c                                   |  717 ++++++++++
 34 files changed, 2770 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/globalscale-mirabox/Makefile
 create mode 100644 arch/arm/boards/globalscale-mirabox/config.h
 create mode 100644 arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c
 create mode 100644 arch/arm/boards/globalscale-mirabox/kwbimage.cfg
 create mode 100644 arch/arm/boards/globalscale-mirabox/lowlevel.c
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/Makefile
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/config.h
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/lowlevel.c
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/Makefile
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/config.h
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/lowlevel.c
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c
 create mode 100644 arch/arm/configs/globalscale_mirabox_defconfig
 create mode 100644 arch/arm/configs/marvell_armada_xp_gp_defconfig
 create mode 100644 arch/arm/configs/plathome_openblocks_ax3_defconfig
 create mode 100644 arch/arm/mach-mvebu/Kconfig
 create mode 100644 arch/arm/mach-mvebu/Makefile
 create mode 100644 arch/arm/mach-mvebu/core.c
 create mode 100644 arch/arm/mach-mvebu/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-mvebu/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-mvebu/include/mach/mvebu.h
 create mode 100644 drivers/clocksource/mvebu.c
 create mode 100644 scripts/kwbimage.c
 create mode 100644 scripts/kwboot.c

-- 
1.7.9.5


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

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

* [PATCH v3 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 2/7] scripts: add kwboot tool Thomas Petazzoni
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

The Marvell EBU SoCs (Kirkwood, Armada 370, Armada XP) have a BootROM
that understand a specific image format, composed of a main header,
several extension headers and a paylod. This image can be booted from
NAND, SPI, SATA, UART, NOR, etc.

This patch adds a tool that allows to extract the components and
configuration of existing images, and to create new images.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 scripts/.gitignore |    1 +
 scripts/Makefile   |    1 +
 scripts/kwbimage.c | 1448 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1450 insertions(+)
 create mode 100644 scripts/kwbimage.c

diff --git a/scripts/.gitignore b/scripts/.gitignore
index bff805d..a28ea52 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -2,6 +2,7 @@ bareboxenv
 bin2c
 gen_netx_image
 kallsyms
+kwbimage
 mk-am35xx-spi-image
 mkimage
 mkublheader
diff --git a/scripts/Makefile b/scripts/Makefile
index f062fc0..e0b9868 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -8,6 +8,7 @@ hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
 hostprogs-y                      += bin2c
 hostprogs-y                      += mkimage
 hostprogs-y                      += bareboxenv
+hostprogs-$(CONFIG_ARCH_MVEBU)   += kwbimage
 hostprogs-$(CONFIG_ARCH_NETX)    += gen_netx_image
 hostprogs-$(CONFIG_ARCH_OMAP)    += omap_signGP mk-am35xx-spi-image
 hostprogs-$(CONFIG_ARCH_S5PCxx)  += s5p_cksum
diff --git a/scripts/kwbimage.c b/scripts/kwbimage.c
new file mode 100644
index 0000000..90714aa
--- /dev/null
+++ b/scripts/kwbimage.c
@@ -0,0 +1,1448 @@
+/*
+ * Image manipulator for Kirkwood, Armada 370 and Armada XP platforms.
+ *
+ * (C) Copyright 2013 Thomas Petazzoni
+ * <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * This tool allows to extract and create bootable images for Marvell
+ * Kirkwood, Marvell Armada 370 and Armada XP SoCs. It supports two
+ * versions of the bootable image format: version 0 (used on Marvell
+ * Kirkwood) and version 1 (used on Marvell Armada 370/XP).
+ *
+ * To extract an image, run:
+ *  ./scripts/kwbimage -x -i <image-file> -o <some-directory>
+ *
+ * In <some-directory>, kwbimage will output 'kwbimage.cfg', the
+ * configuration file that describes the image, 'payload', which is
+ * the bootloader code itself, and it may output a 'binary.0' file
+ * that corresponds to a binary blob (only possible in version 1
+ * images).
+ *
+ * To create an image, run:
+ *  ./scripts/kwbimage -c -i <image-cfg-file> -o <image-file>
+ *
+ * The given configuration file is in the format of the 'kwbimage.cfg'
+ * file, and should reference the payload file (generally the
+ * bootloader code) and optionally a binary blob.
+ *
+ * Not implemented: support for the register headers and secure
+ * headers in v1 images
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
+
+/* Structure of the main header, version 0 (Kirkwood) */
+struct main_hdr_v0 {
+	uint8_t  blockid;		/*0     */
+	uint8_t  nandeccmode;		/*1     */
+	uint16_t nandpagesize;		/*2-3   */
+	uint32_t blocksize;		/*4-7   */
+	uint32_t rsvd1;			/*8-11  */
+	uint32_t srcaddr;		/*12-15 */
+	uint32_t destaddr;		/*16-19 */
+	uint32_t execaddr;		/*20-23 */
+	uint8_t  satapiomode;		/*24    */
+	uint8_t  rsvd3;			/*25    */
+	uint16_t ddrinitdelay;		/*26-27 */
+	uint16_t rsvd2;			/*28-29 */
+	uint8_t  ext;			/*30    */
+	uint8_t  checksum;		/*31    */
+};
+
+struct ext_hdr_v0_reg {
+	uint32_t raddr;
+	uint32_t rdata;
+};
+
+#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20)/sizeof(struct ext_hdr_v0_reg))
+
+struct ext_hdr_v0 {
+	uint32_t              offset;
+	uint8_t               reserved[0x20 - sizeof(uint32_t)];
+	struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
+	uint8_t               reserved2[7];
+	uint8_t               checksum;
+};
+
+/* Structure of the main header, version 1 (Armada 370, Armada XP) */
+struct main_hdr_v1 {
+	uint8_t  blockid;               /* 0 */
+	uint8_t  reserved1;             /* 1 */
+	uint16_t reserved2;             /* 2-3 */
+	uint32_t blocksize;             /* 4-7 */
+	uint8_t  version;               /* 8 */
+	uint8_t  headersz_msb;          /* 9 */
+	uint16_t headersz_lsb;          /* A-B */
+	uint32_t srcaddr;               /* C-F */
+	uint32_t destaddr;              /* 10-13 */
+	uint32_t execaddr;              /* 14-17 */
+	uint8_t  reserved3;             /* 18 */
+	uint8_t  nandblocksize;         /* 19 */
+	uint8_t  nandbadblklocation;    /* 1A */
+	uint8_t  reserved4;             /* 1B */
+	uint16_t reserved5;             /* 1C-1D */
+	uint8_t  ext;                   /* 1E */
+	uint8_t  checksum;              /* 1F */
+};
+
+/*
+ * Header for the optional headers, version 1 (Armada 370, Armada XP)
+ */
+struct opt_hdr_v1 {
+	uint8_t  headertype;
+	uint8_t  headersz_msb;
+	uint16_t headersz_lsb;
+	char     data[0];
+};
+
+/*
+ * Various values for the opt_hdr_v1->headertype field, describing the
+ * different types of optional headers. The "secure" header contains
+ * informations related to secure boot (encryption keys, etc.). The
+ * "binary" header contains ARM binary code to be executed prior to
+ * executing the main payload (usually the bootloader). This is
+ * typically used to execute DDR3 training code. The "register" header
+ * allows to describe a set of (address, value) tuples that are
+ * generally used to configure the DRAM controller.
+ */
+#define OPT_HDR_V1_SECURE_TYPE   0x1
+#define OPT_HDR_V1_BINARY_TYPE   0x2
+#define OPT_HDR_V1_REGISTER_TYPE 0x3
+
+#define KWBHEADER_V1_SIZE(hdr) \
+	(((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
+
+struct boot_mode {
+	unsigned int id;
+	const char *name;
+};
+
+struct boot_mode boot_modes[] = {
+	{ 0x4D, "i2c"  },
+	{ 0x5A, "spi"  },
+	{ 0x8B, "nand" },
+	{ 0x78, "sata" },
+	{ 0x9C, "pex"  },
+	{ 0x69, "uart" },
+	{},
+};
+
+struct nand_ecc_mode {
+	unsigned int id;
+	const char *name;
+};
+
+struct nand_ecc_mode nand_ecc_modes[] = {
+	{ 0x00, "default" },
+	{ 0x01, "hamming" },
+	{ 0x02, "rs" },
+	{ 0x03, "disabled" },
+	{},
+};
+
+/* Used to identify an undefined execution or destination address */
+#define ADDR_INVALID ((uint32_t)-1)
+
+#define BINARY_MAX_ARGS 8
+
+/* In-memory representation of a line of the configuration file */
+struct image_cfg_element {
+	enum {
+		IMAGE_CFG_VERSION = 0x1,
+		IMAGE_CFG_BOOT_FROM,
+		IMAGE_CFG_DEST_ADDR,
+		IMAGE_CFG_EXEC_ADDR,
+		IMAGE_CFG_NAND_BLKSZ,
+		IMAGE_CFG_NAND_BADBLK_LOCATION,
+		IMAGE_CFG_BINARY,
+		IMAGE_CFG_PAYLOAD,
+		IMAGE_CFG_DATA,
+	} type;
+	union {
+		unsigned int version;
+		unsigned int bootfrom;
+		struct {
+			const char *file;
+			unsigned int args[BINARY_MAX_ARGS];
+			unsigned int nargs;
+		} binary;
+		const char *payload;
+		unsigned int dstaddr;
+		unsigned int execaddr;
+		unsigned int nandblksz;
+		unsigned int nandbadblklocation;
+		struct ext_hdr_v0_reg regdata;
+	};
+};
+
+#define IMAGE_CFG_ELEMENT_MAX 256
+
+/*
+ * Byte 8 of the image header contains the version number. In the v0
+ * header, byte 8 was reserved, and always set to 0. In the v1 header,
+ * byte 8 has been changed to a proper field, set to 1.
+ */
+static unsigned int image_version(void *header)
+{
+	unsigned char *ptr = header;
+	return ptr[8];
+}
+
+/*
+ * Utility functions to manipulate boot mode and ecc modes (convert
+ * them back and forth between description strings and the
+ * corresponding numerical identifiers).
+ */
+
+static const char *image_boot_mode_name(unsigned int id)
+{
+	int i;
+	for (i = 0; boot_modes[i].name; i++)
+		if (boot_modes[i].id == id)
+			return boot_modes[i].name;
+	return NULL;
+}
+
+unsigned int image_boot_mode_id(const char *boot_mode_name)
+{
+	int i;
+	for (i = 0; boot_modes[i].name; i++)
+		if (!strcmp(boot_modes[i].name, boot_mode_name))
+			return boot_modes[i].id;
+
+	return 0;
+}
+
+static const char *image_nand_ecc_mode_name(unsigned int id)
+{
+	int i;
+	for (i = 0; nand_ecc_modes[i].name; i++)
+		if (nand_ecc_modes[i].id == id)
+			return nand_ecc_modes[i].name;
+	return NULL;
+}
+
+static struct image_cfg_element *
+image_find_option(struct image_cfg_element *image_cfg,
+		  int cfgn, unsigned int optiontype)
+{
+	int i;
+
+	for (i = 0; i < cfgn; i++) {
+		if (image_cfg[i].type == optiontype)
+			return &image_cfg[i];
+	}
+
+	return NULL;
+}
+
+/*
+ * Compute a 8-bit checksum of a memory area. This algorithm follows
+ * the requirements of the Marvell SoC BootROM specifications.
+ */
+static uint8_t image_checksum8(void *start, uint32_t len)
+{
+	uint8_t csum = 0;
+	uint8_t *p = start;
+
+	/* check len and return zero checksum if invalid */
+	if (!len)
+		return 0;
+
+	do {
+		csum += *p;
+		p++;
+	} while (--len);
+
+	return csum;
+}
+
+static uint32_t image_checksum32 (void *start, uint32_t len)
+{
+	uint32_t csum = 0;
+	uint32_t *p = start;
+
+	/* check len and return zero checksum if invalid */
+	if (!len)
+		return 0;
+
+	if (len % sizeof(uint32_t)) {
+		fprintf (stderr, "Length %d is not in multiple of %zu\n",
+			 len, sizeof(uint32_t));
+		return 0;
+	}
+
+	do {
+		csum += *p;
+		p++;
+		len -= sizeof(uint32_t);
+	} while (len > 0);
+
+	return csum;
+}
+
+static void usage(const char *prog)
+{
+	printf("Usage: %s [-c | -x] -i <input> -o <output>\n", prog);
+	printf("   -c: create a new image\n");
+	printf("   -x: extract an existing image\n");
+	printf("   -i: input file\n");
+	printf("       when used with -c, should point to a kwbimage.cfg file\n");
+	printf("       when used with -x, should point to the image to be extracted\n");
+	printf("   -o: output file/directory\n");
+	printf("       when used with -c, should point to the image file to create\n");
+	printf("       when used with -x, should point to a directory when the image will be extracted\n");
+	printf("   -v: verbose\n");
+	printf("   -h: this help text\n");
+	printf(" Options specific to image creation:\n");
+	printf("   -p: path to payload image. Overrides the PAYLOAD line from kwbimage.cfg\n");
+	printf("   -m: boot media. Overrides the BOOT_FROM line from kwbimage.cfg\n");
+	printf("   -d: load address. Overrides the DEST_ADDR line from kwbimage.cfg\n");
+	printf("   -e: exec address. Overrides the EXEC_ADDR line from kwbimage.cfg\n");
+}
+
+static int image_extract_payload(void *payload, size_t sz, const char *output)
+{
+	char *imageoutname;
+	FILE *imageout;
+	int ret;
+
+	ret = asprintf(&imageoutname, "%s/payload", output);
+	if (ret < 0) {
+		fprintf(stderr, "Cannot allocate memory\n");
+		return -1;
+	}
+
+	imageout = fopen(imageoutname, "w+");
+	if (!imageout) {
+		fprintf(stderr, "Could not open output file %s\n",
+			imageoutname);
+		free(imageoutname);
+		return -1;
+	}
+
+	ret = fwrite(payload, sz, 1, imageout);
+	if (ret != 1) {
+		fprintf(stderr, "Could not write to open file %s\n",
+			imageoutname);
+		fclose(imageout);
+		free(imageoutname);
+		return -1;
+	}
+
+	fclose(imageout);
+	free(imageoutname);
+	return 0;
+}
+
+static int image_extract_v0(void *fdimap, const char *output, FILE *focfg)
+{
+	struct main_hdr_v0 *main_hdr = fdimap;
+	struct ext_hdr_v0 *ext_hdr;
+	const char *boot_mode_name;
+	uint32_t *img_checksum;
+	size_t payloadsz;
+	int cksum, i;
+
+	/*
+	 * Verify checksum. When calculating the header, discard the
+	 * last byte of the header, which itself contains the
+	 * checksum.
+	 */
+	cksum = image_checksum8(main_hdr, sizeof(struct main_hdr_v0)-1);
+	if (cksum != main_hdr->checksum) {
+		fprintf(stderr,
+			"Invalid main header checksum: 0x%08x vs. 0x%08x\n",
+			cksum, main_hdr->checksum);
+		return -1;
+	}
+
+	boot_mode_name = image_boot_mode_name(main_hdr->blockid);
+	if (!boot_mode_name) {
+		fprintf(stderr, "Invalid boot ID: 0x%x\n",
+			main_hdr->blockid);
+		return -1;
+	}
+
+	fprintf(focfg, "VERSION 0\n");
+	fprintf(focfg, "BOOT_FROM %s\n", boot_mode_name);
+	fprintf(focfg, "DESTADDR %08x\n", main_hdr->destaddr);
+	fprintf(focfg, "EXECADDR %08x\n", main_hdr->execaddr);
+
+	if (!strcmp(boot_mode_name, "nand")) {
+		const char *nand_ecc_mode =
+			image_nand_ecc_mode_name(main_hdr->nandeccmode);
+		fprintf(focfg, "NAND_ECC_MODE %s\n",
+			nand_ecc_mode);
+		fprintf(focfg, "NAND_PAGE_SIZE %08x\n",
+			main_hdr->nandpagesize);
+	}
+
+	/* No extension header, we're done */
+	if (!main_hdr->ext)
+		return 0;
+
+	ext_hdr = fdimap + sizeof(struct main_hdr_v0);
+
+	for (i = 0; i < EXT_HDR_V0_REG_COUNT; i++) {
+		if (ext_hdr->rcfg[i].raddr == 0 &&
+		    ext_hdr->rcfg[i].rdata == 0)
+			break;
+
+		fprintf(focfg, "DATA %08x %08x\n",
+			ext_hdr->rcfg[i].raddr,
+			ext_hdr->rcfg[i].rdata);
+	}
+
+	/* The image is concatenated with a 32 bits checksum */
+	payloadsz = main_hdr->blocksize - sizeof(uint32_t);
+	img_checksum = (uint32_t *) (fdimap + main_hdr->srcaddr + payloadsz);
+
+	if (*img_checksum != image_checksum32(fdimap + main_hdr->srcaddr,
+					      payloadsz)) {
+		fprintf(stderr, "The image checksum does not match\n");
+		return -1;
+	}
+
+	/* Finally, handle the image itself */
+	fprintf(focfg, "PAYLOAD %s/payload\n", output);
+	return image_extract_payload(fdimap + main_hdr->srcaddr,
+				     payloadsz, output);
+}
+
+static int image_extract_binary_hdr_v1(const void *binary, const char *output,
+				       FILE *focfg, int hdrnum, size_t binsz)
+{
+	char *binaryoutname;
+	FILE *binaryout;
+	const unsigned int *args;
+	unsigned int nargs;
+	int ret, i;
+
+	args = binary;
+	nargs = args[0];
+	args++;
+
+	ret = asprintf(&binaryoutname, "%s/binary.%d", output,
+		       hdrnum);
+	if (ret < 0) {
+		fprintf(stderr, "Couldn't not allocate memory\n");
+		return ret;
+	}
+
+	binaryout = fopen(binaryoutname, "w+");
+	if (!binaryout) {
+		fprintf(stderr, "Couldn't open output file %s\n",
+			binaryoutname);
+		free(binaryoutname);
+		return -1;
+	}
+
+	ret = fwrite(binary + (nargs + 1) * sizeof(unsigned int),
+		     binsz - (nargs + 1) * sizeof(unsigned int), 1,
+		     binaryout);
+	if (ret != 1) {
+		fprintf(stderr, "Could not write to output file %s\n",
+			binaryoutname);
+		fclose(binaryout);
+		free(binaryoutname);
+		return -1;
+	}
+
+	fclose(binaryout);
+
+	fprintf(focfg, "BINARY %s", binaryoutname);
+	for (i = 0; i < nargs; i++)
+		fprintf(focfg, " %08x", args[i]);
+	fprintf(focfg, "\n");
+
+	free(binaryoutname);
+
+	return 0;
+}
+
+static int image_extract_v1(void *fdimap, const char *output, FILE *focfg)
+{
+	struct main_hdr_v1 *main_hdr = fdimap;
+	struct opt_hdr_v1 *opt_hdr;
+	const char *boot_mode_name;
+	int headersz = KWBHEADER_V1_SIZE(main_hdr);
+	int hasheaders;
+	uint8_t cksum;
+	int opthdrid;
+
+	/*
+	 * Verify the checkum. We have to substract the checksum
+	 * itself, because when the checksum is calculated, the
+	 * checksum field is 0.
+	 */
+	cksum = image_checksum8(main_hdr, headersz);
+	cksum -= main_hdr->checksum;
+
+	if (cksum != main_hdr->checksum) {
+		fprintf(stderr,
+			"Invalid main header checksum: 0x%08x vs. 0x%08x\n",
+			cksum, main_hdr->checksum);
+		return -1;
+	}
+
+	/* First, take care of the main header */
+	boot_mode_name = image_boot_mode_name(main_hdr->blockid);
+	if (!boot_mode_name) {
+		fprintf(stderr, "Invalid boot ID: 0x%x\n",
+			main_hdr->blockid);
+		return -1;
+	}
+
+	fprintf(focfg, "VERSION 1\n");
+	fprintf(focfg, "BOOT_FROM %s\n", boot_mode_name);
+	fprintf(focfg, "DESTADDR %08x\n", main_hdr->destaddr);
+	fprintf(focfg, "EXECADDR %08x\n", main_hdr->execaddr);
+	fprintf(focfg, "NAND_BLKSZ %08x\n",
+		main_hdr->nandblocksize * 64 * 1024);
+	fprintf(focfg, "NAND_BADBLK_LOCATION %02x\n",
+		main_hdr->nandbadblklocation);
+
+	hasheaders = main_hdr->ext;
+	opt_hdr = fdimap + sizeof(struct main_hdr_v1);
+	opthdrid = 0;
+
+	/* Then, go through all the extension headers */
+	while (hasheaders) {
+		int opthdrsz = KWBHEADER_V1_SIZE(opt_hdr);
+
+		switch (opt_hdr->headertype) {
+		case OPT_HDR_V1_BINARY_TYPE:
+			image_extract_binary_hdr_v1(opt_hdr->data, output,
+						    focfg, opthdrid,
+						    opthdrsz -
+						    sizeof(struct opt_hdr_v1));
+			break;
+		case OPT_HDR_V1_SECURE_TYPE:
+		case OPT_HDR_V1_REGISTER_TYPE:
+			fprintf(stderr,
+				"Support for header type 0x%x not implemented\n",
+				opt_hdr->headertype);
+			exit(1);
+			break;
+		default:
+			fprintf(stderr, "Invalid header type 0x%x\n",
+				opt_hdr->headertype);
+			exit(1);
+		}
+
+		/*
+		 * The first byte of the last double word of the
+		 * current header indicates whether there is a next
+		 * header or not.
+		 */
+		hasheaders = ((char *)opt_hdr)[opthdrsz - 4];
+
+		/* Move to the next header */
+		opt_hdr = ((void *)opt_hdr) + opthdrsz;
+		opthdrid++;
+	}
+
+	/* Finally, handle the image itself */
+	fprintf(focfg, "PAYLOAD %s/payload\n", output);
+	return image_extract_payload(fdimap + main_hdr->srcaddr,
+				     main_hdr->blocksize - 4,
+				     output);
+}
+
+static int image_extract(const char *input, const char *output)
+{
+	int fdi, ret;
+	struct stat fdistat, fdostat;
+	void *fdimap;
+	char *focfgname;
+	FILE *focfg;
+
+	fdi = open(input, O_RDONLY);
+	if (fdi < 0) {
+		fprintf(stderr, "Cannot open input file %s: %m\n",
+			input);
+		return -1;
+	}
+
+	ret = fstat(fdi, &fdistat);
+	if (ret < 0) {
+		fprintf(stderr, "Cannot stat input file %s: %m\n",
+			input);
+		close(fdi);
+		return -1;
+	}
+
+	fdimap = mmap(NULL, fdistat.st_size, PROT_READ, MAP_PRIVATE, fdi, 0);
+	if (fdimap == MAP_FAILED) {
+		fprintf(stderr, "Cannot map input file %s: %m\n",
+			input);
+		close(fdi);
+		return -1;
+	}
+
+	close(fdi);
+
+	ret = stat(output, &fdostat);
+	if (ret < 0) {
+		fprintf(stderr, "Cannot stat output directory %s: %m\n",
+			output);
+		munmap(fdimap, fdistat.st_size);
+		return -1;
+	}
+
+	if (!S_ISDIR(fdostat.st_mode)) {
+		fprintf(stderr, "Output %s should be a directory\n",
+			output);
+		munmap(fdimap, fdistat.st_size);
+		return -1;
+	}
+
+	ret = asprintf(&focfgname, "%s/kwbimage.cfg", output);
+	if (ret < 0) {
+		fprintf(stderr, "Failed to allocate memory\n");
+		munmap(fdimap, fdistat.st_size);
+		return -1;
+	}
+
+	focfg = fopen(focfgname, "w+");
+	if (!focfg) {
+		fprintf(stderr, "Output file %s could not be created\n",
+			focfgname);
+		free(focfgname);
+		munmap(fdimap, fdistat.st_size);
+		return -1;
+	}
+
+	free(focfgname);
+
+	if (image_version(fdimap) == 0)
+		ret = image_extract_v0(fdimap, output, focfg);
+	else if (image_version(fdimap) == 1)
+		ret = image_extract_v1(fdimap, output, focfg);
+	else {
+		fprintf(stderr, "Invalid image version %d\n",
+			image_version(fdimap));
+		ret = -1;
+	}
+
+	fclose(focfg);
+	munmap(fdimap, fdistat.st_size);
+	return ret;
+}
+
+static int image_create_payload(void *payload_start, size_t payloadsz,
+				const char *payload_filename)
+{
+	FILE *payload;
+	uint32_t *payload_checksum =
+		(uint32_t *) (payload_start + payloadsz);
+	int ret;
+
+	payload = fopen(payload_filename, "r");
+	if (!payload) {
+		fprintf(stderr, "Cannot open payload file %s\n",
+			payload_filename);
+		return -1;
+	}
+
+	ret = fread(payload_start, payloadsz, 1, payload);
+	if (ret != 1) {
+		fprintf(stderr, "Cannot read payload file %s\n",
+			payload_filename);
+		return -1;
+	}
+
+	fclose(payload);
+
+	*payload_checksum = image_checksum32(payload_start, payloadsz);
+	return 0;
+}
+
+static void *image_create_v0(struct image_cfg_element *image_cfg,
+			     int cfgn, const char *output, size_t *imagesz)
+{
+	struct image_cfg_element *e, *payloade;
+	size_t headersz, payloadsz, totalsz;
+	struct main_hdr_v0 *main_hdr;
+	struct ext_hdr_v0 *ext_hdr;
+	void *image;
+	int has_ext = 0;
+	int cfgi, ret;
+
+	/* Calculate the size of the header and the size of the
+	 * payload */
+	headersz  = sizeof(struct main_hdr_v0);
+	payloadsz = 0;
+
+	e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DATA);
+	if (e) {
+		has_ext = 1;
+		headersz += sizeof(struct ext_hdr_v0);
+	}
+
+	payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD);
+	if (payloade) {
+		struct stat s;
+		int ret;
+
+		ret = stat(payloade->payload, &s);
+		if (ret < 0) {
+			fprintf(stderr, "Cannot stat payload file %s\n",
+				payloade->payload);
+			return NULL;
+		}
+
+		payloadsz = s.st_size;
+	}
+
+	/* Headers, payload and 32-bits checksum */
+	totalsz = headersz + payloadsz + sizeof(uint32_t);
+
+	image = malloc(totalsz);
+	if (!image) {
+		fprintf(stderr, "Cannot allocate memory for image\n");
+		return NULL;
+	}
+
+	memset(image, 0, totalsz);
+
+	main_hdr = image;
+
+	/* Fill in the main header */
+	main_hdr->blocksize = payloadsz + sizeof(uint32_t);
+	main_hdr->srcaddr   = headersz;
+	main_hdr->ext       = has_ext;
+	for (cfgi = 0; cfgi < cfgn; cfgi++) {
+		struct image_cfg_element *el = &image_cfg[cfgi];
+		if (el->type == IMAGE_CFG_BOOT_FROM)
+			main_hdr->blockid = el->bootfrom;
+		else if (el->type == IMAGE_CFG_DEST_ADDR)
+			main_hdr->destaddr = el->dstaddr;
+		else if (el->type == IMAGE_CFG_EXEC_ADDR)
+			main_hdr->execaddr = el->execaddr;
+		else if (el->type != IMAGE_CFG_VERSION)
+			break;
+	}
+
+	main_hdr->checksum = image_checksum8(image,
+					     sizeof(struct main_hdr_v0));
+
+	/* Generate the ext header */
+	if (has_ext) {
+		int datai = 0;
+
+		ext_hdr = image + sizeof(struct main_hdr_v0);
+		ext_hdr->offset = 0x40;
+
+		for (; cfgi < cfgn; cfgi++) {
+			struct image_cfg_element *el = &image_cfg[cfgi];
+			if (el->type == IMAGE_CFG_DATA) {
+				ext_hdr->rcfg[datai].raddr = el->regdata.raddr;
+				ext_hdr->rcfg[datai].rdata = el->regdata.rdata;
+				datai++;
+			}
+			else if (el->type == IMAGE_CFG_PAYLOAD)
+				break;
+			else {
+				fprintf(stderr, "Invalid element of type %d\n",
+					el->type);
+				return NULL;
+			}
+		}
+
+		ext_hdr->checksum = image_checksum8(ext_hdr,
+						    sizeof(struct ext_hdr_v0));
+	}
+
+	if (payloade) {
+		ret = image_create_payload(image + headersz, payloadsz,
+					   payloade->payload);
+		if (ret < 0)
+			return NULL;
+	}
+
+	*imagesz = totalsz;
+	return image;
+}
+
+static void *image_create_v1(struct image_cfg_element *image_cfg,
+			     int cfgn, const char *output, size_t *imagesz)
+{
+	struct image_cfg_element *e, *payloade;
+	struct main_hdr_v1 *main_hdr;
+	size_t headersz, payloadsz, totalsz;
+	void *image, *cur;
+	int hasext = 0;
+	int cfgi, ret;
+
+	/* Calculate the size of the header and the size of the
+	 * payload */
+	headersz = sizeof(struct main_hdr_v1);
+	payloadsz = 0;
+
+	e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BINARY);
+	if (e) {
+		struct stat s;
+
+		ret = stat(e->binary.file, &s);
+		if (ret < 0) {
+			char *cwd = get_current_dir_name();
+			fprintf(stderr,
+				"Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
+				"This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
+				"image for your board. See 'kwbimage -x' to extract it from an existing image.\n",
+				e->binary.file, cwd);
+			free(cwd);
+			return NULL;
+		}
+
+		headersz += s.st_size +
+			e->binary.nargs * sizeof(unsigned int);
+		hasext = 1;
+	}
+
+	payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD);
+	if (payloade) {
+		struct stat s;
+
+		ret = stat(payloade->payload, &s);
+		if (ret < 0) {
+			fprintf(stderr, "Cannot stat payload file %s\n",
+				payloade->payload);
+			return NULL;
+		}
+
+		payloadsz = s.st_size;
+	}
+
+	/* The payload should be aligned on some reasonable
+	 * boundary */
+	headersz = ALIGN_SUP(headersz, 4096);
+
+	/* The total size includes the headers, the payload, and the
+	 * 32 bits checksum at the end of the payload */
+	totalsz = headersz + payloadsz + sizeof(uint32_t);
+
+	image = malloc(totalsz);
+	if (!image) {
+		fprintf(stderr, "Cannot allocate memory for image\n");
+		return NULL;
+	}
+
+	memset(image, 0, totalsz);
+
+	cur = main_hdr = image;
+	cur += sizeof(struct main_hdr_v1);
+
+	main_hdr->blocksize    = payloadsz + sizeof(uint32_t);
+	main_hdr->headersz_lsb = headersz & 0xFFFF;
+	main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
+	main_hdr->srcaddr      = headersz;
+	main_hdr->ext          = hasext;
+
+	/* First, take care of filling the main header */
+	for (cfgi = 0; cfgi < cfgn; cfgi++) {
+		struct image_cfg_element *el = &image_cfg[cfgi];
+		if (el->type == IMAGE_CFG_VERSION)
+			main_hdr->version = 1;
+		else if (el->type == IMAGE_CFG_BOOT_FROM)
+			main_hdr->blockid = el->bootfrom;
+		else if (el->type == IMAGE_CFG_DEST_ADDR)
+			main_hdr->destaddr = el->dstaddr;
+		else if (el->type == IMAGE_CFG_EXEC_ADDR)
+			main_hdr->execaddr = el->execaddr;
+		else if (el->type == IMAGE_CFG_NAND_BLKSZ)
+			main_hdr->nandblocksize = el->nandblksz / (64 * 1024);
+		else if (el->type == IMAGE_CFG_NAND_BADBLK_LOCATION)
+			main_hdr->nandbadblklocation = el->nandbadblklocation;
+		else
+			break;
+	}
+
+	/* Then, fill the extension headers */
+	for (; cfgi < cfgn; cfgi++) {
+		struct image_cfg_element *el = &image_cfg[cfgi];
+
+		if (el->type == IMAGE_CFG_BINARY) {
+			struct opt_hdr_v1 *hdr = cur;
+			unsigned int *args;
+			size_t binhdrsz;
+			struct stat s;
+			int argi;
+			FILE *bin;
+
+			hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
+
+			bin = fopen(el->binary.file, "r");
+			if (!bin) {
+				fprintf(stderr, "Cannot open binary file %s\n",
+					el->binary.file);
+				return NULL;
+			}
+
+			fstat(fileno(bin), &s);
+
+			binhdrsz = sizeof(struct opt_hdr_v1) +
+				(el->binary.nargs + 1) * sizeof(unsigned int) +
+				s.st_size;
+			hdr->headersz_lsb = binhdrsz & 0xFFFF;
+			hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
+
+			cur += sizeof(struct opt_hdr_v1);
+
+			args = cur;
+			*args = el->binary.nargs;
+			args++;
+			for (argi = 0; argi < el->binary.nargs; argi++)
+				args[argi] = el->binary.args[argi];
+
+			cur += (el->binary.nargs + 1) * sizeof(unsigned int);
+
+			ret = fread(cur, s.st_size, 1, bin);
+			if (ret != 1) {
+				fprintf(stderr,
+					"Could not read binary image %s\n",
+					el->binary.file);
+				return NULL;
+			}
+
+			fclose(bin);
+
+			cur += s.st_size;
+
+			/* See if we have a next header or not, and if
+			 * so, add the marker indicating that we are
+			 * not the last header */
+			if ((cfgi < (cfgn - 1)) &&
+			    (image_cfg[cfgi + 1].type != IMAGE_CFG_PAYLOAD))
+				*((unsigned char *) cur) = 1;
+			cur += sizeof(uint32_t);
+		} else if (el->type == IMAGE_CFG_PAYLOAD)
+			break;
+		else {
+			fprintf(stderr, "Invalid element type %d (cfgi=%d)\n",
+				el->type, cfgi);
+			return NULL;
+		}
+	}
+
+	/* Calculate and set the header checksum */
+	main_hdr->checksum = image_checksum8(main_hdr, headersz);
+
+	if (payloade) {
+		ret = image_create_payload(image + headersz, payloadsz,
+					   payloade->payload);
+		if (ret < 0)
+			return NULL;
+	}
+
+	*imagesz = totalsz;
+	return image;
+}
+
+static int image_create_config_parse_oneline(char *line,
+					     struct image_cfg_element *el)
+{
+	char *keyword, *saveptr;
+
+	keyword = strtok_r(line, " ", &saveptr);
+	if (!strcmp(keyword, "VERSION")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_VERSION;
+		el->version = atoi(value);
+	} else if (!strcmp(keyword, "BOOT_FROM")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_BOOT_FROM;
+		el->bootfrom = image_boot_mode_id(value);
+		if (!el->bootfrom) {
+			fprintf(stderr,
+				"Invalid boot media '%s'\n", value);
+			return -1;
+		}
+	} else if (!strcmp(keyword, "DESTADDR")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_DEST_ADDR;
+		el->dstaddr = strtol(value, NULL, 16);
+	} else if (!strcmp(keyword, "EXECADDR")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_EXEC_ADDR;
+		el->execaddr = strtol(value, NULL, 16);
+	} else if (!strcmp(keyword, "NAND_BLKSZ")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_NAND_BLKSZ;
+		el->nandblksz = strtol(value, NULL, 16);
+	} else if (!strcmp(keyword, "NAND_BADBLK_LOCATION")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_NAND_BADBLK_LOCATION;
+		el->nandbadblklocation =
+			strtol(value, NULL, 16);
+	} else if (!strcmp(keyword, "BINARY")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		int argi = 0;
+
+		el->type = IMAGE_CFG_BINARY;
+		el->binary.file = strdup(value);
+		while (1) {
+			value = strtok_r(NULL, " ", &saveptr);
+			if (!value)
+				break;
+			el->binary.args[argi] = strtol(value, NULL, 16);
+			argi++;
+			if (argi >= BINARY_MAX_ARGS) {
+				fprintf(stderr,
+					"Too many argument for binary\n");
+				return -1;
+			}
+		}
+		el->binary.nargs = argi;
+	} else if (!strcmp(keyword, "DATA")) {
+		char *value1 = strtok_r(NULL, " ", &saveptr);
+		char *value2 = strtok_r(NULL, " ", &saveptr);
+
+		if (!value1 || !value2) {
+			fprintf(stderr, "Invalid number of arguments for DATA\n");
+			return -1;
+		}
+
+		el->type = IMAGE_CFG_DATA;
+		el->regdata.raddr = strtol(value1, NULL, 16);
+		el->regdata.rdata = strtol(value2, NULL, 16);
+	} else if (!strcmp(keyword, "PAYLOAD")) {
+		char *value = strtok_r(NULL, " ", &saveptr);
+		el->type = IMAGE_CFG_PAYLOAD;
+		el->payload = strdup(value);
+	} else {
+		fprintf(stderr, "Ignoring unknown line '%s'\n", line);
+	}
+
+	return 0;
+}
+
+/*
+ * Parse the configuration file 'fcfg' into the array of configuration
+ * elements 'image_cfg', and return the number of configuration
+ * elements in 'cfgn'.
+ */
+static int image_create_config_parse(FILE *fcfg,
+				     struct image_cfg_element *image_cfg,
+				     int *cfgn)
+{
+	int ret;
+	int cfgi = 0;
+
+	/* Parse the configuration file */
+	while (!feof(fcfg)) {
+		char *line;
+		char buf[256];
+
+		/* Read the current line */
+		memset(buf, 0, sizeof(buf));
+		line = fgets(buf, sizeof(buf), fcfg);
+		if (!line)
+			break;
+
+		/* Ignore useless lines */
+		if (line[0] == '\n' || line[0] == '#')
+			continue;
+
+		/* Strip final newline */
+		if (line[strlen(line) - 1] == '\n')
+			line[strlen(line) - 1] = 0;
+
+		/* Parse the current line */
+		ret = image_create_config_parse_oneline(line,
+							&image_cfg[cfgi]);
+		if (ret)
+			return ret;
+
+		cfgi++;
+
+		if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
+			fprintf(stderr, "Too many configuration elements in .cfg file\n");
+			return -1;
+		}
+	}
+
+	*cfgn = cfgi;
+	return 0;
+}
+
+static int image_override_payload(struct image_cfg_element *image_cfg,
+				 int *cfgn, const char *payload)
+{
+	struct image_cfg_element *e;
+	int cfgi = *cfgn;
+
+	if (!payload)
+		return 0;
+
+	e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_PAYLOAD);
+	if (e) {
+		e->payload = payload;
+		return 0;
+	}
+
+	image_cfg[cfgi].type = IMAGE_CFG_PAYLOAD;
+	image_cfg[cfgi].payload = payload;
+	cfgi++;
+
+	*cfgn = cfgi;
+	return 0;
+}
+
+static int image_override_bootmedia(struct image_cfg_element *image_cfg,
+				    int *cfgn, const char *bootmedia)
+{
+	struct image_cfg_element *e;
+	int bootfrom;
+	int cfgi = *cfgn;
+
+	if (!bootmedia)
+		return 0;
+
+	bootfrom = image_boot_mode_id(bootmedia);
+	if (!bootfrom) {
+		fprintf(stderr,
+			"Invalid boot media '%s'\n", bootmedia);
+		return -1;
+	}
+
+	e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_BOOT_FROM);
+	if (e) {
+		e->bootfrom = bootfrom;
+		return 0;
+	}
+
+	image_cfg[cfgi].type = IMAGE_CFG_BOOT_FROM;
+	image_cfg[cfgi].bootfrom = bootfrom;
+	cfgi++;
+
+	*cfgn = cfgi;
+	return 0;
+}
+
+static int image_override_dstaddr(struct image_cfg_element *image_cfg,
+				   int *cfgn, uint32_t dstaddr)
+{
+	struct image_cfg_element *e;
+	int cfgi = *cfgn;
+
+	if (dstaddr == ADDR_INVALID)
+		return 0;
+
+	e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_DEST_ADDR);
+	if (e) {
+		e->dstaddr = dstaddr;
+		return 0;
+	}
+
+	image_cfg[cfgi].type = IMAGE_CFG_DEST_ADDR;
+	image_cfg[cfgi].dstaddr = dstaddr;
+	cfgi++;
+
+	*cfgn = cfgi;
+	return 0;
+}
+
+static int image_override_execaddr(struct image_cfg_element *image_cfg,
+				   int *cfgn, uint32_t execaddr)
+{
+	struct image_cfg_element *e;
+	int cfgi = *cfgn;
+
+	if (execaddr == ADDR_INVALID)
+		return 0;
+
+	e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_EXEC_ADDR);
+	if (e) {
+		e->execaddr = execaddr;
+		return 0;
+	}
+
+	image_cfg[cfgi].type = IMAGE_CFG_EXEC_ADDR;
+	image_cfg[cfgi].execaddr = execaddr;
+	cfgi++;
+
+	*cfgn = cfgi;
+	return 0;
+}
+
+static int image_get_version(struct image_cfg_element *image_cfg,
+			     int cfgn)
+{
+	struct image_cfg_element *e;
+
+	e = image_find_option(image_cfg, cfgn, IMAGE_CFG_VERSION);
+	if (!e)
+		return -1;
+
+	return e->version;
+}
+
+static void image_dump_config(struct image_cfg_element *image_cfg,
+			      int cfgn)
+{
+	int cfgi;
+
+	printf("== configuration dump\n");
+
+	for (cfgi = 0; cfgi < cfgn; cfgi++) {
+		struct image_cfg_element *e = &image_cfg[cfgi];
+		switch (e->type) {
+		case IMAGE_CFG_VERSION:
+			printf("VERSION %d\n", e->version);
+			break;
+		case IMAGE_CFG_BOOT_FROM:
+			printf("BOOTFROM %s\n",
+			       image_boot_mode_name(e->bootfrom));
+			break;
+		case IMAGE_CFG_DEST_ADDR:
+			printf("DESTADDR 0x%x\n", e->dstaddr);
+			break;
+		case IMAGE_CFG_EXEC_ADDR:
+			printf("EXECADDR 0x%x\n", e->execaddr);
+			break;
+		case IMAGE_CFG_NAND_BLKSZ:
+			printf("NANDBLKSZ 0x%x\n", e->nandblksz);
+			break;
+		case IMAGE_CFG_NAND_BADBLK_LOCATION:
+			printf("NANDBADBLK 0x%x\n", e->nandbadblklocation);
+			break;
+		case IMAGE_CFG_BINARY:
+			printf("BINARY %s (%d args)\n", e->binary.file,
+			       e->binary.nargs);
+			break;
+		case IMAGE_CFG_PAYLOAD:
+			printf("PAYLOAD %s\n", e->payload);
+			break;
+		case IMAGE_CFG_DATA:
+			printf("DATA 0x%x 0x%x\n",
+			       e->regdata.raddr,
+			       e->regdata.rdata);
+			break;
+		default:
+			printf("Error, unknown type\n");
+			break;
+		}
+	}
+
+	printf("== end configuration dump\n");
+}
+
+static int image_create(const char *input, const char *output,
+			const char *payload, const char *bootmedia,
+			uint32_t dstaddr, uint32_t execaddr,
+			int verbose)
+{
+	struct image_cfg_element *image_cfg;
+	FILE *fcfg, *outputimg;
+	void *image = NULL;
+	int version;
+	size_t imagesz;
+	int cfgn;
+	int ret;
+
+	fcfg = fopen(input, "r");
+	if (!fcfg) {
+		fprintf(stderr, "Could not open input file %s\n",
+			input);
+		return -1;
+	}
+
+	image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
+			   sizeof(struct image_cfg_element));
+	if (!image_cfg) {
+		fprintf(stderr, "Cannot allocate memory\n");
+		fclose(fcfg);
+		return -1;
+	}
+
+	memset(image_cfg, 0,
+	       IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
+	rewind(fcfg);
+
+	ret = image_create_config_parse(fcfg, image_cfg, &cfgn);
+	if (ret) {
+		free(image_cfg);
+		return -1;
+	}
+
+	image_override_payload(image_cfg, &cfgn, payload);
+	image_override_bootmedia(image_cfg, &cfgn, bootmedia);
+	image_override_dstaddr(image_cfg, &cfgn, dstaddr);
+	image_override_execaddr(image_cfg, &cfgn, execaddr);
+
+	if (!image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM) ||
+	    !image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR) ||
+	    !image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR)) {
+		fprintf(stderr,
+			"Missing information (either boot media, exec addr or dest addr)\n");
+		free(image_cfg);
+		return -1;
+	}
+
+	if (verbose)
+		image_dump_config(image_cfg, cfgn);
+
+	version = image_get_version(image_cfg, cfgn);
+
+	if (version == 0)
+		image = image_create_v0(image_cfg, cfgn, output, &imagesz);
+	else if (version == 1)
+		image = image_create_v1(image_cfg, cfgn, output, &imagesz);
+	else if (version == -1) {
+		fprintf(stderr, "File %s does not have the VERSION field\n",
+			input);
+		free(image_cfg);
+		return -1;
+	}
+
+	if (!image) {
+		fprintf(stderr, "Could not create image\n");
+		free(image_cfg);
+		return -1;
+	}
+
+	free(image_cfg);
+
+	outputimg = fopen(output, "w");
+	if (!outputimg) {
+		fprintf(stderr, "Cannot open output image %s for writing\n",
+			output);
+		free(image);
+		return -1;
+	}
+
+	ret = fwrite(image, imagesz, 1, outputimg);
+	if (ret != 1) {
+		fprintf(stderr, "Cannot write to output image %s\n",
+			output);
+		fclose(outputimg);
+		free(image);
+		return -1;
+	}
+
+	fclose(outputimg);
+	free(image);
+
+	return 0;
+}
+
+enum {
+	ACTION_CREATE,
+	ACTION_EXTRACT,
+	ACTION_DUMP,
+	ACTION_HELP,
+};
+
+int main(int argc, char *argv[])
+{
+	int action = -1, opt, verbose = 0;
+	const char *input = NULL, *output = NULL,
+		*payload = NULL, *bootmedia = NULL;
+	uint32_t execaddr = ADDR_INVALID, dstaddr = ADDR_INVALID;
+
+	while ((opt = getopt(argc, argv, "hxci:o:p:m:e:d:v")) != -1) {
+		switch (opt) {
+		case 'x':
+			action = ACTION_EXTRACT;
+			break;
+		case 'c':
+			action = ACTION_CREATE;
+			break;
+		case 'i':
+			input = optarg;
+			break;
+		case 'o':
+			output = optarg;
+			break;
+		case 'p':
+			payload = optarg;
+			break;
+		case 'm':
+			bootmedia = optarg;
+			break;
+		case 'e':
+			execaddr = strtol(optarg, NULL, 0);
+			break;
+		case 'd':
+			dstaddr = strtol(optarg, NULL, 0);
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		case 'h':
+			action = ACTION_HELP;
+			break;
+		}
+	}
+
+	/* We should have consumed all arguments */
+	if (optind != argc) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (action != ACTION_HELP && !input) {
+		fprintf(stderr, "Missing input file\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if ((action == ACTION_EXTRACT || action == ACTION_CREATE) &&
+	    !output) {
+		fprintf(stderr, "Missing output file\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (action == ACTION_EXTRACT &&
+	    (bootmedia || payload ||
+	     (execaddr != ADDR_INVALID) || (dstaddr != ADDR_INVALID))) {
+		fprintf(stderr,
+			"-m, -p, -e or -d do not make sense when extracting an image");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	switch (action) {
+	case ACTION_EXTRACT:
+		return image_extract(input, output);
+	case ACTION_CREATE:
+		return image_create(input, output, payload,
+				    bootmedia, dstaddr, execaddr,
+				    verbose);
+	case ACTION_HELP:
+		usage(argv[0]);
+		return 0;
+	default:
+		fprintf(stderr, "No action specified\n");
+		usage(argv[0]);
+		exit(1);
+	}
+
+	return 0;
+}
-- 
1.7.9.5


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

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

* [PATCH v3 2/7] scripts: add kwboot tool
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09 11:16   ` Jason Cooper
  2013-05-09  9:52 ` [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

This tool is used with Marvell EBU SoC to trigger the UART boot mode
provided by the SoC BootROM, and push the bootloader image to the
target using the Xmodem protocol.

It has been taken from the U-Boot source code, with minor
modifications to make it work with Armada 370/XP platforms.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 scripts/.gitignore |    1 +
 scripts/Makefile   |    2 +-
 scripts/kwboot.c   |  717 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 719 insertions(+), 1 deletion(-)
 create mode 100644 scripts/kwboot.c

diff --git a/scripts/.gitignore b/scripts/.gitignore
index a28ea52..6518c0f 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -3,6 +3,7 @@ bin2c
 gen_netx_image
 kallsyms
 kwbimage
+kwboot
 mk-am35xx-spi-image
 mkimage
 mkublheader
diff --git a/scripts/Makefile b/scripts/Makefile
index e0b9868..cd0b976 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -8,7 +8,7 @@ hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
 hostprogs-y                      += bin2c
 hostprogs-y                      += mkimage
 hostprogs-y                      += bareboxenv
-hostprogs-$(CONFIG_ARCH_MVEBU)   += kwbimage
+hostprogs-$(CONFIG_ARCH_MVEBU)   += kwbimage kwboot
 hostprogs-$(CONFIG_ARCH_NETX)    += gen_netx_image
 hostprogs-$(CONFIG_ARCH_OMAP)    += omap_signGP mk-am35xx-spi-image
 hostprogs-$(CONFIG_ARCH_S5PCxx)  += s5p_cksum
diff --git a/scripts/kwboot.c b/scripts/kwboot.c
new file mode 100644
index 0000000..afc8493
--- /dev/null
+++ b/scripts/kwboot.c
@@ -0,0 +1,717 @@
+/*
+ * Boot a Marvell Kirkwood SoC, with Xmodem over UART0.
+ *
+ * (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
+ *
+ * References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
+ *   Integrated Controller: Functional Specifications" December 2,
+ *   2008. Chapter 24.2 "BootROM Firmware".
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <termios.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+/*
+ * Marvell BootROM UART Sensing
+ */
+
+static unsigned char kwboot_msg_boot[] = {
+	0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
+};
+
+static unsigned char kwboot_msg_debug[] = {
+	0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
+};
+
+#define KWBOOT_MSG_REQ_DELAY	1000 /* ms */
+#define KWBOOT_MSG_RSP_TIMEO	1000 /* ms */
+
+/*
+ * Xmodem Transfers
+ */
+
+#define SOH	1	/* sender start of block header */
+#define EOT	4	/* sender end of block transfer */
+#define ACK	6	/* target block ack */
+#define NAK	21	/* target block negative ack */
+#define CAN	24	/* target/sender transfer cancellation */
+
+struct kwboot_block {
+	uint8_t soh;
+	uint8_t pnum;
+	uint8_t _pnum;
+	uint8_t data[128];
+	uint8_t csum;
+} __attribute((packed));
+
+#define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
+
+static int kwboot_verbose;
+
+static void
+kwboot_printv(const char *fmt, ...)
+{
+	va_list ap;
+
+	if (kwboot_verbose) {
+		va_start(ap, fmt);
+		vprintf(fmt, ap);
+		va_end(ap);
+		fflush(stdout);
+	}
+}
+
+static void
+__spinner(void)
+{
+	const char seq[] = { '-', '\\', '|', '/' };
+	const int div = 8;
+	static int state, bs;
+
+	if (state % div == 0) {
+		fputc(bs, stdout);
+		fputc(seq[state / div % sizeof(seq)], stdout);
+		fflush(stdout);
+	}
+
+	bs = '\b';
+	state++;
+}
+
+static void
+kwboot_spinner(void)
+{
+	if (kwboot_verbose)
+		__spinner();
+}
+
+static void
+__progress(int pct, char c)
+{
+	const int width = 70;
+	static const char *nl = "";
+	static int pos;
+
+	if (pos % width == 0)
+		printf("%s%3d %% [", nl, pct);
+
+	fputc(c, stdout);
+
+	nl = "]\n";
+	pos++;
+
+	if (pct == 100) {
+		while (pos++ < width)
+			fputc(' ', stdout);
+		fputs(nl, stdout);
+	}
+
+	fflush(stdout);
+
+}
+
+static void
+kwboot_progress(int _pct, char c)
+{
+	static int pct;
+
+	if (_pct != -1)
+		pct = _pct;
+
+	if (kwboot_verbose)
+		__progress(pct, c);
+}
+
+static int
+kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
+{
+	int rc, nfds;
+	fd_set rfds;
+	struct timeval tv;
+	ssize_t n;
+
+	rc = -1;
+
+	FD_ZERO(&rfds);
+	FD_SET(fd, &rfds);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = timeo * 1000;
+	if (tv.tv_usec > 1000000) {
+		tv.tv_sec += tv.tv_usec / 1000000;
+		tv.tv_usec %= 1000000;
+	}
+
+	do {
+		nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
+		if (nfds < 0)
+			goto out;
+		if (!nfds) {
+			errno = ETIMEDOUT;
+			goto out;
+		}
+
+		n = read(fd, buf, len);
+		if (n < 0)
+			goto out;
+
+		buf = (char *)buf + n;
+		len -= n;
+	} while (len > 0);
+
+	rc = 0;
+out:
+	return rc;
+}
+
+static int
+kwboot_tty_send(int fd, const void *buf, size_t len)
+{
+	int rc;
+	ssize_t n;
+
+	rc = -1;
+
+	do {
+		n = write(fd, buf, len);
+		if (n < 0)
+			goto out;
+
+		buf = (char *)buf + n;
+		len -= n;
+	} while (len > 0);
+
+	rc = tcdrain(fd);
+out:
+	return rc;
+}
+
+static int
+kwboot_tty_send_char(int fd, unsigned char c)
+{
+	return kwboot_tty_send(fd, &c, 1);
+}
+
+static speed_t
+kwboot_tty_speed(int baudrate)
+{
+	switch (baudrate) {
+	case 115200:
+		return B115200;
+	case 57600:
+		return B57600;
+	case 38400:
+		return B38400;
+	case 19200:
+		return B19200;
+	case 9600:
+		return B9600;
+	}
+
+	return -1;
+}
+
+static int
+kwboot_open_tty(const char *path, speed_t speed)
+{
+	int rc, fd;
+	struct termios tio;
+
+	rc = -1;
+
+	fd = open(path, O_RDWR|O_NOCTTY|O_NDELAY);
+	if (fd < 0)
+		goto out;
+
+	memset(&tio, 0, sizeof(tio));
+
+	tio.c_iflag = 0;
+	tio.c_cflag = CREAD|CLOCAL|CS8;
+
+	tio.c_cc[VMIN] = 1;
+	tio.c_cc[VTIME] = 10;
+
+	cfsetospeed(&tio, speed);
+	cfsetispeed(&tio, speed);
+
+	rc = tcsetattr(fd, TCSANOW, &tio);
+	if (rc)
+		goto out;
+
+	rc = fd;
+out:
+	if (rc < 0) {
+		if (fd >= 0)
+			close(fd);
+	}
+
+	return rc;
+}
+
+static int
+kwboot_bootmsg(int tty, void *msg)
+{
+	int rc;
+	char c;
+
+	kwboot_printv("Sending boot message. Please reboot the target...");
+
+	do {
+		rc = tcflush(tty, TCIOFLUSH);
+		if (rc)
+			break;
+
+		rc = kwboot_tty_send(tty, msg, 8);
+		if (rc) {
+			usleep(KWBOOT_MSG_REQ_DELAY * 1000);
+			continue;
+		}
+
+		rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO);
+
+		kwboot_spinner();
+
+	} while (rc || c != NAK);
+
+	kwboot_printv("\n");
+
+	return rc;
+}
+
+static int
+kwboot_debugmsg(int tty, void *msg)
+{
+	int rc;
+
+	kwboot_printv("Sending debug message. Please reboot the target...");
+
+	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);
+			continue;
+		}
+
+		rc = kwboot_tty_recv(tty, buf, 16, KWBOOT_MSG_RSP_TIMEO);
+
+		kwboot_spinner();
+
+	} while (rc);
+
+	kwboot_printv("\n");
+
+	return rc;
+}
+
+static int
+kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
+		    size_t size, int pnum)
+{
+	const size_t blksz = sizeof(block->data);
+	size_t n;
+	int i;
+
+	block->pnum = pnum;
+	block->_pnum = ~block->pnum;
+
+	n = size < blksz ? size : blksz;
+	memcpy(&block->data[0], data, n);
+	memset(&block->data[n], 0, blksz - n);
+
+	block->csum = 0;
+	for (i = 0; i < n; i++)
+		block->csum += block->data[i];
+
+	return n;
+}
+
+static int
+kwboot_xm_sendblock(int fd, struct kwboot_block *block)
+{
+	int rc, retries;
+	char c;
+
+	retries = 16;
+	do {
+		rc = kwboot_tty_send(fd, block, sizeof(*block));
+		if (rc)
+			break;
+
+		do {
+			rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
+			if (rc)
+				break;
+
+			if (c != ACK && c!= NAK && c != CAN)
+				printf("%c", c);
+
+		} while (c != ACK && c != NAK && c != CAN);
+
+		if (c != ACK)
+			kwboot_progress(-1, '+');
+
+	} while (c == NAK && retries-- > 0);
+
+	rc = -1;
+
+	switch (c) {
+	case ACK:
+		rc = 0;
+		break;
+	case NAK:
+		errno = EBADMSG;
+		break;
+	case CAN:
+		errno = ECANCELED;
+		break;
+	default:
+		errno = EPROTO;
+		break;
+	}
+
+	return rc;
+}
+
+static int
+kwboot_xmodem(int tty, const void *_data, size_t size)
+{
+	const uint8_t *data = _data;
+	int rc, pnum, N, err;
+
+	pnum = 1;
+	N = 0;
+
+	kwboot_printv("Sending boot image...\n");
+
+	do {
+		struct kwboot_block block;
+		int n;
+
+		n = kwboot_xm_makeblock(&block,
+					data + N, size - N,
+					pnum++);
+		if (n < 0)
+			goto can;
+
+		if (!n)
+			break;
+
+		rc = kwboot_xm_sendblock(tty, &block);
+		if (rc)
+			goto out;
+
+		N += n;
+		kwboot_progress(N * 100 / size, '.');
+	} while (1);
+
+	rc = kwboot_tty_send_char(tty, EOT);
+
+out:
+	return rc;
+
+can:
+	err = errno;
+	kwboot_tty_send_char(tty, CAN);
+	errno = err;
+	goto out;
+}
+
+static int
+kwboot_term_pipe(int in, int out, char *quit, int *s)
+{
+	ssize_t nin, nout;
+	char _buf[128], *buf = _buf;
+
+	nin = read(in, buf, sizeof(buf));
+	if (nin < 0)
+		return -1;
+
+	if (quit) {
+		int i;
+
+		for (i = 0; i < nin; i++) {
+			if (*buf == quit[*s]) {
+				(*s)++;
+				if (!quit[*s])
+					return 0;
+				buf++;
+				nin--;
+			} else
+				while (*s > 0) {
+					nout = write(out, quit, *s);
+					if (nout <= 0)
+						return -1;
+					(*s) -= nout;
+				}
+		}
+	}
+
+	while (nin > 0) {
+		nout = write(out, buf, nin);
+		if (nout <= 0)
+			return -1;
+		nin -= nout;
+	}
+
+	return 0;
+}
+
+static int
+kwboot_terminal(int tty)
+{
+	int rc, in, s;
+	char *quit = "\34c";
+	struct termios otio, tio;
+
+	rc = -1;
+
+	in = STDIN_FILENO;
+	if (isatty(in)) {
+		rc = tcgetattr(in, &otio);
+		if (!rc) {
+			tio = otio;
+			cfmakeraw(&tio);
+			rc = tcsetattr(in, TCSANOW, &tio);
+		}
+		if (rc) {
+			perror("tcsetattr");
+			goto out;
+		}
+
+		kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
+			      quit[0]|0100, quit[1]);
+	} else
+		in = -1;
+
+	rc = 0;
+	s = 0;
+
+	do {
+		fd_set rfds;
+		int nfds = 0;
+
+		FD_SET(tty, &rfds);
+		nfds = nfds < tty ? tty : nfds;
+
+		if (in >= 0) {
+			FD_SET(in, &rfds);
+			nfds = nfds < in ? in : nfds;
+		}
+
+		nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
+		if (nfds < 0)
+			break;
+
+		if (FD_ISSET(tty, &rfds)) {
+			rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
+			if (rc)
+				break;
+		}
+
+		if (FD_ISSET(in, &rfds)) {
+			rc = kwboot_term_pipe(in, tty, quit, &s);
+			if (rc)
+				break;
+		}
+	} while (quit[s] != 0);
+
+	tcsetattr(in, TCSANOW, &otio);
+out:
+	return rc;
+}
+
+static void *
+kwboot_mmap_image(const char *path, size_t *size, int prot)
+{
+	int rc, fd, flags;
+	struct stat st;
+	void *img;
+
+	rc = -1;
+	fd = -1;
+	img = NULL;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		goto out;
+
+	rc = fstat(fd, &st);
+	if (rc)
+		goto out;
+
+	flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED;
+
+	img = mmap(NULL, st.st_size, prot, flags, fd, 0);
+	if (img == MAP_FAILED) {
+		img = NULL;
+		goto out;
+	}
+
+	rc = 0;
+	*size = st.st_size;
+out:
+	if (rc && img) {
+		munmap(img, st.st_size);
+		img = NULL;
+	}
+	if (fd >= 0)
+		close(fd);
+
+	return img;
+}
+
+static void
+kwboot_usage(FILE *stream, char *progname)
+{
+	fprintf(stream,
+		"Usage: %s [-d | -b <image>] [ -p ] [ -t ] "
+		"[-B <baud> ] <TTY>\n", progname);
+	fprintf(stream, "\n");
+	fprintf(stream, "  -b <image>: boot <image>\n");
+	fprintf(stream, "  -d: enter debug mode\n");
+	fprintf(stream, "\n");
+	fprintf(stream, "  -t: mini terminal\n");
+	fprintf(stream, "\n");
+	fprintf(stream, "  -B <baud>: set baud rate\n");
+	fprintf(stream, "\n");
+}
+
+int
+main(int argc, char **argv)
+{
+	const char *ttypath, *imgpath;
+	int rv, rc, tty, term;
+	void *bootmsg;
+	void *debugmsg;
+	void *img;
+	size_t size;
+	speed_t speed;
+
+	rv = 1;
+	tty = -1;
+	bootmsg = NULL;
+	debugmsg = NULL;
+	imgpath = NULL;
+	img = NULL;
+	term = 0;
+	size = 0;
+	speed = B115200;
+
+	kwboot_verbose = isatty(STDOUT_FILENO);
+
+	do {
+		int c = getopt(argc, argv, "hb:dptB:");
+		if (c < 0)
+			break;
+
+		switch (c) {
+		case 'b':
+			bootmsg = kwboot_msg_boot;
+			imgpath = optarg;
+			break;
+
+		case 'd':
+			debugmsg = kwboot_msg_debug;
+			break;
+
+		case 't':
+			term = 1;
+			break;
+
+		case 'B':
+			speed = kwboot_tty_speed(atoi(optarg));
+			if (speed == -1)
+				goto usage;
+			break;
+
+		case 'h':
+			rv = 0;
+		default:
+			goto usage;
+		}
+	} while (1);
+
+	if (!bootmsg && !term && !debugmsg)
+		goto usage;
+
+	if (argc - optind < 1)
+		goto usage;
+
+	ttypath = argv[optind++];
+
+	tty = kwboot_open_tty(ttypath, speed);
+	if (tty < 0) {
+		perror(ttypath);
+		goto out;
+	}
+
+	if (imgpath) {
+		img = kwboot_mmap_image(imgpath, &size, PROT_READ);
+		if (!img) {
+			perror(imgpath);
+			goto out;
+		}
+	}
+
+	if (debugmsg) {
+		rc = kwboot_debugmsg(tty, debugmsg);
+		if (rc) {
+			perror("debugmsg");
+			goto out;
+		}
+	}
+
+	if (bootmsg) {
+		rc = kwboot_bootmsg(tty, bootmsg);
+		if (rc) {
+			perror("bootmsg");
+			goto out;
+		}
+	}
+
+	if (img) {
+		rc = kwboot_xmodem(tty, img, size);
+		if (rc) {
+			perror("xmodem");
+			goto out;
+		}
+	}
+
+	if (term) {
+		rc = kwboot_terminal(tty);
+		if (rc && !(errno == EINTR)) {
+			perror("terminal");
+			goto out;
+		}
+	}
+
+	rv = 0;
+out:
+	if (tty >= 0)
+		close(tty);
+
+	if (img)
+		munmap(img, size);
+
+	return rv;
+
+usage:
+	kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
+	goto out;
+}
-- 
1.7.9.5


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

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

* [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 2/7] scripts: add kwboot tool Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-12 11:14   ` antonynpavlov
  2013-05-09  9:52 ` [PATCH v3 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

This commit adds minimal support for the Armada 370 and Armada XP SoCs
from Marvell.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/Kconfig                            |    8 ++
 arch/arm/Makefile                           |    1 +
 arch/arm/mach-mvebu/Kconfig                 |   40 ++++++++
 arch/arm/mach-mvebu/Makefile                |    1 +
 arch/arm/mach-mvebu/core.c                  |  142 +++++++++++++++++++++++++++
 arch/arm/mach-mvebu/include/mach/clkdev.h   |    7 ++
 arch/arm/mach-mvebu/include/mach/debug_ll.h |   40 ++++++++
 arch/arm/mach-mvebu/include/mach/mvebu.h    |   22 +++++
 drivers/clocksource/Kconfig                 |    4 +
 drivers/clocksource/Makefile                |    1 +
 drivers/clocksource/mvebu.c                 |   90 +++++++++++++++++
 11 files changed, 356 insertions(+)
 create mode 100644 arch/arm/mach-mvebu/Kconfig
 create mode 100644 arch/arm/mach-mvebu/Makefile
 create mode 100644 arch/arm/mach-mvebu/core.c
 create mode 100644 arch/arm/mach-mvebu/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-mvebu/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-mvebu/include/mach/mvebu.h
 create mode 100644 drivers/clocksource/mvebu.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a4f821..a044ab3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -79,6 +79,13 @@ config ARCH_IMX
 	select WATCHDOG_IMX_RESET_SOURCE
 	select HAS_DEBUG_LL
 
+config ARCH_MVEBU
+	bool "Marvell EBU platforms"
+	select COMMON_CLK
+	select CLOCKSOURCE_MVEBU
+	select CLKDEV_LOOKUP
+	select HAS_DEBUG_LL
+
 config ARCH_MXS
 	bool "Freescale i.MX23/28 (mxs) based"
 	select GENERIC_GPIO
@@ -161,6 +168,7 @@ source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-highbank/Kconfig
 source arch/arm/mach-imx/Kconfig
 source arch/arm/mach-mxs/Kconfig
+source arch/arm/mach-mvebu/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d506b12..bb47506 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_HIGHBANK)		:= highbank
 machine-$(CONFIG_ARCH_IMX)		:= imx
 machine-$(CONFIG_ARCH_MXS)		:= mxs
+machine-$(CONFIG_ARCH_MVEBU)		:= mvebu
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
new file mode 100644
index 0000000..4cbe546
--- /dev/null
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -0,0 +1,40 @@
+if ARCH_MVEBU
+
+config ARCH_TEXT_BASE
+	hex
+
+config BOARDINFO
+	default
+
+choice
+	prompt "Marvell EBU Processor"
+
+config ARCH_ARMADA_370
+	bool "Armada 370"
+	select CPU_V7
+
+config ARCH_ARMADA_XP
+	bool "Armada XP"
+	select CPU_V7
+
+endchoice
+
+if ARCH_ARMADA_370
+
+choice
+	prompt "Armada 370 Board Type"
+
+endchoice
+
+endif # ARCH_ARMADA_370
+
+if ARCH_ARMADA_XP
+
+choice
+	prompt "Armada XP Board Type"
+
+endchoice
+
+endif # ARCH_ARMADA_XP
+
+endif # ARCH_MVEBU
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
new file mode 100644
index 0000000..820eb10
--- /dev/null
+++ b/arch/arm/mach-mvebu/Makefile
@@ -0,0 +1 @@
+obj-y += core.o
diff --git a/arch/arm/mach-mvebu/core.c b/arch/arm/mach-mvebu/core.c
new file mode 100644
index 0000000..f4672a3
--- /dev/null
+++ b/arch/arm/mach-mvebu/core.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <ns16550.h>
+#include <asm/memory.h>
+#include <asm/barebox-arm.h>
+
+#define MVEBU_INT_REGS_BASE (0xd0000000)
+#define  MVEBU_UART0_BASE     (MVEBU_INT_REGS_BASE + 0x12000)
+#define  MVEBU_SYSCTL_BASE    (MVEBU_INT_REGS_BASE + 0x18200)
+#define  MVEBU_SDRAM_WIN_BASE (MVEBU_INT_REGS_BASE + 0x20180)
+#define  MVEBU_TIMER_BASE     (MVEBU_INT_REGS_BASE + 0x20300)
+#define  MVEBU_SAR_BASE       (MVEBU_INT_REGS_BASE + 0x18230)
+
+#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
+#define  DDR_BASE_CS_HIGH_MASK  0xf
+#define  DDR_BASE_CS_LOW_MASK   0xff000000
+#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
+#define  DDR_SIZE_ENABLED       (1 << 0)
+#define  DDR_SIZE_CS_MASK       0x1c
+#define  DDR_SIZE_CS_SHIFT      2
+#define  DDR_SIZE_MASK          0xff000000
+
+#define SAR_LOW_REG_OFF         0
+#define  SAR_TCLK_FREQ_BIT      20
+#define SAR_HIGH_REG_OFF        0x4
+
+static struct clk *tclk;
+
+static inline void mvebu_memory_find(unsigned long *phys_base,
+				     unsigned long *phys_size)
+{
+	void __iomem *sdram_win = IOMEM(MVEBU_SDRAM_WIN_BASE);
+	int cs;
+
+	*phys_base = ~0;
+	*phys_size = 0;
+
+	for (cs = 0; cs < 4; cs++) {
+		uint32_t base = readl(sdram_win + DDR_BASE_CS_OFF(cs));
+		uint32_t ctrl = readl(sdram_win + DDR_SIZE_CS_OFF(cs));
+
+		/* Skip non-enabled CS */
+		if (! (ctrl & DDR_SIZE_ENABLED))
+			continue;
+
+		base &= DDR_BASE_CS_LOW_MASK;
+		if (base < *phys_base)
+			*phys_base = base;
+		*phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
+	}
+}
+
+void __naked __noreturn mvebu_barebox_entry(void)
+{
+	unsigned long phys_base, phys_size;
+	mvebu_memory_find(&phys_base, &phys_size);
+	barebox_arm_entry(phys_base, phys_size, 0);
+}
+
+static struct NS16550_plat uart0_plat = {
+	.shift = 2,
+};
+
+int mvebu_add_uart0(void)
+{
+	uart0_plat.clock = clk_get_rate(tclk);
+	add_ns16550_device(DEVICE_ID_DYNAMIC, MVEBU_UART0_BASE, 32,
+			   IORESOURCE_MEM_32BIT, &uart0_plat);
+	return 0;
+}
+
+#if defined(CONFIG_ARCH_ARMADA_370)
+static int mvebu_init_clocks(void)
+{
+	uint32_t val;
+	unsigned int rate;
+	void __iomem *sar = IOMEM(MVEBU_SAR_BASE) + SAR_LOW_REG_OFF;
+
+	val = readl(sar);
+
+	/* On Armada 370, the TCLK frequency can be either 166 Mhz or
+	 * 200 Mhz */
+	if (val & (1 << SAR_TCLK_FREQ_BIT))
+		rate = 200 * 1000 * 1000;
+	else
+		rate = 166 * 1000 * 1000;
+
+	tclk = clk_fixed("tclk", rate);
+	return clk_register_clkdev(tclk, NULL, "mvebu-timer");
+}
+#endif
+
+#if defined(CONFIG_ARCH_ARMADA_XP)
+static int mvebu_init_clocks(void)
+{
+	/* On Armada XP, the TCLK frequency is always 250 Mhz */
+	tclk = clk_fixed("tclk", 250 * 1000 * 1000);
+	return clk_register_clkdev(tclk, NULL, "mvebu-timer");
+}
+#endif
+
+static int mvebu_init_soc(void)
+{
+	unsigned long phys_base, phys_size;
+
+	mvebu_init_clocks();
+	add_generic_device("mvebu-timer", DEVICE_ID_SINGLE, NULL,
+			   MVEBU_TIMER_BASE, 0x30, IORESOURCE_MEM,
+			   NULL);
+	mvebu_memory_find(&phys_base, &phys_size);
+	arm_add_mem_device("ram0", phys_base, phys_size);
+	return 0;
+}
+
+postcore_initcall(mvebu_init_soc);
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+	writel(0x1, MVEBU_SYSCTL_BASE + 0x60);
+	writel(0x1, MVEBU_SYSCTL_BASE + 0x64);
+	while (1)
+		;
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-mvebu/include/mach/clkdev.h b/arch/arm/mach-mvebu/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/debug_ll.h b/arch/arm/mach-mvebu/include/mach/debug_ll.h
new file mode 100644
index 0000000..2653573
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/debug_ll.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define __MACH_DEBUG_LL_H__
+
+#include <io.h>
+
+#define UART_BASE 0xd0012000
+#define UART_THR  0x0
+#define UART_LSR  0x14
+#define   UART_LSR_THRE   (1 << 5)
+
+static inline void PUTC_LL(char c)
+{
+	/* Wait until there is space in the FIFO */
+	while (!(readl(UART_BASE + UART_LSR) & UART_LSR_THRE))
+		;
+
+	/* Send the character */
+	writel(c, UART_BASE + UART_THR)
+		;
+
+	/* Wait to make sure it hits the line, in case we die too soon. */
+	while (!(readl(UART_BASE + UART_LSR) & UART_LSR_THRE))
+		;
+}
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/mvebu.h b/arch/arm/mach-mvebu/include/mach/mvebu.h
new file mode 100644
index 0000000..e13a446
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/mvebu.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_H
+#define __MACH_MVEBU_H
+
+int mvebu_add_uart0(void);
+void __naked __noreturn mvebu_barebox_entry(void);
+
+#endif /* __MACH_MVEBU_H */
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9f3558b..dfc89dd 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -14,6 +14,10 @@ config CLOCKSOURCE_CLPS711X
 	bool
 	depends on ARCH_CLPS711X
 
+config CLOCKSOURCE_MVEBU
+	bool
+	depends on ARCH_MVEBU
+
 config CLOCKSOURCE_NOMADIK
 	bool
 	depends on ARM
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index d919881..0b42ce4 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_AMBA_SP804) += amba-sp804.o
 obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o
 obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o
 obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o
+obj-$(CONFIG_CLOCKSOURCE_MVEBU)   += mvebu.o
 obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o
diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c
new file mode 100644
index 0000000..2b48a5c
--- /dev/null
+++ b/drivers/clocksource/mvebu.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <clock.h>
+#include <linux/clk.h>
+#include <io.h>
+
+#define TIMER_CTRL_OFF          0x0000
+#define  TIMER0_EN               0x0001
+#define  TIMER0_RELOAD_EN        0x0002
+#define  TIMER0_25MHZ            0x0800
+#define  TIMER0_DIV(div)         ((div) << 19)
+#define  TIMER1_EN               0x0004
+#define  TIMER1_RELOAD_EN        0x0008
+#define  TIMER1_25MHZ            0x1000
+#define  TIMER1_DIV(div)         ((div) << 22)
+#define TIMER_EVENTS_STATUS     0x0004
+#define  TIMER0_CLR_MASK         (~0x1)
+#define  TIMER1_CLR_MASK         (~0x100)
+#define TIMER0_RELOAD_OFF       0x0010
+#define TIMER0_VAL_OFF          0x0014
+#define TIMER1_RELOAD_OFF       0x0018
+#define TIMER1_VAL_OFF          0x001c
+
+#define TIMER_DIVIDER_SHIFT     5
+
+static __iomem void *timer_base;
+
+uint64_t mvebu_clocksource_read(void)
+{
+	return __raw_readl(timer_base + TIMER0_VAL_OFF);
+}
+
+static struct clocksource cs = {
+	.read	= mvebu_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.shift	= 10,
+};
+
+static int mvebu_timer_probe(struct device_d *dev)
+{
+	struct clk *tclk;
+	u32 val;
+
+	timer_base = dev_request_mem_region(dev, 0);
+
+	tclk = clk_get(dev, "tclk");
+
+	val = __raw_readl(timer_base + TIMER_CTRL_OFF);
+	val &= ~TIMER0_25MHZ;
+	__raw_writel(val, timer_base + TIMER_CTRL_OFF);
+
+	__raw_writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
+	__raw_writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
+
+	val = __raw_readl(timer_base + TIMER_CTRL_OFF);
+	val |= TIMER0_EN | TIMER0_RELOAD_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
+	__raw_writel(val, timer_base + TIMER_CTRL_OFF);
+
+	cs.mult = clocksource_hz2mult(clk_get_rate(tclk), cs.shift);
+
+	init_clock(&cs);
+
+	return 0;
+}
+
+static struct driver_d mvebu_timer_driver = {
+	.name = "mvebu-timer",
+	.probe = mvebu_timer_probe,
+};
+
+static int mvebu_timer_init(void)
+{
+	return platform_driver_register(&mvebu_timer_driver);
+}
+postcore_initcall(mvebu_timer_init);
-- 
1.7.9.5


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

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

* [PATCH v3 4/7] arm: integrate kwbimage in the image generation
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (2 preceding siblings ...)
  2013-05-09  9:52 ` [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

When a ARCH_MVEBU platform is selected, generate barebox.kwb and
barebox.kwbuart images from barebox.bin, using kwbimage.

barebox.kwb is generated by executing kwbimage on the board
kwbimage.cfg file, and is therefore designed to be booted from the
default boot media of the board, as defined by kwbimage.cfg (typically
a NAND flash or SPI flash).

barebox.kwbuart is generated by executing kwbimage on the board
kwbimage.cfg file, but by overriding the boot media to be UART. This
image is suitable for usage with the kwbtool and is generally useful
for recovery purposes.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 Makefile          |    2 +-
 arch/arm/Makefile |   20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index f919993..9fcdd78 100644
--- a/Makefile
+++ b/Makefile
@@ -970,7 +970,7 @@ CLEAN_FILES +=	barebox System.map include/generated/barebox_default_env.h \
 		.tmp_kallsyms* common/barebox_default_env* barebox.ldr \
 		scripts/bareboxenv-target barebox-flash-image \
 		Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
-		barebox.uimage barebox.spi
+		barebox.uimage barebox.spi barebox.kwb barebox.kwbuart
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include2 usr/include
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index bb47506..d9e0cf1 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -263,6 +263,26 @@ KBUILD_TARGET := barebox.zynq
 KBUILD_IMAGE := barebox.zynq
 endif
 
+KWBIMAGE_OPTS = \
+	-c -i $(srctree)/$(BOARD)/kwbimage.cfg -d $(TEXT_BASE) -e $(TEXT_BASE)
+
+quiet_cmd_kwbimage = KWB     $@
+      cmd_kwbimage = scripts/kwbimage -p $< $(KWBIMAGE_OPTS) -o $@
+
+quiet_cmd_kwbimage_uart = KWBUART $@
+      cmd_kwbimage_uart = scripts/kwbimage -m uart -p $< $(KWBIMAGE_OPTS) -o $@
+
+barebox.kwb: $(KBUILD_BINARY) FORCE
+	$(call if_changed,kwbimage)
+
+barebox.kwbuart: $(KBUILD_BINARY) FORCE
+	$(call if_changed,kwbimage_uart)
+
+ifeq ($(CONFIG_ARCH_MVEBU),y)
+KBUILD_TARGET := barebox.kwb barebox.kwbuart
+KBUILD_IMAGE  := barebox.kwb barebox.kwbuart
+endif
+
 pbl := arch/arm/pbl
 zbarebox.S zbarebox.bin zbarebox: barebox.bin
 	$(Q)$(MAKE) $(build)=$(pbl) $(pbl)/$@
-- 
1.7.9.5


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

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

* [PATCH v3 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (3 preceding siblings ...)
  2013-05-09  9:52 ` [PATCH v3 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

The OpenBlocks AX3 platform is manufactured by PlatHome and uses the
MV78260 dual-core SoC from the Armada XP family.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/plathome-openblocks-ax3/Makefile   |    2 ++
 arch/arm/boards/plathome-openblocks-ax3/config.h   |    4 ++++
 .../boards/plathome-openblocks-ax3/kwbimage.cfg    |    3 +++
 arch/arm/boards/plathome-openblocks-ax3/lowlevel.c |   25 ++++++++++++++++++++
 .../plathome-openblocks-ax3.c                      |   25 ++++++++++++++++++++
 arch/arm/configs/plathome_openblocks_ax3_defconfig |    9 +++++++
 arch/arm/mach-mvebu/Kconfig                        |    6 ++++-
 8 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/Makefile
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/config.h
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/lowlevel.c
 create mode 100644 arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c
 create mode 100644 arch/arm/configs/plathome_openblocks_ax3_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d9e0cf1..913dfed 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -143,6 +143,7 @@ board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 board-$(CONFIG_MACH_MINI2440)			:= friendlyarm-mini2440
 board-$(CONFIG_MACH_MINI6410)			:= friendlyarm-mini6410
 board-$(CONFIG_MACH_TINY6410)			:= friendlyarm-tiny6410
+board-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3)	:= plathome-openblocks-ax3
 board-$(CONFIG_MACH_QIL_A9260)			:= qil-a9260
 board-$(CONFIG_MACH_TNY_A9260)			:= tny-a926x
 board-$(CONFIG_MACH_TNY_A9263)			:= tny-a926x
diff --git a/arch/arm/boards/plathome-openblocks-ax3/Makefile b/arch/arm/boards/plathome-openblocks-ax3/Makefile
new file mode 100644
index 0000000..91dc764
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/Makefile
@@ -0,0 +1,2 @@
+obj-y = plathome-openblocks-ax3.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/plathome-openblocks-ax3/config.h b/arch/arm/boards/plathome-openblocks-ax3/config.h
new file mode 100644
index 0000000..ca15136
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
new file mode 100644
index 0000000..69fd1fd
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
@@ -0,0 +1,3 @@
+VERSION 1
+BOOT_FROM spi
+BINARY plathome-openblocks-ax3-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c b/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c
new file mode 100644
index 0000000..e9b2e30
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <mach/mvebu.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+
+void __naked barebox_arm_reset_vector(void)
+{
+	arm_cpu_lowlevel_init();
+	mvebu_barebox_entry();
+}
diff --git a/arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c b/arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c
new file mode 100644
index 0000000..9daf020
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <mach/mvebu.h>
+
+static int plathome_openblocks_ax3_console_init(void)
+{
+	return mvebu_add_uart0();
+}
+
+console_initcall(plathome_openblocks_ax3_console_init);
diff --git a/arch/arm/configs/plathome_openblocks_ax3_defconfig b/arch/arm/configs/plathome_openblocks_ax3_defconfig
new file mode 100644
index 0000000..95449c9
--- /dev/null
+++ b/arch/arm/configs/plathome_openblocks_ax3_defconfig
@@ -0,0 +1,9 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_ARMADA_XP=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 4cbe546..9196251 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -2,9 +2,10 @@ if ARCH_MVEBU
 
 config ARCH_TEXT_BASE
 	hex
+	default 0x2000000 if MACH_PLATHOME_OPENBLOCKS_AX3
 
 config BOARDINFO
-	default
+	default "PlatHome OpenBlocks AX3" if MACH_PLATHOME_OPENBLOCKS_AX3
 
 choice
 	prompt "Marvell EBU Processor"
@@ -33,6 +34,9 @@ if ARCH_ARMADA_XP
 choice
 	prompt "Armada XP Board Type"
 
+config MACH_PLATHOME_OPENBLOCKS_AX3
+	bool "PlatHome OpenBlocks AX3"
+
 endchoice
 
 endif # ARCH_ARMADA_XP
-- 
1.7.9.5


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

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

* [PATCH v3 6/7] arm: add basic support for the Armada 370 Mirabox platform
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (4 preceding siblings ...)
  2013-05-09  9:52 ` [PATCH v3 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09  9:52 ` [PATCH v3 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

The Mirabox is a platform manufactured by Globalscale, and based on
the Marvell Armada 370 SoC.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/globalscale-mirabox/Makefile       |    2 ++
 arch/arm/boards/globalscale-mirabox/config.h       |    4 +++
 .../globalscale-mirabox/globalscale-mirabox.c      |   26 ++++++++++++++++++++
 arch/arm/boards/globalscale-mirabox/kwbimage.cfg   |    5 ++++
 arch/arm/boards/globalscale-mirabox/lowlevel.c     |   26 ++++++++++++++++++++
 arch/arm/configs/globalscale_mirabox_defconfig     |    8 ++++++
 arch/arm/mach-mvebu/Kconfig                        |    5 ++++
 8 files changed, 77 insertions(+)
 create mode 100644 arch/arm/boards/globalscale-mirabox/Makefile
 create mode 100644 arch/arm/boards/globalscale-mirabox/config.h
 create mode 100644 arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c
 create mode 100644 arch/arm/boards/globalscale-mirabox/kwbimage.cfg
 create mode 100644 arch/arm/boards/globalscale-mirabox/lowlevel.c
 create mode 100644 arch/arm/configs/globalscale_mirabox_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 913dfed..575ea6b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -102,6 +102,7 @@ board-$(CONFIG_MACH_EUKREA_CPUIMX51SD)		:= eukrea_cpuimx51
 board-$(CONFIG_MACH_FREESCALE_MX25_3STACK)	:= freescale-mx25-3-stack
 board-$(CONFIG_MACH_FREESCALE_MX35_3STACK)	:= freescale-mx35-3-stack
 board-$(CONFIG_MACH_GE863)			:= telit-evk-pro3
+board-$(CONFIG_MACH_GLOBALSCALE_MIRABOX)        := globalscale-mirabox
 board-$(CONFIG_MACH_HIGHBANK)			:= highbank
 board-$(CONFIG_MACH_IMX21ADS)			:= imx21ads
 board-$(CONFIG_MACH_IMX27ADS)			:= imx27ads
diff --git a/arch/arm/boards/globalscale-mirabox/Makefile b/arch/arm/boards/globalscale-mirabox/Makefile
new file mode 100644
index 0000000..bd5d47e
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/Makefile
@@ -0,0 +1,2 @@
+obj-y = globalscale-mirabox.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/globalscale-mirabox/config.h b/arch/arm/boards/globalscale-mirabox/config.h
new file mode 100644
index 0000000..ca15136
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c b/arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c
new file mode 100644
index 0000000..b8f4bff
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <sizes.h>
+#include <mach/mvebu.h>
+
+static int globalscale_mirabox_console_init(void)
+{
+	return mvebu_add_uart0();
+}
+
+console_initcall(globalscale_mirabox_console_init);
diff --git a/arch/arm/boards/globalscale-mirabox/kwbimage.cfg b/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
new file mode 100644
index 0000000..72283d9
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
@@ -0,0 +1,5 @@
+VERSION 1
+BOOT_FROM nand
+NAND_BLKSZ 00020000
+NAND_BADBLK_LOCATION 01
+BINARY globalscale-mirabox-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/globalscale-mirabox/lowlevel.c b/arch/arm/boards/globalscale-mirabox/lowlevel.c
new file mode 100644
index 0000000..3ca202e
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/lowlevel.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <sizes.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <mach/mvebu.h>
+
+void __naked barebox_arm_reset_vector(void)
+{
+	arm_cpu_lowlevel_init();
+	mvebu_barebox_entry();
+}
diff --git a/arch/arm/configs/globalscale_mirabox_defconfig b/arch/arm/configs/globalscale_mirabox_defconfig
new file mode 100644
index 0000000..ed9d94d
--- /dev/null
+++ b/arch/arm/configs/globalscale_mirabox_defconfig
@@ -0,0 +1,8 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 9196251..8489335 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -3,9 +3,11 @@ if ARCH_MVEBU
 config ARCH_TEXT_BASE
 	hex
 	default 0x2000000 if MACH_PLATHOME_OPENBLOCKS_AX3
+	default 0x2000000 if MACH_GLOBALSCALE_MIRABOX
 
 config BOARDINFO
 	default "PlatHome OpenBlocks AX3" if MACH_PLATHOME_OPENBLOCKS_AX3
+	default "Globalscale Mirabox" if MACH_GLOBALSCALE_MIRABOX
 
 choice
 	prompt "Marvell EBU Processor"
@@ -25,6 +27,9 @@ if ARCH_ARMADA_370
 choice
 	prompt "Armada 370 Board Type"
 
+config MACH_GLOBALSCALE_MIRABOX
+	bool "Globalscale Mirabox"
+
 endchoice
 
 endif # ARCH_ARMADA_370
-- 
1.7.9.5


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

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

* [PATCH v3 7/7] arm: add basic support for the Armada XP GP platform
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (5 preceding siblings ...)
  2013-05-09  9:52 ` [PATCH v3 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni
@ 2013-05-09  9:52 ` Thomas Petazzoni
  2013-05-09 13:33 ` [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-09  9:52 UTC (permalink / raw)
  To: barebox; +Cc: Thomas Petazzoni, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

The Armada XP GP platform is an evaluation platform designed by
Marvell, that uses the MV78460 quad-core SoC from the Armada XP
family.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/marvell-armada-xp-gp/Makefile      |    2 ++
 arch/arm/boards/marvell-armada-xp-gp/config.h      |    4 ++++
 arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg  |    3 +++
 arch/arm/boards/marvell-armada-xp-gp/lowlevel.c    |   25 ++++++++++++++++++++
 .../marvell-armada-xp-gp/marvell-armada-xp-gp.c    |   25 ++++++++++++++++++++
 arch/arm/configs/marvell_armada_xp_gp_defconfig    |   10 ++++++++
 arch/arm/mach-mvebu/Kconfig                        |    5 ++++
 8 files changed, 75 insertions(+)
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/Makefile
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/config.h
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/lowlevel.c
 create mode 100644 arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c
 create mode 100644 arch/arm/configs/marvell_armada_xp_gp_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 575ea6b..ce0921d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -107,6 +107,7 @@ board-$(CONFIG_MACH_HIGHBANK)			:= highbank
 board-$(CONFIG_MACH_IMX21ADS)			:= imx21ads
 board-$(CONFIG_MACH_IMX27ADS)			:= imx27ads
 board-$(CONFIG_MACH_IMX233_OLINUXINO)	:= imx233-olinuxino
+board-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP)	:= marvell-armada-xp-gp
 board-$(CONFIG_MACH_MIOA701)			:= mioa701
 board-$(CONFIG_MACH_MMCCPU)			:= mmccpu
 board-$(CONFIG_MACH_NOMADIK_8815NHK)		:= nhk8815
diff --git a/arch/arm/boards/marvell-armada-xp-gp/Makefile b/arch/arm/boards/marvell-armada-xp-gp/Makefile
new file mode 100644
index 0000000..ea89963
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/Makefile
@@ -0,0 +1,2 @@
+obj-y = marvell-armada-xp-gp.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/marvell-armada-xp-gp/config.h b/arch/arm/boards/marvell-armada-xp-gp/config.h
new file mode 100644
index 0000000..ca15136
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
new file mode 100644
index 0000000..db75969
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
@@ -0,0 +1,3 @@
+VERSION 1
+BOOT_FROM spi
+BINARY marvell-armada-xp-gp-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c b/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c
new file mode 100644
index 0000000..e9b2e30
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <mach/mvebu.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+
+void __naked barebox_arm_reset_vector(void)
+{
+	arm_cpu_lowlevel_init();
+	mvebu_barebox_entry();
+}
diff --git a/arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c b/arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c
new file mode 100644
index 0000000..7351329
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <mach/mvebu.h>
+
+static int marvell_armada_xp_gp_console_init(void)
+{
+	return mvebu_add_uart0();
+}
+
+console_initcall(marvell_armada_xp_gp_console_init);
diff --git a/arch/arm/configs/marvell_armada_xp_gp_defconfig b/arch/arm/configs/marvell_armada_xp_gp_defconfig
new file mode 100644
index 0000000..5a7ef52
--- /dev/null
+++ b/arch/arm/configs/marvell_armada_xp_gp_defconfig
@@ -0,0 +1,10 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_ARMADA_XP=y
+CONFIG_MACH_MARVELL_ARMADA_XP_GP=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 8489335..e553e2d 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -4,10 +4,12 @@ config ARCH_TEXT_BASE
 	hex
 	default 0x2000000 if MACH_PLATHOME_OPENBLOCKS_AX3
 	default 0x2000000 if MACH_GLOBALSCALE_MIRABOX
+	default 0x2000000 if MACH_MARVELL_ARMADA_XP_GP
 
 config BOARDINFO
 	default "PlatHome OpenBlocks AX3" if MACH_PLATHOME_OPENBLOCKS_AX3
 	default "Globalscale Mirabox" if MACH_GLOBALSCALE_MIRABOX
+	default "Marvell Armada XP GP" if MACH_MARVELL_ARMADA_XP_GP
 
 choice
 	prompt "Marvell EBU Processor"
@@ -42,6 +44,9 @@ choice
 config MACH_PLATHOME_OPENBLOCKS_AX3
 	bool "PlatHome OpenBlocks AX3"
 
+config MACH_MARVELL_ARMADA_XP_GP
+	bool "Marvell Armada XP GP"
+
 endchoice
 
 endif # ARCH_ARMADA_XP
-- 
1.7.9.5


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

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

* Re: [PATCH v3 2/7] scripts: add kwboot tool
  2013-05-09  9:52 ` [PATCH v3 2/7] scripts: add kwboot tool Thomas Petazzoni
@ 2013-05-09 11:16   ` Jason Cooper
  2013-05-10 13:25     ` Sascha Hauer
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Cooper @ 2013-05-09 11:16 UTC (permalink / raw)
  To: Thomas Petazzoni, Sascha Hauer
  Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

Thomas,

On Thu, May 09, 2013 at 11:52:46AM +0200, Thomas Petazzoni wrote:
> This tool is used with Marvell EBU SoC to trigger the UART boot mode
> provided by the SoC BootROM, and push the bootloader image to the
> target using the Xmodem protocol.
> 
> It has been taken from the U-Boot source code, with minor
> modifications to make it work with Armada 370/XP platforms.

Could you add a note which revision of u-boot it was pulled from?  That
should make later syncs between the two versions much easier.

To that end, Sascha, do you think it is worth the extra commit to have
one commit copying the file over, and a second adding changes to make it
work with Armada 370/XP?

thx,

Jason.

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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (6 preceding siblings ...)
  2013-05-09  9:52 ` [PATCH v3 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni
@ 2013-05-09 13:33 ` Gregory CLEMENT
  2013-05-11 15:27 ` Sascha Hauer
  2013-05-12  7:56 ` Sascha Hauer
  9 siblings, 0 replies; 18+ messages in thread
From: Gregory CLEMENT @ 2013-05-09 13:33 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

Hi Thomas,

On 05/09/2013 11:52 AM, Thomas Petazzoni wrote:
> Hello,
> 
> Here is a patch set that adds basic support for the Marvell Armada 370
> and Armada XP SOCs. For now, the support is quite minimal, since only
> the serial port is supported. However, a significant part of the work
> has been the development of the tools that allow to extract/create
> bootable images and to push a bootable image through the UART to the
> hardware platform.
> 
> I expect to work on adding support for more devices (such as the
> network interface) and possibly to add support for the older, but
> popular, Marvell Kirkwood SoC family. Contributions are of course
> welcome.

From a user point of view everything is OK now. You can add my
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

for the whole series except the last patch, because I didn't tested yet
on the Armada XP GP platform but I would be very surprise that it doesn't
work for this platform.

Regards,

> 
> Changes since v2:
> 
>  - Use $(srctree) when accessing kwbimage.cfg from arch/arm/Makefile,
>    in order to allow out-of-tree builds to work properly. Noticed by
>    Grégory Clement.
> 
>  - Improve the error message displayed by kwbimage when the DDR3
>    training blob cannot be found. Since it must first be extracted by
>    the user, it is a good idea to guide him. Suggested by Grégory
>    Clement.
> 
>  - Change the file name of the binary blobs for each board, in order
>    to make it different for each board. So instead of being 'binary.0'
>    it is know 'globalscale-mirabox-binary.0', etc. This allows to keep
>    multiple binary blobs for different boards around at the same time.
> 
> Changes since v1:
> 
>  - Drop the patch fixing scripts/checkpatch.pl since it has been
>    merged upstream.
> 
>  - Improve kwbimage to add options that allow to override the payload
>    filename, the boot media, the destination address and execution
>    address from the command line. Suggested by Sascha Hauer.
> 
>  - Add an integration of kwbimage to the Barebox build process. Now,
>    when an ARCH_MVEBU platform is selected, a barebox.kwb file is
>    automatically generated using the board kwbimage.cfg, and a
>    barebox.kwbuart is generated using the board kwbimage.cfg + an
>    override of the boot media to be UART.
> 
>  - Simplify the kwbimage.cfg to no longer contain the payload filename
>    (it is passed by Barebox using kwbimage -p option), the destination
>    and execution addresses (those are passed by Barebox using kwbimage
>    -d and -e options, which allows to ensure they match
>    CONFIG_TEXT_BASE).
> 
>  - Change the default boot media of the kwbimage.cfg to be the real
>    boot media used on the platform, typically SPI or NAND. Since an
>    image for UART is always automatically generated by overriding the
>    boot media, it makes sense to have the real boot media in
>    kwbimage.cfg.
> 
>  - Remove incorrect whitespace change in scripts/Makefile. Noticed by
>    Sascha Hauer.
> 
> In detail, the patch set contains:
> 
>  * A kwbimage tool. This tool allows to extract existing bootloader
>    images, and create new bootloader images. It is more or less
>    similar in purpose to the kwbimage tool from U-Boot, but is capable
>    of handling 'version 1' images used by Armada 370/XP, and not only
>    allows to create images, but also extract images.
> 
>    A typical usage is to first extract an existing bootloader image:
> 
>     ./scripts/kwbimage -x -i <existing-image> -o <some-directory>
> 
>    As an output, you typically get 3 files: kwbimage.cfg (a text file
>    that describes the configuration of the image in a format
>    ressembling the one used by U-Boot), binary.0 (the binary blob that
>    does the DDR3 training) and payload (the bootloader itself).
> 
>    Being able to extract an image is needed in order to get the DDR3
>    training code, and re-use it with Barebox.
> 
>    An image is then later created with:
> 
>     ./scripts/kwbimage -c -i <path/to/kwbimage.cfg> -o <image>
> 
>    For each board, the kwbimage.cfg file is typically located in
>    arch/arm/boards/<board-name>/. The DDR3 training code must however
>    be extracted from an existing bootloader image of your board,
>    usually the one provided by the board manufacturer.
> 
>  * A kwboot tool to push a bootloader through UART. It is directly
>    taken from U-Boot source code, to which I've added some fixes:
> 
>    - Extend the timeouts, to actually make it work on Armada
>      370/XP. This has originally been found by Willy Tarreau.
> 
>    - Ignore non-Xmodem characters, so that the original DDR3 training
>      code can be used without modifications (Willy had to change it to
>      make it output its messages on a different serial port, otherwise
>      it was confusing the Xmodem implementation)
> 
>    - Output to stdout all the non-Xmodem characters so that if
>      something goes wrong during the transfer, we have some
>      informations. It also shows the messages output by the DDR3
>      training code.
> 
>    - Remove the 'patch' feature that patches an image to have the UART
>      type. This requires a knowledge of the header format, which is
>      different between version 0 (kirkwood) and version 1 (armada
>      370/xp). It is not really needed anyway since kwbimage can
>      extract and create images.
> 
>  * The SoC-level code, which for now only consists in a minimal
>    clocksource driver, a function to register an UART, a fixed-rate
>    clock, and a function that determines the amount of RAM by looking
>    at the SDRAM windows registers.
> 
>  * An integration of kwbimage generation. When an ARCH_MVEBU platform
>    is selected, both barebox.kwb and barebox.kwbuart images are
>    generated automatically.
> 
>  * The board-level code for the Armada 370 Mirabox from Globalscale,
>    the Armada XP OpenBlocks AX3 from Plathome and the Armada XP GP
>    from Marvell.
> 
> Best regards,
> 
> Thomas
> 
> Thomas Petazzoni (7):
>   scripts: new kwbimage manipulation tool for Marvell SoC boot images
>   scripts: add kwboot tool
>   arm: initial support for Marvell Armada 370/XP SoCs
>   arm: integrate kwbimage in the image generation
>   arm: add basic support for Armada XP OpenBlocks AX3 platform
>   arm: add basic support for the Armada 370 Mirabox platform
>   arm: add basic support for the Armada XP GP platform
> 
>  Makefile                                           |    2 +-
>  arch/arm/Kconfig                                   |    8 +
>  arch/arm/Makefile                                  |   24 +
>  arch/arm/boards/globalscale-mirabox/Makefile       |    2 +
>  arch/arm/boards/globalscale-mirabox/config.h       |    4 +
>  .../globalscale-mirabox/globalscale-mirabox.c      |   26 +
>  arch/arm/boards/globalscale-mirabox/kwbimage.cfg   |    5 +
>  arch/arm/boards/globalscale-mirabox/lowlevel.c     |   26 +
>  arch/arm/boards/marvell-armada-xp-gp/Makefile      |    2 +
>  arch/arm/boards/marvell-armada-xp-gp/config.h      |    4 +
>  arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg  |    3 +
>  arch/arm/boards/marvell-armada-xp-gp/lowlevel.c    |   25 +
>  .../marvell-armada-xp-gp/marvell-armada-xp-gp.c    |   25 +
>  arch/arm/boards/plathome-openblocks-ax3/Makefile   |    2 +
>  arch/arm/boards/plathome-openblocks-ax3/config.h   |    4 +
>  .../boards/plathome-openblocks-ax3/kwbimage.cfg    |    3 +
>  arch/arm/boards/plathome-openblocks-ax3/lowlevel.c |   25 +
>  .../plathome-openblocks-ax3.c                      |   25 +
>  arch/arm/configs/globalscale_mirabox_defconfig     |    8 +
>  arch/arm/configs/marvell_armada_xp_gp_defconfig    |   10 +
>  arch/arm/configs/plathome_openblocks_ax3_defconfig |    9 +
>  arch/arm/mach-mvebu/Kconfig                        |   54 +
>  arch/arm/mach-mvebu/Makefile                       |    1 +
>  arch/arm/mach-mvebu/core.c                         |  142 ++
>  arch/arm/mach-mvebu/include/mach/clkdev.h          |    7 +
>  arch/arm/mach-mvebu/include/mach/debug_ll.h        |   40 +
>  arch/arm/mach-mvebu/include/mach/mvebu.h           |   22 +
>  drivers/clocksource/Kconfig                        |    4 +
>  drivers/clocksource/Makefile                       |    1 +
>  drivers/clocksource/mvebu.c                        |   90 ++
>  scripts/.gitignore                                 |    2 +
>  scripts/Makefile                                   |    1 +
>  scripts/kwbimage.c                                 | 1448 ++++++++++++++++++++
>  scripts/kwboot.c                                   |  717 ++++++++++
>  34 files changed, 2770 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boards/globalscale-mirabox/Makefile
>  create mode 100644 arch/arm/boards/globalscale-mirabox/config.h
>  create mode 100644 arch/arm/boards/globalscale-mirabox/globalscale-mirabox.c
>  create mode 100644 arch/arm/boards/globalscale-mirabox/kwbimage.cfg
>  create mode 100644 arch/arm/boards/globalscale-mirabox/lowlevel.c
>  create mode 100644 arch/arm/boards/marvell-armada-xp-gp/Makefile
>  create mode 100644 arch/arm/boards/marvell-armada-xp-gp/config.h
>  create mode 100644 arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
>  create mode 100644 arch/arm/boards/marvell-armada-xp-gp/lowlevel.c
>  create mode 100644 arch/arm/boards/marvell-armada-xp-gp/marvell-armada-xp-gp.c
>  create mode 100644 arch/arm/boards/plathome-openblocks-ax3/Makefile
>  create mode 100644 arch/arm/boards/plathome-openblocks-ax3/config.h
>  create mode 100644 arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
>  create mode 100644 arch/arm/boards/plathome-openblocks-ax3/lowlevel.c
>  create mode 100644 arch/arm/boards/plathome-openblocks-ax3/plathome-openblocks-ax3.c
>  create mode 100644 arch/arm/configs/globalscale_mirabox_defconfig
>  create mode 100644 arch/arm/configs/marvell_armada_xp_gp_defconfig
>  create mode 100644 arch/arm/configs/plathome_openblocks_ax3_defconfig
>  create mode 100644 arch/arm/mach-mvebu/Kconfig
>  create mode 100644 arch/arm/mach-mvebu/Makefile
>  create mode 100644 arch/arm/mach-mvebu/core.c
>  create mode 100644 arch/arm/mach-mvebu/include/mach/clkdev.h
>  create mode 100644 arch/arm/mach-mvebu/include/mach/debug_ll.h
>  create mode 100644 arch/arm/mach-mvebu/include/mach/mvebu.h
>  create mode 100644 drivers/clocksource/mvebu.c
>  create mode 100644 scripts/kwbimage.c
>  create mode 100644 scripts/kwboot.c
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

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

* Re: [PATCH v3 2/7] scripts: add kwboot tool
  2013-05-09 11:16   ` Jason Cooper
@ 2013-05-10 13:25     ` Sascha Hauer
  0 siblings, 0 replies; 18+ messages in thread
From: Sascha Hauer @ 2013-05-10 13:25 UTC (permalink / raw)
  To: Jason Cooper
  Cc: Thomas Petazzoni, barebox, Lior Amsalem, Willy Tarreau, Ezequiel Garcia

On Thu, May 09, 2013 at 07:16:39AM -0400, Jason Cooper wrote:
> Thomas,
> 
> On Thu, May 09, 2013 at 11:52:46AM +0200, Thomas Petazzoni wrote:
> > This tool is used with Marvell EBU SoC to trigger the UART boot mode
> > provided by the SoC BootROM, and push the bootloader image to the
> > target using the Xmodem protocol.
> > 
> > It has been taken from the U-Boot source code, with minor
> > modifications to make it work with Armada 370/XP platforms.
> 
> Could you add a note which revision of u-boot it was pulled from?  That
> should make later syncs between the two versions much easier.
> 
> To that end, Sascha, do you think it is worth the extra commit to have
> one commit copying the file over, and a second adding changes to make it
> work with Armada 370/XP?

The revision the tool originally came from should be enough I think.
Anyway, if Thomas is willing to split this into two patches I'll take
that version instead.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (7 preceding siblings ...)
  2013-05-09 13:33 ` [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT
@ 2013-05-11 15:27 ` Sascha Hauer
  2013-05-11 16:27   ` Thomas Petazzoni
  2013-05-12  7:56 ` Sascha Hauer
  9 siblings, 1 reply; 18+ messages in thread
From: Sascha Hauer @ 2013-05-11 15:27 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

On Thu, May 09, 2013 at 11:52:44AM +0200, Thomas Petazzoni wrote:
> 
> Thomas Petazzoni (7):
>   scripts: new kwbimage manipulation tool for Marvell SoC boot images
>   scripts: add kwboot tool
>   arm: initial support for Marvell Armada 370/XP SoCs
>   arm: integrate kwbimage in the image generation
>   arm: add basic support for Armada XP OpenBlocks AX3 platform
>   arm: add basic support for the Armada 370 Mirabox platform
>   arm: add basic support for the Armada XP GP platform
> 

Applied all.

Regarding the commit id from which the kwboot tool has been taken from I
decided to ignore it since the tool hasn't been changed in U-Boot since
the original commit adding it.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-11 15:27 ` Sascha Hauer
@ 2013-05-11 16:27   ` Thomas Petazzoni
  0 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-11 16:27 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

Dear Sascha Hauer,

On Sat, 11 May 2013 17:27:16 +0200, Sascha Hauer wrote:
> On Thu, May 09, 2013 at 11:52:44AM +0200, Thomas Petazzoni wrote:
> > 
> > Thomas Petazzoni (7):
> >   scripts: new kwbimage manipulation tool for Marvell SoC boot images
> >   scripts: add kwboot tool
> >   arm: initial support for Marvell Armada 370/XP SoCs
> >   arm: integrate kwbimage in the image generation
> >   arm: add basic support for Armada XP OpenBlocks AX3 platform
> >   arm: add basic support for the Armada 370 Mirabox platform
> >   arm: add basic support for the Armada XP GP platform
> > 
> 
> Applied all.
> 
> Regarding the commit id from which the kwboot tool has been taken from I
> decided to ignore it since the tool hasn't been changed in U-Boot since
> the original commit adding it.

Ok, thanks!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
                   ` (8 preceding siblings ...)
  2013-05-11 15:27 ` Sascha Hauer
@ 2013-05-12  7:56 ` Sascha Hauer
  2013-05-12  9:12   ` Thomas Petazzoni
  9 siblings, 1 reply; 18+ messages in thread
From: Sascha Hauer @ 2013-05-12  7:56 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

There is a problem with this series: It doesn't build without the
addtional binary needed for the kwb tool. Can we make creating a kwb
image optional so that we are able to build the defconfigs without
additional dependencies?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-12  7:56 ` Sascha Hauer
@ 2013-05-12  9:12   ` Thomas Petazzoni
  2013-05-12 10:24     ` Sascha Hauer
  0 siblings, 1 reply; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-12  9:12 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

Dear Sascha Hauer,

On Sun, 12 May 2013 09:56:44 +0200, Sascha Hauer wrote:
> There is a problem with this series: It doesn't build without the
> addtional binary needed for the kwb tool. Can we make creating a kwb
> image optional so that we are able to build the defconfigs without
> additional dependencies?

Hum, right. So we should make the default build target to not build
barebox.{kwb,kwbuart} and only make barebox.bin?

Or there should be a config option somewhere to say "I also want
the .{kwb,kwbuart} images generated" ?

Neither of those are ideal, because most likely people will not notice
the possibility of building the .{kwb,kwbuart} images, but I understand
the concern of not being able to build defconfigs.

Tell me which solution you prefer, and I'll send a patch that
implements it.

Thanks!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-12  9:12   ` Thomas Petazzoni
@ 2013-05-12 10:24     ` Sascha Hauer
  2013-05-12 10:41       ` Thomas Petazzoni
  0 siblings, 1 reply; 18+ messages in thread
From: Sascha Hauer @ 2013-05-12 10:24 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

On Sun, May 12, 2013 at 11:12:46AM +0200, Thomas Petazzoni wrote:
> Dear Sascha Hauer,
> 
> On Sun, 12 May 2013 09:56:44 +0200, Sascha Hauer wrote:
> > There is a problem with this series: It doesn't build without the
> > addtional binary needed for the kwb tool. Can we make creating a kwb
> > image optional so that we are able to build the defconfigs without
> > additional dependencies?
> 
> Hum, right. So we should make the default build target to not build
> barebox.{kwb,kwbuart} and only make barebox.bin?
> 
> Or there should be a config option somewhere to say "I also want
> the .{kwb,kwbuart} images generated" ?
> 
> Neither of those are ideal, because most likely people will not notice
> the possibility of building the .{kwb,kwbuart} images, but I understand
> the concern of not being able to build defconfigs.
> 
> Tell me which solution you prefer, and I'll send a patch that
> implements it.

How about a warning like:

"Warning: 'plathome-openblocks-ax3-binary.0' does not exist. Not building barebox.kwb"

Also not an ideal solution, but I think there is no really good way to
solve this other than including the binary in the tree which probably
has some licensing issues.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 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

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

* Re: [PATCH v3 0/7] Basic support for Armada 370/XP SOCs
  2013-05-12 10:24     ` Sascha Hauer
@ 2013-05-12 10:41       ` Thomas Petazzoni
  0 siblings, 0 replies; 18+ messages in thread
From: Thomas Petazzoni @ 2013-05-12 10:41 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

Dear Sascha Hauer,

On Sun, 12 May 2013 12:24:04 +0200, Sascha Hauer wrote:

> How about a warning like:
> 
> "Warning: 'plathome-openblocks-ax3-binary.0' does not exist. Not building barebox.kwb"
> 
> Also not an ideal solution, but I think there is no really good way to
> solve this other than including the binary in the tree which probably
> has some licensing issues.

The problem is that the Makefile doesn't know that kwbimage will need
plathome-openblocks-ax3-binary.0, it would have to parse the
kwbimage.cfg file to know about this.

Also, not all .kwb images will require this binary blob. Kirkwood and
Dove do not require such a binary blob, and a kwb image can be built
with just the kwbimage.cfg and barebox.bin. So it is really a
per-kwbimage.cfg knowledge.

Another solution is to add an option to kwbimage that allows it to list
which files are needed to make the build succeed. Then
arch/arm/Makefile can call this, check that we have the needed files.
If not, it shows a warning, otherwise it goes on with the build.

Other ideas welcome, of course.

Best regards,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

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

* Re: [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs
  2013-05-09  9:52 ` [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni
@ 2013-05-12 11:14   ` antonynpavlov
  0 siblings, 0 replies; 18+ messages in thread
From: antonynpavlov @ 2013-05-12 11:14 UTC (permalink / raw)
  To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia

On Thu,  9 May 2013 11:52:47 +0200
Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:

> This commit adds minimal support for the Armada 370 and Armada XP SoCs
> from Marvell.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
>  arch/arm/Kconfig                            |    8 ++
>  arch/arm/Makefile                           |    1 +
>  arch/arm/mach-mvebu/Kconfig                 |   40 ++++++++
>  arch/arm/mach-mvebu/Makefile                |    1 +
>  arch/arm/mach-mvebu/core.c                  |  142 +++++++++++++++++++++++++++
>  arch/arm/mach-mvebu/include/mach/clkdev.h   |    7 ++


Please drop clkdev.h!


>  arch/arm/mach-mvebu/include/mach/debug_ll.h |   40 ++++++++
>  arch/arm/mach-mvebu/include/mach/mvebu.h    |   22 +++++
>  drivers/clocksource/Kconfig                 |    4 +
>  drivers/clocksource/Makefile                |    1 +
>  drivers/clocksource/mvebu.c                 |   90 +++++++++++++++++
>  11 files changed, 356 insertions(+)
>  create mode 100644 arch/arm/mach-mvebu/Kconfig
>  create mode 100644 arch/arm/mach-mvebu/Makefile
>  create mode 100644 arch/arm/mach-mvebu/core.c
>  create mode 100644 arch/arm/mach-mvebu/include/mach/clkdev.h
>  create mode 100644 arch/arm/mach-mvebu/include/mach/debug_ll.h
>  create mode 100644 arch/arm/mach-mvebu/include/mach/mvebu.h
>  create mode 100644 drivers/clocksource/mvebu.c
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0a4f821..a044ab3 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -79,6 +79,13 @@ config ARCH_IMX
>  	select WATCHDOG_IMX_RESET_SOURCE
>  	select HAS_DEBUG_LL
>  
> +config ARCH_MVEBU
> +	bool "Marvell EBU platforms"
> +	select COMMON_CLK
> +	select CLOCKSOURCE_MVEBU
> +	select CLKDEV_LOOKUP
> +	select HAS_DEBUG_LL
> +
>  config ARCH_MXS
>  	bool "Freescale i.MX23/28 (mxs) based"
>  	select GENERIC_GPIO
> @@ -161,6 +168,7 @@ source arch/arm/mach-ep93xx/Kconfig
>  source arch/arm/mach-highbank/Kconfig
>  source arch/arm/mach-imx/Kconfig
>  source arch/arm/mach-mxs/Kconfig
> +source arch/arm/mach-mvebu/Kconfig
>  source arch/arm/mach-netx/Kconfig
>  source arch/arm/mach-nomadik/Kconfig
>  source arch/arm/mach-omap/Kconfig
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index d506b12..bb47506 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
>  machine-$(CONFIG_ARCH_HIGHBANK)		:= highbank
>  machine-$(CONFIG_ARCH_IMX)		:= imx
>  machine-$(CONFIG_ARCH_MXS)		:= mxs
> +machine-$(CONFIG_ARCH_MVEBU)		:= mvebu
>  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
>  machine-$(CONFIG_ARCH_NETX)		:= netx
>  machine-$(CONFIG_ARCH_OMAP)		:= omap
> diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
> new file mode 100644
> index 0000000..4cbe546
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/Kconfig
> @@ -0,0 +1,40 @@
> +if ARCH_MVEBU
> +
> +config ARCH_TEXT_BASE
> +	hex
> +
> +config BOARDINFO
> +	default
> +
> +choice
> +	prompt "Marvell EBU Processor"
> +
> +config ARCH_ARMADA_370
> +	bool "Armada 370"
> +	select CPU_V7
> +
> +config ARCH_ARMADA_XP
> +	bool "Armada XP"
> +	select CPU_V7
> +
> +endchoice
> +
> +if ARCH_ARMADA_370
> +
> +choice
> +	prompt "Armada 370 Board Type"
> +
> +endchoice
> +
> +endif # ARCH_ARMADA_370
> +
> +if ARCH_ARMADA_XP
> +
> +choice
> +	prompt "Armada XP Board Type"
> +
> +endchoice
> +
> +endif # ARCH_ARMADA_XP
> +
> +endif # ARCH_MVEBU
> diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
> new file mode 100644
> index 0000000..820eb10
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/Makefile
> @@ -0,0 +1 @@
> +obj-y += core.o
> diff --git a/arch/arm/mach-mvebu/core.c b/arch/arm/mach-mvebu/core.c
> new file mode 100644
> index 0000000..f4672a3
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/core.c
> @@ -0,0 +1,142 @@
> +/*
> + * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * 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 <common.h>
> +#include <init.h>
> +#include <io.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <ns16550.h>
> +#include <asm/memory.h>
> +#include <asm/barebox-arm.h>
> +
> +#define MVEBU_INT_REGS_BASE (0xd0000000)
> +#define  MVEBU_UART0_BASE     (MVEBU_INT_REGS_BASE + 0x12000)
> +#define  MVEBU_SYSCTL_BASE    (MVEBU_INT_REGS_BASE + 0x18200)
> +#define  MVEBU_SDRAM_WIN_BASE (MVEBU_INT_REGS_BASE + 0x20180)
> +#define  MVEBU_TIMER_BASE     (MVEBU_INT_REGS_BASE + 0x20300)
> +#define  MVEBU_SAR_BASE       (MVEBU_INT_REGS_BASE + 0x18230)
> +
> +#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
> +#define  DDR_BASE_CS_HIGH_MASK  0xf
> +#define  DDR_BASE_CS_LOW_MASK   0xff000000
> +#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
> +#define  DDR_SIZE_ENABLED       (1 << 0)
> +#define  DDR_SIZE_CS_MASK       0x1c
> +#define  DDR_SIZE_CS_SHIFT      2
> +#define  DDR_SIZE_MASK          0xff000000
> +
> +#define SAR_LOW_REG_OFF         0
> +#define  SAR_TCLK_FREQ_BIT      20
> +#define SAR_HIGH_REG_OFF        0x4
> +
> +static struct clk *tclk;
> +
> +static inline void mvebu_memory_find(unsigned long *phys_base,
> +				     unsigned long *phys_size)
> +{
> +	void __iomem *sdram_win = IOMEM(MVEBU_SDRAM_WIN_BASE);
> +	int cs;
> +
> +	*phys_base = ~0;
> +	*phys_size = 0;
> +
> +	for (cs = 0; cs < 4; cs++) {
> +		uint32_t base = readl(sdram_win + DDR_BASE_CS_OFF(cs));
> +		uint32_t ctrl = readl(sdram_win + DDR_SIZE_CS_OFF(cs));
> +
> +		/* Skip non-enabled CS */
> +		if (! (ctrl & DDR_SIZE_ENABLED))
> +			continue;
> +
> +		base &= DDR_BASE_CS_LOW_MASK;
> +		if (base < *phys_base)
> +			*phys_base = base;
> +		*phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
> +	}
> +}
> +
> +void __naked __noreturn mvebu_barebox_entry(void)
> +{
> +	unsigned long phys_base, phys_size;
> +	mvebu_memory_find(&phys_base, &phys_size);
> +	barebox_arm_entry(phys_base, phys_size, 0);
> +}
> +
> +static struct NS16550_plat uart0_plat = {
> +	.shift = 2,
> +};
> +
> +int mvebu_add_uart0(void)
> +{
> +	uart0_plat.clock = clk_get_rate(tclk);
> +	add_ns16550_device(DEVICE_ID_DYNAMIC, MVEBU_UART0_BASE, 32,
> +			   IORESOURCE_MEM_32BIT, &uart0_plat);
> +	return 0;
> +}
> +
> +#if defined(CONFIG_ARCH_ARMADA_370)
> +static int mvebu_init_clocks(void)
> +{
> +	uint32_t val;
> +	unsigned int rate;
> +	void __iomem *sar = IOMEM(MVEBU_SAR_BASE) + SAR_LOW_REG_OFF;
> +
> +	val = readl(sar);
> +
> +	/* On Armada 370, the TCLK frequency can be either 166 Mhz or
> +	 * 200 Mhz */
> +	if (val & (1 << SAR_TCLK_FREQ_BIT))
> +		rate = 200 * 1000 * 1000;
> +	else
> +		rate = 166 * 1000 * 1000;
> +
> +	tclk = clk_fixed("tclk", rate);
> +	return clk_register_clkdev(tclk, NULL, "mvebu-timer");
> +}
> +#endif
> +
> +#if defined(CONFIG_ARCH_ARMADA_XP)
> +static int mvebu_init_clocks(void)
> +{
> +	/* On Armada XP, the TCLK frequency is always 250 Mhz */
> +	tclk = clk_fixed("tclk", 250 * 1000 * 1000);
> +	return clk_register_clkdev(tclk, NULL, "mvebu-timer");
> +}
> +#endif
> +
> +static int mvebu_init_soc(void)
> +{
> +	unsigned long phys_base, phys_size;
> +
> +	mvebu_init_clocks();
> +	add_generic_device("mvebu-timer", DEVICE_ID_SINGLE, NULL,
> +			   MVEBU_TIMER_BASE, 0x30, IORESOURCE_MEM,
> +			   NULL);
> +	mvebu_memory_find(&phys_base, &phys_size);
> +	arm_add_mem_device("ram0", phys_base, phys_size);
> +	return 0;
> +}
> +
> +postcore_initcall(mvebu_init_soc);
> +
> +void __noreturn reset_cpu(unsigned long addr)
> +{
> +	writel(0x1, MVEBU_SYSCTL_BASE + 0x60);
> +	writel(0x1, MVEBU_SYSCTL_BASE + 0x64);
> +	while (1)
> +		;
> +}
> +EXPORT_SYMBOL(reset_cpu);
> diff --git a/arch/arm/mach-mvebu/include/mach/clkdev.h b/arch/arm/mach-mvebu/include/mach/clkdev.h
> new file mode 100644
> index 0000000..04b37a8
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/include/mach/clkdev.h
> @@ -0,0 +1,7 @@
> +#ifndef __ASM_MACH_CLKDEV_H
> +#define __ASM_MACH_CLKDEV_H
> +
> +#define __clk_get(clk) ({ 1; })
> +#define __clk_put(clk) do { } while (0)
> +
> +#endif
> diff --git a/arch/arm/mach-mvebu/include/mach/debug_ll.h b/arch/arm/mach-mvebu/include/mach/debug_ll.h
> new file mode 100644
> index 0000000..2653573
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/include/mach/debug_ll.h
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * 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.
> + *
> + */
> +
> +#ifndef __MACH_DEBUG_LL_H__
> +#define __MACH_DEBUG_LL_H__
> +
> +#include <io.h>
> +
> +#define UART_BASE 0xd0012000
> +#define UART_THR  0x0
> +#define UART_LSR  0x14
> +#define   UART_LSR_THRE   (1 << 5)
> +
> +static inline void PUTC_LL(char c)
> +{
> +	/* Wait until there is space in the FIFO */
> +	while (!(readl(UART_BASE + UART_LSR) & UART_LSR_THRE))
> +		;
> +
> +	/* Send the character */
> +	writel(c, UART_BASE + UART_THR)
> +		;
> +
> +	/* Wait to make sure it hits the line, in case we die too soon. */
> +	while (!(readl(UART_BASE + UART_LSR) & UART_LSR_THRE))
> +		;
> +}
> +#endif
> diff --git a/arch/arm/mach-mvebu/include/mach/mvebu.h b/arch/arm/mach-mvebu/include/mach/mvebu.h
> new file mode 100644
> index 0000000..e13a446
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/include/mach/mvebu.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * 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.
> + *
> + */
> +
> +#ifndef __MACH_MVEBU_H
> +#define __MACH_MVEBU_H
> +
> +int mvebu_add_uart0(void);
> +void __naked __noreturn mvebu_barebox_entry(void);
> +
> +#endif /* __MACH_MVEBU_H */
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 9f3558b..dfc89dd 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -14,6 +14,10 @@ config CLOCKSOURCE_CLPS711X
>  	bool
>  	depends on ARCH_CLPS711X
>  
> +config CLOCKSOURCE_MVEBU
> +	bool
> +	depends on ARCH_MVEBU
> +
>  config CLOCKSOURCE_NOMADIK
>  	bool
>  	depends on ARM
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index d919881..0b42ce4 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -2,4 +2,5 @@ obj-$(CONFIG_AMBA_SP804) += amba-sp804.o
>  obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o
>  obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o
>  obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o
> +obj-$(CONFIG_CLOCKSOURCE_MVEBU)   += mvebu.o
>  obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o
> diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c
> new file mode 100644
> index 0000000..2b48a5c
> --- /dev/null
> +++ b/drivers/clocksource/mvebu.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * 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 <common.h>
> +#include <init.h>
> +#include <clock.h>
> +#include <linux/clk.h>
> +#include <io.h>
> +
> +#define TIMER_CTRL_OFF          0x0000
> +#define  TIMER0_EN               0x0001
> +#define  TIMER0_RELOAD_EN        0x0002
> +#define  TIMER0_25MHZ            0x0800
> +#define  TIMER0_DIV(div)         ((div) << 19)
> +#define  TIMER1_EN               0x0004
> +#define  TIMER1_RELOAD_EN        0x0008
> +#define  TIMER1_25MHZ            0x1000
> +#define  TIMER1_DIV(div)         ((div) << 22)
> +#define TIMER_EVENTS_STATUS     0x0004
> +#define  TIMER0_CLR_MASK         (~0x1)
> +#define  TIMER1_CLR_MASK         (~0x100)
> +#define TIMER0_RELOAD_OFF       0x0010
> +#define TIMER0_VAL_OFF          0x0014
> +#define TIMER1_RELOAD_OFF       0x0018
> +#define TIMER1_VAL_OFF          0x001c
> +
> +#define TIMER_DIVIDER_SHIFT     5
> +
> +static __iomem void *timer_base;
> +
> +uint64_t mvebu_clocksource_read(void)
> +{
> +	return __raw_readl(timer_base + TIMER0_VAL_OFF);
> +}
> +
> +static struct clocksource cs = {
> +	.read	= mvebu_clocksource_read,
> +	.mask	= CLOCKSOURCE_MASK(32),
> +	.shift	= 10,
> +};
> +
> +static int mvebu_timer_probe(struct device_d *dev)
> +{
> +	struct clk *tclk;
> +	u32 val;
> +
> +	timer_base = dev_request_mem_region(dev, 0);
> +
> +	tclk = clk_get(dev, "tclk");
> +
> +	val = __raw_readl(timer_base + TIMER_CTRL_OFF);
> +	val &= ~TIMER0_25MHZ;
> +	__raw_writel(val, timer_base + TIMER_CTRL_OFF);
> +
> +	__raw_writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
> +	__raw_writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
> +
> +	val = __raw_readl(timer_base + TIMER_CTRL_OFF);
> +	val |= TIMER0_EN | TIMER0_RELOAD_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
> +	__raw_writel(val, timer_base + TIMER_CTRL_OFF);
> +
> +	cs.mult = clocksource_hz2mult(clk_get_rate(tclk), cs.shift);
> +
> +	init_clock(&cs);
> +
> +	return 0;
> +}
> +
> +static struct driver_d mvebu_timer_driver = {
> +	.name = "mvebu-timer",
> +	.probe = mvebu_timer_probe,
> +};
> +
> +static int mvebu_timer_init(void)
> +{
> +	return platform_driver_register(&mvebu_timer_driver);
> +}
> +postcore_initcall(mvebu_timer_init);
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
-- 
Best regards,
  Antony Pavlov

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

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

end of thread, other threads:[~2013-05-12 11:15 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-09  9:52 [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni
2013-05-09  9:52 ` [PATCH v3 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni
2013-05-09  9:52 ` [PATCH v3 2/7] scripts: add kwboot tool Thomas Petazzoni
2013-05-09 11:16   ` Jason Cooper
2013-05-10 13:25     ` Sascha Hauer
2013-05-09  9:52 ` [PATCH v3 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni
2013-05-12 11:14   ` antonynpavlov
2013-05-09  9:52 ` [PATCH v3 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni
2013-05-09  9:52 ` [PATCH v3 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni
2013-05-09  9:52 ` [PATCH v3 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni
2013-05-09  9:52 ` [PATCH v3 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni
2013-05-09 13:33 ` [PATCH v3 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT
2013-05-11 15:27 ` Sascha Hauer
2013-05-11 16:27   ` Thomas Petazzoni
2013-05-12  7:56 ` Sascha Hauer
2013-05-12  9:12   ` Thomas Petazzoni
2013-05-12 10:24     ` Sascha Hauer
2013-05-12 10:41       ` Thomas Petazzoni

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