* [PATCH v2 0/7] Basic support for Armada 370/XP SOCs @ 2013-05-08 21:10 Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni ` (7 more replies) 0 siblings, 8 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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 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 | 1443 ++++++++++++++++++++ scripts/kwboot.c | 717 ++++++++++ 34 files changed, 2765 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] 12+ messages in thread
* [PATCH v2 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 2/7] scripts: add kwboot tool Thomas Petazzoni ` (6 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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 | 1443 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1445 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..8edbcf4 --- /dev/null +++ b/scripts/kwbimage.c @@ -0,0 +1,1443 @@ +/* + * 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) { + fprintf(stderr, "Cannot stat binary file %s\n", + e->binary.file); + 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] 12+ messages in thread
* [PATCH v2 2/7] scripts: add kwboot tool 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni ` (5 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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] 12+ messages in thread
* [PATCH v2 3/7] arm: initial support for Marvell Armada 370/XP SoCs 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 2/7] scripts: add kwboot tool Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni ` (4 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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] 12+ messages in thread
* [PATCH v2 4/7] arm: integrate kwbimage in the image generation 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni ` (2 preceding siblings ...) 2013-05-08 21:10 ` [PATCH v2 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 22:18 ` Gregory CLEMENT 2013-05-08 21:10 ` [PATCH v2 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni ` (3 subsequent siblings) 7 siblings, 1 reply; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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..3103db4 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 $(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] 12+ messages in thread
* Re: [PATCH v2 4/7] arm: integrate kwbimage in the image generation 2013-05-08 21:10 ` [PATCH v2 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni @ 2013-05-08 22:18 ` Gregory CLEMENT 0 siblings, 0 replies; 12+ messages in thread From: Gregory CLEMENT @ 2013-05-08 22:18 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia Hi Thomas, On 05/08/2013 11:10 PM, Thomas Petazzoni wrote: > 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..3103db4 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 $(BOARD)/kwbimage.cfg -d $(TEXT_BASE) -e $(TEXT_BASE) if you replace this line by -c -i $(srctree)/$(BOARD)/kwbimage.cfg -d $(TEXT_BASE) -e $(TEXT_BASE) it works when barebox is built out of tree > + > +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)/$@ > -- 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] 12+ messages in thread
* [PATCH v2 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni ` (3 preceding siblings ...) 2013-05-08 21:10 ` [PATCH v2 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni ` (2 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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 3103db4..13799fd 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..05d398c --- /dev/null +++ b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg @@ -0,0 +1,3 @@ +VERSION 1 +BOOT_FROM spi +BINARY 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] 12+ messages in thread
* [PATCH v2 6/7] arm: add basic support for the Armada 370 Mirabox platform 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni ` (4 preceding siblings ...) 2013-05-08 21:10 ` [PATCH v2 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni 2013-05-08 21:53 ` [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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 13799fd..c8bdba7 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..3e20502 --- /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 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] 12+ messages in thread
* [PATCH v2 7/7] arm: add basic support for the Armada XP GP platform 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni ` (5 preceding siblings ...) 2013-05-08 21:10 ` [PATCH v2 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni @ 2013-05-08 21:10 ` Thomas Petazzoni 2013-05-08 21:53 ` [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT 7 siblings, 0 replies; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:10 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 c8bdba7..a46e3b3 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..05d398c --- /dev/null +++ b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg @@ -0,0 +1,3 @@ +VERSION 1 +BOOT_FROM spi +BINARY 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] 12+ messages in thread
* Re: [PATCH v2 0/7] Basic support for Armada 370/XP SOCs 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni ` (6 preceding siblings ...) 2013-05-08 21:10 ` [PATCH v2 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni @ 2013-05-08 21:53 ` Gregory CLEMENT 2013-05-08 21:59 ` Thomas Petazzoni 7 siblings, 1 reply; 12+ messages in thread From: Gregory CLEMENT @ 2013-05-08 21:53 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia Hi Thomas, On 05/08/2013 11:10 PM, 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. > > 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. It is a very nice improvement however, you should maybe mention somwhere that you expect to find a file named binary.0 at the root of the barebox sources. But it is not very important. However you didn't manage the out of tree building when KBUILD_OUTPUT is set. This is more annoying but it should be easily fixed. > > - 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. It didn't work for me when I tested the on the OpenBlocks AX3. The boot media didn't seem to have been overridden ie it still try to boot on the NOR. And if I modify the file arch/arm/boards/plathome-openblocks-ax3//kwbimage.cfg and replace spi by uart, then it works. Thanks for your work, > > - 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 | 1443 ++++++++++++++++++++ > scripts/kwboot.c | 717 ++++++++++ > 34 files changed, 2765 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] 12+ messages in thread
* Re: [PATCH v2 0/7] Basic support for Armada 370/XP SOCs 2013-05-08 21:53 ` [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT @ 2013-05-08 21:59 ` Thomas Petazzoni 2013-05-08 22:11 ` Gregory CLEMENT 0 siblings, 1 reply; 12+ messages in thread From: Thomas Petazzoni @ 2013-05-08 21:59 UTC (permalink / raw) To: Gregory CLEMENT; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia Dear Gregory CLEMENT, On Wed, 08 May 2013 23:53:40 +0200, Gregory CLEMENT wrote: > > - 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. > > It is a very nice improvement however, you should maybe mention somwhere > that you expect to find a file named binary.0 at the root of the barebox > sources. But it is not very important. Indeed, but which "somewhere" do you suggest? > However you didn't manage the out of tree building when KBUILD_OUTPUT is > set. This is more annoying but it should be easily fixed. Aah, I haven't thought of out-of-tree build. I'll test that and I'll have a look. > It didn't work for me when I tested the on the OpenBlocks AX3. The boot > media didn't seem to have been overridden ie it still try to boot on the > NOR. And if I modify the file arch/arm/boards/plathome-openblocks-ax3//kwbimage.cfg > and replace spi by uart, then it works. Are you sure you used barebox.kwbuart and not barebox.kwb? Thanks for your testing! 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] 12+ messages in thread
* Re: [PATCH v2 0/7] Basic support for Armada 370/XP SOCs 2013-05-08 21:59 ` Thomas Petazzoni @ 2013-05-08 22:11 ` Gregory CLEMENT 0 siblings, 0 replies; 12+ messages in thread From: Gregory CLEMENT @ 2013-05-08 22:11 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: Lior Amsalem, barebox, Willy Tarreau, Ezequiel Garcia On 05/08/2013 11:59 PM, Thomas Petazzoni wrote: > Dear Gregory CLEMENT, > > On Wed, 08 May 2013 23:53:40 +0200, Gregory CLEMENT wrote: > >>> - 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. >> >> It is a very nice improvement however, you should maybe mention somwhere >> that you expect to find a file named binary.0 at the root of the barebox >> sources. But it is not very important. > > Indeed, but which "somewhere" do you suggest? My first thought was in the help of the menuconfig, but in the case of someone just do a make board_configs, make, he won't see it. So maybe the best option should just to make the error message more verbose. Instead of "Cannot stat binary file binary.0" some thing like "Didn't find the file binary.0 at /absolute/path/to/barebox/source which is mandatory to generate the kwboot image" > >> However you didn't manage the out of tree building when KBUILD_OUTPUT is >> set. This is more annoying but it should be easily fixed. > > Aah, I haven't thought of out-of-tree build. I'll test that and I'll > have a look. > >> It didn't work for me when I tested the on the OpenBlocks AX3. The boot >> media didn't seem to have been overridden ie it still try to boot on the >> NOR. And if I modify the file arch/arm/boards/plathome-openblocks-ax3//kwbimage.cfg >> and replace spi by uart, then it works. > > Are you sure you used barebox.kwbuart and not barebox.kwb? Oh I didn't notice this one! Indeed if I use barebox.kwbuart it works. Sorry for the noise. Gregory _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-05-08 22:18 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-05-08 21:10 [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 1/7] scripts: new kwbimage manipulation tool for Marvell SoC boot images Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 2/7] scripts: add kwboot tool Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 3/7] arm: initial support for Marvell Armada 370/XP SoCs Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 4/7] arm: integrate kwbimage in the image generation Thomas Petazzoni 2013-05-08 22:18 ` Gregory CLEMENT 2013-05-08 21:10 ` [PATCH v2 5/7] arm: add basic support for Armada XP OpenBlocks AX3 platform Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 6/7] arm: add basic support for the Armada 370 Mirabox platform Thomas Petazzoni 2013-05-08 21:10 ` [PATCH v2 7/7] arm: add basic support for the Armada XP GP platform Thomas Petazzoni 2013-05-08 21:53 ` [PATCH v2 0/7] Basic support for Armada 370/XP SOCs Gregory CLEMENT 2013-05-08 21:59 ` Thomas Petazzoni 2013-05-08 22:11 ` Gregory CLEMENT
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox