Commit 50827a5991bb345319bd0ce76f5e2402fac0c391

Authored by Ian Campbell
Committed by Albert ARIBAUD
1 parent e24ea55c04

sunxi: non-FEL SPL boot support for sun7i

Add support for booting from an MMC card.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Henrik Nordström <henrik@henriknordstrom.net>
Signed-off-by: Ian Campbell <ijc@hellion.org.uk>
Reviewed-by: Marek Vasut <marex@denx.de>
Cc: Tom Cubie <Mr.hipboi@gmail.com>
Reviewed-by: Tom Rini <trini@ti.com>

Showing 9 changed files with 255 additions and 0 deletions Side-by-side Diff

... ... @@ -937,6 +937,13 @@
937 937 u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE
938 938 $(call if_changed,pad_cat)
939 939  
  940 +ifneq ($(CONFIG_SUNXI),)
  941 +OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \
  942 + --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
  943 +u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE
  944 + $(call if_changed,pad_cat)
  945 +endif
  946 +
940 947 ifneq ($(CONFIG_TEGRA),)
941 948 OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
942 949 u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
... ... @@ -1162,6 +1169,9 @@
1162 1169 @:
1163 1170 spl/u-boot-spl: tools prepare
1164 1171 $(Q)$(MAKE) obj=spl -f $(srctree)/spl/Makefile all
  1172 +
  1173 +spl/sunxi-spl.bin: spl/u-boot-spl
  1174 + @:
1165 1175  
1166 1176 tpl/u-boot-tpl.bin: tools prepare
1167 1177 $(Q)$(MAKE) obj=tpl -f $(srctree)/spl/Makefile all CONFIG_TPL_BUILD=y
arch/arm/cpu/armv7/sunxi/config.mk
  1 +# Build a combined spl + u-boot image
  2 +ifdef CONFIG_SPL
  3 +ifndef CONFIG_SPL_BUILD
  4 +ifndef CONFIG_SPL_FEL
  5 +ALL-y += u-boot-sunxi-with-spl.bin
  6 +endif
  7 +endif
  8 +endif
arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
  1 +/*
  2 + * (C) Copyright 2012
  3 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  4 + * Tom Cubie <tangliang@allwinnertech.com>
  5 + *
  6 + * Based on omap-common/u-boot-spl.lds:
  7 + *
  8 + * (C) Copyright 2002
  9 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
  10 + *
  11 + * (C) Copyright 2010
  12 + * Texas Instruments, <www.ti.com>
  13 + * Aneesh V <aneesh@ti.com>
  14 + *
  15 + * SPDX-License-Identifier: GPL-2.0+
  16 + */
  17 +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
  18 + LENGTH = CONFIG_SPL_MAX_SIZE }
  19 +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
  20 + LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
  21 +
  22 +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  23 +OUTPUT_ARCH(arm)
  24 +ENTRY(_start)
  25 +SECTIONS
  26 +{
  27 + .text :
  28 + {
  29 + __start = .;
  30 + arch/arm/cpu/armv7/start.o (.text)
  31 + *(.text*)
  32 + } > .sram
  33 +
  34 + . = ALIGN(4);
  35 + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
  36 +
  37 + . = ALIGN(4);
  38 + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
  39 +
  40 + . = ALIGN(4);
  41 + __image_copy_end = .;
  42 + _end = .;
  43 +
  44 + .bss :
  45 + {
  46 + . = ALIGN(4);
  47 + __bss_start = .;
  48 + *(.bss*)
  49 + . = ALIGN(4);
  50 + __bss_end = .;
  51 + } > .sdram
  52 +}
... ... @@ -379,6 +379,7 @@
379 379 Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak <p.marczak@samsung.com>
380 380 Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang <mk7.kang@samsung.com>
381 381 Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - -
  382 +Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII -
382 383 Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII -
383 384 Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poirier@linaro.org>
384 385 Active arm armv7 u8500 st-ericsson u8500 u8500_href - -
include/configs/sunxi-common.h
... ... @@ -17,6 +17,11 @@
17 17 * High Level Configuration Options
18 18 */
19 19 #define CONFIG_SUNXI /* sunxi family */
  20 +#ifdef CONFIG_SPL_BUILD
  21 +#ifndef CONFIG_SPL_FEL
  22 +#define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */
  23 +#endif
  24 +#endif
20 25  
21 26 #include <asm/arch/cpu.h> /* get chip and board defs */
22 27  
23 28  
... ... @@ -121,11 +126,32 @@
121 126 #define CONFIG_SPL_SERIAL_SUPPORT
122 127 #define CONFIG_SPL_LIBGENERIC_SUPPORT
123 128  
  129 +#ifdef CONFIG_SPL_FEL
  130 +
124 131 #define CONFIG_SPL
125 132 #define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
126 133 #define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
127 134 #define CONFIG_SPL_TEXT_BASE 0x2000
128 135 #define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
  136 +
  137 +#else /* CONFIG_SPL */
  138 +
  139 +#define CONFIG_SPL_BSS_START_ADDR 0x4ff80000
  140 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KiB */
  141 +
  142 +#define CONFIG_SPL_TEXT_BASE 0x20 /* sram start+header */
  143 +#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* 24KB on sun4i/sun7i */
  144 +
  145 +#define CONFIG_SPL_LIBDISK_SUPPORT
  146 +#define CONFIG_SPL_MMC_SUPPORT
  147 +
  148 +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds"
  149 +
  150 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 80 /* 40KiB */
  151 +#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */
  152 +
  153 +#endif /* CONFIG_SPL */
  154 +
129 155 /* end of 32 KiB in sram */
130 156 #define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */
131 157 #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
... ... @@ -189,6 +189,12 @@
189 189 ALL-y += $(obj)/$(BOARD)-spl.bin
190 190 endif
191 191  
  192 +ifdef CONFIG_SUNXI
  193 +ifndef CONFIG_SPL_FEL
  194 +ALL-y += $(obj)/sunxi-spl.bin
  195 +endif
  196 +endif
  197 +
192 198 all: $(ALL-y)
193 199  
194 200 ifdef CONFIG_SAMSUNG
... ... @@ -214,6 +220,13 @@
214 220 LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL)
215 221 ifneq ($(CONFIG_SPL_TEXT_BASE),)
216 222 LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE)
  223 +endif
  224 +
  225 +ifdef CONFIG_SUNXI
  226 +quiet_cmd_mksunxiboot = MKSUNXI $@
  227 +cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@
  228 +$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin
  229 + $(call if_changed,mksunxiboot)
217 230 endif
218 231  
219 232 quiet_cmd_u-boot-spl = LD $@
... ... @@ -11,6 +11,7 @@
11 11 /mkexynosspl
12 12 /mpc86x_clk
13 13 /mxsboot
  14 +/mksunxiboot
14 15 /ncb
15 16 /proftool
16 17 /relocate-rela
... ... @@ -131,6 +131,8 @@
131 131 hostprogs-$(CONFIG_MX28) += mxsboot$(SFX)
132 132 HOSTCFLAGS_mxsboot$(SFX).o := -pedantic
133 133  
  134 +hostprogs-$(CONFIG_SUNXI) += mksunxiboot$(SFX)
  135 +
134 136 hostprogs-$(CONFIG_NETCONSOLE) += ncb$(SFX)
135 137 hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
136 138  
  1 +/*
  2 + * (C) Copyright 2007-2011
  3 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  4 + * Tom Cubie <tangliang@allwinnertech.com>
  5 + *
  6 + * a simple tool to generate bootable image for sunxi platform.
  7 + *
  8 + * SPDX-License-Identifier: GPL-2.0+
  9 + */
  10 +#include <fcntl.h>
  11 +#include <stdio.h>
  12 +#include <unistd.h>
  13 +#include <stdlib.h>
  14 +#include <string.h>
  15 +#include <errno.h>
  16 +#include <sys/types.h>
  17 +#include <sys/stat.h>
  18 +
  19 +/* boot head definition from sun4i boot code */
  20 +struct boot_file_head {
  21 + uint32_t b_instruction; /* one intruction jumping to real code */
  22 + uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
  23 + uint32_t check_sum; /* generated by PC */
  24 + uint32_t length; /* generated by PC */
  25 + /*
  26 + * We use a simplified header, only filling in what is needed
  27 + * by the boot ROM. To be compatible with Allwinner tools we
  28 + * would need to implement the proper fields here instead of
  29 + * padding.
  30 + */
  31 + uint8_t pad[12]; /* align to 32 bytes */
  32 +};
  33 +
  34 +#define BOOT0_MAGIC "eGON.BT0"
  35 +#define STAMP_VALUE 0x5F0A6C39
  36 +
  37 +/* check sum functon from sun4i boot code */
  38 +int gen_check_sum(struct boot_file_head *head_p)
  39 +{
  40 + uint32_t length;
  41 + uint32_t *buf;
  42 + uint32_t loop;
  43 + uint32_t i;
  44 + uint32_t sum;
  45 +
  46 + length = head_p->length;
  47 + if ((length & 0x3) != 0) /* must 4-byte-aligned */
  48 + return -1;
  49 + buf = (uint32_t *)head_p;
  50 + head_p->check_sum = STAMP_VALUE; /* fill stamp */
  51 + loop = length >> 2;
  52 +
  53 + /* calculate the sum */
  54 + for (i = 0, sum = 0; i < loop; i++)
  55 + sum += buf[i];
  56 +
  57 + /* write back check sum */
  58 + head_p->check_sum = sum;
  59 +
  60 + return 0;
  61 +}
  62 +
  63 +#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
  64 +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
  65 +
  66 +#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */
  67 +#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head))
  68 +#define BLOCK_SIZE 512
  69 +
  70 +struct boot_img {
  71 + struct boot_file_head header;
  72 + char code[SRAM_LOAD_MAX_SIZE];
  73 + char pad[BLOCK_SIZE];
  74 +};
  75 +
  76 +int main(int argc, char *argv[])
  77 +{
  78 + int fd_in, fd_out;
  79 + struct boot_img img;
  80 + unsigned file_size, load_size;
  81 + int count;
  82 +
  83 + if (argc < 2) {
  84 + printf("\tThis program makes an input bin file to sun4i " \
  85 + "bootable image.\n" \
  86 + "\tUsage: %s input_file out_putfile\n", argv[0]);
  87 + return EXIT_FAILURE;
  88 + }
  89 +
  90 + fd_in = open(argv[1], O_RDONLY);
  91 + if (fd_in < 0) {
  92 + perror("Open input file");
  93 + return EXIT_FAILURE;
  94 + }
  95 +
  96 + memset(img.pad, 0, BLOCK_SIZE);
  97 +
  98 + /* get input file size */
  99 + file_size = lseek(fd_in, 0, SEEK_END);
  100 +
  101 + if (file_size > SRAM_LOAD_MAX_SIZE) {
  102 + fprintf(stderr, "ERROR: File too large!\n");
  103 + return EXIT_FAILURE;
  104 + } else {
  105 + load_size = ALIGN(file_size, sizeof(int));
  106 + }
  107 +
  108 + fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666);
  109 + if (fd_out < 0) {
  110 + perror("Open output file");
  111 + return EXIT_FAILURE;
  112 + }
  113 +
  114 + /* read file to buffer to calculate checksum */
  115 + lseek(fd_in, 0, SEEK_SET);
  116 + count = read(fd_in, img.code, load_size);
  117 + if (count != load_size) {
  118 + perror("Reading input image");
  119 + return EXIT_FAILURE;
  120 + }
  121 +
  122 + /* fill the header */
  123 + img.header.b_instruction = /* b instruction */
  124 + 0xEA000000 | /* jump to the first instr after the header */
  125 + ((sizeof(struct boot_file_head) / sizeof(int) - 2)
  126 + & 0x00FFFFFF);
  127 + memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */
  128 + img.header.length =
  129 + ALIGN(load_size + sizeof(struct boot_file_head), BLOCK_SIZE);
  130 + gen_check_sum(&img.header);
  131 +
  132 + count = write(fd_out, &img, img.header.length);
  133 + if (count != img.header.length) {
  134 + perror("Writing output");
  135 + return EXIT_FAILURE;
  136 + }
  137 +
  138 + close(fd_in);
  139 + close(fd_out);
  140 +
  141 + return EXIT_SUCCESS;
  142 +}