diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/boards/pcm049/board.c | 4 | ||||
-rw-r--r-- | arch/arm/boards/pcm049/env/config | 2 | ||||
-rw-r--r-- | arch/arm/boards/phycard-a-l1/env/config | 2 | ||||
-rw-r--r-- | arch/arm/boards/phycard-a-l1/pca-a-l1.c | 6 | ||||
-rw-r--r-- | arch/arm/boards/phycard-a-xl2/env/config | 2 | ||||
-rw-r--r-- | arch/arm/boards/phycard-a-xl2/pca-a-xl2.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap/Kconfig | 24 | ||||
-rw-r--r-- | arch/arm/mach-omap/gpio.c | 171 | ||||
-rw-r--r-- | arch/arm/mach-omap/include/mach/xload.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap/omap3_clock.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap/omap3_generic.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-omap/omap4_generic.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-omap/xload.c | 99 | ||||
-rw-r--r-- | common/filetype.c | 2 | ||||
-rw-r--r-- | include/filetype.h | 16 | ||||
-rw-r--r-- | scripts/.gitignore | 1 | ||||
-rw-r--r-- | scripts/Makefile | 2 | ||||
-rw-r--r-- | scripts/mk-am35xx-spi-image.c | 141 |
22 files changed, 403 insertions, 144 deletions
diff --git a/.gitignore b/.gitignore index 7e98a2558b..9af6710290 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ barebox.bin barebox.srec barebox.netx barebox.s5p +barebox.spi barebox.ubl barebox.uimage barebox.map @@ -1032,7 +1032,7 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \ .tmp_kallsyms* barebox_default_env* barebox.ldr \ scripts/bareboxenv-target barebox-flash-image \ Doxyfile.version barebox.srec barebox.s5p barebox.ubl \ - barebox.uimage + barebox.uimage barebox.spi # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config include2 usr/include diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a54ad03445..7b7b0585ae 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -58,6 +58,7 @@ config ARCH_NOMADIK config ARCH_OMAP bool "TI OMAP" select HAS_DEBUG_LL + select GPIOLIB config ARCH_PXA bool "Intel/Marvell PXA based" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 208f0f401c..855043aedf 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -217,6 +217,17 @@ KBUILD_TARGET := barebox.ubl KBUILD_IMAGE := barebox.ubl endif +quiet_cmd_am35xx_spi_image = SPI-IMG $@ + cmd_am35xx_spi_image = scripts/mk-am35xx-spi-image $< > $@ + +barebox.spi: $(KBUILD_BINARY) FORCE + $(call if_changed,am35xx_spi_image) + +ifeq ($(CONFIG_OMAP_BUILD_SPI),y) +KBUILD_TARGET := barebox.spi +KBUILD_IMAGE := barebox.spi +endif + pbl := arch/arm/pbl zbarebox.S zbarebox.bin zbarebox: barebox.bin $(Q)$(MAKE) $(build)=$(pbl) $(pbl)/$@ diff --git a/arch/arm/boards/pcm049/board.c b/arch/arm/boards/pcm049/board.c index 3ef38a7831..3b10d0a649 100644 --- a/arch/arm/boards/pcm049/board.c +++ b/arch/arm/boards/pcm049/board.c @@ -118,9 +118,9 @@ static int pcm049_devices_init(void) #ifdef CONFIG_PARTITION devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "xload_raw"); dev_add_bb_dev("xload_raw", "xload"); - devfs_add_partition("nand0", SZ_128K, SZ_256K, DEVFS_PARTITION_FIXED, "self_raw"); + devfs_add_partition("nand0", SZ_128K, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); - devfs_add_partition("nand0", SZ_128K + SZ_256K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); + devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); #endif diff --git a/arch/arm/boards/pcm049/env/config b/arch/arm/boards/pcm049/env/config index fc64215e5e..0ae3e1bc3c 100644 --- a/arch/arm/boards/pcm049/env/config +++ b/arch/arm/boards/pcm049/env/config @@ -40,7 +40,7 @@ autoboot_timeout=3 bootargs="console=ttyO2,115200" -nand_parts="128k(xload)ro,256k(barebox),128k(bareboxenv),2M(kernel),-(root)" +nand_parts="128k(xload)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)" rootfs_mtdblock_nand=4 # set a fancy prompt (if support is compiled in) diff --git a/arch/arm/boards/phycard-a-l1/env/config b/arch/arm/boards/phycard-a-l1/env/config index 90b2c24781..6de97ed5d5 100644 --- a/arch/arm/boards/phycard-a-l1/env/config +++ b/arch/arm/boards/phycard-a-l1/env/config @@ -70,7 +70,7 @@ bootargs="$bootargs omapdss.def_disp=pd050vl1" #bootargs="$bootargs omapdss.def_disp=pd104slf" #bootargs="$bootargs omapdss.def_disp=pm070wl4" -nand_parts="512k(x-loader)ro,1920k(barebox),128k(bareboxenv),4M(kernel),-(root)" +nand_parts="128k(x-loader)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)" nand_device=omap2-nand.0 rootfs_mtdblock_nand=4 diff --git a/arch/arm/boards/phycard-a-l1/pca-a-l1.c b/arch/arm/boards/phycard-a-l1/pca-a-l1.c index 907198d783..a08518f8d0 100644 --- a/arch/arm/boards/phycard-a-l1/pca-a-l1.c +++ b/arch/arm/boards/phycard-a-l1/pca-a-l1.c @@ -422,13 +422,13 @@ device_initcall(pcaal1_init_devices); static int pcaal1_late_init(void) { #ifdef CONFIG_PARTITION - devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "x-loader"); + devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "x-loader"); dev_add_bb_dev("self_raw", "x_loader0"); - devfs_add_partition("nand0", 0x80000, 0x1e0000, DEVFS_PARTITION_FIXED, "self_raw"); + devfs_add_partition("nand0", SZ_128K, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); - devfs_add_partition("nand0", 0x260000, 0x20000, DEVFS_PARTITION_FIXED, "env_raw"); + devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); #endif return 0; diff --git a/arch/arm/boards/phycard-a-xl2/env/config b/arch/arm/boards/phycard-a-xl2/env/config index 532f2907f9..349a51fb43 100644 --- a/arch/arm/boards/phycard-a-xl2/env/config +++ b/arch/arm/boards/phycard-a-xl2/env/config @@ -39,7 +39,7 @@ autoboot_timeout=3 bootargs="console=ttyO2,115200" -nand_parts="128k(xload)ro,256k(barebox),128k(bareboxenv),4M(kernel),-(root)" +nand_parts="128k(xload)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)" rootfs_mtdblock_nand=4 # set a fancy prompt (if support is compiled in) diff --git a/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c b/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c index 4fec0f0e41..91d45dcc1b 100644 --- a/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c +++ b/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c @@ -136,10 +136,10 @@ static int pcaaxl2_devices_init(void) devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "xload_raw"); dev_add_bb_dev("xload_raw", "xload"); - devfs_add_partition("nand0", SZ_128K, SZ_256K, + devfs_add_partition("nand0", SZ_128K, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); - devfs_add_partition("nand0", SZ_128K + SZ_256K, SZ_128K, + devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); #endif diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index d735284a11..98750c4eb2 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -52,20 +52,7 @@ config ARCH_OMAP4 endchoice -### Generic Clock configurations to be enabled by Mach - invisible to enable. -config OMAP_CLOCK_UART - bool -config OMAP_CLOCK_UART2 - bool -config OMAP_CLOCK_UART3 - bool -config OMAP_CLOCK_I2C - bool - # Blind enable all possible clocks.. think twice before you do this. -config OMAP_CLOCK_ALL - bool - config OMAP_CLOCK_SOURCE_S32K bool @@ -91,6 +78,13 @@ config OMAP_BUILD_IFT prompt "build ift binary" bool +config OMAP_BUILD_SPI + prompt "build SPI binary" + bool + help + Say Y here if you want to build an barebox.spi image as used + on the AM35xx chips when booting form SPI NOR flash. + config ARCH_TEXT_BASE hex default 0x80e80000 if MACH_OMAP343xSDP @@ -110,14 +104,12 @@ choice config MACH_OMAP343xSDP bool "Texas Instrument's SDP343x" - select OMAP_CLOCK_ALL depends on ARCH_OMAP3 help Say Y here if you are using SDP343x platform config MACH_BEAGLE bool "Texas Instrument's Beagle Board" - select OMAP_CLOCK_ALL select HAVE_NOSHELL depends on ARCH_OMAP3 help @@ -125,7 +117,6 @@ config MACH_BEAGLE config MACH_OMAP3EVM bool "Texas Instrument's OMAP3 EVM" - select OMAP_CLOCK_ALL select HAVE_NOSHELL depends on ARCH_OMAP3 help @@ -150,7 +141,6 @@ config MACH_PCM049 config MACH_PCAAL1 bool "Phytec phyCARD-A-L1" - select OMAP_CLOCK_ALL select HAVE_NOSHELL depends on ARCH_OMAP3 help diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c index 142cf524eb..d16d6d9aab 100644 --- a/arch/arm/mach-omap/gpio.c +++ b/arch/arm/mach-omap/gpio.c @@ -36,11 +36,10 @@ * published by the Free Software Foundation. */ #include <common.h> -#include <mach/gpio.h> #include <io.h> #include <errno.h> - -#ifdef CONFIG_ARCH_OMAP3 +#include <gpio.h> +#include <init.h> #define OMAP_GPIO_OE 0x0034 #define OMAP_GPIO_DATAIN 0x0038 @@ -48,129 +47,115 @@ #define OMAP_GPIO_CLEARDATAOUT 0x0090 #define OMAP_GPIO_SETDATAOUT 0x0094 -static void __iomem *gpio_bank[] = { - (void *)0x48310000, - (void *)0x49050000, - (void *)0x49052000, - (void *)0x49054000, - (void *)0x49056000, - (void *)0x49058000, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP4 - -#define OMAP_GPIO_OE 0x0134 -#define OMAP_GPIO_DATAIN 0x0138 -#define OMAP_GPIO_DATAOUT 0x013c -#define OMAP_GPIO_CLEARDATAOUT 0x0190 -#define OMAP_GPIO_SETDATAOUT 0x0194 - -static void __iomem *gpio_bank[] = { - (void *)0x4a310000, - (void *)0x48055000, - (void *)0x48057000, - (void *)0x48059000, - (void *)0x4805b000, - (void *)0x4805d000, +struct omap_gpio_chip { + void __iomem *base; + struct gpio_chip chip; }; -#endif - -static inline void __iomem *get_gpio_base(int gpio) -{ - return gpio_bank[gpio >> 5]; -} -static inline int get_gpio_index(int gpio) +static inline int omap_get_gpio_index(int gpio) { return gpio & 0x1f; } -static inline int gpio_valid(int gpio) +static void omap_gpio_set_value(struct gpio_chip *chip, + unsigned gpio, int value) { - if (gpio < 0) - return -1; - if (gpio / 32 < ARRAY_SIZE(gpio_bank)) - return 0; - return -1; -} - -static int check_gpio(int gpio) -{ - if (gpio_valid(gpio) < 0) { - printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); - return -1; - } - return 0; -} - -void gpio_set_value(unsigned gpio, int value) -{ - void __iomem *reg; + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; u32 l = 0; - if (check_gpio(gpio) < 0) - return; - - reg = get_gpio_base(gpio); - if (value) - reg += OMAP_GPIO_SETDATAOUT; + base += OMAP_GPIO_SETDATAOUT; else - reg += OMAP_GPIO_CLEARDATAOUT; - l = 1 << get_gpio_index(gpio); + base += OMAP_GPIO_CLEARDATAOUT; + + l = 1 << omap_get_gpio_index(gpio); - __raw_writel(l, reg); + writel(l, base); } -int gpio_direction_input(unsigned gpio) +static int omap_gpio_direction_input(struct gpio_chip *chip, + unsigned gpio) { - void __iomem *reg; + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; u32 val; - if (check_gpio(gpio) < 0) - return -EINVAL; - - reg = get_gpio_base(gpio); - - reg += OMAP_GPIO_OE; + base += OMAP_GPIO_OE; - val = __raw_readl(reg); - val |= 1 << get_gpio_index(gpio); - __raw_writel(val, reg); + val = readl(base); + val |= 1 << omap_get_gpio_index(gpio); + writel(val, base); return 0; } -int gpio_direction_output(unsigned gpio, int value) +static int omap_gpio_direction_output(struct gpio_chip *chip, + unsigned gpio, int value) { - void __iomem *reg; + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; u32 val; - if (check_gpio(gpio) < 0) - return -EINVAL; - reg = get_gpio_base(gpio); + omap_gpio_set_value(chip, gpio, value); - gpio_set_value(gpio, value); + base += OMAP_GPIO_OE; - reg += OMAP_GPIO_OE; - - val = __raw_readl(reg); - val &= ~(1 << get_gpio_index(gpio)); - __raw_writel(val, reg); + val = readl(base); + val &= ~(1 << omap_get_gpio_index(gpio)); + writel(val, base); return 0; } -int gpio_get_value(unsigned gpio) +static int omap_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct omap_gpio_chip *omapgpio = + container_of(chip, struct omap_gpio_chip, chip); + void __iomem *base = omapgpio->base; + + base += OMAP_GPIO_DATAIN; + + return (readl(base) & (1 << omap_get_gpio_index(gpio))) != 0; + +} + +static struct gpio_ops omap_gpio_ops = { + .direction_input = omap_gpio_direction_input, + .direction_output = omap_gpio_direction_output, + .get = omap_gpio_get_value, + .set = omap_gpio_set_value, +}; + +static int omap_gpio_probe(struct device_d *dev) { - void __iomem *reg; + struct omap_gpio_chip *omapgpio; + + omapgpio = xzalloc(sizeof(*omapgpio)); + omapgpio->base = dev_request_mem_region(dev, 0); + omapgpio->chip.ops = &omap_gpio_ops; + omapgpio->chip.base = -1; + omapgpio->chip.ngpio = 32; + omapgpio->chip.dev = dev; + gpiochip_add(&omapgpio->chip); - if (check_gpio(gpio) < 0) - return -EINVAL; - reg = get_gpio_base(gpio); + dev_dbg(dev, "probed gpiochip%d with base %d\n", + dev->id, omapgpio->chip.base); + + return 0; +} - reg += OMAP_GPIO_DATAIN; +static struct driver_d omap_gpio_driver = { + .name = "omap-gpio", + .probe = omap_gpio_probe, +}; - return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; +static int omap_gpio_add(void) +{ + register_driver(&omap_gpio_driver); + return 0; } +coredevice_initcall(omap_gpio_add); diff --git a/arch/arm/mach-omap/include/mach/xload.h b/arch/arm/mach-omap/include/mach/xload.h index 844b57f0e5..63b68df15c 100644 --- a/arch/arm/mach-omap/include/mach/xload.h +++ b/arch/arm/mach-omap/include/mach/xload.h @@ -1,13 +1,11 @@ #ifndef _MACH_XLOAD_H #define _MACH_XLOAD_H -void *omap_xload_boot_nand(int offset, int size); -void *omap_xload_boot_mmc(void); - enum omap_boot_src { OMAP_BOOTSRC_UNKNOWN, OMAP_BOOTSRC_MMC1, OMAP_BOOTSRC_NAND, + OMAP_BOOTSRC_SPI1, }; enum omap_boot_src omap3_bootsrc(void); diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c index 646235e4c2..463633a53d 100644 --- a/arch/arm/mach-omap/omap3_clock.c +++ b/arch/arm/mach-omap/omap3_clock.c @@ -674,18 +674,6 @@ static void per_clocks_enable(void) /* Enable the ICLK for 32K Sync Timer as its used in udelay */ sr32(CM_REG(ICLKEN_WKUP), 2, 1, 0x1); -#ifdef CONFIG_OMAP_CLOCK_UART - /* Enable UART1 clocks */ - sr32(CM_REG(FCLKEN1_CORE), 13, 1, 0x1); - sr32(CM_REG(ICLKEN1_CORE), 13, 1, 0x1); -#endif -#ifdef CONFIG_OMAP_CLOCK_I2C - /* Turn on all 3 I2C clocks */ - sr32(CM_REG(FCLKEN1_CORE), 15, 3, 0x7); - sr32(CM_REG(ICLKEN1_CORE), 15, 3, 0x7); /* I2C1,2,3 = on */ -#endif - -#ifdef CONFIG_OMAP_CLOCK_ALL #define FCK_IVA2_ON 0x00000001 #define FCK_CORE1_ON 0x03fffe29 #define ICK_CORE1_ON 0x3ffffffb @@ -710,7 +698,7 @@ static void per_clocks_enable(void) sr32(CM_REG(ICLKEN_CAM), 0, 32, ICK_CAM_ON); sr32(CM_REG(FCLKEN_PER), 0, 32, FCK_PER_ON); sr32(CM_REG(ICLKEN_PER), 0, 32, ICK_PER_ON); -#endif + /* Settle down my friend */ sdelay(1000); } diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c index 4ab265a9ba..0e9cd7162c 100644 --- a/arch/arm/mach-omap/omap3_generic.c +++ b/arch/arm/mach-omap/omap3_generic.c @@ -515,3 +515,22 @@ const struct gpmc_config omap3_nand_cfg = { .base = 0x28000000, .size = GPMC_SIZE_16M, }; + +static int omap3_gpio_init(void) +{ + add_generic_device("omap-gpio", 0, NULL, 0x48310000, + 0x100, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 1, NULL, 0x49050000, + 0x100, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 2, NULL, 0x49052000, + 0x100, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 3, NULL, 0x49054000, + 0x100, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 4, NULL, 0x49056000, + 0x100, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 5, NULL, 0x49058000, + 0x100, IORESOURCE_MEM, NULL); + + return 0; +} +coredevice_initcall(omap3_gpio_init); diff --git a/arch/arm/mach-omap/omap4_generic.c b/arch/arm/mach-omap/omap4_generic.c index 617d786984..a159dfcb7e 100644 --- a/arch/arm/mach-omap/omap4_generic.c +++ b/arch/arm/mach-omap/omap4_generic.c @@ -572,3 +572,22 @@ const struct gpmc_config omap4_nand_cfg = { .base = 0x28000000, .size = GPMC_SIZE_16M, }; + +static int omap4_gpio_init(void) +{ + add_generic_device("omap-gpio", 0, NULL, 0x4a310100, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 1, NULL, 0x48055100, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 2, NULL, 0x48057100, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 3, NULL, 0x48059100, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 4, NULL, 0x4805b100, + 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("omap-gpio", 5, NULL, 0x4805d100, + 0x1000, IORESOURCE_MEM, NULL); + + return 0; +} +coredevice_initcall(omap4_gpio_init); diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c index 13024abac7..9fa8221ec9 100644 --- a/arch/arm/mach-omap/xload.c +++ b/arch/arm/mach-omap/xload.c @@ -7,16 +7,65 @@ #include <fcntl.h> #include <mach/xload.h> #include <sizes.h> +#include <filetype.h> -void *omap_xload_boot_nand(int offset, int size) +static void *read_image_head(const char *name) { + void *header = xmalloc(ARM_HEAD_SIZE); + struct cdev *cdev; int ret; - void *to = xmalloc(size); + + cdev = cdev_open(name, O_RDONLY); + if (!cdev) { + printf("failed to open partition\n"); + return NULL; + } + + ret = cdev_read(cdev, header, ARM_HEAD_SIZE, 0, 0); + cdev_close(cdev); + + if (ret != ARM_HEAD_SIZE) { + printf("failed to read from partition\n"); + return NULL; + } + + return header; +} + +static unsigned int get_image_size(void *head) +{ + unsigned int ret = 0; + unsigned int *psize = head + ARM_HEAD_SIZE_OFFSET; + + if (is_barebox_arm_head(head)) + ret = *psize; + debug("Detected barebox image size %u\n", ret); + + return ret; +} + +static void *omap_xload_boot_nand(int offset) +{ + int ret; + int size; + void *to, *header; struct cdev *cdev; - devfs_add_partition("nand0", offset, size, DEVFS_PARTITION_FIXED, "x"); + devfs_add_partition("nand0", offset, SZ_1M, DEVFS_PARTITION_FIXED, "x"); dev_add_bb_dev("x", "bbx"); + header = read_image_head("bbx"); + if (header == NULL) + return NULL; + + size = get_image_size(header); + if (!size) { + printf("failed to get image size\n"); + return NULL; + } + + to = xmalloc(size); + cdev = cdev_open("bbx", O_RDONLY); if (!cdev) { printf("failed to open nand\n"); @@ -32,7 +81,7 @@ void *omap_xload_boot_nand(int offset, int size) return to; } -void *omap_xload_boot_mmc(void) +static void *omap_xload_boot_mmc(void) { int ret; void *buf; @@ -54,6 +103,42 @@ void *omap_xload_boot_mmc(void) return buf; } +static void *omap_xload_boot_spi(int offset) +{ + int ret; + int size; + void *to, *header; + struct cdev *cdev; + + devfs_add_partition("m25p0", offset, SZ_1M, DEVFS_PARTITION_FIXED, "x"); + + header = read_image_head("x"); + if (header == NULL) + return NULL; + + size = get_image_size(header); + if (!size) { + printf("failed to get image size\n"); + return NULL; + } + + to = xmalloc(size); + + cdev = cdev_open("x", O_RDONLY); + if (!cdev) { + printf("failed to open spi flash\n"); + return NULL; + } + + ret = cdev_read(cdev, to, size, 0, 0); + if (ret != size) { + printf("failed to read from spi flash\n"); + return NULL; + } + + return to; +} + enum omap_boot_src omap_bootsrc(void) { #if defined(CONFIG_ARCH_OMAP3) @@ -80,7 +165,11 @@ int run_shell(void) printf("unknown boot source. Fall back to nand\n"); case OMAP_BOOTSRC_NAND: printf("booting from NAND\n"); - func = omap_xload_boot_nand(SZ_128K, SZ_256K); + func = omap_xload_boot_nand(SZ_128K); + break; + case OMAP_BOOTSRC_SPI1: + printf("booting from SPI1\n"); + func = omap_xload_boot_spi(SZ_128K); break; } diff --git a/common/filetype.c b/common/filetype.c index 6a0dcfb760..3d544cd6ce 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -102,7 +102,7 @@ enum filetype file_detect_type(void *_buf) if (strncmp(buf8, "#!/bin/sh", 9) == 0) return filetype_sh; - if (buf[8] == 0x65726162 && buf[9] == 0x00786f62) + if (is_barebox_arm_head(_buf)) return filetype_arm_barebox; if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01) return filetype_arm_zimage; diff --git a/include/filetype.h b/include/filetype.h index 37eb62020d..209dc11a3d 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -27,4 +27,20 @@ enum filetype file_detect_type(void *_buf); enum filetype file_name_detect_type(const char *filename); enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec); +#define ARM_HEAD_SIZE 0x30 +#define ARM_HEAD_MAGICWORD_OFFSET 0x20 +#define ARM_HEAD_SIZE_OFFSET 0x2C + +#ifdef CONFIG_ARM +static inline int is_barebox_arm_head(const char *head) +{ + return !strcmp(head + ARM_HEAD_MAGICWORD_OFFSET, "barebox"); +} +#else +static inline int is_barebox_arm_head(const char *head) +{ + return 0; +} +#endif + #endif /* __FILE_TYPE_H */ diff --git a/scripts/.gitignore b/scripts/.gitignore index 6e63f85792..3f1cbdb912 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -2,6 +2,7 @@ bareboxenv bin2c gen_netx_image kallsyms +mk-am35xx-spi-image mkimage mkublheader omap_signGP diff --git a/scripts/Makefile b/scripts/Makefile index 7ca5e2973d..55ccdac539 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -9,7 +9,7 @@ hostprogs-y += bin2c hostprogs-y += mkimage hostprogs-y += bareboxenv hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image -hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP +hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-am35xx-spi-image hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader diff --git a/scripts/mk-am35xx-spi-image.c b/scripts/mk-am35xx-spi-image.c new file mode 100644 index 0000000000..ec311fdd4d --- /dev/null +++ b/scripts/mk-am35xx-spi-image.c @@ -0,0 +1,141 @@ +/* + * mk-am35xx-spi-image.c - convert a barebox image for SPI loading on AM35xx + * + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/** + * @file + * @brief convert a barebox image for SPI loading on AM35xx + * + * FileName: scripts/mk-am35xx-spi-image.c + * + * Booting from SPI on an AM35xx (and possibly other TI SOCs) requires + * a special format: + * + * - 32 bit image size in big-endian + * - 32 bit load address in big-endian + * - binary image converted from little- to big-endian + * + * This tool converts barebox.bin to the required format. + */ + +#define _BSD_SOURCE + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdint.h> +#include <limits.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <endian.h> + +void usage(char *prgname) +{ + printf("usage: %s [OPTION] FILE > IMAGE\n" + "\n" + "options:\n" + " -a <address> memory address for the loaded image in SRAM\n", + prgname); +} + +int main(int argc, char *argv[]) +{ + FILE *input; + int opt; + off_t pos; + size_t size; + uint32_t addr = 0x40200000; + uint32_t temp; + + while((opt = getopt(argc, argv, "a:")) != -1) { + switch (opt) { + case 'a': + addr = strtoul(optarg, NULL, 0); + break; + } + } + + if (optind >= argc) { + usage(argv[0]); + exit(1); + } + + input = fopen(argv[optind], "r"); + if (input == NULL) { + perror("fopen"); + exit(EXIT_FAILURE); + } + + if (fseeko(input, 0, SEEK_END) == -1) { + perror("fseeko"); + exit(EXIT_FAILURE); + } + + pos = ftello(input); + if (pos == -1) { + perror("ftello"); + exit(EXIT_FAILURE); + } + if (pos % 4) { + printf("error: image size must be a multiple of 4 bytes\n"); + exit(EXIT_FAILURE); + } + if (pos > 0x100000) { + printf("error: image should be smaller than 1 MiB\n"); + exit(EXIT_FAILURE); + } + + if (fseeko(input, 0, SEEK_SET) == -1) { + perror("fseeko"); + exit(EXIT_FAILURE); + } + + /* image size */ + temp = htobe32((uint32_t)pos); + fwrite(&temp, sizeof(uint32_t), 1, stdout); + + /* memory address */ + temp = htobe32(addr); + fwrite(&temp, sizeof(uint32_t), 1, stdout); + + for (;;) { + size = fread(&temp, 1, sizeof(uint32_t), input); + if (!size) + break; + if (size != 4) { + perror("fread"); + exit(EXIT_FAILURE); + } + temp = htobe32(le32toh(temp)); + if (fwrite(&temp, 1, sizeof(uint32_t), stdout) != 4) { + perror("fwrite"); + exit(EXIT_FAILURE); + } + } + + if (fclose(input) != 0) { + perror("fclose"); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} |