[U-Boot] [PATCH 0/7] SPL Linux boot

This addds direct Linux boot to SPL. It implements a savebp command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
checkpatch whines about not using strict_strtoull - since this is not available I can't change this.
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (7): arm: Add Prep subcommand support to bootm Add savebp command arm: Add savebp implementation for arm omap-common/spl: Add linux boot to SPL devkit8000/spl: init GPMC for dm9000 in SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++++++---- arch/arm/include/asm/omap_common.h | 2 + arch/arm/include/asm/savebp.h | 27 ++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/bootm.c | 116 +++++++++++++++------------ arch/arm/lib/savebp.c | 92 +++++++++++++++++++++ board/timll/devkit8000/devkit8000.c | 33 ++++++-- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_savebp.c | 123 +++++++++++++++++++++++++++++ include/command.h | 5 + include/configs/devkit8000.h | 14 +++- 13 files changed, 446 insertions(+), 82 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c create mode 100644 common/cmd_savebp.c

Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/lib/bootm.c | 116 +++++++++++++++++++++++++++---------------------- common/cmd_bootm.c | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..d3152ae 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,7 @@ -/* +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * - Added prep subcommand support + * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger mgroeger@sysgo.de @@ -55,7 +58,7 @@ static struct tag *params;
static ulong get_sp(void); #if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag); #endif
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*kernel_entry)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params) = NULL;
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - s = getenv ("machid"); - if (s) { - machid = simple_strtoul (s, NULL, 16); - printf ("Using machid 0x%x from environment\n", machid); - } - - show_boot_progress (15); + if ((flag != 0) && (!(flag & BOOTM_STATE_OS_GO || + flag & BOOTM_STATE_OS_PREP))) + return 1; /* subcommand not implemented */ + else if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + s = getenv("machid"); + if (s) { + strict_strtoul(s, 16, (long unsigned int *) &machid); + printf("Using machid 0x%x from environment\n", machid); + } + + show_boot_progress(15);
#ifdef CONFIG_OF_LIBFDT - if (images->ft_len) - return bootm_linux_fdt(machid, images); + if (images->ft_len) + return bootm_linux_fdt(machid, images, flag); #endif
- kernel_entry = (void (*)(int, int, uint))images->ep; + kernel_entry = (void (*)(int, int, uint))images->ep;
- debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG) - setup_start_tag (bd); + setup_start_tag(bd); #ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); + setup_serial_tag(¶ms); #endif #ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); + setup_revision_tag(¶ms); #endif #ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); + setup_memory_tags(bd); #endif #ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); + setup_commandline_tag(bd, commandline); #endif #ifdef CONFIG_INITRD_TAG - if (images->rd_start && images->rd_end) - setup_initrd_tag (bd, images->rd_start, images->rd_end); + if (images->rd_start && images->rd_end) + setup_initrd_tag(bd, images->rd_start, images->rd_end); #endif - setup_end_tag(bd); + setup_end_tag(bd); #endif + if (flag & BOOTM_STATE_OS_PREP) + return 0; + }
- announce_and_cleanup(); - - kernel_entry(0, machid, bd->bi_boot_params); - /* does not return */ + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + } return 1; }
@@ -174,10 +181,10 @@ static int fixup_memory_node(void *blob) return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); }
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag) { ulong rd_len; - void (*kernel_entry)(int zero, int dt_machid, void *dtblob); + void (*kernel_entry)(int zero, int dt_machid, void *dtblob) = NULL; ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; @@ -185,34 +192,39 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) struct lmb *lmb = &images->lmb; int ret;
- kernel_entry = (void (*)(int, int, void *))images->ep; - - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + kernel_entry = (void (*)(int, int, void *))images->ep;
- rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, - initrd_start, initrd_end); - if (ret) - return ret; + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret;
- fdt_chosen(*of_flat_tree, 1); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
- fixup_memory_node(*of_flat_tree); + fdt_chosen(*of_flat_tree, 1);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + fixup_memory_node(*of_flat_tree);
- announce_and_cleanup(); + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- kernel_entry(0, machid, *of_flat_tree); - /* does not return */ + if (flag & BOOTM_STATE_OS_PREP) + return 0; + } + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, *of_flat_tree); + /* does not return */ + } return 1; } #endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

This adds a savebp command to the u-boot.
Related config: CONFIG_CMD_SAVEBP activate/deactivate the command CONFIG_CMD_SAVEBP_NAND_OFS Offset in NAND to use CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-begin + 0x100 Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- common/Makefile | 1 + common/cmd_savebp.c | 123 ++++++++++++++++++++++++++++++++++++++++++ include/configs/devkit8000.h | 6 ++ 3 files changed, 130 insertions(+), 0 deletions(-) create mode 100644 common/cmd_savebp.c
diff --git a/common/Makefile b/common/Makefile index 124a427..0b42968 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SAVEBP) += cmd_savebp.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c new file mode 100644 index 0000000..cc988fd --- /dev/null +++ b/common/cmd_savebp.c @@ -0,0 +1,123 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +#define TYPE_FDT 0 +#define TYPE_ATAGS 1 + +static inline int str2off(const char *p, loff_t *num) +{ + char *endptr; + + *num = simple_strtoull(p, &endptr, 16); + return *p != '\0' && *endptr == '\0'; +} + +int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + loff_t offset; + char *bootm_argsv[] = {"do_bootm", "xxxxxxx"}; + int img_type = TYPE_ATAGS; + int ret = 0; + + /* - Validate args - */ + switch (argc) { + case 3: /*2. arg offset */ + if (!str2off(argv[2], &offset)) { + printf("'%s' is not a number\n", argv[2]); + return cmd_usage(cmdtp); + } + case 2: /* 1. arg atags or fdt */ + if (!(strcmp(argv[1], "fdt") || strcmp(argv[1], "atags"))) + return cmd_usage(cmdtp); + if (!strcmp(argv[1], "fdt")) + img_type = TYPE_FDT; + /* using standard offset */ + offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS; + printf("using standard destination at: 0x%x\n", + (uint32_t)offset); + break; + default: + return cmd_usage(cmdtp); + } + + /* - do the work - */ + /* exec bootm_start as subcommand of do_bootm to init the images + * data structure */ + debug("exec bootm subcommand start\n"); + bootm_argsv[1] = "start"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand start bootm retcode: %d\n", ret); + + debug("exec bootm subcommand loados\n"); + bootm_argsv[1] = "loados"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand loados bootm retcode: %d\n", ret); + +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + debug("exec bootm subcommand ramdisk\n"); + bootm_argsv[1] = "ramdisk"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand ramdisk bootm retcode: %d\n", ret); +#endif + +#ifdef CONFIG_OF_LIBFDT + if (img_type == TYPE_FDT) { + debug("exec bootm subcommand fdt\n"); + bootm_argsv[1] = "fdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand fdt bootm retcode: %d\n", ret); + } +#endif + + debug("exec bootm subcommand cmdline\n"); + bootm_argsv[1] = "cmdline"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand cmdline bootm retcode: %d\n", ret); + + debug("exec bootm bdt cmdline\n"); + bootm_argsv[1] = "bdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand bdt bootm retcode: %d\n", ret); + + debug("exec bootm subcommand prep\n"); + bootm_argsv[1] = "prep"; + ret = do_bootm(find_cmd("do_bootm"), 0, 2, bootm_argsv); + debug("Subcommand prep bootm retcode: %d\n", ret); + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + /* call arch specific handlers */ + if (img_type == TYPE_FDT) + do_savebp_fdt(offset); + else + do_savebp_atags(offset); + + return 0; +} + +U_BOOT_CMD( + savebp, 3 , 1, do_savebp, "save boot params to NAND flash", + "[ftd|atags] [nand_offset] saves the parameter image to NAND. Kernel image has to be in RAM!"); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 9cbdb5d..80b441a 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -353,4 +353,10 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

This adds the savebp implementation to the arm platform.
Related CONFIGs: CONFIG_CMD_SAVEBP_WRITE_SIZE defines the size of the image to write
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/include/asm/savebp.h | 27 ++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/savebp.c | 92 +++++++++++++++++++++++++++++++++++++++++ include/command.h | 5 ++ include/configs/devkit8000.h | 1 + 5 files changed, 126 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c
diff --git a/arch/arm/include/asm/savebp.h b/arch/arm/include/asm/savebp.h new file mode 100644 index 0000000..3774e45 --- /dev/null +++ b/arch/arm/include/asm/savebp.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SAVEBP_H_ +#define _SAVEBP_H_ + +extern bootm_headers_t images; + +#endif /* _SAVEBP_H_ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..abf7a6a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,7 @@ COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o +COBJS-$(CONFIG_CMD_SAVEBP) += savebp.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif diff --git a/arch/arm/lib/savebp.c b/arch/arm/lib/savebp.c new file mode 100644 index 0000000..412f623 --- /dev/null +++ b/arch/arm/lib/savebp.c @@ -0,0 +1,92 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <image.h> + +#include <nand.h> +#include <asm/savebp.h> + +#ifdef CONFIG_OMAP34XX +#include <asm/arch/sys_proto.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* This function writes given bootparams to NAND flash + * adr: Start adress of Kernel parameter image (ATAGS, FDT) + * length: length of the image in byte + * off: offset in NAND flash + * + * borrowd heavily from common/cmd_nand.c + */ +static void boot_params_to_nand(u_char *adr, size_t length, loff_t off) +{ + nand_info_t *nand = &nand_info[0]; /* use 0 as in SPL */ + nand_erase_options_t opts; +#ifdef CONFIG_OMAP34XX + omap_nand_switch_ecc(1); /* use hw ecc on omap for SPL compat */ +#endif + /* erase */ + memset(&opts, 0, sizeof(opts)); + opts.offset = off; + opts.length = length; + opts.quiet = 1; + opts.spread = 1; + nand_erase_opts(nand, &opts); + + /* write */ + if (nand_write_skip_bad(nand, off, &length, adr, 0)) { + printf("FAILED!\n"); + return; + } + + printf("Written to offset 0x%llX, size: %d bytes\n", + off, length); +} + +/* Saves FDT to NAND */ +int do_savebp_fdt(loff_t offset) +{ + /* XXX: Problem address of FDT is needed here... */ + boot_params_to_nand((u_char *)images.ft_addr, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + return 0; +} + + +/* Saves ATAGS to NAND */ +int do_savebp_atags(loff_t offset) +{ + /* Vars */ + bd_t *bd = gd->bd; + + printf("write ATAGS to NAND...\n"); + + /* save em */ + /* used fixed size - easier to read later just ignore garbage */ + boot_params_to_nand((u_char *)bd->bi_boot_params, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + + return 0; +} diff --git a/include/command.h b/include/command.h index 8310fe5..3ae68a8 100644 --- a/include/command.h +++ b/include/command.h @@ -101,6 +101,11 @@ extern int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+#ifdef CONFIG_CMD_SAVEBP +int do_savebp_atags(loff_t offset); +int do_savebp_fdt(loff_t offset); +#endif + #endif /* __ASSEMBLY__ */
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 80b441a..4d0573c 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -355,6 +355,7 @@
/* SPL OS boot options */ #define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000

This adds Linux booting to the SPL
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_SPL_MACHID Machine ID of the used board CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl.c | 48 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 7 +++- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..9c22c7a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+#ifdef CONFIG_SPL_OS_BOOT +/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +int spl_uboot_key(void) +{ + int val = 0; + if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) { + omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1); + val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY); + omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif /* CONFIG_SPL_OS_BOOT */ + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +#ifdef CONFIG_SPL_OS_BOOT +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_SYS_SPL_MACHID, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,12 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 4d0573c..3897ab4 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,7 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +328,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +358,9 @@ #define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 +#define CONFIG_SYS_SPL_MACHID MACH_TYPE_DEVKIT8000 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl.c | 1 + arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c22c7a..0c38bbb 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -175,6 +175,7 @@ void board_init_r(gd_t *id, ulong dummy) #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); break; #endif diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 9b53742..3dd0eeb 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -62,6 +62,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -80,14 +92,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -119,7 +124,7 @@ void set_muxconf_regs(void) MUX_DEVKIT8000(); }
-#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_DRIVER_DM9000 /* * Routine: board_eth_init * Description: Setting up the Ethernet hardware. @@ -129,3 +134,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

This implements booting of Linux from NAND in SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 48 +++++++++++++++++++--------- 1 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..06254b2 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -46,26 +46,42 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + CONFIG_CMD_SAVEBP_WRITE_SIZE, + (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 06254b2..408892f 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -49,16 +51,29 @@ void spl_nand_load_image(void) #ifdef CONFIG_SPL_OS_BOOT if (!spl_uboot_key()) { /* load parameter image */ - nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS, CONFIG_CMD_SAVEBP_WRITE_SIZE, - (void *)CONFIG_SYS_SPL_ARGS_ADDR); + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SAVEBP_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
/* load linux */ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds direct Linux boot to SPL. It implements a savebp command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
checkpatch whines about not using strict_strtoull - since this is not available - I can't change this.
V2 changes: FIX FDT creation ADD Readme
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (8): arm: Add Prep subcommand support to bootm Add savebp command arm: Add savebp implementation for arm omap-common/spl: Add linux boot to SPL devkit8000/spl: init GPMC for dm9000 in SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem savebp: added Readme
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++++--- arch/arm/include/asm/omap_common.h | 2 + arch/arm/include/asm/savebp.h | 27 +++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/bootm.c | 116 ++++++++++++---------- arch/arm/lib/savebp.c | 91 ++++++++++++++++++ board/timll/devkit8000/devkit8000.c | 33 +++++-- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_savebp.c | 149 +++++++++++++++++++++++++++++ doc/README.commands.savebp | 28 ++++++ include/command.h | 5 + include/configs/devkit8000.h | 14 +++- 14 files changed, 499 insertions(+), 82 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c create mode 100644 common/cmd_savebp.c create mode 100644 doc/README.commands.savebp

Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ----
V2 changes: nothing --- arch/arm/lib/bootm.c | 116 +++++++++++++++++++++++++++---------------------- common/cmd_bootm.c | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..d3152ae 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,7 @@ -/* +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * - Added prep subcommand support + * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger mgroeger@sysgo.de @@ -55,7 +58,7 @@ static struct tag *params;
static ulong get_sp(void); #if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag); #endif
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*kernel_entry)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params) = NULL;
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - s = getenv ("machid"); - if (s) { - machid = simple_strtoul (s, NULL, 16); - printf ("Using machid 0x%x from environment\n", machid); - } - - show_boot_progress (15); + if ((flag != 0) && (!(flag & BOOTM_STATE_OS_GO || + flag & BOOTM_STATE_OS_PREP))) + return 1; /* subcommand not implemented */ + else if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + s = getenv("machid"); + if (s) { + strict_strtoul(s, 16, (long unsigned int *) &machid); + printf("Using machid 0x%x from environment\n", machid); + } + + show_boot_progress(15);
#ifdef CONFIG_OF_LIBFDT - if (images->ft_len) - return bootm_linux_fdt(machid, images); + if (images->ft_len) + return bootm_linux_fdt(machid, images, flag); #endif
- kernel_entry = (void (*)(int, int, uint))images->ep; + kernel_entry = (void (*)(int, int, uint))images->ep;
- debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG) - setup_start_tag (bd); + setup_start_tag(bd); #ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); + setup_serial_tag(¶ms); #endif #ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); + setup_revision_tag(¶ms); #endif #ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); + setup_memory_tags(bd); #endif #ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); + setup_commandline_tag(bd, commandline); #endif #ifdef CONFIG_INITRD_TAG - if (images->rd_start && images->rd_end) - setup_initrd_tag (bd, images->rd_start, images->rd_end); + if (images->rd_start && images->rd_end) + setup_initrd_tag(bd, images->rd_start, images->rd_end); #endif - setup_end_tag(bd); + setup_end_tag(bd); #endif + if (flag & BOOTM_STATE_OS_PREP) + return 0; + }
- announce_and_cleanup(); - - kernel_entry(0, machid, bd->bi_boot_params); - /* does not return */ + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + } return 1; }
@@ -174,10 +181,10 @@ static int fixup_memory_node(void *blob) return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); }
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag) { ulong rd_len; - void (*kernel_entry)(int zero, int dt_machid, void *dtblob); + void (*kernel_entry)(int zero, int dt_machid, void *dtblob) = NULL; ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; @@ -185,34 +192,39 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) struct lmb *lmb = &images->lmb; int ret;
- kernel_entry = (void (*)(int, int, void *))images->ep; - - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + kernel_entry = (void (*)(int, int, void *))images->ep;
- rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, - initrd_start, initrd_end); - if (ret) - return ret; + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret;
- fdt_chosen(*of_flat_tree, 1); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
- fixup_memory_node(*of_flat_tree); + fdt_chosen(*of_flat_tree, 1);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + fixup_memory_node(*of_flat_tree);
- announce_and_cleanup(); + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- kernel_entry(0, machid, *of_flat_tree); - /* does not return */ + if (flag & BOOTM_STATE_OS_PREP) + return 0; + } + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, *of_flat_tree); + /* does not return */ + } return 1; } #endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

This adds a savebp command to the u-boot.
Related config: CONFIG_CMD_SAVEBP activate/deactivate the command CONFIG_CMD_SAVEBP_NAND_OFS Offset in NAND to use CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message --- common/Makefile | 1 + common/cmd_savebp.c | 149 ++++++++++++++++++++++++++++++++++++++++++ include/configs/devkit8000.h | 6 ++ 3 files changed, 156 insertions(+), 0 deletions(-) create mode 100644 common/cmd_savebp.c
diff --git a/common/Makefile b/common/Makefile index 124a427..0b42968 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SAVEBP) += cmd_savebp.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c new file mode 100644 index 0000000..a8801ca --- /dev/null +++ b/common/cmd_savebp.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +#define TYPE_FDT 0 +#define TYPE_ATAGS 1 + +static inline int str2off(const char *p, loff_t *num) +{ + char *endptr; + + *num = simple_strtoull(p, &endptr, 16); + return *p != '\0' && *endptr == '\0'; +} + +int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + loff_t offset; + int img_type = TYPE_ATAGS; + int ret = 0; + int bootm_argc = 5; + char *bootm_argsv[] = {"do_bootm", "xxxxxxx", "0x82000000", "-", + "0x80000100"}; + + offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS; + bootm_argsv[2] = getenv("loadaddr"); + /* - Validate args - */ + switch (argc) { + case 6: /* 4. fdt addr */ + if (strcmp(argv[5], "-")) + strcpy(bootm_argsv[4], argv[5]); + case 5: /* 5. initrd addr */ + if (strcmp(argv[4], "-")) + strcpy(bootm_argsv[3], argv[4]); + case 4: /* 3. arg kernel addr */ + if (strcmp(argv[3], "-")) + strcpy(bootm_argsv[2], argv[3]); + case 3: /* 2. arg offset */ + if (strcmp(argv[2], "-")) { + if (!str2off(argv[2], &offset)) { + printf("'%s' is not a number\n", argv[2]); + return cmd_usage(cmdtp); + } + } + case 2: /* 1. arg atags or fdt */ + if (!strcmp(argv[1], "fdt")) + img_type = TYPE_FDT; + bootm_argc = 5; + else if (!strcmp(argv[1], "atags")) { + img_type = TYPE_ATAGS; + bootm_argc = 4; + } else { + return cmd_usage(cmdtp); + } + /* using standard offset */ + printf("using standard destination at: 0x%x\n", + (uint32_t)offset); + break; + default: + return cmd_usage(cmdtp); + } + debug("using as bootm arsgs: %s / %s / %s / %s / %s\n" + , bootm_argsv[0], bootm_argsv[1], bootm_argsv[2], + bootm_argsv[3], bootm_argsv[4]); + + /* - do the work - */ + /* exec bootm_start as subcommand of do_bootm to init the images + * data structure */ + debug("exec bootm subcommand start\n"); + bootm_argsv[1] = "start"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand start bootm retcode: %d\n", ret); + + debug("exec bootm subcommand loados\n"); + bootm_argsv[1] = "loados"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand loados bootm retcode: %d\n", ret); + +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + debug("exec bootm subcommand ramdisk\n"); + bootm_argsv[1] = "ramdisk"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand ramdisk bootm retcode: %d\n", ret); +#endif + +#ifdef CONFIG_OF_LIBFDT + if (img_type == TYPE_FDT) { + debug("exec bootm subcommand fdt\n"); + bootm_argsv[1] = "fdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, + bootm_argsv); + debug("Subcommand fdt bootm retcode: %d\n", ret); + } +#endif + + debug("exec bootm subcommand cmdline\n"); + bootm_argsv[1] = "cmdline"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand cmdline bootm retcode: %d\n", ret); + + debug("exec bootm bdt cmdline\n"); + bootm_argsv[1] = "bdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand bdt bootm retcode: %d\n", ret); + + debug("exec bootm subcommand prep\n"); + bootm_argsv[1] = "prep"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand prep bootm retcode: %d\n", ret); + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + /* call arch specific handlers */ + if (img_type == TYPE_FDT) + do_savebp_fdt(offset); + else + do_savebp_atags(offset); + + return 0; +} + +U_BOOT_CMD( + savebp, 6 , 1, do_savebp, "save boot params to NAND flash", + "[ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr] \ + saves the parameter image to NAND. All but the first paramter \ + can be omitted to use standard values. If nothing or a '-' is \ + used standardvalues are used where necessary"); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 9cbdb5d..80b441a 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -353,4 +353,10 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

This adds the savebp implementation to the arm platform.
Related CONFIGs: CONFIG_CMD_SAVEBP_WRITE_SIZE defines the size of the image to write
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: DEL _cosmetic_ old comment --- arch/arm/include/asm/savebp.h | 27 ++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/savebp.c | 91 +++++++++++++++++++++++++++++++++++++++++ include/command.h | 5 ++ include/configs/devkit8000.h | 1 + 5 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c
diff --git a/arch/arm/include/asm/savebp.h b/arch/arm/include/asm/savebp.h new file mode 100644 index 0000000..3774e45 --- /dev/null +++ b/arch/arm/include/asm/savebp.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SAVEBP_H_ +#define _SAVEBP_H_ + +extern bootm_headers_t images; + +#endif /* _SAVEBP_H_ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..abf7a6a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,7 @@ COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o +COBJS-$(CONFIG_CMD_SAVEBP) += savebp.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif diff --git a/arch/arm/lib/savebp.c b/arch/arm/lib/savebp.c new file mode 100644 index 0000000..e0cfd83 --- /dev/null +++ b/arch/arm/lib/savebp.c @@ -0,0 +1,91 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <image.h> + +#include <nand.h> +#include <asm/savebp.h> + +#ifdef CONFIG_OMAP34XX +#include <asm/arch/sys_proto.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* This function writes given bootparams to NAND flash + * adr: Start adress of Kernel parameter image (ATAGS, FDT) + * length: length of the image in byte + * off: offset in NAND flash + * + * borrowd heavily from common/cmd_nand.c + */ +static void boot_params_to_nand(u_char *adr, size_t length, loff_t off) +{ + nand_info_t *nand = &nand_info[0]; /* use 0 as in SPL */ + nand_erase_options_t opts; +#ifdef CONFIG_OMAP34XX + omap_nand_switch_ecc(1); /* use hw ecc on omap for SPL compat */ +#endif + /* erase */ + memset(&opts, 0, sizeof(opts)); + opts.offset = off; + opts.length = length; + opts.quiet = 1; + opts.spread = 1; + nand_erase_opts(nand, &opts); + + /* write */ + if (nand_write_skip_bad(nand, off, &length, adr, 0)) { + printf("FAILED!\n"); + return; + } + + printf("Written to offset 0x%llX, size: %d bytes\n", + off, length); +} + +/* Saves FDT to NAND */ +int do_savebp_fdt(loff_t offset) +{ + boot_params_to_nand((u_char *)images.ft_addr, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + return 0; +} + + +/* Saves ATAGS to NAND */ +int do_savebp_atags(loff_t offset) +{ + /* Vars */ + bd_t *bd = gd->bd; + + printf("write ATAGS to NAND...\n"); + + /* save em */ + /* used fixed size - easier to read later just ignore garbage */ + boot_params_to_nand((u_char *)bd->bi_boot_params, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + + return 0; +} diff --git a/include/command.h b/include/command.h index 8310fe5..3ae68a8 100644 --- a/include/command.h +++ b/include/command.h @@ -101,6 +101,11 @@ extern int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+#ifdef CONFIG_CMD_SAVEBP +int do_savebp_atags(loff_t offset); +int do_savebp_fdt(loff_t offset); +#endif + #endif /* __ASSEMBLY__ */
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 80b441a..4d0573c 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -355,6 +355,7 @@
/* SPL OS boot options */ #define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000

This adds Linux booting to the SPL
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_SPL_MACHID Machine ID of the used board CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl.c | 48 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 7 +++- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..9c22c7a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+#ifdef CONFIG_SPL_OS_BOOT +/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +int spl_uboot_key(void) +{ + int val = 0; + if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) { + omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1); + val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY); + omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif /* CONFIG_SPL_OS_BOOT */ + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +#ifdef CONFIG_SPL_OS_BOOT +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_SYS_SPL_MACHID, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,12 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 4d0573c..3897ab4 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,7 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +328,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +358,9 @@ #define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 +#define CONFIG_SYS_SPL_MACHID MACH_TYPE_DEVKIT8000 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl.c | 1 + arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c22c7a..0c38bbb 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -175,6 +175,7 @@ void board_init_r(gd_t *id, ulong dummy) #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); break; #endif diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 9b53742..3dd0eeb 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -62,6 +62,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -80,14 +92,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -119,7 +124,7 @@ void set_muxconf_regs(void) MUX_DEVKIT8000(); }
-#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_DRIVER_DM9000 /* * Routine: board_eth_init * Description: Setting up the Ethernet hardware. @@ -129,3 +134,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

This implements booting of Linux from NAND in SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 48 +++++++++++++++++++--------- 1 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..06254b2 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -46,26 +46,42 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + CONFIG_CMD_SAVEBP_WRITE_SIZE, + (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 06254b2..408892f 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -49,16 +51,29 @@ void spl_nand_load_image(void) #ifdef CONFIG_SPL_OS_BOOT if (!spl_uboot_key()) { /* load parameter image */ - nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS, CONFIG_CMD_SAVEBP_WRITE_SIZE, - (void *)CONFIG_SYS_SPL_ARGS_ADDR); + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SAVEBP_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
/* load linux */ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds a Readme for the savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: ADDED in V2 --- doc/README.commands.savebp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 doc/README.commands.savebp
diff --git a/doc/README.commands.savebp b/doc/README.commands.savebp new file mode 100644 index 0000000..dc05ee0 --- /dev/null +++ b/doc/README.commands.savebp @@ -0,0 +1,28 @@ +The savebp (=save boot parameters) is used to save a boot parameter image to +non-volatile memory. + +To execute the command everything has to be in place as if bootm should be +used. +(kernel image, initrd-image, fdt-image etc.) + +Call is: +savebp [ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr] + +Only the first parameter [ftd|atags] is mandatory if the others are left blank +standard values are used. + +e.g: +savebp fdt 0x680000 0x82000000 0x80000100 - +savebo atags + +typical call on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND */ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +savebp fdt 0x680000 0x82000000 0x80000100 - /* Save the image */ + +------------Behind the scene--------------- +Atm the implementation is that we have /common/cmd_savebp.c which implements +the command tself and the subcommand calls to bootm. +Then the arch specific implementation of do_save_atags or do_savebp_fdt +in /arch/arm/lib is called.

Adds direct Linux boot to SPL. It implements a savebp command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
checkpatch whines about not using strict_strtoull - since this is not available - I can't change this.
V2 changes: FIX FDT creation ADD Readme
V3 changes: FIX missing brackets
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (8): arm: Add Prep subcommand support to bootm Add savebp command arm: Add savebp implementation for arm omap-common/spl: Add linux boot to SPL devkit8000/spl: init GPMC for dm9000 in SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem savebp: added Readme
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++++--- arch/arm/include/asm/omap_common.h | 2 + arch/arm/include/asm/savebp.h | 27 +++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/bootm.c | 116 ++++++++++++---------- arch/arm/lib/savebp.c | 91 ++++++++++++++++++ board/timll/devkit8000/devkit8000.c | 33 +++++-- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_savebp.c | 149 +++++++++++++++++++++++++++++ doc/README.commands.savebp | 28 ++++++ include/command.h | 5 + include/configs/devkit8000.h | 14 +++- 14 files changed, 499 insertions(+), 82 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c create mode 100644 common/cmd_savebp.c create mode 100644 doc/README.commands.savebp

Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ----
V2 changes: nothing
V3 changes: nothing --- arch/arm/lib/bootm.c | 116 +++++++++++++++++++++++++++---------------------- common/cmd_bootm.c | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..d3152ae 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,7 @@ -/* +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * - Added prep subcommand support + * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger mgroeger@sysgo.de @@ -55,7 +58,7 @@ static struct tag *params;
static ulong get_sp(void); #if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag); #endif
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*kernel_entry)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params) = NULL;
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - s = getenv ("machid"); - if (s) { - machid = simple_strtoul (s, NULL, 16); - printf ("Using machid 0x%x from environment\n", machid); - } - - show_boot_progress (15); + if ((flag != 0) && (!(flag & BOOTM_STATE_OS_GO || + flag & BOOTM_STATE_OS_PREP))) + return 1; /* subcommand not implemented */ + else if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + s = getenv("machid"); + if (s) { + strict_strtoul(s, 16, (long unsigned int *) &machid); + printf("Using machid 0x%x from environment\n", machid); + } + + show_boot_progress(15);
#ifdef CONFIG_OF_LIBFDT - if (images->ft_len) - return bootm_linux_fdt(machid, images); + if (images->ft_len) + return bootm_linux_fdt(machid, images, flag); #endif
- kernel_entry = (void (*)(int, int, uint))images->ep; + kernel_entry = (void (*)(int, int, uint))images->ep;
- debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG) - setup_start_tag (bd); + setup_start_tag(bd); #ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); + setup_serial_tag(¶ms); #endif #ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); + setup_revision_tag(¶ms); #endif #ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); + setup_memory_tags(bd); #endif #ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); + setup_commandline_tag(bd, commandline); #endif #ifdef CONFIG_INITRD_TAG - if (images->rd_start && images->rd_end) - setup_initrd_tag (bd, images->rd_start, images->rd_end); + if (images->rd_start && images->rd_end) + setup_initrd_tag(bd, images->rd_start, images->rd_end); #endif - setup_end_tag(bd); + setup_end_tag(bd); #endif + if (flag & BOOTM_STATE_OS_PREP) + return 0; + }
- announce_and_cleanup(); - - kernel_entry(0, machid, bd->bi_boot_params); - /* does not return */ + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + } return 1; }
@@ -174,10 +181,10 @@ static int fixup_memory_node(void *blob) return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); }
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag) { ulong rd_len; - void (*kernel_entry)(int zero, int dt_machid, void *dtblob); + void (*kernel_entry)(int zero, int dt_machid, void *dtblob) = NULL; ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; @@ -185,34 +192,39 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) struct lmb *lmb = &images->lmb; int ret;
- kernel_entry = (void (*)(int, int, void *))images->ep; - - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) { + kernel_entry = (void (*)(int, int, void *))images->ep;
- rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, - initrd_start, initrd_end); - if (ret) - return ret; + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret;
- fdt_chosen(*of_flat_tree, 1); + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry);
- fixup_memory_node(*of_flat_tree); + fdt_chosen(*of_flat_tree, 1);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + fixup_memory_node(*of_flat_tree);
- announce_and_cleanup(); + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- kernel_entry(0, machid, *of_flat_tree); - /* does not return */ + if (flag & BOOTM_STATE_OS_PREP) + return 0; + } + if (flag == 0 || flag & BOOTM_STATE_OS_GO) { + announce_and_cleanup();
+ kernel_entry(0, machid, *of_flat_tree); + /* does not return */ + } return 1; } #endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: nothing
V3 changes: nothing
arch/arm/lib/bootm.c | 116 +++++++++++++++++++++++++++---------------------- common/cmd_bootm.c | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..d3152ae 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,7 @@ -/* +/* Copyright (C) 2011
- Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de
- Added prep subcommand support
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- Marius Groeger mgroeger@sysgo.de
@@ -55,7 +58,7 @@ static struct tag *params;
static ulong get_sp(void); #if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag); #endif
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number;
- void (*kernel_entry)(int zero, int arch, uint params);
- void (*kernel_entry)(int zero, int arch, uint params) = NULL;
This should not be necessary, kernel_entry would be on bss which should be initialized to zero by start.S.
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif
- if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
- s = getenv ("machid");
- if (s) {
machid = simple_strtoul (s, NULL, 16);
printf ("Using machid 0x%x from environment\n", machid);
- }
- show_boot_progress (15);
- if ((flag != 0) && (!(flag & BOOTM_STATE_OS_GO ||
flag & BOOTM_STATE_OS_PREP)))
switch'n'case would be much cleaner here. And seperating the functionality into functions would be nice too.
return 1; /* subcommand not implemented */
- else if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) {
s = getenv("machid");
if (s) {
strict_strtoul(s, 16, (long unsigned int *) &machid);
printf("Using machid 0x%x from environment\n", machid);
}
show_boot_progress(15);
#ifdef CONFIG_OF_LIBFDT
- if (images->ft_len)
return bootm_linux_fdt(machid, images);
if (images->ft_len)
return bootm_linux_fdt(machid, images, flag);
#endif
- kernel_entry = (void (*)(int, int, uint))images->ep;
kernel_entry = (void (*)(int, int, uint))images->ep;
- debug ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) kernel_entry);
debug("## Transferring control to Linux (at address %08lx)" \
"...\n", (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG)
- setup_start_tag (bd);
setup_start_tag(bd);
#ifdef CONFIG_SERIAL_TAG
- setup_serial_tag (¶ms);
setup_serial_tag(¶ms);
#endif #ifdef CONFIG_REVISION_TAG
- setup_revision_tag (¶ms);
setup_revision_tag(¶ms);
#endif #ifdef CONFIG_SETUP_MEMORY_TAGS
- setup_memory_tags (bd);
setup_memory_tags(bd);
#endif #ifdef CONFIG_CMDLINE_TAG
- setup_commandline_tag (bd, commandline);
setup_commandline_tag(bd, commandline);
#endif #ifdef CONFIG_INITRD_TAG
- if (images->rd_start && images->rd_end)
setup_initrd_tag (bd, images->rd_start, images->rd_end);
if (images->rd_start && images->rd_end)
setup_initrd_tag(bd, images->rd_start, images->rd_end);
#endif
- setup_end_tag(bd);
setup_end_tag(bd);
#endif
if (flag & BOOTM_STATE_OS_PREP)
return 0;
- }
- announce_and_cleanup();
- kernel_entry(0, machid, bd->bi_boot_params);
- /* does not return */
- if (flag == 0 || flag & BOOTM_STATE_OS_GO) {
flag == 0? Shouldn't that be flag == BOOTM_STATE_OS_GO?
announce_and_cleanup();
kernel_entry(0, machid, bd->bi_boot_params);
/* does not return */
} return 1;
}
@@ -174,10 +181,10 @@ static int fixup_memory_node(void *blob) return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); }
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag) { ulong rd_len;
- void (*kernel_entry)(int zero, int dt_machid, void *dtblob);
- void (*kernel_entry)(int zero, int dt_machid, void *dtblob) = NULL;
same as above.
ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; @@ -185,34 +192,39 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) struct lmb *lmb = &images->lmb; int ret;
- kernel_entry = (void (*)(int, int, void *))images->ep;
- boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- if ((flag == 0) || flag & BOOTM_STATE_OS_PREP) {
kernel_entry = (void (*)(int, int, void *))images->ep;
same as above, a cleaner aproach is to gather information for fdt in a dedicated function and in another do the hand-over to linux kernel.
- rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
initrd_start, initrd_end);
- if (ret)
return ret;
boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
- if (ret)
return ret;
rd_len = images->rd_end - images->rd_start;
ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
initrd_start, initrd_end);
if (ret)
return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) kernel_entry);
ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
if (ret)
return ret;
- fdt_chosen(*of_flat_tree, 1);
debug("## Transferring control to Linux (at address %08lx)" \
"...\n", (ulong) kernel_entry);
- fixup_memory_node(*of_flat_tree);
fdt_chosen(*of_flat_tree, 1);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
fixup_memory_node(*of_flat_tree);
- announce_and_cleanup();
fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- kernel_entry(0, machid, *of_flat_tree);
- /* does not return */
if (flag & BOOTM_STATE_OS_PREP)
return 0;
}
if (flag == 0 || flag & BOOTM_STATE_OS_GO) {
announce_and_cleanup();
kernel_entry(0, machid, *of_flat_tree);
/* does not return */
} return 1;
} #endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
is this necessary?
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)
regards
Andreas Bießmann

Dear Andreas,
On 08/25/2011 11:40 AM, Andreas Bießmann wrote:
Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in savebp command
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
V2 changes: nothing
V3 changes: nothing
arch/arm/lib/bootm.c | 116 +++++++++++++++++++++++++++---------------------- common/cmd_bootm.c | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..d3152ae 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,7 @@ -/* +/* Copyright (C) 2011
- Corscience GmbH& Co. KG - Simon Schwarzschwarz@corscience.de
- Added prep subcommand support
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH<www.elinos.com>
- Marius Groegermgroeger@sysgo.de
@@ -55,7 +58,7 @@ static struct tag *params;
static ulong get_sp(void); #if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag); #endif
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number;
- void (*kernel_entry)(int zero, int arch, uint params);
- void (*kernel_entry)(int zero, int arch, uint params) = NULL;
This should not be necessary, kernel_entry would be on bss which should be initialized to zero by start.S.
I added this because of compiler warnings that it could be used uninitialized.
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif
- if ((flag != 0)&& (flag != BOOTM_STATE_OS_GO))
return 1;
- s = getenv ("machid");
- if (s) {
machid = simple_strtoul (s, NULL, 16);
printf ("Using machid 0x%x from environment\n", machid);
- }
- show_boot_progress (15);
- if ((flag != 0)&& (!(flag& BOOTM_STATE_OS_GO ||
flag& BOOTM_STATE_OS_PREP)))
switch'n'case would be much cleaner here. And seperating the functionality into functions would be nice too.
Hehe. Somehow I did know that this topic will come up. I intended to change the code as little as possible.
So essentially this would mean to rewrite this to reflect the structure of the ppc version. Will do if there are no objections.
If there are no objections I also would like to separate this patch from this series. This has some advantages: - Support for the prep subcommand is essential for saving the boot parameters. (if prep is in saving can also be done manually) - I think that there won't be much discussion about the usefulness of implementing this - just some about the how.
return 1; /* subcommand not implemented */
else if ((flag == 0) || flag& BOOTM_STATE_OS_PREP) {
s = getenv("machid");
if (s) {
strict_strtoul(s, 16, (long unsigned int *)&machid);
printf("Using machid 0x%x from environment\n", machid);
}
show_boot_progress(15);
#ifdef CONFIG_OF_LIBFDT
- if (images->ft_len)
return bootm_linux_fdt(machid, images);
if (images->ft_len)
#endifreturn bootm_linux_fdt(machid, images, flag);
- kernel_entry = (void (*)(int, int, uint))images->ep;
kernel_entry = (void (*)(int, int, uint))images->ep;
- debug ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) kernel_entry);
debug("## Transferring control to Linux (at address %08lx)" \
"...\n", (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG)
- setup_start_tag (bd);
#ifdef CONFIG_SERIAL_TAGsetup_start_tag(bd);
- setup_serial_tag (¶ms);
#endif #ifdef CONFIG_REVISION_TAGsetup_serial_tag(¶ms);
- setup_revision_tag (¶ms);
#endif #ifdef CONFIG_SETUP_MEMORY_TAGSsetup_revision_tag(¶ms);
- setup_memory_tags (bd);
#endif #ifdef CONFIG_CMDLINE_TAGsetup_memory_tags(bd);
- setup_commandline_tag (bd, commandline);
#endif #ifdef CONFIG_INITRD_TAGsetup_commandline_tag(bd, commandline);
- if (images->rd_start&& images->rd_end)
setup_initrd_tag (bd, images->rd_start, images->rd_end);
if (images->rd_start&& images->rd_end)
#endifsetup_initrd_tag(bd, images->rd_start, images->rd_end);
- setup_end_tag(bd);
#endifsetup_end_tag(bd);
if (flag& BOOTM_STATE_OS_PREP)
return 0;
- }
- announce_and_cleanup();
- kernel_entry(0, machid, bd->bi_boot_params);
- /* does not return */
- if (flag == 0 || flag& BOOTM_STATE_OS_GO) {
flag == 0? Shouldn't that be flag == BOOTM_STATE_OS_GO?
flag = 0 means that no subcommand was issued -> execute everything.
announce_and_cleanup();
kernel_entry(0, machid, bd->bi_boot_params);
/* does not return */
} return 1; }
@@ -174,10 +181,10 @@ static int fixup_memory_node(void *blob) return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); }
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static int bootm_linux_fdt(int machid, bootm_headers_t *images, int flag) { ulong rd_len;
- void (*kernel_entry)(int zero, int dt_machid, void *dtblob);
- void (*kernel_entry)(int zero, int dt_machid, void *dtblob) = NULL;
same as above.
see above
ulong of_size = images->ft_len; char **of_flat_tree =&images->ft_addr; ulong *initrd_start =&images->initrd_start; @@ -185,34 +192,39 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) struct lmb *lmb =&images->lmb; int ret;
- kernel_entry = (void (*)(int, int, void *))images->ep;
- boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- if ((flag == 0) || flag& BOOTM_STATE_OS_PREP) {
kernel_entry = (void (*)(int, int, void *))images->ep;
same as above, a cleaner aproach is to gather information for fdt in a dedicated function and in another do the hand-over to linux kernel.
If no objections - will be done in the rewrite.
- rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
initrd_start, initrd_end);
- if (ret)
return ret;
boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
- ret = boot_relocate_fdt(lmb, of_flat_tree,&of_size);
- if (ret)
return ret;
rd_len = images->rd_end - images->rd_start;
ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
initrd_start, initrd_end);
if (ret)
return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) kernel_entry);
ret = boot_relocate_fdt(lmb, of_flat_tree,&of_size);
if (ret)
return ret;
- fdt_chosen(*of_flat_tree, 1);
debug("## Transferring control to Linux (at address %08lx)" \
"...\n", (ulong) kernel_entry);
- fixup_memory_node(*of_flat_tree);
fdt_chosen(*of_flat_tree, 1);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
fixup_memory_node(*of_flat_tree);
- announce_and_cleanup();
fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- kernel_entry(0, machid, *of_flat_tree);
- /* does not return */
if (flag& BOOTM_STATE_OS_PREP)
return 0;
}
if (flag == 0 || flag& BOOTM_STATE_OS_GO) {
announce_and_cleanup();
kernel_entry(0, machid, *of_flat_tree);
/* does not return */
} return 1; } #endif
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
is this necessary?
This is done to be able to get the fdt address in arch-dependent savebp cmd. Suggestions for a cleaner solution are welcome ;)
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)
regards
Andreas Bießmann
Regards, thx for reviewing Simon

Dear Simon,
Am 26.08.2011 11:57, schrieb Simon Schwarz:
Dear Andreas,
On 08/25/2011 11:40 AM, Andreas Bießmann wrote:
Dear Simon,
<snip>
void arch_lmb_reserve(struct lmb *lmb) @@ -98,63 +101,67 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number;
- void (*kernel_entry)(int zero, int arch, uint params);
- void (*kernel_entry)(int zero, int arch, uint params) = NULL;
This should not be necessary, kernel_entry would be on bss which should be initialized to zero by start.S.
I added this because of compiler warnings that it could be used uninitialized.
I see, you changed the flow of this function elementary. Sorry, did not realize that.
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif
- if ((flag != 0)&& (flag != BOOTM_STATE_OS_GO))
return 1;
- s = getenv ("machid");
- if (s) {
machid = simple_strtoul (s, NULL, 16);
printf ("Using machid 0x%x from environment\n", machid);
- }
- show_boot_progress (15);
- if ((flag != 0)&& (!(flag& BOOTM_STATE_OS_GO ||
flag& BOOTM_STATE_OS_PREP)))
switch'n'case would be much cleaner here. And seperating the functionality into functions would be nice too.
Hehe. Somehow I did know that this topic will come up. I intended to change the code as little as possible.
Well, switch'n'case is not correct here, sorry for misleading comment.
So essentially this would mean to rewrite this to reflect the structure of the ppc version. Will do if there are no objections.
+1 for rewrite, Albert how do you think about?
If there are no objections I also would like to separate this patch from this series. This has some advantages:
- Support for the prep subcommand is essential for saving the boot
parameters. (if prep is in saving can also be done manually)
- I think that there won't be much discussion about the usefulness of
implementing this - just some about the how.
I think it would be good idea to add the 'bootm prep' command to arm implementation of bootm in a separate step.
<snip>
- if (flag == 0 || flag& BOOTM_STATE_OS_GO) {
flag == 0? Shouldn't that be flag == BOOTM_STATE_OS_GO?
flag = 0 means that no subcommand was issued -> execute everything.
again, sorry for the noise.
<snip>
best regards
Andreas Bießmann

This adds a savebp command to the u-boot.
Related config: CONFIG_CMD_SAVEBP activate/deactivate the command CONFIG_CMD_SAVEBP_NAND_OFS Offset in NAND to use CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets --- common/Makefile | 1 + common/cmd_savebp.c | 149 ++++++++++++++++++++++++++++++++++++++++++ include/configs/devkit8000.h | 6 ++ 3 files changed, 156 insertions(+), 0 deletions(-) create mode 100644 common/cmd_savebp.c
diff --git a/common/Makefile b/common/Makefile index 124a427..0b42968 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SAVEBP) += cmd_savebp.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c new file mode 100644 index 0000000..4091ccb --- /dev/null +++ b/common/cmd_savebp.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +#define TYPE_FDT 0 +#define TYPE_ATAGS 1 + +static inline int str2off(const char *p, loff_t *num) +{ + char *endptr; + + *num = simple_strtoull(p, &endptr, 16); + return *p != '\0' && *endptr == '\0'; +} + +int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + loff_t offset; + int img_type = TYPE_ATAGS; + int ret = 0; + int bootm_argc = 5; + char *bootm_argsv[] = {"do_bootm", "xxxxxxx", "0x82000000", "-", + "0x80000100"}; + + offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS; + bootm_argsv[2] = getenv("loadaddr"); + /* - Validate args - */ + switch (argc) { + case 6: /* 4. fdt addr */ + if (strcmp(argv[5], "-")) + strcpy(bootm_argsv[4], argv[5]); + case 5: /* 5. initrd addr */ + if (strcmp(argv[4], "-")) + strcpy(bootm_argsv[3], argv[4]); + case 4: /* 3. arg kernel addr */ + if (strcmp(argv[3], "-")) + strcpy(bootm_argsv[2], argv[3]); + case 3: /* 2. arg offset */ + if (strcmp(argv[2], "-")) { + if (!str2off(argv[2], &offset)) { + printf("'%s' is not a number\n", argv[2]); + return cmd_usage(cmdtp); + } + } + case 2: /* 1. arg atags or fdt */ + if (!strcmp(argv[1], "fdt")) { + img_type = TYPE_FDT; + bootm_argc = 5; + } else if (!strcmp(argv[1], "atags")) { + img_type = TYPE_ATAGS; + bootm_argc = 4; + } else { + return cmd_usage(cmdtp); + } + /* using standard offset */ + printf("using standard destination at: 0x%x\n", + (uint32_t)offset); + break; + default: + return cmd_usage(cmdtp); + } + debug("using as bootm arsgs: %s / %s / %s / %s / %s\n" + , bootm_argsv[0], bootm_argsv[1], bootm_argsv[2], + bootm_argsv[3], bootm_argsv[4]); + + /* - do the work - */ + /* exec bootm_start as subcommand of do_bootm to init the images + * data structure */ + debug("exec bootm subcommand start\n"); + bootm_argsv[1] = "start"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand start bootm retcode: %d\n", ret); + + debug("exec bootm subcommand loados\n"); + bootm_argsv[1] = "loados"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand loados bootm retcode: %d\n", ret); + +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + debug("exec bootm subcommand ramdisk\n"); + bootm_argsv[1] = "ramdisk"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand ramdisk bootm retcode: %d\n", ret); +#endif + +#ifdef CONFIG_OF_LIBFDT + if (img_type == TYPE_FDT) { + debug("exec bootm subcommand fdt\n"); + bootm_argsv[1] = "fdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, + bootm_argsv); + debug("Subcommand fdt bootm retcode: %d\n", ret); + } +#endif + + debug("exec bootm subcommand cmdline\n"); + bootm_argsv[1] = "cmdline"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand cmdline bootm retcode: %d\n", ret); + + debug("exec bootm bdt cmdline\n"); + bootm_argsv[1] = "bdt"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand bdt bootm retcode: %d\n", ret); + + debug("exec bootm subcommand prep\n"); + bootm_argsv[1] = "prep"; + ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv); + debug("Subcommand prep bootm retcode: %d\n", ret); + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + /* call arch specific handlers */ + if (img_type == TYPE_FDT) + do_savebp_fdt(offset); + else + do_savebp_atags(offset); + + return 0; +} + +U_BOOT_CMD( + savebp, 6 , 1, do_savebp, "save boot params to NAND flash", + "[ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr] \ + saves the parameter image to NAND. All but the first paramter \ + can be omitted to use standard values. If nothing or a '-' is \ + used standardvalues are used where necessary"); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 9cbdb5d..80b441a 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -353,4 +353,10 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds a savebp command to the u-boot.
Related config: CONFIG_CMD_SAVEBP activate/deactivate the command CONFIG_CMD_SAVEBP_NAND_OFS Offset in NAND to use CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL
This is not used in the code ... why defining it then (here)?
CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Well this is gd->bd->bi_boot_params (at least on ARM), so why don't you use that parameter here?
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
common/Makefile | 1 + common/cmd_savebp.c | 149 ++++++++++++++++++++++++++++++++++++++++++ include/configs/devkit8000.h | 6 ++
where is the documentation?
3 files changed, 156 insertions(+), 0 deletions(-) create mode 100644 common/cmd_savebp.c
diff --git a/common/Makefile b/common/Makefile index 124a427..0b42968 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SAVEBP) += cmd_savebp.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c new file mode 100644 index 0000000..4091ccb --- /dev/null +++ b/common/cmd_savebp.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2011
- Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <command.h>
+#define TYPE_FDT 0 +#define TYPE_ATAGS 1
should'nt this go into some header? How about enum here?
+static inline int str2off(const char *p, loff_t *num) +{
- char *endptr;
- *num = simple_strtoull(p, &endptr, 16);
- return *p != '\0' && *endptr == '\0';
+}
could be merged with the one in cmd_nand.c. Maybe move the one from cmd_nand.c to some header?
+int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- loff_t offset;
- int img_type = TYPE_ATAGS;
- int ret = 0;
- int bootm_argc = 5;
- char *bootm_argsv[] = {"do_bootm", "xxxxxxx", "0x82000000", "-",
"0x80000100"};
- offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS;
- bootm_argsv[2] = getenv("loadaddr");
- /* - Validate args - */
- switch (argc) {
- case 6: /* 4. fdt addr */
^ wrong number?
if (strcmp(argv[5], "-"))
strcpy(bootm_argsv[4], argv[5]);
If one set '-' as fifth argument bootm_argsv will stay with your given "0x80000100" ... shouldn't the default argument be pre-calculated at compile time. I guess the 0x80000100 is CONFIG_SYS_SDRAM_BASE + 0x100 in your case (or tell it CONFIG_SYS_SPL_ARGS_ADDR).
BTW: it is unsafe to use strcpy() here cause you may have some greater string in 'src' than in 'dst' you should use strncpy() with strlen(dst) as 'count' or even strdup() here.
In my opinion it would be best to use something like this here:
---8<--- char *bootm_argsv[5];
bootm_argsv[0] = "bootm"; ... bootm_argsv[4] = strdup(argv[5]); ... --->8---
Or even
bootm_argsv[4] = argv[5];
But that have to be investigated, I don't know currently if it will work.
- case 5: /* 5. initrd addr */
^ wrong number?
if (strcmp(argv[4], "-"))
strcpy(bootm_argsv[3], argv[4]);
- case 4: /* 3. arg kernel addr */
if (strcmp(argv[3], "-"))
strcpy(bootm_argsv[2], argv[3]);
- case 3: /* 2. arg offset */
if (strcmp(argv[2], "-")) {
if (!str2off(argv[2], &offset)) {
printf("'%s' is not a number\n", argv[2]);
return cmd_usage(cmdtp);
}
}
- case 2: /* 1. arg atags or fdt */
if (!strcmp(argv[1], "fdt")) {
img_type = TYPE_FDT;
bootm_argc = 5;
} else if (!strcmp(argv[1], "atags")) {
img_type = TYPE_ATAGS;
bootm_argc = 4;
} else {
return cmd_usage(cmdtp);
}
/* using standard offset */
printf("using standard destination at: 0x%x\n",
(uint32_t)offset);
break;
- default:
return cmd_usage(cmdtp);
- }
- debug("using as bootm arsgs: %s / %s / %s / %s / %s\n"
, bootm_argsv[0], bootm_argsv[1], bootm_argsv[2],
bootm_argsv[3], bootm_argsv[4]);
- /* - do the work - */
- /* exec bootm_start as subcommand of do_bootm to init the images
* data structure */
- debug("exec bootm subcommand start\n");
- bootm_argsv[1] = "start";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand start bootm retcode: %d\n", ret);
- debug("exec bootm subcommand loados\n");
- bootm_argsv[1] = "loados";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand loados bootm retcode: %d\n", ret);
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- debug("exec bootm subcommand ramdisk\n");
- bootm_argsv[1] = "ramdisk";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand ramdisk bootm retcode: %d\n", ret);
+#endif
+#ifdef CONFIG_OF_LIBFDT
- if (img_type == TYPE_FDT) {
debug("exec bootm subcommand fdt\n");
bootm_argsv[1] = "fdt";
ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc,
bootm_argsv);
debug("Subcommand fdt bootm retcode: %d\n", ret);
- }
+#endif
- debug("exec bootm subcommand cmdline\n");
- bootm_argsv[1] = "cmdline";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand cmdline bootm retcode: %d\n", ret);
- debug("exec bootm bdt cmdline\n");
- bootm_argsv[1] = "bdt";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand bdt bootm retcode: %d\n", ret);
- debug("exec bootm subcommand prep\n");
- bootm_argsv[1] = "prep";
- ret = do_bootm(find_cmd("do_bootm"), 0, bootm_argc, bootm_argsv);
- debug("Subcommand prep bootm retcode: %d\n", ret);
- if (ret) {
printf("ERROR prep subcommand failed!\n");
return -1;
- }
- /* call arch specific handlers */
- if (img_type == TYPE_FDT)
do_savebp_fdt(offset);
- else
do_savebp_atags(offset);
where are these two do_savebp_x() functions?
- return 0;
+}
+U_BOOT_CMD(
- savebp, 6 , 1, do_savebp, "save boot params to NAND flash",
- "[ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr] \
- saves the parameter image to NAND. All but the first paramter \
- can be omitted to use standard values. If nothing or a '-' is \
- used standardvalues are used where necessary");
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 9cbdb5d..80b441a 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -353,4 +353,10 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
0x400000)
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */
regards
Andreas Bießmann

Dear Andreas,
On 08/25/2011 12:37 PM, Andreas Bießmann wrote:
Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds a savebp command to the u-boot.
Related config: CONFIG_CMD_SAVEBP activate/deactivate the command CONFIG_CMD_SAVEBP_NAND_OFS Offset in NAND to use CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL
This is not used in the code ... why defining it then (here)?
Will move the description to the proper patch.
CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Well this is gd->bd->bi_boot_params (at least on ARM), so why don't you use that parameter here?
Because this is used in SPL where the bd struct is not fully initialized.
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
common/Makefile | 1 + common/cmd_savebp.c | 149 ++++++++++++++++++++++++++++++++++++++++++ include/configs/devkit8000.h | 6 ++
where is the documentation?
Last patch - will squash it.
3 files changed, 156 insertions(+), 0 deletions(-) create mode 100644 common/cmd_savebp.c
diff --git a/common/Makefile b/common/Makefile index 124a427..0b42968 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SAVEBP) += cmd_savebp.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c new file mode 100644 index 0000000..4091ccb --- /dev/null +++ b/common/cmd_savebp.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2011
- Corscience GmbH& Co. KG - Simon Schwarzschwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include<common.h> +#include<command.h>
+#define TYPE_FDT 0 +#define TYPE_ATAGS 1
should'nt this go into some header? How about enum here?
Will change.
+static inline int str2off(const char *p, loff_t *num) +{
- char *endptr;
- *num = simple_strtoull(p,&endptr, 16);
- return *p != '\0'&& *endptr == '\0';
+}
could be merged with the one in cmd_nand.c. Maybe move the one from cmd_nand.c to some header?
Hm, what would be the best place for that? It's at least useful for mmc and nand. common.h? mtd_common.h?
+int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- loff_t offset;
- int img_type = TYPE_ATAGS;
- int ret = 0;
- int bootm_argc = 5;
- char *bootm_argsv[] = {"do_bootm", "xxxxxxx", "0x82000000", "-",
"0x80000100"};
- offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS;
- bootm_argsv[2] = getenv("loadaddr");
- /* - Validate args - */
- switch (argc) {
- case 6: /* 4. fdt addr */
^ wrong number?
Changed.
if (strcmp(argv[5], "-"))
strcpy(bootm_argsv[4], argv[5]);
If one set '-' as fifth argument bootm_argsv will stay with your given "0x80000100" ... shouldn't the default argument be pre-calculated at compile time. I guess the 0x80000100 is CONFIG_SYS_SDRAM_BASE + 0x100 in your case (or tell it CONFIG_SYS_SPL_ARGS_ADDR).
Will change.
BTW: it is unsafe to use strcpy() here cause you may have some greater string in 'src' than in 'dst' you should use strncpy() with strlen(dst) as 'count' or even strdup() here.
will do.
In my opinion it would be best to use something like this here:
---8<--- char *bootm_argsv[5];
bootm_argsv[0] = "bootm"; ... bootm_argsv[4] = strdup(argv[5]); ... --->8---
Or even
bootm_argsv[4] = argv[5];
But that have to be investigated, I don't know currently if it will work.
Will think about...
- case 5: /* 5. initrd addr */
^ wrong number?
changed.
<snip>
- }
- /* call arch specific handlers */
- if (img_type == TYPE_FDT)
do_savebp_fdt(offset);
- else
do_savebp_atags(offset);
where are these two do_savebp_x() functions?
later patch will change sequence.
Regards, thanks for the feedback! Simon

This adds the savebp implementation to the arm platform.
Related CONFIGs: CONFIG_CMD_SAVEBP_WRITE_SIZE defines the size of the image to write
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: DEL _cosmetic_ old comment
V3 changes: nothing --- arch/arm/include/asm/savebp.h | 27 ++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/savebp.c | 91 +++++++++++++++++++++++++++++++++++++++++ include/command.h | 5 ++ include/configs/devkit8000.h | 1 + 5 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/savebp.h create mode 100644 arch/arm/lib/savebp.c
diff --git a/arch/arm/include/asm/savebp.h b/arch/arm/include/asm/savebp.h new file mode 100644 index 0000000..3774e45 --- /dev/null +++ b/arch/arm/include/asm/savebp.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SAVEBP_H_ +#define _SAVEBP_H_ + +extern bootm_headers_t images; + +#endif /* _SAVEBP_H_ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..abf7a6a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,7 @@ COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o +COBJS-$(CONFIG_CMD_SAVEBP) += savebp.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif diff --git a/arch/arm/lib/savebp.c b/arch/arm/lib/savebp.c new file mode 100644 index 0000000..e0cfd83 --- /dev/null +++ b/arch/arm/lib/savebp.c @@ -0,0 +1,91 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <image.h> + +#include <nand.h> +#include <asm/savebp.h> + +#ifdef CONFIG_OMAP34XX +#include <asm/arch/sys_proto.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* This function writes given bootparams to NAND flash + * adr: Start adress of Kernel parameter image (ATAGS, FDT) + * length: length of the image in byte + * off: offset in NAND flash + * + * borrowd heavily from common/cmd_nand.c + */ +static void boot_params_to_nand(u_char *adr, size_t length, loff_t off) +{ + nand_info_t *nand = &nand_info[0]; /* use 0 as in SPL */ + nand_erase_options_t opts; +#ifdef CONFIG_OMAP34XX + omap_nand_switch_ecc(1); /* use hw ecc on omap for SPL compat */ +#endif + /* erase */ + memset(&opts, 0, sizeof(opts)); + opts.offset = off; + opts.length = length; + opts.quiet = 1; + opts.spread = 1; + nand_erase_opts(nand, &opts); + + /* write */ + if (nand_write_skip_bad(nand, off, &length, adr, 0)) { + printf("FAILED!\n"); + return; + } + + printf("Written to offset 0x%llX, size: %d bytes\n", + off, length); +} + +/* Saves FDT to NAND */ +int do_savebp_fdt(loff_t offset) +{ + boot_params_to_nand((u_char *)images.ft_addr, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + return 0; +} + + +/* Saves ATAGS to NAND */ +int do_savebp_atags(loff_t offset) +{ + /* Vars */ + bd_t *bd = gd->bd; + + printf("write ATAGS to NAND...\n"); + + /* save em */ + /* used fixed size - easier to read later just ignore garbage */ + boot_params_to_nand((u_char *)bd->bi_boot_params, + CONFIG_CMD_SAVEBP_WRITE_SIZE, offset); + + return 0; +} diff --git a/include/command.h b/include/command.h index 8310fe5..3ae68a8 100644 --- a/include/command.h +++ b/include/command.h @@ -101,6 +101,11 @@ extern int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+#ifdef CONFIG_CMD_SAVEBP +int do_savebp_atags(loff_t offset); +int do_savebp_fdt(loff_t offset); +#endif + #endif /* __ASSEMBLY__ */
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 80b441a..4d0573c 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -355,6 +355,7 @@
/* SPL OS boot options */ #define CONFIG_CMD_SAVEBP +#define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000

Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds the savebp implementation to the arm platform.
please reorder your series and let this come before 'Add savebp command' cause that patch uses functionality from this one.
Related CONFIGs: CONFIG_CMD_SAVEBP_WRITE_SIZE defines the size of the image to write
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: DEL _cosmetic_ old comment
V3 changes: nothing
arch/arm/include/asm/savebp.h | 27 ++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/savebp.c | 91 +++++++++++++++++++++++++++++++++++++++++ include/command.h | 5 ++ include/configs/devkit8000.h | 1 +
documentation of CONFIG_CMD_SAVEBP_WRITE_SIZE is missing
diff --git a/arch/arm/include/asm/savebp.h b/arch/arm/include/asm/savebp.h new file mode 100644 index 0000000..3774e45 --- /dev/null +++ b/arch/arm/include/asm/savebp.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2011
- Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#ifndef _SAVEBP_H_ +#define _SAVEBP_H_
+extern bootm_headers_t images;
You made that available globally in your first patch of this series, please remove that from first patch and move to this one.
<snip>
BTW while reading this patch I got another idea to solve problem 'how get we saved the boot information to <storage>'. The required information regardless of whether it is ATAGS or FDT is only a blob at some place in ram after the 'bootm x' commands used in 'Add savebp command'. Saving a blob from location X with size Y to location Z is easy and already implemented.
So the only required thing is to get the 'blob' prepared in RAM. In my opinion this could be a subcommand of bootm instead of a new command.
How about:
---8<--- # bootm savebp ...done boot information is @0x80000100 with size 0x100 # nandecc hw # nand erase ... # nand write 80000100 ... --->8---
regards
Andreas Bießmann

Dear Andreas,
On 08/25/2011 01:08 PM, Andreas Bießmann wrote:
Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds the savebp implementation to the arm platform.
please reorder your series and let this come before 'Add savebp command' cause that patch uses functionality from this one.
Will do.
Related CONFIGs: CONFIG_CMD_SAVEBP_WRITE_SIZE defines the size of the image to write
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
V2 changes: DEL _cosmetic_ old comment
V3 changes: nothing
arch/arm/include/asm/savebp.h | 27 ++++++++++++ arch/arm/lib/Makefile | 1 + arch/arm/lib/savebp.c | 91 +++++++++++++++++++++++++++++++++++++++++ include/command.h | 5 ++ include/configs/devkit8000.h | 1 +
documentation of CONFIG_CMD_SAVEBP_WRITE_SIZE is missing
Will add.
diff --git a/arch/arm/include/asm/savebp.h b/arch/arm/include/asm/savebp.h new file mode 100644 index 0000000..3774e45 --- /dev/null +++ b/arch/arm/include/asm/savebp.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2011
- Corscience GmbH& Co. KG - Simon Schwarzschwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#ifndef _SAVEBP_H_ +#define _SAVEBP_H_
+extern bootm_headers_t images;
You made that available globally in your first patch of this series, please remove that from first patch and move to this one.
ok.
<snip>
BTW while reading this patch I got another idea to solve problem 'how get we saved the boot information to<storage>'. The required information regardless of whether it is ATAGS or FDT is only a blob at some place in ram after the 'bootm x' commands used in 'Add savebp command'. Saving a blob from location X with size Y to location Z is easy and already implemented.
So the only required thing is to get the 'blob' prepared in RAM. In my opinion this could be a subcommand of bootm instead of a new command.
How about:
---8<--- # bootm savebp ...done boot information is @0x80000100 with size 0x100 # nandecc hw # nand erase ... # nand write 80000100 ... --->8---
This was actually my first implementation (although not with a switch): http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/102669
It was criticised because saving the parameter images is not the responsibility of bootm - which is true. Although adding a switch would be a cleaner solution than my first implementation - would that be acceptable?
How about implementing it as bootm subcommand?
regards
Andreas Bießmann
Regards & thx for reviewing Simon

Dear Simon,
Am 26.08.2011 12:10, schrieb Simon Schwarz:
Dear Andreas,
<snip>
BTW while reading this patch I got another idea to solve problem 'how get we saved the boot information to<storage>'. The required information regardless of whether it is ATAGS or FDT is only a blob at some place in ram after the 'bootm x' commands used in 'Add savebp command'. Saving a blob from location X with size Y to location Z is easy and already implemented.
So the only required thing is to get the 'blob' prepared in RAM. In my opinion this could be a subcommand of bootm instead of a new command.
How about:
---8<--- # bootm savebp ...done boot information is @0x80000100 with size 0x100 # nandecc hw # nand erase ... # nand write 80000100 ... --->8---
This was actually my first implementation (although not with a switch): http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/102669
It was criticised because saving the parameter images is not the responsibility of bootm - which is true. Although adding a switch would be a cleaner solution than my first implementation - would that be acceptable?
How about implementing it as bootm subcommand?
Another question, how often will one change the boot information for SPL booting? I guess most people will use the normal u-boot to test different configurations and start directly into the OS. When one has some satisfying configuration he will store this for SPL boot into flash regardless whether it is a separate command or a list of commands.
The current solution (having savebp command utilize do_bootm()) couples these two commands in a way which may lead to problems in future (but I don't know what others think about ... Wolfgang?).
I vote for a well documented guide or an example script to gather the boot information and store it for SPL booting (at least for this patch set). I know your bachelor thesis filing date is end of September and I would appreciate to have this functionality in before. The rest of this series seems quite good to me. Except for some minor changes to the arm-bootm prep command ... but read my answer to that patch.
best regards
Andreas Bießmann

This adds Linux booting to the SPL
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_SPL_MACHID Machine ID of the used board CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl.c | 48 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 7 +++- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..9c22c7a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+#ifdef CONFIG_SPL_OS_BOOT +/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +int spl_uboot_key(void) +{ + int val = 0; + if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) { + omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1); + val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY); + omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif /* CONFIG_SPL_OS_BOOT */ + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +#ifdef CONFIG_SPL_OS_BOOT +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_SYS_SPL_MACHID, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,12 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 4d0573c..3897ab4 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,7 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +328,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +358,9 @@ #define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 +#define CONFIG_SYS_SPL_MACHID MACH_TYPE_DEVKIT8000 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds Linux booting to the SPL
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_SPL_MACHID Machine ID of the used board CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: nothing
V3 changes: nothing
arch/arm/cpu/armv7/omap-common/spl.c | 48 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 7 +++- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..9c22c7a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+#ifdef CONFIG_SPL_OS_BOOT
Is this required? -ffunction-sections and --gc-sections should do he job.
+/* Return the value of the U-boot key
- RETURN
- 0 if not pressed
- positiv if pressed
- */
+int spl_uboot_key(void) +{
- int val = 0;
- if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) {
omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1);
val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY);
omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY);
- }
- return !val;
+} +#endif /* CONFIG_SPL_OS_BOOT */
void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +#ifdef CONFIG_SPL_OS_BOOT
here too.
+/* This function jumps to an image with argument. Normally an FDT or ATAGS
- image.
- arg: Pointer to paramter image in RAM
- */
+void jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%X\n", arg);
- typedef void (*image_entry_arg_t)(int, int, void *)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t) spl_image.entry_point;
- /* cleanup_before_linux(); */ /*write SPL function for that*/
- image_entry(0, CONFIG_SYS_SPL_MACHID, arg);
the MACHID is saved in gd->bd, couldn't this be used here? BTW: You missed setting CONFIG_SYS_SPL_MACHID in your board configuration header in this patch. Where is it done?
+} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif
+void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); }
void jump_to_image_no_args(void) __attribute__ ((noreturn));
void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,12 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT
- case IH_OS_LINUX:
debug("Jumping to Linux\n");
jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
break;
+#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 4d0573c..3897ab4 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,7 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +328,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +358,9 @@ #define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 +#define CONFIG_SYS_SPL_MACHID MACH_TYPE_DEVKIT8000 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

On 08/25/2011 01:28 PM, Andreas Bießmann wrote:
Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
This adds Linux booting to the SPL
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_SPL_MACHID Machine ID of the used board CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
V2 changes: nothing
V3 changes: nothing
arch/arm/cpu/armv7/omap-common/spl.c | 48 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 7 +++- 2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..9c22c7a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include<asm/arch/mmc_host_def.h> #include<i2c.h> #include<image.h> +#include<asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK,&gdata, CONFIG_SPL_TEXT_BASE); }
+#ifdef CONFIG_SPL_OS_BOOT
Is this required? -ffunction-sections and --gc-sections should do he job.
true. Will change
+/* Return the value of the U-boot key
- RETURN
- 0 if not pressed
- positiv if pressed
- */
+int spl_uboot_key(void) +{
- int val = 0;
- if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) {
omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1);
val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY);
omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY);
- }
- return !val;
+} +#endif /* CONFIG_SPL_OS_BOOT */
- void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header);
@@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +#ifdef CONFIG_SPL_OS_BOOT
here too.
too.
+/* This function jumps to an image with argument. Normally an FDT or ATAGS
- image.
- arg: Pointer to paramter image in RAM
- */
+void jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%X\n", arg);
- typedef void (*image_entry_arg_t)(int, int, void *)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t) spl_image.entry_point;
- /* cleanup_before_linux(); */ /*write SPL function for that*/
- image_entry(0, CONFIG_SYS_SPL_MACHID, arg);
the MACHID is saved in gd->bd, couldn't this be used here? BTW: You missed setting CONFIG_SYS_SPL_MACHID in your board configuration header in this patch. Where is it done?
In SPL gd is not fully initialized.
CONFIG_SYS_SPL_MACHID is set see below in include/configs/devkit8000.h
+} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif
+void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); }
- void jump_to_image_no_args(void) __attribute__ ((noreturn));
- void board_init_r(gd_t *id, ulong dummy) { u32 boot_device;
@@ -134,6 +172,12 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT
- case IH_OS_LINUX:
debug("Jumping to Linux\n");
jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
break;
+#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 4d0573c..3897ab4 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,7 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +328,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +358,9 @@ #define CONFIG_CMD_SAVEBP_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SAVEBP_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 +#define CONFIG_SYS_SPL_MACHID MACH_TYPE_DEVKIT8000 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */
Regards, thx for reviewing Simon

Dear Simon
Am 26.08.2011 12:17, schrieb Simon Schwarz:
On 08/25/2011 01:28 PM, Andreas Bießmann wrote:
Dear Simon,
<snip>
+/* This function jumps to an image with argument. Normally an FDT or ATAGS
- image.
- arg: Pointer to paramter image in RAM
- */
+void jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%X\n", arg);
- typedef void (*image_entry_arg_t)(int, int, void *)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t) spl_image.entry_point;
- /* cleanup_before_linux(); */ /*write SPL function for that*/
- image_entry(0, CONFIG_SYS_SPL_MACHID, arg);
the MACHID is saved in gd->bd, couldn't this be used here? BTW: You missed setting CONFIG_SYS_SPL_MACHID in your board configuration header in this patch. Where is it done?
In SPL gd is not fully initialized.
I see ... but how about using existing CONFIG_MACH_TYPE then?
CONFIG_SYS_SPL_MACHID is set see below in include/configs/devkit8000.h
Sorry for the noise, did not see it.
regards
Andreas Bießmann

Dear Andreas,
On 08/26/2011 12:45 PM, Andreas Bießmann wrote:
Dear Simon
Am 26.08.2011 12:17, schrieb Simon Schwarz:
On 08/25/2011 01:28 PM, Andreas Bießmann wrote:
Dear Simon,
<snip>
+/* This function jumps to an image with argument. Normally an FDT or ATAGS
- image.
- arg: Pointer to paramter image in RAM
- */
+void jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%X\n", arg);
- typedef void (*image_entry_arg_t)(int, int, void *)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t) spl_image.entry_point;
- /* cleanup_before_linux(); */ /*write SPL function for that*/
- image_entry(0, CONFIG_SYS_SPL_MACHID, arg);
the MACHID is saved in gd->bd, couldn't this be used here? BTW: You missed setting CONFIG_SYS_SPL_MACHID in your board configuration header in this patch. Where is it done?
In SPL gd is not fully initialized.
I see ... but how about using existing CONFIG_MACH_TYPE then?
done.
CONFIG_SYS_SPL_MACHID is set see below in include/configs/devkit8000.h
Sorry for the noise, did not see it.
regards
Andreas Bießmann
regards Simon

On 08/26/2011 01:22 PM, Simon Schwarz wrote:
Dear Andreas,
On 08/26/2011 12:45 PM, Andreas Bießmann wrote:
Dear Simon
Am 26.08.2011 12:17, schrieb Simon Schwarz:
On 08/25/2011 01:28 PM, Andreas Bießmann wrote:
Dear Simon,
<snip>
+/* This function jumps to an image with argument. Normally an FDT or ATAGS
- image.
- arg: Pointer to paramter image in RAM
- */
+void jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%X\n", arg);
- typedef void (*image_entry_arg_t)(int, int, void *)
- __attribute__ ((noreturn));
- image_entry_arg_t image_entry =
- (image_entry_arg_t) spl_image.entry_point;
- /* cleanup_before_linux(); */ /*write SPL function for that*/
- image_entry(0, CONFIG_SYS_SPL_MACHID, arg);
the MACHID is saved in gd->bd, couldn't this be used here? BTW: You missed setting CONFIG_SYS_SPL_MACHID in your board configuration header in this patch. Where is it done?
In SPL gd is not fully initialized.
I see ... but how about using existing CONFIG_MACH_TYPE then?
done.
I correct myself: not done.
If I use CONFIG_MACH_TYPE u-boot doesn't boot any more. This seems to be a bug in handling this define.
Any ideas on this?
Regards Simon

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl.c | 1 + arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c22c7a..0c38bbb 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -175,6 +175,7 @@ void board_init_r(gd_t *id, ulong dummy) #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); break; #endif diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 9b53742..3dd0eeb 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -62,6 +62,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -80,14 +92,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -119,7 +124,7 @@ void set_muxconf_regs(void) MUX_DEVKIT8000(); }
-#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_DRIVER_DM9000 /* * Routine: board_eth_init * Description: Setting up the Ethernet hardware. @@ -129,3 +134,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

This implements booting of Linux from NAND in SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 48 +++++++++++++++++++--------- 1 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..06254b2 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -46,26 +46,42 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + CONFIG_CMD_SAVEBP_WRITE_SIZE, + (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 06254b2..408892f 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -49,16 +51,29 @@ void spl_nand_load_image(void) #ifdef CONFIG_SPL_OS_BOOT if (!spl_uboot_key()) { /* load parameter image */ - nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS , + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SAVEBP_NAND_OFS, CONFIG_CMD_SAVEBP_WRITE_SIZE, - (void *)CONFIG_SYS_SPL_ARGS_ADDR); + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SAVEBP_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
/* load linux */ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds a Readme for the savebp command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: ADDED in V2
V3 changes: nothing --- doc/README.commands.savebp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 doc/README.commands.savebp
diff --git a/doc/README.commands.savebp b/doc/README.commands.savebp new file mode 100644 index 0000000..dc05ee0 --- /dev/null +++ b/doc/README.commands.savebp @@ -0,0 +1,28 @@ +The savebp (=save boot parameters) is used to save a boot parameter image to +non-volatile memory. + +To execute the command everything has to be in place as if bootm should be +used. +(kernel image, initrd-image, fdt-image etc.) + +Call is: +savebp [ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr] + +Only the first parameter [ftd|atags] is mandatory if the others are left blank +standard values are used. + +e.g: +savebp fdt 0x680000 0x82000000 0x80000100 - +savebo atags + +typical call on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND */ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +savebp fdt 0x680000 0x82000000 0x80000100 - /* Save the image */ + +------------Behind the scene--------------- +Atm the implementation is that we have /common/cmd_savebp.c which implements +the command tself and the subcommand calls to bootm. +Then the arch specific implementation of do_save_atags or do_savebp_fdt +in /arch/arm/lib is called.

Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
Adds a Readme for the savebp command
This patch should be merged with 'Add savebp command'
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: ADDED in V2
V3 changes: nothing
doc/README.commands.savebp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 doc/README.commands.savebp
diff --git a/doc/README.commands.savebp b/doc/README.commands.savebp new file mode 100644 index 0000000..dc05ee0 --- /dev/null +++ b/doc/README.commands.savebp @@ -0,0 +1,28 @@ +The savebp (=save boot parameters) is used to save a boot parameter image to +non-volatile memory.
+To execute the command everything has to be in place as if bootm should be +used. +(kernel image, initrd-image, fdt-image etc.)
+Call is: +savebp [ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr]
+Only the first parameter [ftd|atags] is mandatory if the others are left blank +standard values are used.
+e.g: +savebp fdt 0x680000 0x82000000 0x80000100 - +savebo atags
+typical call on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND */
why read the kernel image here?
+tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +savebp fdt 0x680000 0x82000000 0x80000100 - /* Save the image */
+------------Behind the scene--------------- +Atm the implementation is that we have /common/cmd_savebp.c which implements +the command tself and the subcommand calls to bootm.
^itself
+Then the arch specific implementation of do_save_atags or do_savebp_fdt +in /arch/arm/lib is called.
(therefore a errormessage should/could be added to common/cmd_savebp.c, if ARCH != ARM)
regrads
Andreas Bießmann

On 08/25/2011 01:15 PM, Andreas Bießmann wrote:
Dear Simon,
Am 25.08.2011 10:33, schrieb Simon Schwarz:
Adds a Readme for the savebp command
This patch should be merged with 'Add savebp command'
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
V2 changes: ADDED in V2
V3 changes: nothing
doc/README.commands.savebp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 doc/README.commands.savebp
diff --git a/doc/README.commands.savebp b/doc/README.commands.savebp new file mode 100644 index 0000000..dc05ee0 --- /dev/null +++ b/doc/README.commands.savebp @@ -0,0 +1,28 @@ +The savebp (=save boot parameters) is used to save a boot parameter image to +non-volatile memory.
+To execute the command everything has to be in place as if bootm should be +used. +(kernel image, initrd-image, fdt-image etc.)
+Call is: +savebp [ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr]
+Only the first parameter [ftd|atags] is mandatory if the others are left blank +standard values are used.
+e.g: +savebp fdt 0x680000 0x82000000 0x80000100 - +savebo atags
+typical call on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND */
why read the kernel image here?
Because bootm needs it.
+tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +savebp fdt 0x680000 0x82000000 0x80000100 - /* Save the image */
+------------Behind the scene--------------- +Atm the implementation is that we have /common/cmd_savebp.c which implements +the command tself and the subcommand calls to bootm.
^itself
+Then the arch specific implementation of do_save_atags or do_savebp_fdt +in /arch/arm/lib is called.
(therefore a errormessage should/could be added to common/cmd_savebp.c, if ARCH != ARM)
will add.
regrads
Andreas Bießmann
Regards Simon

Hello.
On 25-08-2011 12:33, Simon Schwarz wrote:
Adds a Readme for the savebp command
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
[...]
diff --git a/doc/README.commands.savebp b/doc/README.commands.savebp new file mode 100644 index 0000000..dc05ee0 --- /dev/null +++ b/doc/README.commands.savebp @@ -0,0 +1,28 @@ +The savebp (=save boot parameters) is used to save a boot parameter image to +non-volatile memory.
+To execute the command everything has to be in place as if bootm should be +used. +(kernel image, initrd-image, fdt-image etc.)
+Call is: +savebp [ftd|atags] [nand_offset] [kernel_addr] [initrd_addr] [fdt_addr]
+Only the first parameter [ftd|atags] is mandatory if the others are left blank +standard values are used.
+e.g: +savebp fdt 0x680000 0x82000000 0x80000100 - +savebo atags
+typical call on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND */ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +savebp fdt 0x680000 0x82000000 0x80000100 - /* Save the image */
+------------Behind the scene--------------- +Atm the implementation is that we have /common/cmd_savebp.c which implements
Only ATM.
+the command tself and the subcommand calls to bootm.
s/tself/itself/
+Then the arch specific implementation of do_save_atags or do_savebp_fdt +in /arch/arm/lib is called.
WBR, Sergei

Dear Simon Schwarz,
In message 1314261196-23197-1-git-send-email-simonschwarzcor@gmail.com you wrote:
Adds direct Linux boot to SPL. It implements a savebp command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Thanks for this work. It is highly appreciated.
checkpatch whines about not using strict_strtoull - since this is not available - I can't change this.
That's OK.
A question ex ante: what is the "bp" in "savebp" supposed to mean? I cannot come up with a good interpretation (might might show the effects of me working in a way too hot environment, or might indicate that we should chose a better name).
Best regards,
Wolfgang Denk

Dear Wolfgang Denk,
On 08/25/2011 12:17 PM, Wolfgang Denk wrote:
Dear Simon Schwarz,
In message1314261196-23197-1-git-send-email-simonschwarzcor@gmail.com you wrote:
Adds direct Linux boot to SPL. It implements a savebp command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Thanks for this work. It is highly appreciated.
checkpatch whines about not using strict_strtoull - since this is not available - I can't change this.
That's OK.
A question ex ante: what is the "bp" in "savebp" supposed to mean? I cannot come up with a good interpretation (might might show the effects of me working in a way too hot environment, or might indicate that we should chose a better name).
Today: Definatly too hot ;)
It means "save boot parameters" - better proposals welcome.
Best regards,
Wolfgang Denk
Regards Simon

Dear Simon,
In message 4E563136.2030608@gmail.com you wrote:
A question ex ante: what is the "bp" in "savebp" supposed to mean? I
...
It means "save boot parameters" - better proposals welcome.
If it's not too much of trouble I would indeed ask you to change that name.
Dismissing ecological considerations (should we save BP?), the ntroduction of such a command name would break a number of boards which use "save" as abbreviation for "saveenv" in their default configurations:
FPS850L M5253DEMO M5329EVB M5475EVB TQM850L TQM860M FPS860L M5271EVB M5373EVB M5485EVB TQM850M TQM862L M5208EVBE M5272C3 M54451EVB NSCU TQM855L TQM862M M52277EVB M5275EVB M54451EVB TQM823L TQM855M TQM866M M52277EVB M5282EVB M54455EVB TQM823M TQM860L virtlab2 M5235EVB M53017EVB M54455EVB
Yes, it has always been a bad idea to use abbreviated command names in environment settings, but it's being done again and again (myself not being immune to that temptation).
So please let's use a different name, one that does not start with "save".
Also, I think we should try and make the approach a bit more generic. Your current implementation supports only NAND as storage. But what if we want to do the same when booting from SDCard?
Maybe we should split the steps of extracting the FDT and ATAGS images and the process of actually writing them to persistent storage in two separate steps - for the second step we can then use existing standard commands, so only the "export" step is needed.
As all this is about preparing for a SPL boot, I suggest we name the new command "spl"; the resulting user interface could be like this:
spl export <img> addr [args ...]
with "img" being either "fdt" or "atags". [This would allow to add other SPL related commands easily in case we should need them.
What do you think?
Best regards,
Wolfgang Denk

Hi Wolfgang,
On Friday 26 August 2011 05:06 PM, Wolfgang Denk wrote:
Dear Simon,
...
As all this is about preparing for a SPL boot, I suggest we name the new command "spl"; the resulting user interface could be like this:
spl export <img> addr [args ...]
How about skipping the spl part and have command named 'export', if that's not existing already? To me this sounds better than 'spl export':
export <img> addr [args ...]
best regards, Aneesh

Dear Aneesh V,
In message 4E5787B7.1060209@ti.com you wrote:
As all this is about preparing for a SPL boot, I suggest we name the new command "spl"; the resulting user interface could be like this:
spl export <img> addr [args ...]
How about skipping the spl part and have command named 'export', if that's not existing already? To me this sounds better than 'spl export':
export <img> addr [args ...]
I think the command name should establish a mental context to what er are doing. We may need additional commands in the context of SPL setup, so "spl export" serves a double purpose: it creates the context that we are doing something for SPL, and it allows for extensions.
"export" alone could be about anything.
See for example the environment handling - here we also provide a sub-command "env export", but I (intentionally) never attempted to add "export" as direct command to export the environment variables.
Best regards,
Wolfgang Denk

Dear Wolfgang,
On 08/26/2011 01:36 PM, Wolfgang Denk wrote:
Dear Simon,
In message4E563136.2030608@gmail.com you wrote:
A question ex ante: what is the "bp" in "savebp" supposed to mean? I
...
It means "save boot parameters" - better proposals welcome.
If it's not too much of trouble I would indeed ask you to change that name.
Dismissing ecological considerations (should we save BP?), the ntroduction of such a command name would break a number of boards which use "save" as abbreviation for "saveenv" in their default configurations:
FPS850L M5253DEMO M5329EVB M5475EVB TQM850L TQM860M FPS860L M5271EVB M5373EVB M5485EVB TQM850M TQM862L M5208EVBE M5272C3 M54451EVB NSCU TQM855L TQM862M M52277EVB M5275EVB M54451EVB TQM823L TQM855M TQM866M M52277EVB M5282EVB M54455EVB TQM823M TQM860L virtlab2 M5235EVB M53017EVB M54455EVB
Yes, it has always been a bad idea to use abbreviated command names in environment settings, but it's being done again and again (myself not being immune to that temptation).
So please let's use a different name, one that does not start with "save".
Ecological reasons accepted :)
Also, I think we should try and make the approach a bit more generic. Your current implementation supports only NAND as storage. But what if we want to do the same when booting from SDCard?
Agreed.
Maybe we should split the steps of extracting the FDT and ATAGS images and the process of actually writing them to persistent storage in two separate steps - for the second step we can then use existing standard commands, so only the "export" step is needed.
Essentially it would already be possible to extract FDT/ATAGS if arm bootm implementation would implement prep subcommand.
I plan to split 1/8 from this set - see discussion for this patch. After that extract the images is just reading the start address and reading/calculating the size of them.
As all this is about preparing for a SPL boot, I suggest we name the new command "spl"; the resulting user interface could be like this:
spl export<img> addr [args ...]
with "img" being either "fdt" or "atags". [This would allow to add other SPL related commands easily in case we should need them.
No objections.
What do you think?
Best regards,
Wolfgang Denk
Regards Simon

Dear Wolfgang,
Am 26.08.2011 13:36, schrieb Wolfgang Denk:
Dear Simon,
In message 4E563136.2030608@gmail.com you wrote:
A question ex ante: what is the "bp" in "savebp" supposed to mean? I
...
It means "save boot parameters" - better proposals welcome.
<snip>
Also, I think we should try and make the approach a bit more generic. Your current implementation supports only NAND as storage. But what if we want to do the same when booting from SDCard?
Maybe we should split the steps of extracting the FDT and ATAGS images and the process of actually writing them to persistent storage in two separate steps - for the second step we can then use existing standard commands, so only the "export" step is needed.
Well the 'export' step can already be done by exiting commands. e.g.
bootm start bootm loados bootm ramdisk (if CONFIG_SYS_BOOT_RAMDISK_HIGH) bootm fdt (if CONFIG_OF_LIBFDT) bootm cmdline bootm bdt bootm prep
Now the required date is ready to use at gd->bd->bi_boot_params, this information should the board maintainer/user know as (for arm boards) it is always set in board_init().
The data can now be written with already available commands regardless whether they are nand or nor or fat/ext/ubi... write commands.
All this could be done in a new command or one can utilize a self written script ...
The main parts of Simon's series are 'gather boot information' (make it possible for arm), 'safe boot information' (the question discussed in this mail' and 'use spl to start linux'. In my opinion (with knowledge of his bachelor thesis filing date) the parts 'gather boot information' and 'use spl to start linux' are most important cause the part 'safe boot information' can currently be done with existing commands.
As all this is about preparing for a SPL boot, I suggest we name the new command "spl"; the resulting user interface could be like this:
spl export <img> addr [args ...]
with "img" being either "fdt" or "atags". [This would allow to add other SPL related commands easily in case we should need them.
Nevertheless +1 for spl in the new command name (only export as suggested by Aneesh) is a bit weak.
best regards
Andreas Bießmann

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260) - CONFIG_MACH_TYPE fix (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809) - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (6): removed static from images in cmd_bootm.c Add cmd_spl command devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem
arch/arm/cpu/armv7/omap-common/spl.c | 45 ++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 33 ++++-- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_spl.c | 214 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 16 ++- 10 files changed, 407 insertions(+), 30 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

This removes static modifier from cmd_bootm.c to make it public and usable by savebp
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- common/cmd_bootm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1966da4..c642299 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message --- common/Makefile | 1 + common/cmd_spl.c | 214 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 283 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 124a427..6945175 100644 --- a/common/Makefile +++ b/common/Makefile @@ -158,6 +158,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..51fc680 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* - do the work - */ + /* exec subcommands of do_bootm to init the images + * data structure */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", "cmdline", "bdt", "prep", '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 9cbdb5d..09a2505 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -353,4 +353,11 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 9b53742..3dd0eeb 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -62,6 +62,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -80,14 +92,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -119,7 +124,7 @@ void set_muxconf_regs(void) MUX_DEVKIT8000(); }
-#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_DRIVER_DM9000 /* * Routine: board_eth_init * Description: Setting up the Ethernet hardware. @@ -129,3 +134,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above --- arch/arm/cpu/armv7/omap-common/spl.c | 45 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 9 +++++- 2 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..4fe3837 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/omap_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,23 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +int spl_uboot_key(void) +{ + int val = 0; + if (!omap_request_gpio(CONFIG_SPL_OS_BOOT_KEY)) { + omap_set_gpio_direction(CONFIG_SPL_OS_BOOT_KEY, 1); + val = omap_get_gpio_datain(CONFIG_SPL_OS_BOOT_KEY); + omap_free_gpio(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +108,23 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +133,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +168,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 09a2505..72a4f40 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -38,7 +38,9 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 + +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -328,7 +330,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -358,6 +360,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 62 +++++++++++++++++++++------- 1 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..93f5183 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -46,26 +48,54 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 93f5183..ec56565 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -72,7 +72,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5: - Rebased on u-boot-ti - fixed MAKEALL warnings and errors - adapted to general gpio interface
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260) - CONFIG_MACH_TYPE fix (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809) - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (6): removed static from images in cmd_bootm.c Add cmd_spl command devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 31 +++- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_spl.c | 214 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 16 ++- 10 files changed, 410 insertions(+), 29 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

This removes static modifier from cmd_bootm.c to make it public and usable by savebp
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- common/cmd_bootm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8909ee7..cec6e7b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message --- common/Makefile | 1 + common/cmd_spl.c | 214 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 283 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 2edbd71..8b3321e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -160,6 +160,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..51fc680 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* - do the work - */ + /* exec subcommands of do_bootm to init the images + * data structure */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", "cmdline", "bdt", "prep", '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 1d49b86..629efb0 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -354,4 +354,11 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index f50d113..9124569 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +93,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -138,3 +143,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface --- arch/arm/cpu/armv7/omap-common/spl.c | 49 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 9 +++++- 2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..a7afd0a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +#ifdef CONFIG_SPL_OS_BOOT +int spl_uboot_key(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 629efb0..5d1014b 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -37,7 +37,9 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 + +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -329,7 +331,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -359,6 +361,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 62 +++++++++++++++++++++------- 1 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..93f5183 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -46,26 +48,54 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 93f5183..ec56565 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -72,7 +72,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5: - Rebased on u-boot-ti - fixed MAKEALL warnings and errors - adapted to general gpio interface Changes in V6: - Change old commit message
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260) - CONFIG_MACH_TYPE fix (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809) - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (6): removed static from images in cmd_bootm.c Add cmd_spl command devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL omap-common: Add NAND SPL linux booting omap-common: fixes BSS overwriting problem
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 +++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 31 +++- common/Makefile | 1 + common/cmd_bootm.c | 2 +- common/cmd_spl.c | 214 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 16 ++- 10 files changed, 410 insertions(+), 29 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

This removes static modifier from images variable in cmd_bootm.c.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
--- V6 changes: - removed the mention of savebp from commit message --- common/cmd_bootm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8909ee7..cec6e7b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -156,7 +156,7 @@ static boot_os_fn *boot_os[] = { #endif };
-static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +bootm_headers_t images; /* pointers to os/initrd/fdt images */
/* Allow for arch specific config before we boot */ void __arch_preboot_os(void)

Dear Simon Schwarz,
In message 1317284033-16188-2-git-send-email-simonschwarzcor@gmail.com you wrote:
This removes static modifier from images variable in cmd_bootm.c.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V6 changes:
- removed the mention of savebp from commit message
common/cmd_bootm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk

This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message --- common/Makefile | 1 + common/cmd_spl.c | 214 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 283 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 2edbd71..8b3321e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -160,6 +160,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..51fc680 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* - do the work - */ + /* exec subcommands of do_bootm to init the images + * data structure */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", "cmdline", "bdt", "prep", '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 1d49b86..629efb0 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -354,4 +354,11 @@ #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 #define CONFIG_SYS_NAND_U_BOOT_SIZE 0x200000
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Dear Simon Schwarz,
In message 1317284033-16188-3-git-send-email-simonschwarzcor@gmail.com you wrote:
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
common/Makefile | 1 + common/cmd_spl.c | 214 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 283 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
Applied, thanks.
Best regards,
Wolfgang Denk

Dear Simon Schwarz,
In message 1317284033-16188-3-git-send-email-simonschwarzcor@gmail.com you wrote:
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
...
+++ b/common/cmd_spl.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2011
- Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de
Incorrect multiline comment style.
+int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT
- /* Create subcommand string */
- char *subcommand[] = {"start", "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- "ramdisk",
+#endif
- "fdt", "cmdline", "bdt", "prep", '\0'};
Please format struct entries one per line.
- char *subcommand[] = {"start", "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- "ramdisk",
+#endif
- "cmdline", "bdt", "prep", '\0'};
Ditto.
+/* Arguments:
- 1: subcommand
- 2: image_type
- 3: nand_offset
- 4: kernel_addr
- 5: initrd_addr
- 6: fdt_adr */
Incorrect multiline comment style.
+/* Copyright (C) 2011
- Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de
Incorrect multiline comment style.
Please fix globally.
+#define SPL_EXPORT (0x00000001)
+#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002)
Please remove unnecessary parens.
Best regards,
Wolfgang Denk

Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 015cede..0906f49 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -77,6 +77,8 @@ u32 omap_boot_mode(void);
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index f50d113..9124569 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +93,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -138,3 +143,13 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL + * Linux boot */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

Dear Simon Schwarz,
In message 1317284033-16188-4-git-send-email-simonschwarzcor@gmail.com you wrote:
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
...
+#ifdef CONFIG_SPL_OS_BOOT +/* do board specific preperation before SPL
- Linux boot */
Incorrect multiline comment style.
Best regards,
Wolfgang Denk

This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface --- arch/arm/cpu/armv7/omap-common/spl.c | 49 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 9 +++++- 2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index c76fea6..a7afd0a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> +#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +#ifdef CONFIG_SPL_OS_BOOT +int spl_uboot_key(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +110,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +137,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -134,6 +172,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 629efb0..5d1014b 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -37,7 +37,9 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 + +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -329,7 +331,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -359,6 +361,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Dear Simon Schwarz,
In message 1317284033-16188-5-git-send-email-simonschwarzcor@gmail.com you wrote:
+/* Return the value of the U-boot key
- RETURN
- 0 if not pressed
- positiv if pressed
- */
Incorrect multiline comment style.
Please fix globally in _all_ your patches.
Best regards,
Wolfgang Denk

This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 62 +++++++++++++++++++++------- 1 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index af02a59..93f5183 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <timestamp_autogenerated.h> #include <version_autogenerated.h> @@ -33,6 +34,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -46,26 +48,54 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 93f5183..ec56565 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -72,7 +72,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5: - Rebased on u-boot-ti - fixed MAKEALL warnings and errors - adapted to general gpio interface Changes in V6: - Change old commit message
Changes in V7: - Correct style and format errors
based on: - The new SPL layout - OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260) - CONFIG_MACH_TYPE fix (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809) - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Related to: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669
Simon Schwarz (5): Add cmd_spl command omap-common: Add NAND SPL linux booting omap-common/spl: Add linux boot to SPL devkit8000/spl: init GPMC for dm9000 in SPL omap-common: fixes BSS overwriting problem
arch/arm/cpu/armv7/omap-common/spl.c | 51 +++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 63 ++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 33 ++++- common/Makefile | 1 + common/cmd_spl.c | 224 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 16 ++- 9 files changed, 423 insertions(+), 28 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) --- common/Makefile | 1 + common/cmd_spl.c | 224 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 1b672ad..4056e41 100644 --- a/common/Makefile +++ b/common/Makefile @@ -164,6 +164,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..eb498c6 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 6c51a27..f603f55 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -361,4 +361,11 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80108000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 62 +++++++++++++++++++++------- 1 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..1b9e171 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +47,54 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* load parameter image */ + /* load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

On Mon, Oct 31, 2011 at 9:23 AM, Simon Schwarz simonschwarzcor@googlemail.com wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
[snip]
- /* load parameter image */
- /* load to temp position since nand_spl_load_image reads
- * a whole block which is typically larger than
- * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite
- * following sections like BSS */
In v6 Wolfgang asked you to fix incorrect multiline comments in the whole series, but this is still here :( This is the only problem I see so if you can't respin this patch shortly I'll update the comment and SIgned-off-by the change since it's just reformatting a comment, which I assume is fine with you.

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501) --- arch/arm/cpu/armv7/omap-common/spl.c | 51 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 9 ++++- 2 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index d37ca0f..bafddfb 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,6 +64,26 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +#ifdef CONFIG_SPL_OS_BOOT +int spl_uboot_key(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -90,7 +111,26 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -99,8 +139,8 @@ static void jump_to_image_no_args(void) debug("image entry point: 0x%X\n", spl_image.entry_point); image_entry(); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -137,6 +177,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index f603f55..a848f4d 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -37,7 +37,9 @@ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-#define CONFIG_SYS_TEXT_BASE 0x80008000 +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 + +#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SDRC /* The chip has SDRC controller */
@@ -333,7 +335,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -366,6 +368,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
---
V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500) --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 3f2f004..ab86774 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -78,6 +78,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index fee0dff..11c8671 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +93,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -138,3 +143,15 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

On Mon, Oct 31, 2011 at 9:23 AM, Simon Schwarz simonschwarzcor@googlemail.com wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Not a NAK since the code does this before the patch as well, but a clean up to devkit8000 I'd like to see is switching this over to enable_gpmc_cs_config()

From: Simon Schwarz simonschwarzcor@googlemail.com
spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com ---
V2 changes: nothing
V3 changes: nothing
V4 changes: nothing
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 1b9e171..903255b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -71,7 +71,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

On 31/10/2011 17:23, Simon Schwarz wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
@@ -71,7 +71,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
spl_image.size, (void *)spl_image.load_addr);
spl_image.size,
(void *)spl_image.load_addr - sizeof(header));
^---
Do you mean maybe sizeof(*header) ?
However, spl_image.load_addr was already decremented in spl_parse_image_header() and correctly set to 64 byte before the load address. Do we really need it ?
I found the readon of the kernel corrupt image. We are setting a very hard address in /nand_spl_simple.c:
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
Because the image for a TI SOC is loaded at 0x80008000, we have a conflict and the image is corrupted where the ECC is computed.
It is not a really good idea to fix in this way where to compute the ECC. Should be not better to put it in the CONFIG_SYS_INIT_RAM_ADDR area ?
Best regards, Stefano Babic

On 12/06/2011 06:18 PM, Stefano Babic wrote:
On 31/10/2011 17:23, Simon Schwarz wrote:
From: Simon Schwarzsimonschwarzcor@googlemail.com
spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
@@ -71,7 +71,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
spl_image.size, (void *)spl_image.load_addr);
spl_image.size,
(void *)spl_image.load_addr - sizeof(header));
^---
Do you mean maybe sizeof(*header) ?
However, spl_image.load_addr was already decremented in spl_parse_image_header() and correctly set to 64 byte before the load address. Do we really need it ?
I found the readon of the kernel corrupt image. We are setting a very hard address in /nand_spl_simple.c:
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
Because the image for a TI SOC is loaded at 0x80008000, we have a conflict and the image is corrupted where the ECC is computed.
It is not a really good idea to fix in this way where to compute the ECC. Should be not better to put it in the CONFIG_SYS_INIT_RAM_ADDR area ?
Best regards, Stefano Babic
Hmm. This is from the former nand_spl.
Why not use malloc for this? Thanks to changes in the FAT driver we now have it in the SPL.
I don't see a reason to have this in SRAM when SDRAM is available.
Regards Simon

On 06/12/2011 18:53, Simon Schwarz wrote:
Hmm. This is from the former nand_spl.
Yes, I know. Until the load address does not conflict with the fix offset, we have never seen this problem.
Why not use malloc for this?
Of course, malloc - I want only to get rid of such hardcoded values ;-)
Thanks to changes in the FAT driver we now have it in the SPL.
I don't see a reason to have this in SRAM when SDRAM is available.
No reason at all, of course.
Stefano

Dear Simon Schwarz,
In message 4EDE56AB.3070504@gmail.com you wrote:
Why not use malloc for this? Thanks to changes in the FAT driver we now have it in the SPL.
No, please do NOT do that!!!
I knew I should have never accepted to allow this in the SPL fromt he beginning, and indeed it was a mistake not to block this.
Please now don't use it without thinking if it's really, really needed!
I recommend NOT to use malloc() at all in SPL code.
[Guess I should have a more carefull eye on all SPL related submissions and install a "grep-malloc-and-NAK" script. :-( ]
Best regards,
Wolfgang Denk

On 12/06/2011 11:53 AM, Simon Schwarz wrote:
On 12/06/2011 06:18 PM, Stefano Babic wrote:
I found the readon of the kernel corrupt image. We are setting a very hard address in /nand_spl_simple.c:
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
Because the image for a TI SOC is loaded at 0x80008000, we have a conflict and the image is corrupted where the ECC is computed.
It is not a really good idea to fix in this way where to compute the ECC. Should be not better to put it in the CONFIG_SYS_INIT_RAM_ADDR area ?
There's a patch to fix this (with some minor changes requested): http://patchwork.ozlabs.org/patch/128018/
Best regards, Stefano Babic
Hmm. This is from the former nand_spl.
Why not use malloc for this? Thanks to changes in the FAT driver we now have it in the SPL.
I don't see a reason to have this in SRAM when SDRAM is available.
nand_spl_simple.c is used by some very small SPL targets -- 4K or so. malloc doesn't fit.
-Scott

On 12/06/2011 06:18 PM, Stefano Babic wrote:
On 31/10/2011 17:23, Simon Schwarz wrote:
From: Simon Schwarzsimonschwarzcor@googlemail.com
spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
@@ -71,7 +71,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
spl_image.size, (void *)spl_image.load_addr);
spl_image.size,
(void *)spl_image.load_addr - sizeof(header));
^---
Do you mean maybe sizeof(*header) ?
However, spl_image.load_addr was already decremented in spl_parse_image_header() and correctly set to 64 byte before the load address. Do we really need it ?
[SNIP]
Best regards, Stefano Babic
You are right -> V9. Lets see if we get it to two digits ;)
Regards Simon

On 31/10/2011 17:23, Simon Schwarz wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5:
- Rebased on u-boot-ti
- fixed MAKEALL warnings and errors
- adapted to general gpio interface
Changes in V6:
- Change old commit message
Changes in V7:
- Correct style and format errors
based on:
- The new SPL layout
- OMAP3 new SPL layout (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260)
- CONFIG_MACH_TYPE fix (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
- Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Related to:
Hi Simon,
I am trying your patches on the Beagleboard - really I want to get a feeling how it is possible to introduce this mechanism for other architectures, too.
I have the major issue when the SPL gives the control to the kernel ( Linux-3.2.0-rc4-00154-g8e8da02). The code is started, however I get the error "uncompression error" in the gunzip() function of the kernel - really at the beginning of the code.
I have already checked the boot parameters area at address 0x80000100 created by spl export, and it is the same as the parameters generated by bootm under u-boot (where, of course, everything is working fine).
In jump_to_image_linux() all parameters are correct and image_entry points to the load address read from the uImage header (0x80008000 for TI kernel).
The most obvious thing could be that the Kernel image is not copied correctly from NAND to RAM, but checking some parts of memory I have not found any discrepancy. Of course, I must check better this point, but it seems to me not so probable that there is an issue with the NAND.
I have also added the cache functions to invalidate I-Cache to the SPL, calling the cleanup_before_linux() function - but no success. Do you have any hints ?
Best regards, Stefano Babic

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5: - Rebased on u-boot-ti - fixed MAKEALL warnings and errors - adapted to general gpio interface Changes in V6: - Change old commit message
Changes in V7: - Correct style and format errors
Changes in V8: - rebased on u-boot
based on: - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Simon Schwarz (5): Add cmd_spl command omap-common: Add NAND SPL linux booting devkit8000/spl: init GPMC for dm9000 in SPL omap-common: fixes BSS overwriting problem omap-common/spl: Add linux boot to SPL
arch/arm/cpu/armv7/omap-common/spl.c | 51 +++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 65 +++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 33 ++++- common/Makefile | 1 + common/cmd_spl.c | 224 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 13 ++- 9 files changed, 423 insertions(+), 27 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) REBASE on u-boot --- common/Makefile | 1 + common/cmd_spl.c | 224 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 1b672ad..4056e41 100644 --- a/common/Makefile +++ b/common/Makefile @@ -164,6 +164,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..eb498c6 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index a2e1d2d..bb7509b 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -368,4 +368,11 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
--- V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: FIX multiline comment style REBASE on u-boot --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 64 +++++++++++++++++++++------- 1 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..db52879 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +47,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index f1562ea..878ca71 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index fee0dff..11c8671 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +93,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -138,3 +143,15 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

From: Simon Schwarz simonschwarzcor@googlemail.com
spl_nand overwrote BSS section because it reads a whole block everytime. Now loads the block to spare area and just copy the needed junk to destination. Whole block read is necessary for ecc check!
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: nothing
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: REBASE on u-boot --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index db52879..486c34e 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -73,7 +73,8 @@ void spl_nand_load_image(void) CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, + (void *)spl_image.load_addr - sizeof(header)); } else #endif {

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes: REBASE on u-boot --- arch/arm/cpu/armv7/omap-common/spl.c | 51 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 6 +++- 2 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index d6d7d65..a739ba7 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,26 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +#ifdef CONFIG_SPL_OS_BOOT +int spl_uboot_key(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -91,7 +112,26 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -104,8 +144,8 @@ static void jump_to_image_no_args(void) #endif image_entry((u32 *)&boot_params_ptr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -142,6 +182,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index bb7509b..668253f 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -36,6 +36,7 @@ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000
/* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM @@ -339,7 +340,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -373,6 +374,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5: - Rebased on u-boot-ti - fixed MAKEALL warnings and errors - adapted to general gpio interface Changes in V6: - Change old commit message
Changes in V7: - Correct style and format errors
Changes in V8: - rebased on u-boot
Changes in V9: - Deleted a left-over patch from the series this also fixed the first problem mentioned here: - http://article.gmane.org/gmane.comp.boot-loaders.u-boot/119452
based on: - Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Simon Schwarz (4): Add cmd_spl command omap-common: Add NAND SPL linux booting devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL
arch/arm/cpu/armv7/omap-common/spl.c | 51 +++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 64 ++++++-- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 33 ++++- common/Makefile | 1 + common/cmd_spl.c | 224 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 13 ++- 9 files changed, 422 insertions(+), 27 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) REBASE on u-boot --- common/Makefile | 1 + common/cmd_spl.c | 224 ++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++ include/cmd_spl.h | 30 ++++++ include/configs/devkit8000.h | 7 ++ 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 1b672ad..4056e41 100644 --- a/common/Makefile +++ b/common/Makefile @@ -164,6 +164,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..eb498c6 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != '\0') { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = {"start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + '\0'}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = {"start", "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", "bdt", "prep", '\0'}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..dd3431d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +extern bootm_headers_t images; + +enum image_type {FDT, ATAGS}; + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index a2e1d2d..bb7509b 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -368,4 +368,11 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

On Tuesday 06 December 2011 13:34:35 Simon Schwarz wrote:
--- /dev/null +++ b/common/cmd_spl.c
+int call_bootm(int argc, char * const argv[], char *subcommand[])
static
+int spl_export_fdt(int argc, char * const argv[])
static
+#ifdef CONFIG_OF_LIBFDT
- /* Create subcommand string */
- char *subcommand[] = {"start",
that start needs to be on a new line
- '\0'};
if this were NULL (and the call_bootm() checked for that) would be more natural to argv[] processing
+int spl_export_atags(int argc, char * const argv[])
static
- char *subcommand[] = {"start", "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- "ramdisk",
+#endif
- "cmdline", "bdt", "prep", '\0'};
char *subcommand[] = { ... some strings ... ... some more strings ... };
+int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static
+{
delete that newline
- cmd_tbl_t *c;
i think you can const this ...
+int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static
- cmd_tbl_t *c;
i think you can const this ...
cmd = (int)c->cmd;
you're casting a pointer to an integer ? wtf is going on ?
--- /dev/null +++ b/include/cmd_spl.h
needs #ifdef protection against multiple inclusion
+extern bootm_headers_t images;
i get the feeling this isn't the right place for this and it should be in include/image.h instead ...
+enum image_type {FDT, ATAGS};
these names are too short, and the "image" namespace is taken by image.h already ... but leading on to the following defines ...
+#define SPL_EXPORT (0x00000001)
+#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002)
why do these need to be defines ? enum spl_export_type { SPL_EXPORT_FDT = 1, SPL_EXPORT_ATAGS = 2, };
also, drop the paren here
--- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h
generally board updates should be a sep commit -mike

Hi Mike,
2011/12/8 Mike Frysinger vapier@gentoo.org:
On Tuesday 06 December 2011 13:34:35 Simon Schwarz wrote:
--- /dev/null +++ b/common/cmd_spl.c
+int call_bootm(int argc, char * const argv[], char *subcommand[])
static
done.
+int spl_export_fdt(int argc, char * const argv[])
static
done.
+#ifdef CONFIG_OF_LIBFDT
- /* Create subcommand string */
- char *subcommand[] = {"start",
that start needs to be on a new line
- '\0'};
ok. Will change this to NULL.
if this were NULL (and the call_bootm() checked for that) would be more natural to argv[] processing
+int spl_export_atags(int argc, char * const argv[])
static
done
- char *subcommand[] = {"start", "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- "ramdisk",
+#endif
- "cmdline", "bdt", "prep", '\0'};
char *subcommand[] = { ... some strings ... ... some more strings ... };
done
+int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static
done
+{
delete that newline
done
- cmd_tbl_t *c;
i think you can const this ...
right should work -> done.
+int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static
done.
- cmd_tbl_t *c;
i think you can const this ...
done.
- cmd = (int)c->cmd;
you're casting a pointer to an integer ? wtf is going on ?
This is the same as in bootm.c. cmd is overloaded with the state of the statemachine. It is used as an integer.
--- /dev/null +++ b/include/cmd_spl.h
needs #ifdef protection against multiple inclusion
right. done.
+extern bootm_headers_t images;
i get the feeling this isn't the right place for this and it should be in include/image.h instead ...
I trust you with this ;)
+enum image_type {FDT, ATAGS};
these names are too short, and the "image" namespace is taken by image.h already ... but leading on to the following defines ...
Hm - it seems that they are not used anyway. deleted.
+#define SPL_EXPORT (0x00000001)
+#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002)
why do these need to be defines ? enum spl_export_type { SPL_EXPORT_FDT = 1, SPL_EXPORT_ATAGS = 2, };
also, drop the paren here
I used bootm.c as reference - it's the same there.
--- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h
generally board updates should be a sep commit
will do.
-mike
Thanks! Simon

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
--- V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: FIX multiline comment style REBASE on u-boot --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 64 +++++++++++++++++++++------- 1 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..db52879 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,7 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +47,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

On 06/12/2011 19:34, Simon Schwarz wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
Hi Simon,
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..db52879 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,7 @@ void spl_nand_load_image(void) { struct image_header *header;
- int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n");
@@ -45,26 +47,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT
- if (!spl_uboot_key()) {
Using a gpio or whatever mechanis is baord specific. What about to set a weak function and let that the board decides itself what to do ?
Not always a GPIO can be used for this purpose.
I have noted another issue. If the kernel image is not found, the fallback is to load u-boot. However, u-boot is searched at the address in NAND of the kernel, not at CONFIG_SYS_NAND_U_BOOT_OFFS.
This means that if the kernel is not loaded at all, the SPL starts to start a u-boot.bin instead of u-boot.img loaded at CONFIG_CMD_SPL_NAND_OFS, and this fails.
/*
* load parameter image
* load to temp position since nand_spl_load_image reads
* a whole block which is typically larger than
* CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite
* following sections like BSS
*/
nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
CONFIG_CMD_SPL_WRITE_SIZE,
(void *)CONFIG_SYS_TEXT_BASE);
/* copy to destintion */
for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
src = (int *)CONFIG_SYS_TEXT_BASE;
src < (int *)(CONFIG_SYS_TEXT_BASE +
CONFIG_CMD_SPL_WRITE_SIZE);
src++, dst++) {
writel(readl(src), dst);
}
/* load linux */
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header);
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
The function you write are in omap-common/spl_nand.c, but they are not specific for OMAP, and any architecture can profit from your work. What about to move common functions away from TI related directory ? I do not know which is the best place, maybe a new directory under the root as spllib ?
Stefano

On 12/07/2011 04:39 PM, Stefano Babic wrote:
On 06/12/2011 19:34, Simon Schwarz wrote:
From: Simon Schwarzsimonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com
Hi Simon,
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..db52879 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include<asm/u-boot.h> #include<asm/utils.h> #include<asm/arch/sys_proto.h> +#include<asm/io.h> #include<nand.h> #include<version.h> #include<asm/omap_common.h> @@ -32,6 +33,7 @@ void spl_nand_load_image(void) { struct image_header *header;
- int *src, *dst; switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n");
@@ -45,26 +47,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT
- if (!spl_uboot_key()) {
Using a gpio or whatever mechanis is baord specific. What about to set a weak function and let that the board decides itself what to do ?
Sounds reasonable to me. So I'am ok with this.
Not always a GPIO can be used for this purpose.
I have noted another issue. If the kernel image is not found, the fallback is to load u-boot. However, u-boot is searched at the address in NAND of the kernel, not at CONFIG_SYS_NAND_U_BOOT_OFFS.
This means that if the kernel is not loaded at all, the SPL starts to start a u-boot.bin instead of u-boot.img loaded at CONFIG_CMD_SPL_NAND_OFS, and this fails.
/*
* load parameter image
* load to temp position since nand_spl_load_image reads
* a whole block which is typically larger than
* CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite
* following sections like BSS
*/
nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
CONFIG_CMD_SPL_WRITE_SIZE,
(void *)CONFIG_SYS_TEXT_BASE);
/* copy to destintion */
for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
src = (int *)CONFIG_SYS_TEXT_BASE;
src< (int *)(CONFIG_SYS_TEXT_BASE +
CONFIG_CMD_SPL_WRITE_SIZE);
src++, dst++) {
writel(readl(src), dst);
}
/* load linux */
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header);
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
Hm, I don't think that we want any fallback here. I would prefere an error message and hang. The direct boot is designed to be used in the field - so IMHO we don't want to start the bootloader automatically if a normal startup fails.
The function you write are in omap-common/spl_nand.c, but they are not specific for OMAP, and any architecture can profit from your work. What about to move common functions away from TI related directory ? I do not know which is the best place, maybe a new directory under the root as spllib ?
Hm thats generally right. I would prefer lib_spl. Somehow it feels like going back to nand_spl times. Duno if there are better places?
The first two points I will fix/rework hopfully on monday (I'am not in the next two days)
Regards Simon

On 07/12/2011 18:57, Simon Schwarz wrote:
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
Hm, I don't think that we want any fallback here. I would prefere an error message and hang. The direct boot is designed to be used in the field - so IMHO we don't want to start the bootloader automatically if a normal startup fails.
this is also reasonable - we should drop the current behavior: if Linux is not found, SPL tries to start the loaded code as u-boot.bin.
Better to hang with a message.
The function you write are in omap-common/spl_nand.c, but they are not specific for OMAP, and any architecture can profit from your work. What about to move common functions away from TI related directory ? I do not know which is the best place, maybe a new directory under the root as spllib ?
Hm thats generally right. I would prefer lib_spl. Somehow it feels like going back to nand_spl times. Duno if there are better places?
Tom probably can suggest us something..
BR, Stefano Babic

On Wed, Dec 7, 2011 at 11:10 AM, Stefano Babic sbabic@denx.de wrote:
On 07/12/2011 18:57, Simon Schwarz wrote:
[snip]
The function you write are in omap-common/spl_nand.c, but they are not specific for OMAP, and any architecture can profit from your work. What about to move common functions away from TI related directory ? I do not know which is the best place, maybe a new directory under the root as spllib ?
Hm thats generally right. I would prefer lib_spl. Somehow it feels like going back to nand_spl times. Duno if there are better places?
Tom probably can suggest us something..
common/spl_<a few files>.c ?

Dear Simon Schwarz,
In message 4EDFA8FD.9000405@gmail.com you wrote:
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
Hm, I don't think that we want any fallback here. I would prefere an error message and hang. The direct boot is designed to be used in the field - so IMHO we don't want to start the bootloader automatically if a normal startup fails.
I feel it is better to start U-Boot and enable the user to analyze the situation instead of just hanging hard.
Just my 0.02#
Best regards,
Wolfgang Denk

On 07/12/2011 19:47, Wolfgang Denk wrote:
Dear Simon Schwarz,
In message 4EDFA8FD.9000405@gmail.com you wrote:
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
Hm, I don't think that we want any fallback here. I would prefere an error message and hang. The direct boot is designed to be used in the field - so IMHO we don't want to start the bootloader automatically if a normal startup fails.
I feel it is better to start U-Boot and enable the user to analyze the situation instead of just hanging hard.
Just my 0.02#
Personally I think also that having a fallback is a good idea. I have in mind a lot of boards that have not buttons or an available interface to a simple GPIO, making any interaction impossible. If we have not a fallback, we increase the risk for the end users to damage the boards if for example the kernel is updated.
Apart a mechanism with a GPIO, can we think to use in a simple way the console for this ? SPL supports it, and we could share the same mechanism for all boards, in such way as we stop the autoboot in U-Boot.
Stefano

On Thursday 08 December 2011 05:14:36 Stefano Babic wrote:
On 07/12/2011 19:47, Wolfgang Denk wrote:
Simon Schwarz wrote:
So if the parse function fails, we should have the fallback to u-boot, exactly as we have now the fallback from u-boot.img to u-boot.bin.
Hm, I don't think that we want any fallback here. I would prefere an error message and hang. The direct boot is designed to be used in the field - so IMHO we don't want to start the bootloader automatically if a normal startup fails.
I feel it is better to start U-Boot and enable the user to analyze the situation instead of just hanging hard.
Just my 0.02#
Personally I think also that having a fallback is a good idea. I have in mind a lot of boards that have not buttons or an available interface to a simple GPIO, making any interaction impossible. If we have not a fallback, we increase the risk for the end users to damage the boards if for example the kernel is updated.
Apart a mechanism with a GPIO, can we think to use in a simple way the console for this ? SPL supports it, and we could share the same mechanism for all boards, in such way as we stop the autoboot in U-Boot.
isn't this the purpose of the boot progress / led code ? -mike

On 08/12/2011 16:54, Mike Frysinger wrote:
Apart a mechanism with a GPIO, can we think to use in a simple way the console for this ? SPL supports it, and we could share the same mechanism for all boards, in such way as we stop the autoboot in U-Boot.
isn't this the purpose of the boot progress / led code ? -mike
Well, I would like to import less code in SPL to take it as small as possible. Under U-Boot we have a lot of possibilities, but we need only a simple way with SPL.
Stefano

On Thursday 08 December 2011 11:40:48 Stefano Babic wrote:
On 08/12/2011 16:54, Mike Frysinger wrote:
Apart a mechanism with a GPIO, can we think to use in a simple way the console for this ? SPL supports it, and we could share the same mechanism for all boards, in such way as we stop the autoboot in U-Boot.
isn't this the purpose of the boot progress / led code ?
Well, I would like to import less code in SPL to take it as small as possible. Under U-Boot we have a lot of possibilities, but we need only a simple way with SPL.
the status led should be fairly light weight (once you've got the GPIO core). check out the two files: drivers/misc/status_led.c drivers/misc/gpio_led.c -mike

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index f1562ea..878ca71 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index fee0dff..11c8671 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,18 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); + writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); + writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); + writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); + writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); + writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); + writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +93,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -138,3 +143,15 @@ int board_eth_init(bd_t *bis) return dm9000_initialize(bis); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif

On Tue, Dec 6, 2011 at 11:34 AM, Simon Schwarz simonschwarzcor@googlemail.com wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
Since we have a little time before this goes into a 'next' branch, can you please rework this to an enable_gpmc_cs_config() call? Thanks.

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes: REBASE on u-boot --- arch/arm/cpu/armv7/omap-common/spl.c | 51 ++++++++++++++++++++++++++++++++- include/configs/devkit8000.h | 6 +++- 2 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index d6d7d65..a739ba7 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,26 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Return the value of the U-boot key + * + * RETURN + * 0 if not pressed + * positiv if pressed + */ +#ifdef CONFIG_SPL_OS_BOOT +int spl_uboot_key(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -91,7 +112,26 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%X\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +void jump_to_image_linux(void *) __attribute__ ((noreturn)); +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -104,8 +144,8 @@ static void jump_to_image_no_args(void) #endif image_entry((u32 *)&boot_params_ptr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -142,6 +182,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index bb7509b..668253f 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -36,6 +36,7 @@ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3430 1 /* which is in a 3430 */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000
/* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM @@ -339,7 +340,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -373,6 +374,9 @@ #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ 0x400000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 #define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) #endif /* __CONFIG_H */

On Tuesday 06 December 2011 13:34:38 Simon Schwarz wrote:
--- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c
+void jump_to_image_linux(void *arg) +{ ... +} +void jump_to_image_linux(void *) __attribute__ ((noreturn));
no need for this. do it in one line: __noreturn void jump_to_image_linux(void *arg) { ... }
(include linux/compiler.h if need be) -mike

On Wed, Dec 7, 2011 at 5:50 PM, Mike Frysinger vapier@gentoo.org wrote:
On Tuesday 06 December 2011 13:34:38 Simon Schwarz wrote:
--- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c
+void jump_to_image_linux(void *arg) +{ ... +} +void jump_to_image_linux(void *) __attribute__ ((noreturn));
no need for this. do it in one line: __noreturn void jump_to_image_linux(void *arg) { ... }
(include linux/compiler.h if need be)
Style? I prefer the single line version myself but I've seen lots of the long form when poking around before.

On Wednesday 07 December 2011 20:09:13 Tom Rini wrote:
On Wed, Dec 7, 2011 at 5:50 PM, Mike Frysinger vapier@gentoo.org wrote:
On Tuesday 06 December 2011 13:34:38 Simon Schwarz wrote:
--- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c
+void jump_to_image_linux(void *arg) +{ ... +} +void jump_to_image_linux(void *) __attribute__ ((noreturn));
no need for this. do it in one line: __noreturn void jump_to_image_linux(void *arg) { ... }
(include linux/compiler.h if need be)
Style? I prefer the single line version myself but I've seen lots of the long form when poking around before.
i think it's a matter of people not knowing the subtle behavior of gcc attributes and func prototypes vs func definitions.
i.e. they're used to seeing: void foo(void) __attribute__((...));
so they try doing: void foo(void) __attribute__((...)) { }
which fails to build, so they get confused and just copy & paste the line twice since that works. that's my biggest problem with this -- the manual duplication of the func signature.
what they don't realize is you can do w/out duplication: void __attribute__((...)) foo(void) { } -mike

On Wednesday, December 7, 2011, Mike Frysinger vapier@gentoo.org wrote:
On Wednesday 07 December 2011 20:09:13 Tom Rini wrote:
On Wed, Dec 7, 2011 at 5:50 PM, Mike Frysinger vapier@gentoo.org wrote:
On Tuesday 06 December 2011 13:34:38 Simon Schwarz wrote:
--- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c
+void jump_to_image_linux(void *arg) +{ ... +} +void jump_to_image_linux(void *) __attribute__ ((noreturn));
no need for this. do it in one line: __noreturn void jump_to_image_linux(void *arg) { ... }
(include linux/compiler.h if need be)
Style? I prefer the single line version myself but I've seen lots of the long form when poking around before.
i think it's a matter of people not knowing the subtle behavior of gcc attributes and func prototypes vs func definitions.
i.e. they're used to seeing: void foo(void) __attribute__((...));
so they try doing: void foo(void) __attribute__((...)) { }
which fails to build, so they get confused and just copy & paste the line twice since that works. that's my biggest problem with this -- the manual duplication of the func signature.
what they don't realize is you can do w/out duplication: void __attribute__((...)) foo(void) { }
Quite possible. Wolfgang, is there a style thing here or would you like to see all of the long form versions converted to the short form and use <linux/compiler.h>? If so I'll make a note on my todo list... Thanks!

Dear Tom Rini,
In message CA+M6bXn-YQyYWcp++xN8Nyu283wfW2kOgiEQ8P08pbHsg7sM7w@mail.gmail.com you wrote:
what they don't realize is you can do w/out duplication: void __attribute__((...)) foo(void) { }
Quite possible. Wolfgang, is there a style thing here or would you like to see all of the long form versions converted to the short form and use <linux/compiler.h>? If so I'll make a note on my todo list... Thanks!
It would be nice to see this converted to using the short form.
Thanks in advance.
Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
On Wednesday, December 7, 2011, Mike Frysinger <<a href=3D"mailto:vapier= @gentoo.org">vapier@gentoo.org</a>> wrote:<br>> On Wednesday 07 Decem= ber 2011 20:09:13 Tom Rini wrote:<br>>> On Wed, Dec 7, 2011 at 5:50 P= M, Mike Frysinger <<a href=3D"mailto:vapier@gentoo.org">vapier@gentoo.or= g</a>> wrote:<br>
...
Um... please don't.
Best regards,
Wolfgang Denk

On Tue, Dec 6, 2011 at 11:34 AM, Simon Schwarz simonschwarzcor@googlemail.com wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
After talking with Albert on IRC about this, there's concern about the general impact (esp since the pre-req is a generic change) so it'd be best if people can try and Tested-by this series now and get this in early in the merge window to check for unexpected fallout.

On 06/12/2011 23:41, Tom Rini wrote:
On Tue, Dec 6, 2011 at 11:34 AM, Simon Schwarz simonschwarzcor@googlemail.com wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
After talking with Albert on IRC about this, there's concern about the general impact (esp since the pre-req is a generic change) so it'd be best if people can try and Tested-by this series now and get this in early in the merge window to check for unexpected fallout.
Agree with you - I am testing the patches and I am finding some issues - better to be ready when the merge window will open again.
Stefano

On 06/12/2011 19:34, Simon Schwarz wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5:
- Rebased on u-boot-ti
- fixed MAKEALL warnings and errors
- adapted to general gpio interface
Changes in V6:
- Change old commit message
Changes in V7:
- Correct style and format errors
Changes in V8:
- rebased on u-boot
Changes in V9:
- Deleted a left-over patch from the series this also fixed the first problem mentioned here:
based on:
- Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Hi Simon,
I am testing your patches (V9) - the kernel image is not corrupted anynmore due to the ECC, but I am not able to boot successfully the kernel. I am testing now with a second hardware (twister, I have recently posted the patches for this board, also OMAP3) to have a comparison with the beagleboard.
The kernel starts but it stops very soon, I think after the machine-id check and it seems it cannot poarse correctly the tags. However, the parameters exported by "spl export" are correct and I have not found any difference with the "bootm" command under U-boot.
I am starting to debug the kernel to get some more infos, but do you have some hints ? How do you test it ?
Best regards, Stefano Babic

On 12/07/2011 04:52 PM, Stefano Babic wrote:
On 06/12/2011 19:34, Simon Schwarz wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V5:
- Rebased on u-boot-ti
- fixed MAKEALL warnings and errors
- adapted to general gpio interface
Changes in V6:
- Change old commit message
Changes in V7:
- Correct style and format errors
Changes in V8:
- rebased on u-boot
Changes in V9:
- Deleted a left-over patch from the series this also fixed the first problem mentioned here:
based on:
- Prep subcommand patch for arm (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)
Hi Simon,
I am testing your patches (V9) - the kernel image is not corrupted anynmore due to the ECC, but I am not able to boot successfully the kernel. I am testing now with a second hardware (twister, I have recently posted the patches for this board, also OMAP3) to have a comparison with the beagleboard.
The kernel starts but it stops very soon, I think after the machine-id check and it seems it cannot poarse correctly the tags. However, the parameters exported by "spl export" are correct and I have not found any difference with the "bootm" command under U-boot.
I am starting to debug the kernel to get some more infos, but do you have some hints ? How do you test it ?
Best regards, Stefano Babic
Hi Stefano,
great that someone has a closer look on this!
The only problem i had was a wrong machine id (The one to use is defined in the board config file).
So I didn't do any debugging in the kernel besides from activating early printk.
Regards Simon

On Tuesday 06 December 2011 13:34:34 Simon Schwarz wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
sounds like you just obsoleted Qi. nice! http://wiki.openmoko.org/wiki/Qi -mike

Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V10: - spl_start_uboot replaces spl_uboot_key and is defined weak - if the linux image is not found a normal u-boot is started - some minor changes
based on: - Prep subcommand patch for arm
Please test this patch - there have been major changes!
Simon Schwarz (7): Add cmd_spl command devki8000: add config for spl command omap-common: Add NAND SPL linux booting devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL omap/spl: change output of spl_parse_image_header devkit8000: Implement and activate direct OS boot
arch/arm/cpu/armv7/omap-common/spl.c | 51 ++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 75 ++++++++-- arch/arm/include/asm/omap_common.h | 3 + board/timll/devkit8000/devkit8000.c | 57 ++++++- common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 15 ++- include/image.h | 2 + 10 files changed, 464 insertions(+), 30 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) REBASE on u-boot
V8 changes: nothing
V9 changes: nothing
V10 changes: CHG list is now terminated by NULL not \0 ADD static modifiers to most of cmd_spl.c functions DEL board changes ADD include protection to cmd_spl.h DEL not used enum image_tyep CHG some cosmetic CHG images extern moved from cmd_spl.h to image.h --- common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 2d9ae8c..910c056 100644 --- a/common/Makefile +++ b/common/Makefile @@ -162,6 +162,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..deab8e9 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != NULL) { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +static int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..2845367 --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_ + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) + +#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index 466c980..2cc0575 100644 --- a/include/image.h +++ b/include/image.h @@ -267,6 +267,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or

This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V10 changes: This is new in V10 was split from other patch --- include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 758326b..d3ca0dd 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -356,4 +356,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
--- V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: FIX multiline comment style REBASE on u-boot
V9 changes: nothing
V10 changes: ADD unused __attribute__ to src and dst because they provoked a warning if SPL os boot was not active --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 66 ++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..2a66214 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,9 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +49,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: use enable_gpmc_cs_config to config the GPMC for dm9000 --- arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 39 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 1ec651b..62200e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index b06aab6..05de3c1 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,24 @@ int board_init(void) return 0; }
+static u32 gpmc_net_config[GPMC_MAX_REG] = { + NET_GPMC_CONFIG1, + NET_GPMC_CONFIG2, + NET_GPMC_CONFIG3, + NET_GPMC_CONFIG4, + NET_GPMC_CONFIG5, + NET_GPMC_CONFIG6, + NET_GPMC_CONFIG7, +}; + + +/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +99,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -139,6 +150,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: CHG used short form to mark not returning function DEL devkit8000 config changes from this patch CHG spl_uboot_key renamed to spl_start_uboot and defined weak to be implemented board specific CHG If the Linux image for the direct OS boot is not found the SPL tries to load a u-boot image CHG %X in %p in debug message --- arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++++++++++++++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 17 +++++++--- arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c35a09..955a83b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + printf("SPL: Please implement spl_start_uboot() for your board\n"); + printf("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -91,7 +111,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +__noreturn void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -105,8 +143,8 @@ static void jump_to_image_no_args(void) u32 boot_params_ptr_addr = (u32)&boot_params_ptr; image_entry((u32 *)boot_params_ptr_addr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -146,6 +184,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 2a66214..ec64226 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -29,7 +29,6 @@ #include <version.h> #include <asm/omap_common.h>
- void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT - if (!spl_uboot_key()) { + if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -74,9 +73,17 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } else + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else { + printf("The Expected Linux image was not" + "found. Please check your NAND" + "configuration.\n"); + printf("Trying to start u-boot now...\n"); + } + } #endif { #ifdef CONFIG_NAND_ENV_DST diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 62200e5..8a7d1e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -89,6 +89,7 @@ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); int spl_uboot_key(void); void spl_board_prepare_for_linux(void); +int spl_start_uboot(void);
/* NAND SPL functions */ void spl_nand_load_image(void);

On 13/12/2011 11:20, Simon Schwarz wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com
Hi Simon and Myself (as I will continue Simon's work),
void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT
- if (!spl_uboot_key()) {
- if (!spl_start_uboot()) { /*
- load parameter image
- load to temp position since nand_spl_load_image reads
@@ -74,9 +73,17 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header);
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
spl_image.size, (void *)spl_image.load_addr);
- } else
if (header->ih_os == IH_OS_LINUX) {
/* happy - was a linux */
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
spl_image.size, (void *)spl_image.load_addr);
From my test I found a bug here. The image is loaded, but because we do
not return from function, code goes on and loads u-boot, too. As result, u-boot instead of linux is always started.
If I am not overseeing something, I'll fix in next version.
} else {
printf("The Expected Linux image was not"
"found. Please check your NAND"
"configuration.\n");
printf("Trying to start u-boot now...\n");
}
- }
#endif {
in fact we have not anymore the "else" branch, and now u-boot is loaded.
Regards, Stefano

This only outputs "Assuming u-boot.bin..." if debug is active.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- v10 changes: NEW in v10 --- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 955a83b..1671a03 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -101,7 +101,7 @@ void spl_parse_image_header(const struct image_header *header) /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - puts("Assuming u-boot.bin ..\n"); + debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE;

- Implements spl_start_uboot() for devkit8000 - Add configs to activate direct OS boot from SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com --- V10 changes: sliced from the implementation added an implementation of spl_start_uboot for devkit8000 --- board/timll/devkit8000/devkit8000.c | 18 ++++++++++++++++++ include/configs/devkit8000.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 05de3c1..6ca4fe2 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -41,6 +41,7 @@ #include <asm/arch/mem.h> #include <asm/mach-types.h> #include "devkit8000.h" +#include <asm/gpio.h> #ifdef CONFIG_DRIVER_DM9000 #include <net.h> #include <netdev.h> @@ -160,6 +161,23 @@ void spl_board_prepare_for_linux(void) gpmc_dm9000_config(); }
+/* + * devkit8000 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if the button is not pressed + * 1 if the button is pressed + */ +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} #endif
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index d3ca0dd..2bcab72 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -35,7 +35,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ - +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 /* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM * 64 bytes before this address should be set aside for u-boot.img's @@ -327,7 +327,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -357,6 +357,9 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
/* SPL OS boot options */ +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_CMD_SPL #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\

Hi,
I have not yet factored out the general elements of SPL direct boot. ATM i don't have the time - so if someone wants to take it :)
If not this will have to wait, maybe until next year.
Regards Simon
On 12/13/2011 11:20 AM, Simon Schwarz wrote:
Adds direct Linux boot to SPL. It implements a spl export command to save ATAGS or FDT to NAND flash. The kernel image has to be in place for this!
Changes in V10:
- spl_start_uboot replaces spl_uboot_key and is defined weak
- if the linux image is not found a normal u-boot is started
- some minor changes
based on:
- Prep subcommand patch for arm
Please test this patch - there have been major changes!
Simon Schwarz (7): Add cmd_spl command devki8000: add config for spl command omap-common: Add NAND SPL linux booting devkit8000/spl: init GPMC for dm9000 in SPL omap-common/spl: Add linux boot to SPL omap/spl: change output of spl_parse_image_header devkit8000: Implement and activate direct OS boot
arch/arm/cpu/armv7/omap-common/spl.c | 51 ++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 75 ++++++++-- arch/arm/include/asm/omap_common.h | 3 + board/timll/devkit8000/devkit8000.c | 57 ++++++- common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++ include/cmd_spl.h | 30 ++++ include/configs/devkit8000.h | 15 ++- include/image.h | 2 + 10 files changed, 464 insertions(+), 30 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h

On 13/12/2011 11:25, Simon Schwarz wrote:
Hi,
Hi Simon,
I have not yet factored out the general elements of SPL direct boot. ATM i don't have the time - so if someone wants to take it :)
I take your proposal and I will go on working on this patchset - I can test the patches on a AM3517 board (I get Linux booting). However, I hope you can have a little piece of time to review my changes ;-)
Stefano

On 12/13/2011 11:36 AM, Stefano Babic wrote:
On 13/12/2011 11:25, Simon Schwarz wrote:
Hi,
Hi Simon,
I have not yet factored out the general elements of SPL direct boot. ATM i don't have the time - so if someone wants to take it :)
I take your proposal and I will go on working on this patchset - I can test the patches on a AM3517 board (I get Linux booting). However, I hope you can have a little piece of time to review my changes ;-)
Stefano
Hi Stefano,
great! I will do my best ;)
Regards Simon

Hi,
this is a new submission of the Simon's work to add a way to boot Linux directly from the SPL. From the last patchset series, the main changes introduced by me are the following:
- compile the cache functions in SPL to make cleanup_before_linux() available. - do not call I"C function on boards where I2C is not available - fix a bug from last version (fallback to U-Boot) - move all related SPL stuff to common/ and fix omap related functions.
Tested on the twister board (patches for this board in u-boot-ti, next)
Note: to test it is also required Simon's patch:
arm: Add Prep subcommand support to bootm
http://patchwork.ozlabs.org/patch/129753/
[PATCH V11 01/13] Add cmd_spl command [PATCH V11 02/13] devki8000: add config for spl command [PATCH V11 03/13] omap-common: Add NAND SPL linux booting [PATCH V11 04/13] devkit8000/spl: init GPMC for dm9000 in SPL [PATCH V11 05/13] omap-common/spl: Add linux boot to SPL [PATCH V11 06/13] omap/spl: change output of spl_parse_image_header [PATCH V11 07/13] devkit8000: Implement and activate direct OS boot [PATCH V11 08/13] Add cache functions to SPL for armv7 [PATCH V11 09/13] OMAP3: SPL: do not call I2C init if no I2C is [PATCH V11 10/13] OMAP3: move SPL files to be used by other [PATCH V11 11/13] TI: SPL: make SPL available for other SOCs as TI [PATCH V11 12/13] SPL: call cleanup_before_linux() before booting [PATCH V11 13/13] OMAP3: twister: add support to boot Linux from

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) REBASE on u-boot
V8 changes: nothing
V9 changes: nothing
V10 changes: CHG list is now terminated by NULL not \0 ADD static modifiers to most of cmd_spl.c functions DEL board changes ADD include protection to cmd_spl.h DEL not used enum image_tyep CHG some cosmetic CHG images extern moved from cmd_spl.h to image.h
V11 changes: nothing
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 1be7236..91f3f2e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -165,6 +165,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..deab8e9 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != NULL) { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +static int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..2845367 --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_ + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) + +#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index 466c980..2cc0575 100644 --- a/include/image.h +++ b/include/image.h @@ -267,6 +267,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de ---
V10 changes: This is new in V10 was split from other patch
include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 2b6a6ee..e323877 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -351,4 +351,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: FIX multiline comment style REBASE on u-boot
V9 changes: nothing
V10 changes: ADD unused __attribute__ to src and dst because they provoked a warning if SPL os boot was not active
V11 changes: nothing arch/arm/cpu/armv7/omap-common/spl_nand.c | 66 ++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..2a66214 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,9 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +49,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: use enable_gpmc_cs_config to config the GPMC for dm9000
arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 39 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 1ec651b..62200e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index b06aab6..05de3c1 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,24 @@ int board_init(void) return 0; }
+static u32 gpmc_net_config[GPMC_MAX_REG] = { + NET_GPMC_CONFIG1, + NET_GPMC_CONFIG2, + NET_GPMC_CONFIG3, + NET_GPMC_CONFIG4, + NET_GPMC_CONFIG5, + NET_GPMC_CONFIG6, + NET_GPMC_CONFIG7, +}; + + +/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +99,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -139,6 +150,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: CHG used short form to mark not returning function DEL devkit8000 config changes from this patch CHG spl_uboot_key renamed to spl_start_uboot and defined weak to be implemented board specific CHG If the Linux image for the direct OS boot is not found the SPL tries to load a u-boot image CHG %X in %p in debug message
V11 changes: U-Boot was always started instead of Linux
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++++++++++++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 53 ++++++++++++++++------------ arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 78 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c35a09..955a83b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + printf("SPL: Please implement spl_start_uboot() for your board\n"); + printf("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -91,7 +111,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +__noreturn void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -105,8 +143,8 @@ static void jump_to_image_no_args(void) u32 boot_params_ptr_addr = (u32)&boot_params_ptr; image_entry((u32 *)boot_params_ptr_addr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -146,6 +184,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 2a66214..1295e88 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -29,7 +29,6 @@ #include <version.h> #include <asm/omap_common.h>
- void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT - if (!spl_uboot_key()) { + if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -74,31 +73,39 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } else + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); + return; + } else { + printf("The Expected Linux image was not" + "found. Please check your NAND" + "configuration.\n"); + printf("Trying to start u-boot now...\n"); + } + } #endif - { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); nand_deselect(); } diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 62200e5..8a7d1e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -89,6 +89,7 @@ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); int spl_uboot_key(void); void spl_board_prepare_for_linux(void); +int spl_start_uboot(void);
/* NAND SPL functions */ void spl_nand_load_image(void);

From: Simon Schwarz simonschwarzcor@googlemail.com
This only outputs "Assuming u-boot.bin..." if debug is active.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de ---
V11: no changes
arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 955a83b..1671a03 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -101,7 +101,7 @@ void spl_parse_image_header(const struct image_header *header) /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - puts("Assuming u-boot.bin ..\n"); + debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE;

From: Simon Schwarz simonschwarzcor@googlemail.com
- Implements spl_start_uboot() for devkit8000 - Add configs to activate direct OS boot from SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de ---
V10 changes: sliced from the implementation added an implementation of spl_start_uboot for devkit8000
board/timll/devkit8000/devkit8000.c | 18 ++++++++++++++++++ include/configs/devkit8000.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 05de3c1..6ca4fe2 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -41,6 +41,7 @@ #include <asm/arch/mem.h> #include <asm/mach-types.h> #include "devkit8000.h" +#include <asm/gpio.h> #ifdef CONFIG_DRIVER_DM9000 #include <net.h> #include <netdev.h> @@ -160,6 +161,23 @@ void spl_board_prepare_for_linux(void) gpmc_dm9000_config(); }
+/* + * devkit8000 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if the button is not pressed + * 1 if the button is pressed + */ +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} #endif
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index e323877..eb7c376 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -35,7 +35,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ - +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 /* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM * 64 bytes before this address should be set aside for u-boot.img's @@ -327,7 +327,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -352,6 +352,9 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
/* SPL OS boot options */ +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_CMD_SPL #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/Makefile | 4 ++-- arch/arm/cpu/armv7/cpu.c | 2 ++ arch/arm/lib/Makefile | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index f97fa3d..69f1910 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,9 +27,9 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-ifndef CONFIG_SPL_BUILD +#ifndef CONFIG_SPL_BUILD COBJS += cache_v7.o -endif +#endif
COBJS += cpu.o COBJS += syslib.o diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 662c496..c6fa8ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -52,7 +52,9 @@ int cleanup_before_linux(void) * * we turn off caches etc ... */ +#ifndef CONFIG_SPL_BUILD disable_interrupts(); +#endif
/* * Turn off I-cache and invalidate it diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..39a9550 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,8 +39,6 @@ GLCOBJS += div0.o
COBJS-y += board.o COBJS-y += bootm.o -COBJS-y += cache.o -COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o @@ -48,6 +46,9 @@ SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif
+COBJS-y += cache.o +COBJS-y += cache-cp15.o + SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com
As I said in my reply to the intro email..
-ifndef CONFIG_SPL_BUILD +#ifndef CONFIG_SPL_BUILD
Is why I assume this is an RFC :)
This patch is fine, assuming omap4/5 are still within size limits.

Call i2c initialization in spl_board_init only if I2C is configured for the board.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap3/board.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1f33c63..889d650 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -92,7 +92,9 @@ u32 omap_boot_device(void)
void spl_board_init(void) { +#ifdef CONFIG_HARD_I2C i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif } #endif /* CONFIG_SPL_BUILD */

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Call i2c initialization in spl_board_init only if I2C is configured for the board.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com
arch/arm/cpu/armv7/omap3/board.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1f33c63..889d650 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -92,7 +92,9 @@ u32 omap_boot_device(void)
void spl_board_init(void) { +#ifdef CONFIG_HARD_I2C
This should be CONFIG_HARD_I2C || CONFIG_SOFT_I2C. Or perhaps since we're in SPL, CONFIG_SPL_I2C_SUPPORT ?

The SPL used on OMAPx can be reused by other SOCs from different architectures. Move common files into common/ directory.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/Makefile | 10 ---------- common/Makefile | 4 ++++ {arch/arm/cpu/armv7/omap-common => common}/spl.c | 0 .../arm/cpu/armv7/omap-common => common}/spl_mmc.c | 0 .../cpu/armv7/omap-common => common}/spl_nand.c | 0 5 files changed, 4 insertions(+), 10 deletions(-) rename {arch/arm/cpu/armv7/omap-common => common}/spl.c (100%) rename {arch/arm/cpu/armv7/omap-common => common}/spl_mmc.c (100%) rename {arch/arm/cpu/armv7/omap-common => common}/spl_nand.c (100%)
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index a684611..e65e992 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -40,16 +40,6 @@ COBJS += emif-common.o SOBJS += lowlevel_init.o endif
-ifdef CONFIG_SPL_BUILD -COBJS += spl.o -ifdef CONFIG_SPL_NAND_SUPPORT -COBJS += spl_nand.o -endif -ifdef CONFIG_SPL_MMC_SUPPORT -COBJS += spl_mmc.o -endif -endif - ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o diff --git a/common/Makefile b/common/Makefile index 91f3f2e..41b67ca 100644 --- a/common/Makefile +++ b/common/Makefile @@ -186,6 +186,10 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +else +COBJS-y += spl.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o endif
COBJS-y += console.o diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/common/spl.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl.c rename to common/spl.c diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/common/spl_mmc.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl_mmc.c rename to common/spl_mmc.c diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/common/spl_nand.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl_nand.c rename to common/spl_nand.c

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
The SPL used on OMAPx can be reused by other SOCs from different architectures. Move common files into common/ directory.
Thanks for tackling this. My immediate concern however is that this breaks building nand_spl/ boards, but is that really a good concern still?

On 16/12/2011 16:55, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
The SPL used on OMAPx can be reused by other SOCs from different architectures. Move common files into common/ directory.
Thanks for tackling this. My immediate concern however is that this breaks building nand_spl/ boards, but is that really a good concern still?
I think the way we have to do is to accept boards implementing the new SPL framework, and put nand_spl in obsolescence. If a board is broken, it must be fixed porting it to the new SPL.
Stefano

The SPL is developped first for TI-OMAPx. The patch move OMAP specific function into OMAP directory.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/Makefile | 2 + arch/arm/cpu/armv7/omap-common/spl_omap.c | 71 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap3/board.c | 4 ++ arch/arm/include/asm/omap_common.h | 34 -------------- common/spl.c | 1 + common/spl_mmc.c | 21 ++------- common/spl_nand.c | 14 +----- include/spl.h | 68 +++++++++++++++++++++++++++ 8 files changed, 153 insertions(+), 62 deletions(-) create mode 100644 arch/arm/cpu/armv7/omap-common/spl_omap.c create mode 100644 include/spl.h
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index e65e992..6fb544c 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -44,6 +44,8 @@ ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o endif +else +COBJS += spl_omap.o endif
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/omap-common/spl_omap.c b/arch/arm/cpu/armv7/omap-common/spl_omap.c new file mode 100644 index 0000000..692d8c2 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/spl_omap.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V aneesh@ti.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <mmc.h> +#include <nand.h> +#include <fat.h> +#include <spl.h> +#include <version.h> +#include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + switch (omap_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0); + break; + case BOOT_DEVICE_MMC2: + omap_mmc_init(1); + break; + } + return 0; +} +#endif + +#ifdef CONFIG_SPL_NAND_SUPPORT +void spl_arch_nand_init(void) +{ + switch (omap_boot_mode()) { + case NAND_MODE_HW_ECC: + debug("spl: nand - using hw ecc\n"); + gpmc_init(); + nand_init(); + break; + default: + puts("spl: ERROR: This bootmode is not implemented - hanging"); + hang(); + } +} +#endif + +u32 spl_boot_mode(void) +{ + return omap_boot_mode(); +} diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 889d650..f06d614 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -42,6 +42,10 @@ #include <asm/omap_common.h> #include <i2c.h>
+#ifdef CONFIG_SPL_BUILD +#include <spl.h> +#endif + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 8a7d1e5..e46e612 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -64,43 +64,9 @@ void preloader_console_init(void); #define BOOT_DEVICE_XIPWAIT 7 #endif
-/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 -#define NAND_MODE_HW_ECC 3 - -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; - -extern u32* boot_params_ptr; u32 omap_boot_device(void); u32 omap_boot_mode(void);
-/* SPL common function s*/ -void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(char *omap_rev_string); -int spl_uboot_key(void); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif - /* * silicon revisions. * Moving this to common, so that most of code can be moved to common, diff --git a/common/spl.c b/common/spl.c index 1671a03..5fdf3fb 100644 --- a/common/spl.c +++ b/common/spl.c @@ -30,6 +30,7 @@ #include <mmc.h> #include <fat.h> #include <version.h> +#include <spl.h> #include <asm/omap_common.h> #include <asm/arch/mmc_host_def.h> #include <i2c.h> diff --git a/common/spl_mmc.c b/common/spl_mmc.c index 6f5b43e..9c0086c 100644 --- a/common/spl_mmc.c +++ b/common/spl_mmc.c @@ -29,25 +29,12 @@ #include <mmc.h> #include <fat.h> #include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> +#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (omap_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0); - break; - case BOOT_DEVICE_MMC2: - omap_mmc_init(1); - break; - } - return 0; -} -#endif +/* Define the sector size, this is usually 512 bytes */ +#define MMCSD_SECTOR_SIZE 512
static void mmc_load_image_raw(struct mmc *mmc) { @@ -135,7 +122,7 @@ void spl_mmc_load_image(void) printf("spl: mmc init failed: err - %d\n", err); hang(); } - boot_mode = omap_boot_mode(); + boot_mode = spl_boot_mode(); if (boot_mode == MMCSD_MODE_RAW) { debug("boot mode - RAW\n"); mmc_load_image_raw(mmc); diff --git a/common/spl_nand.c b/common/spl_nand.c index 1295e88..1adaf03 100644 --- a/common/spl_nand.c +++ b/common/spl_nand.c @@ -27,7 +27,7 @@ #include <asm/io.h> #include <nand.h> #include <version.h> -#include <asm/omap_common.h> +#include <spl.h>
void spl_nand_load_image(void) { @@ -35,16 +35,8 @@ void spl_nand_load_image(void) int *src __attribute__((unused)); int *dst __attribute__((unused));
- switch (omap_boot_mode()) { - case NAND_MODE_HW_ECC: - debug("spl: nand - using hw ecc\n"); - gpmc_init(); - nand_init(); - break; - default: - puts("spl: ERROR: This bootmode is not implemented - hanging"); - hang(); - } + /* Call the architecture NAND init function */ + spl_arch_nand_init();
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); diff --git a/include/spl.h b/include/spl.h new file mode 100644 index 0000000..af16163 --- /dev/null +++ b/include/spl.h @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2011, Stefano Babic sbabic@denx.de + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V aneesh@ti.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SPL_COMMON_H_ +#define _SPL_COMMON_H_ + +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0 +#define MMCSD_MODE_RAW 1 +#define MMCSD_MODE_FAT 2 +#define NAND_MODE_HW_ECC 3 + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; +}; + +extern struct spl_image_info spl_image; + +extern u32 *boot_params_ptr; + +/* SPL common function s*/ +void spl_parse_image_header(const struct image_header *header); +void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void); +int spl_start_uboot(void); +u32 spl_boot_mode(void); + +/* NAND SPL functions */ +void spl_nand_load_image(void); +void spl_arch_nand_init(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void); +#endif + +#endif +

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
The SPL is developped first for TI-OMAPx. The patch move OMAP specific function into OMAP directory.
I wonder if we should fold this into the mv'ing patch as well.
[snip]
diff --git a/include/spl.h b/include/spl.h +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0
Not your bad spacing of course, but please fix.
+/* NAND SPL functions */ +void spl_nand_load_image(void); +void spl_arch_nand_init(void);
+/* MMC SPL functions */ +void spl_mmc_load_image(void);
These should be covered by #ifdef CONFIG_SPL_(NAND||MMC)_SUPPORT

On 16/12/2011 16:59, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
The SPL is developped first for TI-OMAPx. The patch move OMAP specific function into OMAP directory.
I wonder if we should fold this into the mv'ing patch as well.
I can squash the two patches, but I thought the review is easier as I did. The previous patch shows clearly that the patch was only moved, and the changes in Makefile makes possible to build the boards making the patch bisectable. This patch then
[snip]
diff --git a/include/spl.h b/include/spl.h +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0
Not your bad spacing of course, but please fix.
Thanks to have found, I will fix it.
+/* NAND SPL functions */ +void spl_nand_load_image(void); +void spl_arch_nand_init(void);
+/* MMC SPL functions */ +void spl_mmc_load_image(void);
These should be covered by #ifdef CONFIG_SPL_(NAND||MMC)_SUPPORT
Do we need in the header file for the prototypes ? We have never done, and it should be not necessary.
Stefano

On Fri, Dec 16, 2011 at 9:18 AM, Stefano Babic sbabic@denx.de wrote:
On 16/12/2011 16:59, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
The SPL is developped first for TI-OMAPx. The patch move OMAP specific function into OMAP directory.
I wonder if we should fold this into the mv'ing patch as well.
I can squash the two patches, but I thought the review is easier as I did. The previous patch shows clearly that the patch was only moved, and the changes in Makefile makes possible to build the boards making the patch bisectable. This patch then
Yeah, I guess that works too then, nevermind.
[snip]
diff --git a/include/spl.h b/include/spl.h +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0
Not your bad spacing of course, but please fix.
Thanks to have found, I will fix it.
+/* NAND SPL functions */ +void spl_nand_load_image(void); +void spl_arch_nand_init(void);
+/* MMC SPL functions */ +void spl_mmc_load_image(void);
These should be covered by #ifdef CONFIG_SPL_(NAND||MMC)_SUPPORT
Do we need in the header file for the prototypes ? We have never done, and it should be not necessary.
I would swear there's other examples like this (and someone brought this to my attention when i first posted spl_board_init internally).

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/spl.c b/common/spl.c index 5fdf3fb..cf5395e 100644 --- a/common/spl.c +++ b/common/spl.c @@ -125,7 +125,7 @@ __noreturn void jump_to_image_linux(void *arg) __attribute__ ((noreturn)); image_entry_arg_t image_entry = (image_entry_arg_t) spl_image.entry_point; - /* cleanup_before_linux(); */ /*write SPL function for that*/ + cleanup_before_linux(); image_entry(0, CONFIG_MACH_TYPE, arg); } #endif

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- board/technexion/twister/twister.c | 23 +++++++++++++++++++++++ include/configs/twister.h | 16 ++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c index 950e76c..fc88301 100644 --- a/board/technexion/twister/twister.c +++ b/board/technexion/twister/twister.c @@ -114,3 +114,26 @@ int board_mmc_init(bd_t *bis) return omap_mmc_init(0); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + /* init cs for extern lan */ + enable_gpmc_cs_config(gpmc_smc911, &gpmc_cfg->cs[5], + CONFIG_SMC911X_BASE, GPMC_SIZE_16M); +} +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif diff --git a/include/configs/twister.h b/include/configs/twister.h index 64a886d..68ad31e 100644 --- a/include/configs/twister.h +++ b/include/configs/twister.h @@ -51,4 +51,20 @@ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_TAM3517_SETTINGS \ "bootcmd=run nandboot\0"
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x600000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 7 + +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) +#define CONFIG_SPL_BOARD_INIT + +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_HARD_I2C +#endif + #endif /* __CONFIG_H */

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com
[snip]
+#ifdef CONFIG_SPL_BUILD +#undef CONFIG_HARD_I2C +#endif
If we switch the I2C test to CONFIG_SPL_I2C_SUPPORT this part here can go away, yes?

On 16/12/2011 17:01, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com
[snip]
+#ifdef CONFIG_SPL_BUILD +#undef CONFIG_HARD_I2C +#endif
If we switch the I2C test to CONFIG_SPL_I2C_SUPPORT this part here can go away, yes?
Right, I will fix in this way.
Stefano

On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Hi,
this is a new submission of the Simon's work to add a way to boot Linux directly from the SPL. From the last patchset series, the main changes introduced by me are the following:
- compile the cache functions in SPL to make cleanup_before_linux()
available.
- do not call I"C function on boards where I2C is not available
- fix a bug from last version (fallback to U-Boot)
- move all related SPL stuff to common/ and fix omap related
functions.
Tested on the twister board (patches for this board in u-boot-ti, next)
Note: to test it is also required Simon's patch:
arm: Add Prep subcommand support to bootm
I'm going to mark this series as RFC in patchwork as I see you did +#ifneq... in some Makefiles and I know you know better :) That said, can you confirm MAKEALL -s omap3 -s omap4 -s omap5 works? omap4/5 has smaller size requirements than omap3(ish) stuff and I don't have 100% faith in linker magic to make sure the cache stuff added to SPL in arch/arm/lib/ isn't going to bloat up the omap4/5 stuff slightly.

On 16/12/2011 16:45, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Hi,
this is a new submission of the Simon's work to add a way to boot Linux directly from the SPL. From the last patchset series, the main changes introduced by me are the following:
- compile the cache functions in SPL to make cleanup_before_linux()
available.
- do not call I"C function on boards where I2C is not available
- fix a bug from last version (fallback to U-Boot)
- move all related SPL stuff to common/ and fix omap related
functions.
Tested on the twister board (patches for this board in u-boot-ti, next)
Note: to test it is also required Simon's patch:
arm: Add Prep subcommand support to bootm
I'm going to mark this series as RFC in patchwork as I see you did +#ifneq... in some Makefiles and I know you know better :) That said, can you confirm MAKEALL -s omap3 -s omap4 -s omap5 works?
I'll do, I have not yet tested and I built OMAP3. I have seen a couple of other things due to the moved stuff that I should fix.
omap4/5 has smaller size requirements than omap3(ish) stuff and I don't have 100% faith in linker magic to make sure the cache stuff added to SPL in arch/arm/lib/ isn't going to bloat up the omap4/5 stuff slightly.
Ok, understood, I'll check it - if the added code is too much, I will introduce a new CONFIG_SPL_SUPPORT_CACHE to make build optional.
Stefano

On 16/12/2011 16:45, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Hi,
Hi Tom,
I'm going to mark this series as RFC in patchwork as I see you did +#ifneq... in some Makefiles and I know you know better :) That said, can you confirm MAKEALL -s omap3 -s omap4 -s omap5 works?
there is a missing include in this patchset (fixed in next version), but I can compile all.
omap4/5 has smaller size requirements than omap3(ish) stuff and I don't have 100% faith in linker magic to make sure the cache stuff added to SPL in arch/arm/lib/ isn't going to bloat up the omap4/5 stuff slightly.
Checking MLO without and with this patchset for an OMAP4 board (panda), I get:
without patchset (u-boot-ti): 33012 bytes with the patchset (SPL_OS not enabled): 33424
I cannot test it, but is seems still in order, right ?
Stefano

On Mon, Dec 19, 2011 at 1:43 AM, Stefano Babic sbabic@denx.de wrote:
On 16/12/2011 16:45, Tom Rini wrote:
On Fri, Dec 16, 2011 at 8:37 AM, Stefano Babic sbabic@denx.de wrote:
Hi,
Hi Tom,
I'm going to mark this series as RFC in patchwork as I see you did +#ifneq... in some Makefiles and I know you know better :) That said, can you confirm MAKEALL -s omap3 -s omap4 -s omap5 works?
there is a missing include in this patchset (fixed in next version), but I can compile all.
omap4/5 has smaller size requirements than omap3(ish) stuff and I don't have 100% faith in linker magic to make sure the cache stuff added to SPL in arch/arm/lib/ isn't going to bloat up the omap4/5 stuff slightly.
Checking MLO without and with this patchset for an OMAP4 board (panda), I get:
without patchset (u-boot-ti): 33012 bytes with the patchset (SPL_OS not enabled): 33424
I cannot test it, but is seems still in order, right ?
Yes, when it's too large it fails to link. Thanks!

Hi Tom,
last version of patchset has not received comments since a long time - Simon sends to me a confirm that tests on the devkit8000 are successful.
Any chance to get the patchset merged soon or do you have any open points ?
Thanks, Stefano

On Wed, Jan 25, 2012 at 4:50 AM, Stefano Babic sbabic@denx.de wrote:
Hi Tom,
last version of patchset has not received comments since a long time - Simon sends to me a confirm that tests on the devkit8000 are successful.
Any chance to get the patchset merged soon or do you have any open points ?
I've sent Albert a pull request now for the few things I've got queued up other than this. Once he takes that I'll take the Linux SPL series in, give it a few whacks and move it along to Albert.

Hi,
here an updated version of the patchset to boot Linux directly from SPL. It fixes the (minor) comments received in version 11.
List of changes:
- drop commented lines into arch/arm/cpu/armv7/Makefile after checking build for OMAP4/5 - use CONFIG_SPL_I2C_SUPPORT to protect I2C code - fix TAB / spaces issues (codestyle) - add missing include to fix OMAP4/5 build - use a different GPIO on the twister board to select image to boot
[PATCH V12 01/14] Add cmd_spl command [PATCH V12 02/14] devki8000: add config for spl command [PATCH V12 03/14] omap-common: Add NAND SPL linux booting [PATCH V12 04/14] devkit8000/spl: init GPMC for dm9000 in SPL [PATCH V12 05/14] omap-common/spl: Add linux boot to SPL [PATCH V12 06/14] omap/spl: change output of spl_parse_image_header [PATCH V12 07/14] devkit8000: Implement and activate direct OS boot [PATCH V12 08/14] Add cache functions to SPL for armv7 [PATCH V12 09/14] OMAP3: SPL: do not call I2C init if no I2C is set. [PATCH V12 10/14] OMAP3: move SPL files to be used by other [PATCH V12 11/14] TI: SPL: make SPL available for other SOCs as TI [PATCH V12 12/14] SPL: call cleanup_before_linux() before booting [PATCH V12 13/14] Fix build OMAP4/5 [PATCH V12 14/14] OMAP3: twister: add support to boot Linux from SPL

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: CHG corrected bootm call. Now bootm is called with five parameters including Address of FDT in RAM. This fixes the hang on savebp fdt call. ADD debug output of the actual bootm parameter call CHG help message
V3 changes: FIX added missing brackets
V4 changes: CHG Corrected argument number in comments CHG added check for CONFIG_OF_LIBFDT CHG squashed the README to this commit DEL define description from commit message - unused in this patch CHG renamed to spl now with subcommand export, very different now ADD New call style with subcommands. CHG added printf where the image is located CHG Patched README to reflect changes CHG parameter count CHG usage message
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style, cosmetic changes (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499) REBASE on u-boot
V8 changes: nothing
V9 changes: nothing
V10 changes: CHG list is now terminated by NULL not \0 ADD static modifiers to most of cmd_spl.c functions DEL board changes ADD include protection to cmd_spl.h DEL not used enum image_tyep CHG some cosmetic CHG images extern moved from cmd_spl.h to image.h
V11 changes: nothing
V12 changes: nothing
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 1be7236..91f3f2e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -165,6 +165,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..deab8e9 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != NULL) { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +static int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..2845367 --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_ + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) + +#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index 466c980..2cc0575 100644 --- a/include/image.h +++ b/include/image.h @@ -267,6 +267,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V10 changes: This is new in V10 was split from other patch
include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 2b6a6ee..e323877 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -351,4 +351,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

Dear Stefano Babic,
I do not want to be pedantic, but the subject line contains 'devki8000' which should be 'devkit8000'.
best regards
Andreas Bießmann

Am 07/01/2012 11:21, schrieb Andreas Bießmann:
Dear Stefano Babic,
I do not want to be pedantic, but the subject line contains 'devki8000' which should be 'devkit8000'.
You are not pedantic, the subject contain an error, and I will fix it - thanks !
Best regards, Stefano Babic

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V13: subject "devki8000" must be devkit8000 (A. Biessmann)
V10 changes: This is new in V10 was split from other patch
include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 758326b..d3ca0dd 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -356,4 +356,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: ADD define description to commit message CHG renaming some defines - renaming SAVEBP SPL
V5 changes: nothing
V6 changes: nothing
V7 changes: nothing
V8 changes: FIX multiline comment style REBASE on u-boot
V9 changes: nothing
V10 changes: ADD unused __attribute__ to src and dst because they provoked a warning if SPL os boot was not active
V11 changes: nothing
V12 changes: nothing
arch/arm/cpu/armv7/omap-common/spl_nand.c | 66 ++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..2a66214 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,9 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +49,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: use enable_gpmc_cs_config to config the GPMC for dm9000
arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 39 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 1ec651b..62200e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index b06aab6..05de3c1 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,24 @@ int board_init(void) return 0; }
+static u32 gpmc_net_config[GPMC_MAX_REG] = { + NET_GPMC_CONFIG1, + NET_GPMC_CONFIG2, + NET_GPMC_CONFIG3, + NET_GPMC_CONFIG4, + NET_GPMC_CONFIG5, + NET_GPMC_CONFIG6, + NET_GPMC_CONFIG7, +}; + + +/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -81,14 +99,7 @@ int misc_init_r(void) #endif
#ifdef CONFIG_DRIVER_DM9000 - /* Configure GPMC registers for DM9000 */ - writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1); - writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2); - writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3); - writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4); - writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5); - writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6); - writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7); + gpmc_dm9000_config();
/* Use OMAP DIE_ID as MAC address */ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { @@ -139,6 +150,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

Hi Stefano,
2012/1/4 Stefano Babic sbabic@denx.de:
From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de
V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: use enable_gpmc_cs_config to config the GPMC for dm9000
arch/arm/include/asm/omap_common.h | 2 + board/timll/devkit8000/devkit8000.c | 39 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 1ec651b..62200e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index b06aab6..05de3c1 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -63,6 +63,24 @@ int board_init(void) return 0; }
+static u32 gpmc_net_config[GPMC_MAX_REG] = {
- NET_GPMC_CONFIG1,
- NET_GPMC_CONFIG2,
- NET_GPMC_CONFIG3,
- NET_GPMC_CONFIG4,
- NET_GPMC_CONFIG5,
- NET_GPMC_CONFIG6,
- NET_GPMC_CONFIG7,
+};
There is a patch, already mainline, doing the same thing by Thomas Weber (13b178ed) - so this part should be deleted.
Regards Simon

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: noting
V5 changes: nothing
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: use enable_gpmc_cs_config to config the GPMC for dm9000
V13: Rebased on u-boot-ti (Simon Schwarz)
arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 1ec651b..62200e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -87,6 +87,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 10f189e..dded697 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -73,6 +73,13 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -144,6 +151,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V2 changes: nothing
V3 changes: nothing
V4 changes: CHG Using CONFIG_MACH_TYPE now. DEL CONFIG_SYS_SPL_MACHID CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch depending on the patch linked above
V5 changes: FIX compile errors for OMAP4 REBASE u-boot-ti adapted new general gpio interface
V6 changes: nothing
V7 changes: FIX multiline comment style (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes: REBASE on u-boot
V9 changes: nothing
V10 changes: CHG used short form to mark not returning function DEL devkit8000 config changes from this patch CHG spl_uboot_key renamed to spl_start_uboot and defined weak to be implemented board specific CHG If the Linux image for the direct OS boot is not found the SPL tries to load a u-boot image CHG %X in %p in debug message
V11 changes: U-Boot was always started instead of Linux
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++++++++++++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 53 ++++++++++++++++------------ arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 78 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c35a09..955a83b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -35,6 +35,7 @@ #include <i2c.h> #include <image.h> #include <malloc.h> +#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + printf("SPL: Please implement spl_start_uboot() for your board\n"); + printf("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -91,7 +111,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +__noreturn void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -105,8 +143,8 @@ static void jump_to_image_no_args(void) u32 boot_params_ptr_addr = (u32)&boot_params_ptr; image_entry((u32 *)boot_params_ptr_addr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -146,6 +184,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 2a66214..1295e88 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -29,7 +29,6 @@ #include <version.h> #include <asm/omap_common.h>
- void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT - if (!spl_uboot_key()) { + if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -74,31 +73,39 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } else + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); + return; + } else { + printf("The Expected Linux image was not" + "found. Please check your NAND" + "configuration.\n"); + printf("Trying to start u-boot now...\n"); + } + } #endif - { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); nand_deselect(); } diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 62200e5..8a7d1e5 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -89,6 +89,7 @@ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(char *omap_rev_string); int spl_uboot_key(void); void spl_board_prepare_for_linux(void); +int spl_start_uboot(void);
/* NAND SPL functions */ void spl_nand_load_image(void);

From: Simon Schwarz simonschwarzcor@googlemail.com
This only outputs "Assuming u-boot.bin..." if debug is active.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V11: no changes
V12: no changes
arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 955a83b..1671a03 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -101,7 +101,7 @@ void spl_parse_image_header(const struct image_header *header) /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - puts("Assuming u-boot.bin ..\n"); + debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE;

From: Simon Schwarz simonschwarzcor@googlemail.com
- Implements spl_start_uboot() for devkit8000 - Add configs to activate direct OS boot from SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- V10 changes: sliced from the implementation added an implementation of spl_start_uboot for devkit8000
board/timll/devkit8000/devkit8000.c | 18 ++++++++++++++++++ include/configs/devkit8000.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 05de3c1..6ca4fe2 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -41,6 +41,7 @@ #include <asm/arch/mem.h> #include <asm/mach-types.h> #include "devkit8000.h" +#include <asm/gpio.h> #ifdef CONFIG_DRIVER_DM9000 #include <net.h> #include <netdev.h> @@ -160,6 +161,23 @@ void spl_board_prepare_for_linux(void) gpmc_dm9000_config(); }
+/* + * devkit8000 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if the button is not pressed + * 1 if the button is pressed + */ +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} #endif
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index e323877..eb7c376 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -35,7 +35,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ - +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 /* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM * 64 bytes before this address should be set aside for u-boot.img's @@ -327,7 +327,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -352,6 +352,9 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
/* SPL OS boot options */ +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_CMD_SPL #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
Changes since V11:
- enable cache files in Makefile after checking build for OMAP4/5
arch/arm/cpu/armv7/Makefile | 2 -- arch/arm/cpu/armv7/cpu.c | 2 ++ arch/arm/lib/Makefile | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index f97fa3d..6b2addc 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,9 +27,7 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-ifndef CONFIG_SPL_BUILD COBJS += cache_v7.o -endif
COBJS += cpu.o COBJS += syslib.o diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 662c496..c6fa8ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -52,7 +52,9 @@ int cleanup_before_linux(void) * * we turn off caches etc ... */ +#ifndef CONFIG_SPL_BUILD disable_interrupts(); +#endif
/* * Turn off I-cache and invalidate it diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..39a9550 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,8 +39,6 @@ GLCOBJS += div0.o
COBJS-y += board.o COBJS-y += bootm.o -COBJS-y += cache.o -COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o @@ -48,6 +46,9 @@ SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif
+COBJS-y += cache.o +COBJS-y += cache-cp15.o + SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))

Hi Stefano,
On Wednesday 04 January 2012 09:25 AM, Stefano Babic wrote:
Signed-off-by: Stefano Babicsbabic@denx.de CC: Tom Rinitom.rini@gmail.com CC: Wolfgang Denkwd@denx.de CC: Simon Schwarzsimonschwarzcor@gmail.com
Changes since V11:
- enable cache files in Makefile after checking build for OMAP4/5
How are you allocating memory for the page-tables(gd->tlb_addr)? Also we need to take care of the complexities when u-boot runs after SPL. Please have a look at this.
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/100012/match=spl+cac...
arch/arm/cpu/armv7/Makefile | 2 -- arch/arm/cpu/armv7/cpu.c | 2 ++ arch/arm/lib/Makefile | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index f97fa3d..6b2addc 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,9 +27,7 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-ifndef CONFIG_SPL_BUILD COBJS += cache_v7.o -endif
COBJS += cpu.o COBJS += syslib.o diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 662c496..c6fa8ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -52,7 +52,9 @@ int cleanup_before_linux(void) * * we turn off caches etc ... */ +#ifndef CONFIG_SPL_BUILD disable_interrupts(); +#endif
/* * Turn off I-cache and invalidate it diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..39a9550 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,8 +39,6 @@ GLCOBJS += div0.o
COBJS-y += board.o COBJS-y += bootm.o -COBJS-y += cache.o -COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o @@ -48,6 +46,9 @@ SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif
+COBJS-y += cache.o +COBJS-y += cache-cp15.o
- SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))

On 04/01/2012 12:33, Aneesh V wrote:
Hi Stefano,
Hi,
On Wednesday 04 January 2012 09:25 AM, Stefano Babic wrote:
Signed-off-by: Stefano Babicsbabic@denx.de CC: Tom Rinitom.rini@gmail.com CC: Wolfgang Denkwd@denx.de CC: Simon Schwarzsimonschwarzcor@gmail.com
Changes since V11:
- enable cache files in Makefile after checking build for OMAP4/5
How are you allocating memory for the page-tables(gd->tlb_addr)? Also we need to take care of the complexities when u-boot runs after SPL.
I know, and the patch can be considered a preparation for adding d-cache later - dcache is not enabled at all in this patchset. At the moment, cleanup_before_linux() is called as in U-Boot, but caches are already disabled. I know memory for the page tables must be reserved, but this part is not yet done.
Please have a look at this.
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/100012/match=spl+cac...
I am aware of this. And this is also the reason I see caches as a second-step approach. Firstly, we should have a way to boot linux directly from SPL, without enabling cache. Then we have the possibility to increase the mumber of our testers, because, as far as I know, only me and Simon have tried with this patchset to get some measurement.
In my current tests on the twister board (AM3517 based), most time is spent really to load the kernel (~2MB, with a lot of drivers..). As answer to your point 1 in the previous thread, maybe it is really worth to enable cache to speed up the loading part respecting enabling DMA. Adding DMA means adding DMA support in each specific driver (NAND vs MMC vs..), while with d-cache we have a solution working independenlty from the supported media. But it makes sense to have a large number of boards supporting direct booting before making some wrong assumptions ;-)
Best regards, Stefano Babic

Call i2c initialization in spl_board_init only if I2C is configured for the board.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
V12: - use CONFIG_SPL_I2C_SUPPORT to protect I2C code
arch/arm/cpu/armv7/omap3/board.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1f33c63..1f6a3e9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -92,7 +92,9 @@ u32 omap_boot_device(void)
void spl_board_init(void) { +#ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif } #endif /* CONFIG_SPL_BUILD */

The SPL used on OMAPx can be reused by other SOCs from different architectures. Move common files into common/ directory.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
V12: no changes
arch/arm/cpu/armv7/omap-common/Makefile | 10 ---------- common/Makefile | 4 ++++ {arch/arm/cpu/armv7/omap-common => common}/spl.c | 0 .../arm/cpu/armv7/omap-common => common}/spl_mmc.c | 0 .../cpu/armv7/omap-common => common}/spl_nand.c | 0 5 files changed, 4 insertions(+), 10 deletions(-) rename {arch/arm/cpu/armv7/omap-common => common}/spl.c (100%) rename {arch/arm/cpu/armv7/omap-common => common}/spl_mmc.c (100%) rename {arch/arm/cpu/armv7/omap-common => common}/spl_nand.c (100%)
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index a684611..e65e992 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -40,16 +40,6 @@ COBJS += emif-common.o SOBJS += lowlevel_init.o endif
-ifdef CONFIG_SPL_BUILD -COBJS += spl.o -ifdef CONFIG_SPL_NAND_SUPPORT -COBJS += spl_nand.o -endif -ifdef CONFIG_SPL_MMC_SUPPORT -COBJS += spl_mmc.o -endif -endif - ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o diff --git a/common/Makefile b/common/Makefile index 91f3f2e..41b67ca 100644 --- a/common/Makefile +++ b/common/Makefile @@ -186,6 +186,10 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +else +COBJS-y += spl.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o endif
COBJS-y += console.o diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/common/spl.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl.c rename to common/spl.c diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/common/spl_mmc.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl_mmc.c rename to common/spl_mmc.c diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/common/spl_nand.c similarity index 100% rename from arch/arm/cpu/armv7/omap-common/spl_nand.c rename to common/spl_nand.c

The SPL is developped first for TI-OMAPx. The patch move OMAP specific function into OMAP directory.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
V12: replace tab with space defining MMCSD_MODE_UNDEFINED
arch/arm/cpu/armv7/omap-common/Makefile | 2 + arch/arm/cpu/armv7/omap-common/spl_omap.c | 71 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap3/board.c | 4 ++ arch/arm/include/asm/omap_common.h | 34 -------------- common/spl.c | 1 + common/spl_mmc.c | 21 ++------- common/spl_nand.c | 14 +----- include/spl.h | 68 +++++++++++++++++++++++++++ 8 files changed, 153 insertions(+), 62 deletions(-) create mode 100644 arch/arm/cpu/armv7/omap-common/spl_omap.c create mode 100644 include/spl.h
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index e65e992..6fb544c 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -44,6 +44,8 @@ ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o endif +else +COBJS += spl_omap.o endif
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/omap-common/spl_omap.c b/arch/arm/cpu/armv7/omap-common/spl_omap.c new file mode 100644 index 0000000..692d8c2 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/spl_omap.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V aneesh@ti.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <mmc.h> +#include <nand.h> +#include <fat.h> +#include <spl.h> +#include <version.h> +#include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + switch (omap_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0); + break; + case BOOT_DEVICE_MMC2: + omap_mmc_init(1); + break; + } + return 0; +} +#endif + +#ifdef CONFIG_SPL_NAND_SUPPORT +void spl_arch_nand_init(void) +{ + switch (omap_boot_mode()) { + case NAND_MODE_HW_ECC: + debug("spl: nand - using hw ecc\n"); + gpmc_init(); + nand_init(); + break; + default: + puts("spl: ERROR: This bootmode is not implemented - hanging"); + hang(); + } +} +#endif + +u32 spl_boot_mode(void) +{ + return omap_boot_mode(); +} diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1f6a3e9..11a6caa 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -42,6 +42,10 @@ #include <asm/omap_common.h> #include <i2c.h>
+#ifdef CONFIG_SPL_BUILD +#include <spl.h> +#endif + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 8a7d1e5..e46e612 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -64,43 +64,9 @@ void preloader_console_init(void); #define BOOT_DEVICE_XIPWAIT 7 #endif
-/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 -#define NAND_MODE_HW_ECC 3 - -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; - -extern u32* boot_params_ptr; u32 omap_boot_device(void); u32 omap_boot_mode(void);
-/* SPL common function s*/ -void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(char *omap_rev_string); -int spl_uboot_key(void); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif - /* * silicon revisions. * Moving this to common, so that most of code can be moved to common, diff --git a/common/spl.c b/common/spl.c index 1671a03..5fdf3fb 100644 --- a/common/spl.c +++ b/common/spl.c @@ -30,6 +30,7 @@ #include <mmc.h> #include <fat.h> #include <version.h> +#include <spl.h> #include <asm/omap_common.h> #include <asm/arch/mmc_host_def.h> #include <i2c.h> diff --git a/common/spl_mmc.c b/common/spl_mmc.c index 6f5b43e..9c0086c 100644 --- a/common/spl_mmc.c +++ b/common/spl_mmc.c @@ -29,25 +29,12 @@ #include <mmc.h> #include <fat.h> #include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> +#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (omap_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0); - break; - case BOOT_DEVICE_MMC2: - omap_mmc_init(1); - break; - } - return 0; -} -#endif +/* Define the sector size, this is usually 512 bytes */ +#define MMCSD_SECTOR_SIZE 512
static void mmc_load_image_raw(struct mmc *mmc) { @@ -135,7 +122,7 @@ void spl_mmc_load_image(void) printf("spl: mmc init failed: err - %d\n", err); hang(); } - boot_mode = omap_boot_mode(); + boot_mode = spl_boot_mode(); if (boot_mode == MMCSD_MODE_RAW) { debug("boot mode - RAW\n"); mmc_load_image_raw(mmc); diff --git a/common/spl_nand.c b/common/spl_nand.c index 1295e88..1adaf03 100644 --- a/common/spl_nand.c +++ b/common/spl_nand.c @@ -27,7 +27,7 @@ #include <asm/io.h> #include <nand.h> #include <version.h> -#include <asm/omap_common.h> +#include <spl.h>
void spl_nand_load_image(void) { @@ -35,16 +35,8 @@ void spl_nand_load_image(void) int *src __attribute__((unused)); int *dst __attribute__((unused));
- switch (omap_boot_mode()) { - case NAND_MODE_HW_ECC: - debug("spl: nand - using hw ecc\n"); - gpmc_init(); - nand_init(); - break; - default: - puts("spl: ERROR: This bootmode is not implemented - hanging"); - hang(); - } + /* Call the architecture NAND init function */ + spl_arch_nand_init();
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); diff --git a/include/spl.h b/include/spl.h new file mode 100644 index 0000000..6ea3823 --- /dev/null +++ b/include/spl.h @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2011, Stefano Babic sbabic@denx.de + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V aneesh@ti.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SPL_COMMON_H_ +#define _SPL_COMMON_H_ + +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0 +#define MMCSD_MODE_RAW 1 +#define MMCSD_MODE_FAT 2 +#define NAND_MODE_HW_ECC 3 + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; +}; + +extern struct spl_image_info spl_image; + +extern u32 *boot_params_ptr; + +/* SPL common function s*/ +void spl_parse_image_header(const struct image_header *header); +void omap_rev_string(char *omap_rev_string); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void); +int spl_start_uboot(void); +u32 spl_boot_mode(void); + +/* NAND SPL functions */ +void spl_nand_load_image(void); +void spl_arch_nand_init(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void); +#endif + +#endif +

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/spl.c b/common/spl.c index 5fdf3fb..cf5395e 100644 --- a/common/spl.c +++ b/common/spl.c @@ -125,7 +125,7 @@ __noreturn void jump_to_image_linux(void *arg) __attribute__ ((noreturn)); image_entry_arg_t image_entry = (image_entry_arg_t) spl_image.entry_point; - /* cleanup_before_linux(); */ /*write SPL function for that*/ + cleanup_before_linux(); image_entry(0, CONFIG_MACH_TYPE, arg); } #endif

Signed-off-by: Stefano Babic sbabic@denx.de --- arch/arm/cpu/armv7/omap-common/hwinit-common.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index f65705d..4040d02 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -32,6 +32,7 @@ #include <asm/sizes.h> #include <asm/emif.h> #include <asm/omap_common.h> +#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
V12: - change GPIO to select U-Boot als image
board/technexion/twister/twister.c | 23 +++++++++++++++++++++++ include/configs/twister.h | 12 ++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c index 950e76c..fc88301 100644 --- a/board/technexion/twister/twister.c +++ b/board/technexion/twister/twister.c @@ -114,3 +114,26 @@ int board_mmc_init(bd_t *bis) return omap_mmc_init(0); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + /* init cs for extern lan */ + enable_gpmc_cs_config(gpmc_smc911, &gpmc_cfg->cs[5], + CONFIG_SMC911X_BASE, GPMC_SIZE_16M); +} +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} +#endif diff --git a/include/configs/twister.h b/include/configs/twister.h index 64a886d..a852481 100644 --- a/include/configs/twister.h +++ b/include/configs/twister.h @@ -51,4 +51,16 @@ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_TAM3517_SETTINGS \ "bootcmd=run nandboot\0"
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x600000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 55 + +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) +#define CONFIG_SPL_BOARD_INIT + #endif /* __CONFIG_H */

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com ---
After rebasing V12, I see that prototype for omap_rev_string() was changed ==> fixed
include/spl.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/spl.h b/include/spl.h index 6ea3823..d060826 100644 --- a/include/spl.h +++ b/include/spl.h @@ -47,7 +47,7 @@ extern u32 *boot_params_ptr;
/* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(char *omap_rev_string); +void omap_rev_string(void); int spl_uboot_key(void); void spl_board_prepare_for_linux(void); int spl_start_uboot(void);

Rebased patchset to add Linux booting from SPL. As discussed in the ML, this patchset does not make SPL common to all SOCs to avoid breaking some architecture - this job will be done later with a different patchset.
For this reason, a couple of patches moving files in the common/ directory are dropped - the other patches are not changed from V12. (exception due only to rebase on current u-boot-ti)

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 2d9ae8c..910c056 100644 --- a/common/Makefile +++ b/common/Makefile @@ -162,6 +162,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..deab8e9 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{ + char *bootm_argv[5]; + char command[] = "do_bootm"; + + int i = 0; + int ret = 0; + + /* create paramter array */ + bootm_argv[0] = command; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != NULL) { + bootm_argv[1] = subcommand[i]; + debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0], + bootm_argv[1], bootm_argv[2], bootm_argv[3], + bootm_argv[4], argc); + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +/* assemble the bootm paramteres for fdt creation */ +static int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "fdt", + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect paramters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + return 0; +#else + printf("Das U-Boot was build without fdt support - aborting\n"); + return -1; +#endif +} + +/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + /* Create subcommand string */ + char *subcommand[] = { + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", + "bdt", + "prep", + NULL}; + + /* inspect parameters and execute bootm */ + argc--; + argv++; + if (call_bootm(argc, argv, subcommand)) + return -1; + + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + return 0; +#endif + printf("Das U-Boot was build without ATAGS support - aborting\n"); + return -1; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT_FDT: + argc--; + argv++; + return spl_export_fdt(argc, argv); + break; + case SPL_EXPORT_ATAGS: + argc--; + argv++; + return spl_export_atags(argc, argv); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +/* + * Arguments: + * 1: subcommand + * 2: image_type + * 3: nand_offset + * 4: kernel_addr + * 5: initrd_addr + * 6: fdt_adr + */ + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has to subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..2845367 --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_ + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) + +#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index bbf80f0..a1c6e4e 100644 --- a/include/image.h +++ b/include/image.h @@ -268,6 +268,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or

On Sat, Feb 4, 2012 at 3:22 AM, Stefano Babic sbabic@denx.de wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
The include/image.h part seems unnecessary and breaks cam_enc_4xx so I've dropped that from my tree.

On Fri, Feb 10, 2012 at 11:48 AM, Tom Rini tom.rini@gmail.com wrote:
On Sat, Feb 4, 2012 at 3:22 AM, Stefano Babic sbabic@denx.de wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
The include/image.h part seems unnecessary and breaks cam_enc_4xx so I've dropped that from my tree.
Whoops, spoke too soon, I'll resolve the cam_enc_4xx conflict and rename one of the variables.

On Fri, Feb 10, 2012 at 11:53 AM, Tom Rini tom.rini@gmail.com wrote:
On Fri, Feb 10, 2012 at 11:48 AM, Tom Rini tom.rini@gmail.com wrote:
On Sat, Feb 4, 2012 at 3:22 AM, Stefano Babic sbabic@denx.de wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
The include/image.h part seems unnecessary and breaks cam_enc_4xx so I've dropped that from my tree.
Whoops, spoke too soon, I'll resolve the cam_enc_4xx conflict and rename one of the variables.
I've gone with renaming the cam_enc_4xx variable to 'imgs' and will post the patch shortly. Heiko, if the rename is OK with you can you Ack it so I can push the Linux SPL series soon? Thanks!

Hello Tom,
Tom Rini wrote:
On Fri, Feb 10, 2012 at 11:53 AM, Tom Rini tom.rini@gmail.com wrote:
On Fri, Feb 10, 2012 at 11:48 AM, Tom Rini tom.rini@gmail.com wrote:
On Sat, Feb 4, 2012 at 3:22 AM, Stefano Babic sbabic@denx.de wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
The include/image.h part seems unnecessary and breaks cam_enc_4xx so I've dropped that from my tree.
Whoops, spoke too soon, I'll resolve the cam_enc_4xx conflict and rename one of the variables.
I've gone with renaming the cam_enc_4xx variable to 'imgs' and will post the patch shortly. Heiko, if the rename is OK with you can you Ack it so I can push the Linux SPL series soon? Thanks!
Done. Thanks for the fix!
bye, Heiko

Dear Stefano Babic,
In message 1328350963-30989-2-git-send-email-sbabic@denx.de you wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command
CONFIG_CMD_CPL??? Is this a typo, and you mean CONFIG_CMD_SPL ?
CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
What about other storage devices?
...
+/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{
- char *bootm_argv[5];
- char command[] = "do_bootm";
...
+}
Why is this needed? Why don't you run do_bootm() directly?
+static int spl_export_fdt(int argc, char * const argv[]) +{
...
- /* inspect paramters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM: 0x%p\n",
(void *)images.ft_addr);
- return 0;
+#else
- printf("Das U-Boot was build without fdt support - aborting\n");
- return -1;
+#endif +}
+/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{
...
- /* inspect parameters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM at: 0x%p\n",
(void *)gd->bd->bi_boot_params);
- return 0;
+#endif
- printf("Das U-Boot was build without ATAGS support - aborting\n");
- return -1;
+}
This is basicly identical code, only the data structures differ.
Please use a common function, and pass (a pointer to) the data as argument.
- if (c) {
cmd = (int)c->cmd;
switch (cmd) {
case SPL_EXPORT_FDT:
argc--;
argv++;
return spl_export_fdt(argc, argv);
break;
case SPL_EXPORT_ATAGS:
argc--;
argv++;
return spl_export_atags(argc, argv);
break;
default:
This will also eliminate this switch() - you just have to set the pointer to the respective data to pass.
+/*
- Arguments:
- 1: subcommand
- 2: image_type
- 3: nand_offset
- 4: kernel_addr
- 5: initrd_addr
- 6: fdt_adr
- */
I think it is broken to restrict this by design to NAND booting only.
This is a command that attemtps to deal with SPL booting in general, so it should support all possible kinds of boot media - NOR, NAND, MMC, SPI flash, USB, ...
Best regards,
Wolfgang Denk

On 13/02/2012 08:54, Wolfgang Denk wrote:
Dear Stefano Babic,
In message 1328350963-30989-2-git-send-email-sbabic@denx.de you wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command
CONFIG_CMD_CPL??? Is this a typo, and you mean CONFIG_CMD_SPL ?
Yes, this a type - must be fixed.
CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
What about other storage devices?
Booting from other storage devices is not yet implemented, but it is surely desired. I can imagine that after this patchset will flow into mainline, there will be more use cases, and further storages will be added.
At the moment, only NAND is implemented and for this reason only CONFIG_CMD_SPL_NAND_OFS is defined. This leaves the possibility to have different offsets from different boot devices for the kernel parameter area.
...
+/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{
- char *bootm_argv[5];
- char command[] = "do_bootm";
...
+}
Why is this needed? Why don't you run do_bootm() directly?
Mmmhh... At least using find_cmd("do_bootm") in do_bootm should be not required, if this is what you mind.
+static int spl_export_fdt(int argc, char * const argv[]) +{
...
- /* inspect paramters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM: 0x%p\n",
(void *)images.ft_addr);
- return 0;
+#else
- printf("Das U-Boot was build without fdt support - aborting\n");
- return -1;
+#endif +}
+/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{
...
- /* inspect parameters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM at: 0x%p\n",
(void *)gd->bd->bi_boot_params);
- return 0;
+#endif
- printf("Das U-Boot was build without ATAGS support - aborting\n");
- return -1;
+}
This is basicly identical code, only the data structures differ.
Please use a common function, and pass (a pointer to) the data as argument.
Clear, thanks, I'll fix it.
- if (c) {
cmd = (int)c->cmd;
switch (cmd) {
case SPL_EXPORT_FDT:
argc--;
argv++;
return spl_export_fdt(argc, argv);
break;
case SPL_EXPORT_ATAGS:
argc--;
argv++;
return spl_export_atags(argc, argv);
break;
default:
This will also eliminate this switch() - you just have to set the pointer to the respective data to pass.
You're right !
+/*
- Arguments:
- 1: subcommand
- 2: image_type
- 3: nand_offset
- 4: kernel_addr
- 5: initrd_addr
- 6: fdt_adr
- */
I think it is broken to restrict this by design to NAND booting only.
It is not. The comment is wrong and does not correspond to the implemented command. The result of spl export is not written automatically to storage, and this let the possibility to write it into the correct storage device.
"spl export <img=atags|fdt> [kernel_addr] [initrd_addr] "
nand_offset is something obsolete - and the whole comment does not add more info as we can read after the U_BOOT_CMD. I will drop it.
This is a command that attemtps to deal with SPL booting in general, so it should support all possible kinds of boot media - NOR, NAND, MMC, SPI flash, USB, ...
Right. However, this restriction is not in this patch (apart the wrong comment). I think the command is already general and not limited to a storage device. But there is this limitation in another patch.
The restriction about storage media is in board_init_r(), in [PATCH V13 03/12] omap-common: Add NAND SPL linux booting. Maybe you can take a look.
Here the selection if booting the kernel or u-boot is taken inside spl_nand_load_image(). So at this point we have already decided which is the storage media, and this function starts the kernel. So maybe we should also rename it to a general name, such as spl_load_image().
Really this function has not a lot to do to do with NAND, except the fact it calls nand_spl_load_image() to copy from NAND to RAM. Your comment applies very well to this function. It should be made more general, maybe adding function pointers that must be called after selecting the right device, something like:
device_media->load_image(addr, size);
where device_media->load_image points to the specific devic media function to copy an image, for NAND it is nand_spl_load_image.
What do you think about ?
We have already discussed how we can proceed with this feature and how to merge it into mainline. Maybe it is worth to spend again a couple of words. The other main restriction is the fact that this feature is OMAP-only, and not so general as it should be. Not only, also the SPL framework runs mainly on TI SOCs, and it is really a pity. Most of part that are now hidden in omap-common/ can be generalized for the other SOCs, and duplication can be avoided. IMHO there is already some code that can be factorized between OMAp and Davinci.
Because there is a high probability to break other boards (I have already posted patches in this direction, but I broke davinci), we decided to make several steps. Firstly pushing this feature, then making SPL common - I will add now also making booting from SPL device-independent.
My question is if we proceed with several steps, or we want to push only a complete version. Any thought about this ?
Best regards, Stefano Babic

On 02/04/2012 11:22 AM, Stefano Babic wrote:
From: Simon Schwarzsimonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_CPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com CC: Tom Rinitom.rini@gmail.com CC: Stefano Babicsbabic@denx.de CC: Wolfgang Denkwd@denx.de
common/Makefile | 1 + common/cmd_spl.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 +++++++ include/cmd_spl.h | 30 ++++++ include/image.h | 2 + 5 files changed, 293 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 2d9ae8c..910c056 100644 --- a/common/Makefile +++ b/common/Makefile @@ -162,6 +162,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..deab8e9 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,229 @@ +/*
- Copyright (C) 2011
- Corscience GmbH& Co. KG - Simon Schwarzschwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include<common.h> +#include<command.h> +#include<cmd_spl.h>
+DECLARE_GLOBAL_DATA_PTR;
+/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], char *subcommand[]) +{
- char *bootm_argv[5];
- char command[] = "do_bootm";
- int i = 0;
- int ret = 0;
- /* create paramter array */
- bootm_argv[0] = command;
- switch (argc) {
- case 3:
bootm_argv[4] = argv[2]; /* fdt addr */
- case 2:
bootm_argv[3] = argv[1]; /* initrd addr */
- case 1:
bootm_argv[2] = argv[0]; /* kernel addr */
- }
- /*
* - do the work -
* exec subcommands of do_bootm to init the images
* data structure
*/
- while (subcommand[i] != NULL) {
bootm_argv[1] = subcommand[i];
debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0],
bootm_argv[1], bootm_argv[2], bootm_argv[3],
bootm_argv[4], argc);
ret = do_bootm(find_cmd("do_bootm"), 0, argc+2,
bootm_argv);
debug("Subcommand retcode: %d\n", ret);
i++;
- }
- if (ret) {
printf("ERROR prep subcommand failed!\n");
return -1;
- }
- return 0;
+}
+/* assemble the bootm paramteres for fdt creation */ +static int spl_export_fdt(int argc, char * const argv[]) +{ +#ifdef CONFIG_OF_LIBFDT
- /* Create subcommand string */
- char *subcommand[] = {
- "start",
- "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
- "ramdisk",
+#endif
- "fdt",
- "cmdline",
- "bdt",
- "prep",
- NULL};
- /* inspect paramters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM: 0x%p\n",
(void *)images.ft_addr);
- return 0;
+#else
- printf("Das U-Boot was build without fdt support - aborting\n");
- return -1;
+#endif +}
+/* assemble the bootm patameters for atags creation */ +static int spl_export_atags(int argc, char * const argv[]) +{ +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
- defined(CONFIG_CMDLINE_TAG) || \
- defined(CONFIG_INITRD_TAG) || \
- defined(CONFIG_SERIAL_TAG) || \
- defined(CONFIG_REVISION_TAG)
- /* Create subcommand string */
- char *subcommand[] = {
"start",
"loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
"ramdisk",
+#endif
"cmdline",
"bdt",
"prep",
NULL};
- /* inspect parameters and execute bootm */
- argc--;
- argv++;
- if (call_bootm(argc, argv, subcommand))
return -1;
- printf("Argument image is now in RAM at: 0x%p\n",
(void *)gd->bd->bi_boot_params);
- return 0;
+#endif
- printf("Das U-Boot was build without ATAGS support - aborting\n");
- return -1;
+}
+static cmd_tbl_t cmd_spl_export_sub[] = {
- U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""),
- U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""),
+};
+static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- const cmd_tbl_t *c;
- int cmd;
- if (argc< 2) /* no subcommand */
return cmd_usage(cmdtp);
- c = find_cmd_tbl(argv[1],&cmd_spl_export_sub[0],
ARRAY_SIZE(cmd_spl_export_sub));
- if (c) {
cmd = (int)c->cmd;
switch (cmd) {
case SPL_EXPORT_FDT:
argc--;
argv++;
return spl_export_fdt(argc, argv);
break;
case SPL_EXPORT_ATAGS:
argc--;
argv++;
return spl_export_atags(argc, argv);
break;
default:
/* unrecognized command */
return cmd_usage(cmdtp);
}
- } else {
/* Unrecognized command */
return cmd_usage(cmdtp);
- }
- return 0;
+}
+static cmd_tbl_t cmd_spl_sub[] = {
- U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""),
+};
+static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- const cmd_tbl_t *c;
- int cmd;
- if (argc< 2) /* no subcommand */
return cmd_usage(cmdtp);
- c = find_cmd_tbl(argv[1],&cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub));
- if (c) {
cmd = (int)c->cmd;
switch (cmd) {
case SPL_EXPORT:
argc--;
argv++;
if (spl_export(cmdtp, flag, argc, argv))
printf("Subcommand failed\n");
break;
default:
/* unrecognized command */
return cmd_usage(cmdtp);
}
- } else {
/* Unrecognized command */
return cmd_usage(cmdtp);
- }
- return 0;
+}
+/*
- Arguments:
- 1: subcommand
- 2: image_type
- 3: nand_offset
- 4: kernel_addr
- 5: initrd_addr
- 6: fdt_adr
- */
+U_BOOT_CMD(
- spl, 6 , 1, do_spl, "SPL configuration",
- "export<img=atags|fdt> [kernel_addr] [initrd_addr] "
- "[fdt_addr if<img> = fdt] - export a kernel parameter image\n"
- "\t initrd_img can be set to "-" if fdt_addr without initrd img is"
- "used");
diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..818dd53 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL.
+SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.)
+export has to subcommands:
two subcommands:
- atags: exports the ATAGS
- fdt: exports the FDT
+Call is: +spl export<ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt]
+TYPICAL CALL
+on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */
+call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write<adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..2845367 --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2011
- Corscience GmbH& Co. KG - Simon Schwarzschwarz@corscience.de
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_
+#define SPL_EXPORT (0x00000001)
+#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002)
+#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index bbf80f0..a1c6e4e 100644 --- a/include/image.h +++ b/include/image.h @@ -268,6 +268,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images;
- /*
- Some systems (for example LWMON) have very short watchdog periods;
- we must make sure to split long operations like memmove() or

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 758326b..d3ca0dd 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -356,4 +356,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 66 ++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..2a66214 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,9 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +49,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 34bec45..92aa4f9 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -92,6 +92,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(void); +int spl_uboot_key(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 10f189e..dded697 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -73,6 +73,13 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -144,6 +151,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

Hello Stefano, On 02/04/2012 11:22 AM, Stefano Babic wrote:
From: Simon Schwarzsimonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com CC: Tom Rinitom.rini@gmail.com CC: Stefano Babicsbabic@denx.de CC: Wolfgang Denkwd@denx.de
arch/arm/include/asm/omap_common.h | 2 ++ board/timll/devkit8000/devkit8000.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 34bec45..92aa4f9 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -92,6 +92,8 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(void); +int spl_uboot_key(void);
shouldn't this be spl_start_uboot ? The request if the key for starting u-boot is pressed?
Thomas
+void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 10f189e..dded697 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -73,6 +73,13 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{
- enable_gpmc_cs_config(gpmc_net_config,&gpmc_cfg->cs[6],
CONFIG_DM9000_BASE, GPMC_SIZE_16M);
+}
- /*
- Routine: misc_init_r
- Description: Configure board specific parts
@@ -144,6 +151,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/*
- Do board specific preperation before SPL
- Linux boot
- */
+void spl_board_prepare_for_linux(void) +{
- gpmc_dm9000_config();
+}
+#endif
- /*
- Routine: get_board_mem_timings
- Description: If we use SPL then there is no x-loader nor config header

On 19/02/2012 06:57, Thomas Weber wrote:
Hello Stefano,
Hallo Thomas,
+int spl_uboot_key(void);
shouldn't this be spl_start_uboot ? The request if the key for starting u-boot is pressed?
It is - the prototype for spl_uboot_key is obsolete, I remove it for the next version, thanks.
Stefano

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl.c | 48 +++++++++++++++++++++++++- arch/arm/cpu/armv7/omap-common/spl_nand.c | 53 ++++++++++++++++------------ arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 77 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 9c1f7e3..f99c0e5 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -65,6 +65,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + printf("SPL: Please implement spl_start_uboot() for your board\n"); + printf("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -92,7 +111,25 @@ void spl_parse_image_header(const struct image_header *header) } }
-static void jump_to_image_no_args(void) +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +__noreturn void jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + +void jump_to_image_no_args(void) { typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn)); image_entry_noargs_t image_entry = @@ -106,8 +143,8 @@ static void jump_to_image_no_args(void) u32 boot_params_ptr_addr = (u32)&boot_params_ptr; image_entry((u32 *)boot_params_ptr_addr); } - void jump_to_image_no_args(void) __attribute__ ((noreturn)); + void board_init_r(gd_t *id, ulong dummy) { u32 boot_device; @@ -145,6 +182,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 2a66214..1295e88 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -29,7 +29,6 @@ #include <version.h> #include <asm/omap_common.h>
- void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT - if (!spl_uboot_key()) { + if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -74,31 +73,39 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } else + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); + return; + } else { + printf("The Expected Linux image was not" + "found. Please check your NAND" + "configuration.\n"); + printf("Trying to start u-boot now...\n"); + } + } #endif - { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); nand_deselect(); } diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 92aa4f9..ecfd799 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -94,6 +94,7 @@ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(void); int spl_uboot_key(void); void spl_board_prepare_for_linux(void); +int spl_start_uboot(void);
/* NAND SPL functions */ void spl_nand_load_image(void);

From: Simon Schwarz simonschwarzcor@googlemail.com
This only outputs "Assuming u-boot.bin..." if debug is active.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index f99c0e5..5f7ba2c 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -101,7 +101,7 @@ void spl_parse_image_header(const struct image_header *header) /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - puts("Assuming u-boot.bin ..\n"); + debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE;

From: Simon Schwarz simonschwarzcor@googlemail.com
- Implements spl_start_uboot() for devkit8000 - Add configs to activate direct OS boot from SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- board/timll/devkit8000/devkit8000.c | 18 ++++++++++++++++++ include/configs/devkit8000.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index dded697..d75e86b 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -41,6 +41,7 @@ #include <asm/arch/mem.h> #include <asm/mach-types.h> #include "devkit8000.h" +#include <asm/gpio.h> #ifdef CONFIG_DRIVER_DM9000 #include <net.h> #include <netdev.h> @@ -161,6 +162,23 @@ void spl_board_prepare_for_linux(void) gpmc_dm9000_config(); }
+/* + * devkit8000 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if the button is not pressed + * 1 if the button is pressed + */ +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} #endif
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index d3ca0dd..2bcab72 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -35,7 +35,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ - +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 /* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM * 64 bytes before this address should be set aside for u-boot.img's @@ -327,7 +327,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -357,6 +357,9 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
/* SPL OS boot options */ +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_CMD_SPL #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/Makefile | 2 -- arch/arm/cpu/armv7/cpu.c | 2 ++ arch/arm/lib/Makefile | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index f97fa3d..6b2addc 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,9 +27,7 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-ifndef CONFIG_SPL_BUILD COBJS += cache_v7.o -endif
COBJS += cpu.o COBJS += syslib.o diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 662c496..c6fa8ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -52,7 +52,9 @@ int cleanup_before_linux(void) * * we turn off caches etc ... */ +#ifndef CONFIG_SPL_BUILD disable_interrupts(); +#endif
/* * Turn off I-cache and invalidate it diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..39a9550 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,8 +39,6 @@ GLCOBJS += div0.o
COBJS-y += board.o COBJS-y += bootm.o -COBJS-y += cache.o -COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o @@ -48,6 +46,9 @@ SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif
+COBJS-y += cache.o +COBJS-y += cache-cp15.o + SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))

Call i2c initialization in spl_board_init only if I2C is configured for the board.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap3/board.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 871aa37..d942bfe 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -92,7 +92,9 @@ u32 omap_boot_device(void)
void spl_board_init(void) { +#ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif } #endif /* CONFIG_SPL_BUILD */

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 5f7ba2c..d9dd864 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -124,7 +124,7 @@ __noreturn void jump_to_image_linux(void *arg) __attribute__ ((noreturn)); image_entry_arg_t image_entry = (image_entry_arg_t) spl_image.entry_point; - /* cleanup_before_linux(); */ /*write SPL function for that*/ + cleanup_before_linux(); image_entry(0, CONFIG_MACH_TYPE, arg); } #endif

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- board/technexion/twister/twister.c | 23 +++++++++++++++++++++++ include/configs/twister.h | 12 ++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c index 06fac7b..4d34d24 100644 --- a/board/technexion/twister/twister.c +++ b/board/technexion/twister/twister.c @@ -114,3 +114,26 @@ int board_mmc_init(bd_t *bis) return omap_mmc_init(0); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + /* init cs for extern lan */ + enable_gpmc_cs_config(gpmc_smc911, &gpmc_cfg->cs[5], + CONFIG_SMC911X_BASE, GPMC_SIZE_16M); +} +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return val; +} +#endif diff --git a/include/configs/twister.h b/include/configs/twister.h index 64a886d..a852481 100644 --- a/include/configs/twister.h +++ b/include/configs/twister.h @@ -51,4 +51,16 @@ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_TAM3517_SETTINGS \ "bootcmd=run nandboot\0"
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x600000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 55 + +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) +#define CONFIG_SPL_BOARD_INIT + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com Acked-by: Stefano Babic sbabic@denx.de Tested-by: Stefano Babic sbabic@denx.de --- arch/arm/include/asm/bootm.h | 26 ++++ arch/arm/lib/bootm.c | 341 ++++++++++++++++++++++-------------------- 2 files changed, 202 insertions(+), 165 deletions(-) create mode 100644 arch/arm/include/asm/bootm.h
diff --git a/arch/arm/include/asm/bootm.h b/arch/arm/include/asm/bootm.h new file mode 100644 index 0000000..db2ff94 --- /dev/null +++ b/arch/arm/include/asm/bootm.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef ARM_BOOTM_H +#define ARM_BOOTM_H + +#ifdef CONFIG_USB_DEVICE +extern void udc_disconnect(void); +#endif + +#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index afa0093..03c25e9 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,8 @@ -/* +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * - Added prep subcommand support + * - Reorganized source - modeled after powerpc version + * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger mgroeger@sysgo.de @@ -29,35 +33,26 @@ #include <fdt.h> #include <libfdt.h> #include <fdt_support.h> +#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) -static void setup_start_tag (bd_t *bd); - -# ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd); -# endif -static void setup_commandline_tag (bd_t *bd, char *commandline); - -# ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, - ulong initrd_end); -# endif -static void setup_end_tag (bd_t *bd); - +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) static struct tag *params; -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ - -static ulong get_sp(void); -#if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); #endif
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + void arch_lmb_reserve(struct lmb *lmb) { ulong sp; @@ -80,85 +75,7 @@ void arch_lmb_reserve(struct lmb *lmb) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); }
-static void announce_and_cleanup(void) -{ - printf("\nStarting kernel ...\n\n"); - -#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect(void); - udc_disconnect(); - } -#endif - cleanup_before_linux(); -} - -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) -{ - bd_t *bd = gd->bd; - char *s; - int machid = bd->bi_arch_number; - void (*kernel_entry)(int zero, int arch, uint params); - -#ifdef CONFIG_CMDLINE_TAG - char *commandline = getenv ("bootargs"); -#endif - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - s = getenv ("machid"); - if (s) { - machid = simple_strtoul (s, NULL, 16); - printf ("Using machid 0x%x from environment\n", machid); - } - - show_boot_progress (15); - #ifdef CONFIG_OF_LIBFDT - if (images->ft_len) - return bootm_linux_fdt(machid, images); -#endif - - kernel_entry = (void (*)(int, int, uint))images->ep; - - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); - -#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) - setup_start_tag (bd); -#ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); -#endif -#ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); -#endif -#ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); -#endif -#ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); -#endif -#ifdef CONFIG_INITRD_TAG - if (images->rd_start && images->rd_end) - setup_initrd_tag (bd, images->rd_start, images->rd_end); -#endif - setup_end_tag(bd); -#endif - - announce_and_cleanup(); - - kernel_entry(0, machid, bd->bi_boot_params); - /* does not return */ - - return 1; -} - -#if defined(CONFIG_OF_LIBFDT) static int fixup_memory_node(void *blob) { bd_t *bd = gd->bd; @@ -173,60 +90,26 @@ static int fixup_memory_node(void *blob)
return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); } +#endif
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static void announce_and_cleanup(void) { - ulong rd_len; - void (*kernel_entry)(int zero, int dt_machid, void *dtblob); - ulong of_size = images->ft_len; - char **of_flat_tree = &images->ft_addr; - ulong *initrd_start = &images->initrd_start; - ulong *initrd_end = &images->initrd_end; - struct lmb *lmb = &images->lmb; - int ret; - - kernel_entry = (void (*)(int, int, void *))images->ep; - - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); - - rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, - initrd_start, initrd_end); - if (ret) - return ret; - - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; - - debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); - - fdt_chosen(*of_flat_tree, 1); - - fixup_memory_node(*of_flat_tree); - - fdt_fixup_ethernet(*of_flat_tree); - - fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); - - announce_and_cleanup(); - - kernel_entry(0, machid, *of_flat_tree); - /* does not return */ + printf("\nStarting kernel ...\n\n");
- return 1; -} +#ifdef CONFIG_USB_DEVICE + udc_disconnect(); #endif + cleanup_before_linux(); +}
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) static void setup_start_tag (bd_t *bd) { - params = (struct tag *) bd->bi_boot_params; + params = (struct tag *)bd->bi_boot_params;
params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size (tag_core); @@ -237,10 +120,10 @@ static void setup_start_tag (bd_t *bd)
params = tag_next (params); } - +#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd) +static void setup_memory_tags(bd_t *bd) { int i;
@@ -254,10 +137,10 @@ static void setup_memory_tags (bd_t *bd) params = tag_next (params); } } -#endif /* CONFIG_SETUP_MEMORY_TAGS */ - +#endif
-static void setup_commandline_tag (bd_t *bd, char *commandline) +#ifdef CONFIG_CMDLINE_TAG +static void setup_commandline_tag(bd_t *bd, char *commandline) { char *p;
@@ -281,10 +164,10 @@ static void setup_commandline_tag (bd_t *bd, char *commandline)
params = tag_next (params); } - +#endif
#ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end) +static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end) { /* an ATAG_INITRD node tells the kernel where the compressed * ramdisk can be found. ATAG_RDIMG is a better name, actually. @@ -297,10 +180,10 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
params = tag_next (params); } -#endif /* CONFIG_INITRD_TAG */ +#endif
#ifdef CONFIG_SERIAL_TAG -void setup_serial_tag (struct tag **tmp) +void setup_serial_tag(struct tag **tmp) { struct tag *params = *tmp; struct tag_serialnr serialnr; @@ -328,19 +211,147 @@ void setup_revision_tag(struct tag **in_params) params->u.revision.rev = rev; params = tag_next (params); } -#endif /* CONFIG_REVISION_TAG */ +#endif
-static void setup_end_tag (bd_t *bd) +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) +static void setup_end_tag(bd_t *bd) { params->hdr.tag = ATAG_NONE; params->hdr.size = 0; } -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ +#endif
-static ulong get_sp(void) +#ifdef CONFIG_OF_LIBFDT +static int create_fdt(bootm_headers_t *images) { - ulong ret; + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + ulong *initrd_start = &images->initrd_start; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + ulong rd_len; + int ret;
- asm("mov %0, sp" : "=r"(ret) : ); - return ret; + debug("using: FDT\n"); + + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret; + + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret; + + fdt_chosen(*of_flat_tree, 1); + fixup_memory_node(*of_flat_tree); + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + return 0; +} +#endif + +/* Subcommand: PREP */ +static void boot_prep_linux(bootm_headers_t *images) +{ +#ifdef CONFIG_CMDLINE_TAG + char *commandline = getenv("bootargs"); +#endif + +#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) { + debug("using: FDT\n"); + if (create_fdt(images)) { + printf("FDT creation failed! hanging..."); + hang(); + } + } else +#endif + { +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + debug("using: ATAGS\n"); + setup_start_tag(gd->bd); +#ifdef CONFIG_SERIAL_TAG + setup_serial_tag(¶ms); +#endif +#ifdef CONFIG_CMDLINE_TAG + setup_commandline_tag(gd->bd, commandline); +#endif +#ifdef CONFIG_REVISION_TAG + setup_revision_tag(¶ms); +#endif +#ifdef CONFIG_SETUP_MEMORY_TAGS + setup_memory_tags(gd->bd); +#endif +#ifdef CONFIG_INITRD_TAG + if (images->rd_start && images->rd_end) + setup_initrd_tag(gd->bd, images->rd_start, + images->rd_end); +#endif + setup_end_tag(gd->bd); +#else /* all tags */ + printf("FDT and ATAGS support not compiled in - hanging\n"); + hang(); +#endif /* all tags */ + } +} + +/* Subcommand: GO */ +static void boot_jump_linux(bootm_headers_t *images) +{ + int machid = gd->bd->bi_arch_number; + char *s; + void (*kernel_entry)(int zero, int arch, uint params); + + kernel_entry = (void (*)(int, int, uint))images->ep; + + s = getenv("machid"); + if (s) { + strict_strtoul(s, 16, (long unsigned int *) &machid); + printf("Using machid 0x%x from environment\n", machid); + } + + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry); + show_boot_progress(15); + announce_and_cleanup(); + kernel_entry(0, machid, gd->bd->bi_boot_params); +} + +/* Main Entry point for arm bootm implementation + * + * Modeled after the powerpc implementation + * DIFFERENCE: Instead of calling prep and go at the end + * they are called if subcommand is equal 0. + */ +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + /* No need for those on ARM */ + if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & BOOTM_STATE_OS_GO) { + boot_jump_linux(images); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images); + return 0; }

Hi all,
Le 04/02/2012 11:22, Stefano Babic a écrit :
From: Simon Schwarzsimonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com Acked-by: Stefano Babicsbabic@denx.de Tested-by: Stefano Babicsbabic@denx.de
That one's assigned to me on patchwork, but already resides in several branches of the imx tree.
Stefano, why not put it in imx master for pulling?
Amicalement,

On Sun, Feb 12, 2012 at 7:48 AM, Albert ARIBAUD albert.u.boot@aribaud.net wrote:
Hi all,
Le 04/02/2012 11:22, Stefano Babic a écrit :
From: Simon Schwarzsimonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com Acked-by: Stefano Babicsbabic@denx.de Tested-by: Stefano Babicsbabic@denx.de
That one's assigned to me on patchwork, but already resides in several branches of the imx tree.
Stefano, why not put it in imx master for pulling?
What happened was that Stefano has working with me on getting the series into u-boot-ti (since it's just booting on OMAP*ish boards right now) so there's a branch or two for testing / avoiding a repost just to get ToT again. I expect to include it in a pull request next week (need to double check the MAKEALL -s arm before/after, then do the same for ppc).

On 12/02/2012 15:58, Tom Rini wrote:
On Sun, Feb 12, 2012 at 7:48 AM, Albert ARIBAUD albert.u.boot@aribaud.net wrote:
Hi all,
Le 04/02/2012 11:22, Stefano Babic a écrit :
From: Simon Schwarzsimonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com Acked-by: Stefano Babicsbabic@denx.de Tested-by: Stefano Babicsbabic@denx.de
That one's assigned to me on patchwork, but already resides in several branches of the imx tree.
Stefano, why not put it in imx master for pulling?
What happened was that Stefano has working with me on getting the series into u-boot-ti (since it's just booting on OMAP*ish boards right now) so there's a branch or two for testing / avoiding a repost just to get ToT again. I expect to include it in a pull request next week (need to double check the MAKEALL -s arm before/after, then do the same for ppc).
Right - the patches were tested and run on OMAP-3 platform at the moment. Making this code available for the other SOCs will come later.
My branches on u-boot-imx are only for testing, for anyone who wants to try booting the Kernel from SPL without having to fight with the different version of the patchset.
It is planned that the whole series will be pulled by Tom soon. It is surely right if you assign this patch to Tom on patchwork ;-).
Best regards, Stefano

On Sun, Feb 12, 2012 at 8:21 AM, Stefano Babic sbabic@denx.de wrote:
On 12/02/2012 15:58, Tom Rini wrote:
On Sun, Feb 12, 2012 at 7:48 AM, Albert ARIBAUD albert.u.boot@aribaud.net wrote:
Hi all,
Le 04/02/2012 11:22, Stefano Babic a écrit :
From: Simon Schwarzsimonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarzsimonschwarzcor@gmail.com Acked-by: Stefano Babicsbabic@denx.de Tested-by: Stefano Babicsbabic@denx.de
That one's assigned to me on patchwork, but already resides in several branches of the imx tree.
Stefano, why not put it in imx master for pulling?
What happened was that Stefano has working with me on getting the series into u-boot-ti (since it's just booting on OMAP*ish boards right now) so there's a branch or two for testing / avoiding a repost just to get ToT again. I expect to include it in a pull request next week (need to double check the MAKEALL -s arm before/after, then do the same for ppc).
Right - the patches were tested and run on OMAP-3 platform at the moment. Making this code available for the other SOCs will come later.
My branches on u-boot-imx are only for testing, for anyone who wants to try booting the Kernel from SPL without having to fight with the different version of the patchset.
It is planned that the whole series will be pulled by Tom soon. It is surely right if you assign this patch to Tom on patchwork ;-).
I'll hit up patchwork tomorrow since I thought I had gotten all of the old versions marked as superseded and assigned the latest to me.

Hi,
this should be the final version for the patchset introducing direct Linux booting from SPL.
Only Patch 1/14: "Add cmd_spl command" was modified. Patches 2/13 up to 12/13 are untouched from V13. Patch 13/13 fix a small issue by compiling the cam_enc_4xx board (Tom Rini)
Changelog --------------
[PATCH V14 01/13] Add cmd_spl command [PATCH V14 02/13] devkit8000: add config for spl command [PATCH V14 03/13] omap-common: Add NAND SPL linux booting [PATCH V14 04/13] devkit8000/spl: init GPMC for dm9000 in SPL [PATCH V14 05/13] omap-common/spl: Add linux boot to SPL [PATCH V14 06/13] omap/spl: change output of spl_parse_image_header [PATCH V14 07/13] devkit8000: Implement and activate direct OS boot [PATCH V14 08/13] Add cache functions to SPL for armv7 [PATCH V14 09/13] OMAP3: SPL: do not call I2C init if no I2C is set. [PATCH V14 10/13] SPL: call cleanup_before_linux() before booting [PATCH V14 11/13] OMAP3: twister: add support to boot Linux from SPL [PATCH V14 12/13] arm: Add Prep subcommand support to bootm [PATCH V14 13/13] cam_enc_4xx: Rename 'images' to 'imgs'

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds a spl command to the u-boot.
Related config: CONFIG_CMD_SPL activate/deactivate the command CONFIG_CMD_SPL_NAND_OFS Offset in NAND to use
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de ---
Changes since V13: - spelling in commit message (Wolfgang Denk) - drop local variable for do_bootm (Wolfgang Denk) - factorize common code for spl_export_* (Wolfgang Denk) - drop wrong comments (Wolfgang Denk) - fix bug when DEBUG is set (Stefano Babic)
common/Makefile | 1 + common/cmd_spl.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++ doc/README.commands.spl | 31 ++++++++ include/cmd_spl.h | 31 ++++++++ include/image.h | 2 + 5 files changed, 253 insertions(+), 0 deletions(-) create mode 100644 common/cmd_spl.c create mode 100644 doc/README.commands.spl create mode 100644 include/cmd_spl.h
diff --git a/common/Makefile b/common/Makefile index 0189aac..819c1f7 100644 --- a/common/Makefile +++ b/common/Makefile @@ -162,6 +162,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 0000000..9ec054a --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char **subcmd_list[] = { + + [SPL_EXPORT_FDT] = (const char * []) { +#ifdef CONFIG_OF_LIBFDT + "start", + "loados", + #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", + #endif + "fdt", + "cmdline", + "bdt", + "prep", +#endif + NULL, + }, + [SPL_EXPORT_ATAGS] = (const char * []) { +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + "start", + "loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH + "ramdisk", +#endif + "cmdline", + "bdt", + "prep", +#endif + NULL, + }, + NULL +}; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], const char *subcommand[]) +{ + char *bootm_argv[5]; + + int i = 0; + int ret = 0; + int j; + + /* create paramter array */ + bootm_argv[0] = "do_bootm"; + switch (argc) { + case 3: + bootm_argv[4] = argv[2]; /* fdt addr */ + case 2: + bootm_argv[3] = argv[1]; /* initrd addr */ + case 1: + bootm_argv[2] = argv[0]; /* kernel addr */ + } + + + /* + * - do the work - + * exec subcommands of do_bootm to init the images + * data structure + */ + while (subcommand[i] != NULL) { + bootm_argv[1] = (char *)subcommand[i]; + debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); + for (j = 0; j < argc; j++) + debug("%s ", bootm_argv[j + 2]); + debug("\n"); + + ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, + bootm_argv); + debug("Subcommand retcode: %d\n", ret); + i++; + } + + if (ret) { + printf("ERROR prep subcommand failed!\n"); + return -1; + } + + return 0; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { + U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), + U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], + ARRAY_SIZE(cmd_spl_export_sub)); + if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) { + argc -= 2; + argv += 2; + if (call_bootm(argc, argv, subcmd_list[(int)c->cmd])) + return -1; + switch ((int)c->cmd) { + case SPL_EXPORT_FDT: + printf("Argument image is now in RAM: 0x%p\n", + (void *)images.ft_addr); + break; + case SPL_EXPORT_ATAGS: + printf("Argument image is now in RAM at: 0x%p\n", + (void *)gd->bd->bi_boot_params); + break; + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + + return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { + U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const cmd_tbl_t *c; + int cmd; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); + if (c) { + cmd = (int)c->cmd; + switch (cmd) { + case SPL_EXPORT: + argc--; + argv++; + if (spl_export(cmdtp, flag, argc, argv)) + printf("Subcommand failed\n"); + break; + default: + /* unrecognized command */ + return cmd_usage(cmdtp); + } + } else { + /* Unrecognized command */ + return cmd_usage(cmdtp); + } + return 0; +} + +U_BOOT_CMD( + spl, 6 , 1, do_spl, "SPL configuration", + "export <img=atags|fdt> [kernel_addr] [initrd_addr] " + "[fdt_addr if <img> = fdt] - export a kernel parameter image\n" + "\t initrd_img can be set to "-" if fdt_addr without initrd img is" + "used"); diff --git a/doc/README.commands.spl b/doc/README.commands.spl new file mode 100644 index 0000000..ac33273 --- /dev/null +++ b/doc/README.commands.spl @@ -0,0 +1,31 @@ +The spl command is used to export a boot parameter image to RAM. Later +it may implement more functions connected to the SPL. + +SUBCOMMAND EXPORT +To execute the command everything has to be in place as if bootm should be +used. (kernel image, initrd-image, fdt-image etc.) + +export has two subcommands: + atags: exports the ATAGS + fdt: exports the FDT + +Call is: +spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt] + + +TYPICAL CALL + +on OMAP3: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +spl export atags /* export ATAGS */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write 0x80000100 0x680000 0x20000 /* write the image - one page */ + +call with FDT: +nandecc hw +nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/ +tftpboot 0x80000100 devkit8000.dtb /* Read fdt */ +spl export fdt 0x82000000 - 0x80000100 /* export FDT */ +nand erase 0x680000 0x20000 /* erase - one page */ +nand write <adress shown by spl export> 0x680000 0x20000 diff --git a/include/cmd_spl.h b/include/cmd_spl.h new file mode 100644 index 0000000..6d6206d --- /dev/null +++ b/include/cmd_spl.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _NAND_SPL_H_ +#define _NAND_SPL_H_ + +#define SPL_EXPORT (0x00000001) + +#define SPL_EXPORT_FDT (0x00000001) +#define SPL_EXPORT_ATAGS (0x00000002) +#define SPL_EXPORT_LAST SPL_EXPORT_ATAGS + +#endif /* _NAND_SPL_H_ */ diff --git a/include/image.h b/include/image.h index bbf80f0..a1c6e4e 100644 --- a/include/image.h +++ b/include/image.h @@ -268,6 +268,8 @@ typedef struct bootm_headers { #endif } bootm_headers_t;
+extern bootm_headers_t images; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds some configs for devkit8000 to use the new spl command
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- include/configs/devkit8000.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 2b6a6ee..e323877 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -351,4 +351,12 @@ #define CONFIG_SYS_SPL_MALLOC_START 0x80208000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x400000) +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
This implements booting of Linux from NAND in SPL
Related config parameters: CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normally RAM-start + 0x100 (on ARM)
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 66 ++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 38d06b1..2a66214 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,6 +24,7 @@ #include <asm/u-boot.h> #include <asm/utils.h> #include <asm/arch/sys_proto.h> +#include <asm/io.h> #include <nand.h> #include <version.h> #include <asm/omap_common.h> @@ -32,6 +33,9 @@ void spl_nand_load_image(void) { struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + switch (omap_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); @@ -45,26 +49,56 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_uboot_key()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + }
+ /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } else +#endif + { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)image_load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + } nand_deselect(); }

From: Simon Schwarz simonschwarzcor@googlemail.com
Linux crashes if the GPMC isn't configured for the dm9000.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/include/asm/omap_common.h | 1 + board/timll/devkit8000/devkit8000.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 25f95b4..85eac7d 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -92,6 +92,7 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); void omap_rev_string(void); +void spl_board_prepare_for_linux(void);
/* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index 10f189e..dded697 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -73,6 +73,13 @@ int board_init(void) return 0; }
+/* Configure GPMC registers for DM9000 */ +static void gpmc_dm9000_config(void) +{ + enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], + CONFIG_DM9000_BASE, GPMC_SIZE_16M); +} + /* * Routine: misc_init_r * Description: Configure board specific parts @@ -144,6 +151,18 @@ int board_eth_init(bd_t *bis) } #endif
+#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + gpmc_dm9000_config(); +} + +#endif + /* * Routine: get_board_mem_timings * Description: If we use SPL then there is no x-loader nor config header

From: Simon Schwarz simonschwarzcor@googlemail.com
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs: CONFIG_SPL_OS_BOOT Activates/Deactivates the OS booting feature CONFIG_SPL_OS_BOOT_KEY defines the IO-pin number u-boot switch - if pressed u-boot is booted CONFIG_SYS_NAND_SPL_KERNEL_OFFS Offset in NAND of direct boot kernel image to use in SPL CONFIG_SYS_SPL_ARGS_ADDR Address where the kernel boot arguments are expected - this is normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl.c | 44 ++++++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/spl_nand.c | 53 ++++++++++++++++------------ arch/arm/include/asm/omap_common.h | 1 + 3 files changed, 75 insertions(+), 23 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 99bb382..6b54ac7 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -65,6 +65,25 @@ void board_init_f(ulong dummy) relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); }
+/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + printf("SPL: Please implement spl_start_uboot() for your board\n"); + printf("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); @@ -92,6 +111,24 @@ void spl_parse_image_header(const struct image_header *header) } }
+/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +static void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + /* cleanup_before_linux(); */ /*write SPL function for that*/ + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + static void __noreturn jump_to_image_no_args(void) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); @@ -149,6 +186,13 @@ void board_init_r(gd_t *id, ulong dummy) debug("Jumping to U-Boot\n"); jump_to_image_no_args(); break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif default: puts("Unsupported OS image.. Jumping nevertheless..\n"); jump_to_image_no_args(); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 2a66214..1295e88 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -29,7 +29,6 @@ #include <version.h> #include <asm/omap_common.h>
- void spl_nand_load_image(void) { struct image_header *header; @@ -50,7 +49,7 @@ void spl_nand_load_image(void) /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); #ifdef CONFIG_SPL_OS_BOOT - if (!spl_uboot_key()) { + if (!spl_start_uboot()) { /* * load parameter image * load to temp position since nand_spl_load_image reads @@ -74,31 +73,39 @@ void spl_nand_load_image(void) nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } else + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); + return; + } else { + printf("The Expected Linux image was not" + "found. Please check your NAND" + "configuration.\n"); + printf("Trying to start u-boot now...\n"); + } + } #endif - { #ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); #ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); #endif #endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - } + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); nand_deselect(); } diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 85eac7d..6f25948 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -93,6 +93,7 @@ u32 omap_boot_mode(void); void spl_parse_image_header(const struct image_header *header); void omap_rev_string(void); void spl_board_prepare_for_linux(void); +int spl_start_uboot(void);
/* NAND SPL functions */ void spl_nand_load_image(void);

From: Simon Schwarz simonschwarzcor@googlemail.com
This only outputs "Assuming u-boot.bin..." if debug is active.
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 6b54ac7..963acb0 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -101,7 +101,7 @@ void spl_parse_image_header(const struct image_header *header) /* Signature not found - assume u-boot.bin */ printf("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - puts("Assuming u-boot.bin ..\n"); + debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE;

From: Simon Schwarz simonschwarzcor@googlemail.com
- Implements spl_start_uboot() for devkit8000 - Add configs to activate direct OS boot from SPL
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com CC: Tom Rini tom.rini@gmail.com CC: Stefano Babic sbabic@denx.de CC: Wolfgang Denk wd@denx.de --- board/timll/devkit8000/devkit8000.c | 18 ++++++++++++++++++ include/configs/devkit8000.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c index dded697..d75e86b 100644 --- a/board/timll/devkit8000/devkit8000.c +++ b/board/timll/devkit8000/devkit8000.c @@ -41,6 +41,7 @@ #include <asm/arch/mem.h> #include <asm/mach-types.h> #include "devkit8000.h" +#include <asm/gpio.h> #ifdef CONFIG_DRIVER_DM9000 #include <net.h> #include <netdev.h> @@ -161,6 +162,23 @@ void spl_board_prepare_for_linux(void) gpmc_dm9000_config(); }
+/* + * devkit8000 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if the button is not pressed + * 1 if the button is pressed + */ +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return !val; +} #endif
/* diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index e323877..eb7c376 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -35,7 +35,7 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP34XX 1 /* which is a 34XX */ #define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */ - +#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000 /* * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM * 64 bytes before this address should be set aside for u-boot.img's @@ -327,7 +327,7 @@ #define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/ +#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/ #define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */ @@ -352,6 +352,9 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
/* SPL OS boot options */ +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 26 + #define CONFIG_CMD_SPL #define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ #define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/Makefile | 2 -- arch/arm/cpu/armv7/cpu.c | 2 ++ arch/arm/lib/Makefile | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index f97fa3d..6b2addc 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,9 +27,7 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-ifndef CONFIG_SPL_BUILD COBJS += cache_v7.o -endif
COBJS += cpu.o COBJS += syslib.o diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 662c496..c6fa8ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -52,7 +52,9 @@ int cleanup_before_linux(void) * * we turn off caches etc ... */ +#ifndef CONFIG_SPL_BUILD disable_interrupts(); +#endif
/* * Turn off I-cache and invalidate it diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 300c8fa..39a9550 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -39,8 +39,6 @@ GLCOBJS += div0.o
COBJS-y += board.o COBJS-y += bootm.o -COBJS-y += cache.o -COBJS-y += cache-cp15.o COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o COBJS-y += interrupts.o COBJS-y += reset.o @@ -48,6 +46,9 @@ SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o endif
+COBJS-y += cache.o +COBJS-y += cache-cp15.o + SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))

Call i2c initialization in spl_board_init only if I2C is configured for the board.
Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap3/board.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index aabc651..1fee574 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -92,7 +92,9 @@ u32 omap_boot_device(void)
void spl_board_init(void) { +#ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif } #endif /* CONFIG_SPL_BUILD */

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 963acb0..0f2e0a2 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -124,7 +124,7 @@ static void __noreturn jump_to_image_linux(void *arg) __attribute__ ((noreturn)); image_entry_arg_t image_entry = (image_entry_arg_t) spl_image.entry_point; - /* cleanup_before_linux(); */ /*write SPL function for that*/ + cleanup_before_linux(); image_entry(0, CONFIG_MACH_TYPE, arg); } #endif

Signed-off-by: Stefano Babic sbabic@denx.de CC: Tom Rini tom.rini@gmail.com CC: Wolfgang Denk wd@denx.de CC: Simon Schwarz simonschwarzcor@gmail.com --- board/technexion/twister/twister.c | 23 +++++++++++++++++++++++ include/configs/twister.h | 12 ++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c index 50c70ab..b927586 100644 --- a/board/technexion/twister/twister.c +++ b/board/technexion/twister/twister.c @@ -136,3 +136,26 @@ int board_mmc_init(bd_t *bis) return omap_mmc_init(0); } #endif + +#ifdef CONFIG_SPL_OS_BOOT +/* + * Do board specific preperation before SPL + * Linux boot + */ +void spl_board_prepare_for_linux(void) +{ + /* init cs for extern lan */ + enable_gpmc_cs_config(gpmc_smc911, &gpmc_cfg->cs[5], + CONFIG_SMC911X_BASE, GPMC_SIZE_16M); +} +int spl_start_uboot(void) +{ + int val = 0; + if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) { + gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY); + val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY); + gpio_free(CONFIG_SPL_OS_BOOT_KEY); + } + return val; +} +#endif diff --git a/include/configs/twister.h b/include/configs/twister.h index 64a886d..a852481 100644 --- a/include/configs/twister.h +++ b/include/configs/twister.h @@ -51,4 +51,16 @@ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_TAM3517_SETTINGS \ "bootcmd=run nandboot\0"
+/* SPL OS boot options */ +#define CONFIG_CMD_SPL +#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */ +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 +#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\ + 0x600000) +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_OS_BOOT_KEY 55 + +#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100) +#define CONFIG_SPL_BOARD_INIT + #endif /* __CONFIG_H */

From: Simon Schwarz simonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
Signed-off-by: Simon Schwarz simonschwarzcor@gmail.com Acked-by: Stefano Babic sbabic@denx.de Tested-by: Stefano Babic sbabic@denx.de --- arch/arm/include/asm/bootm.h | 26 ++++ arch/arm/lib/bootm.c | 341 ++++++++++++++++++++++-------------------- 2 files changed, 202 insertions(+), 165 deletions(-) create mode 100644 arch/arm/include/asm/bootm.h
diff --git a/arch/arm/include/asm/bootm.h b/arch/arm/include/asm/bootm.h new file mode 100644 index 0000000..db2ff94 --- /dev/null +++ b/arch/arm/include/asm/bootm.h @@ -0,0 +1,26 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef ARM_BOOTM_H +#define ARM_BOOTM_H + +#ifdef CONFIG_USB_DEVICE +extern void udc_disconnect(void); +#endif + +#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index afa0093..03c25e9 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -1,4 +1,8 @@ -/* +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@corscience.de + * - Added prep subcommand support + * - Reorganized source - modeled after powerpc version + * * (C) Copyright 2002 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Marius Groeger mgroeger@sysgo.de @@ -29,35 +33,26 @@ #include <fdt.h> #include <libfdt.h> #include <fdt_support.h> +#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) -static void setup_start_tag (bd_t *bd); - -# ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd); -# endif -static void setup_commandline_tag (bd_t *bd, char *commandline); - -# ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, - ulong initrd_end); -# endif -static void setup_end_tag (bd_t *bd); - +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) static struct tag *params; -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ - -static ulong get_sp(void); -#if defined(CONFIG_OF_LIBFDT) -static int bootm_linux_fdt(int machid, bootm_headers_t *images); #endif
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + void arch_lmb_reserve(struct lmb *lmb) { ulong sp; @@ -80,85 +75,7 @@ void arch_lmb_reserve(struct lmb *lmb) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); }
-static void announce_and_cleanup(void) -{ - printf("\nStarting kernel ...\n\n"); - -#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect(void); - udc_disconnect(); - } -#endif - cleanup_before_linux(); -} - -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) -{ - bd_t *bd = gd->bd; - char *s; - int machid = bd->bi_arch_number; - void (*kernel_entry)(int zero, int arch, uint params); - -#ifdef CONFIG_CMDLINE_TAG - char *commandline = getenv ("bootargs"); -#endif - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - - s = getenv ("machid"); - if (s) { - machid = simple_strtoul (s, NULL, 16); - printf ("Using machid 0x%x from environment\n", machid); - } - - show_boot_progress (15); - #ifdef CONFIG_OF_LIBFDT - if (images->ft_len) - return bootm_linux_fdt(machid, images); -#endif - - kernel_entry = (void (*)(int, int, uint))images->ep; - - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); - -#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) - setup_start_tag (bd); -#ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); -#endif -#ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); -#endif -#ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); -#endif -#ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); -#endif -#ifdef CONFIG_INITRD_TAG - if (images->rd_start && images->rd_end) - setup_initrd_tag (bd, images->rd_start, images->rd_end); -#endif - setup_end_tag(bd); -#endif - - announce_and_cleanup(); - - kernel_entry(0, machid, bd->bi_boot_params); - /* does not return */ - - return 1; -} - -#if defined(CONFIG_OF_LIBFDT) static int fixup_memory_node(void *blob) { bd_t *bd = gd->bd; @@ -173,60 +90,26 @@ static int fixup_memory_node(void *blob)
return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); } +#endif
-static int bootm_linux_fdt(int machid, bootm_headers_t *images) +static void announce_and_cleanup(void) { - ulong rd_len; - void (*kernel_entry)(int zero, int dt_machid, void *dtblob); - ulong of_size = images->ft_len; - char **of_flat_tree = &images->ft_addr; - ulong *initrd_start = &images->initrd_start; - ulong *initrd_end = &images->initrd_end; - struct lmb *lmb = &images->lmb; - int ret; - - kernel_entry = (void (*)(int, int, void *))images->ep; - - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); - - rd_len = images->rd_end - images->rd_start; - ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, - initrd_start, initrd_end); - if (ret) - return ret; - - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); - if (ret) - return ret; - - debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel_entry); - - fdt_chosen(*of_flat_tree, 1); - - fixup_memory_node(*of_flat_tree); - - fdt_fixup_ethernet(*of_flat_tree); - - fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); - - announce_and_cleanup(); - - kernel_entry(0, machid, *of_flat_tree); - /* does not return */ + printf("\nStarting kernel ...\n\n");
- return 1; -} +#ifdef CONFIG_USB_DEVICE + udc_disconnect(); #endif + cleanup_before_linux(); +}
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) static void setup_start_tag (bd_t *bd) { - params = (struct tag *) bd->bi_boot_params; + params = (struct tag *)bd->bi_boot_params;
params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size (tag_core); @@ -237,10 +120,10 @@ static void setup_start_tag (bd_t *bd)
params = tag_next (params); } - +#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd) +static void setup_memory_tags(bd_t *bd) { int i;
@@ -254,10 +137,10 @@ static void setup_memory_tags (bd_t *bd) params = tag_next (params); } } -#endif /* CONFIG_SETUP_MEMORY_TAGS */ - +#endif
-static void setup_commandline_tag (bd_t *bd, char *commandline) +#ifdef CONFIG_CMDLINE_TAG +static void setup_commandline_tag(bd_t *bd, char *commandline) { char *p;
@@ -281,10 +164,10 @@ static void setup_commandline_tag (bd_t *bd, char *commandline)
params = tag_next (params); } - +#endif
#ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end) +static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end) { /* an ATAG_INITRD node tells the kernel where the compressed * ramdisk can be found. ATAG_RDIMG is a better name, actually. @@ -297,10 +180,10 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
params = tag_next (params); } -#endif /* CONFIG_INITRD_TAG */ +#endif
#ifdef CONFIG_SERIAL_TAG -void setup_serial_tag (struct tag **tmp) +void setup_serial_tag(struct tag **tmp) { struct tag *params = *tmp; struct tag_serialnr serialnr; @@ -328,19 +211,147 @@ void setup_revision_tag(struct tag **in_params) params->u.revision.rev = rev; params = tag_next (params); } -#endif /* CONFIG_REVISION_TAG */ +#endif
-static void setup_end_tag (bd_t *bd) +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) +static void setup_end_tag(bd_t *bd) { params->hdr.tag = ATAG_NONE; params->hdr.size = 0; } -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ +#endif
-static ulong get_sp(void) +#ifdef CONFIG_OF_LIBFDT +static int create_fdt(bootm_headers_t *images) { - ulong ret; + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + ulong *initrd_start = &images->initrd_start; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + ulong rd_len; + int ret;
- asm("mov %0, sp" : "=r"(ret) : ); - return ret; + debug("using: FDT\n"); + + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret; + + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return ret; + + fdt_chosen(*of_flat_tree, 1); + fixup_memory_node(*of_flat_tree); + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + return 0; +} +#endif + +/* Subcommand: PREP */ +static void boot_prep_linux(bootm_headers_t *images) +{ +#ifdef CONFIG_CMDLINE_TAG + char *commandline = getenv("bootargs"); +#endif + +#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) { + debug("using: FDT\n"); + if (create_fdt(images)) { + printf("FDT creation failed! hanging..."); + hang(); + } + } else +#endif + { +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ + defined(CONFIG_CMDLINE_TAG) || \ + defined(CONFIG_INITRD_TAG) || \ + defined(CONFIG_SERIAL_TAG) || \ + defined(CONFIG_REVISION_TAG) + debug("using: ATAGS\n"); + setup_start_tag(gd->bd); +#ifdef CONFIG_SERIAL_TAG + setup_serial_tag(¶ms); +#endif +#ifdef CONFIG_CMDLINE_TAG + setup_commandline_tag(gd->bd, commandline); +#endif +#ifdef CONFIG_REVISION_TAG + setup_revision_tag(¶ms); +#endif +#ifdef CONFIG_SETUP_MEMORY_TAGS + setup_memory_tags(gd->bd); +#endif +#ifdef CONFIG_INITRD_TAG + if (images->rd_start && images->rd_end) + setup_initrd_tag(gd->bd, images->rd_start, + images->rd_end); +#endif + setup_end_tag(gd->bd); +#else /* all tags */ + printf("FDT and ATAGS support not compiled in - hanging\n"); + hang(); +#endif /* all tags */ + } +} + +/* Subcommand: GO */ +static void boot_jump_linux(bootm_headers_t *images) +{ + int machid = gd->bd->bi_arch_number; + char *s; + void (*kernel_entry)(int zero, int arch, uint params); + + kernel_entry = (void (*)(int, int, uint))images->ep; + + s = getenv("machid"); + if (s) { + strict_strtoul(s, 16, (long unsigned int *) &machid); + printf("Using machid 0x%x from environment\n", machid); + } + + debug("## Transferring control to Linux (at address %08lx)" \ + "...\n", (ulong) kernel_entry); + show_boot_progress(15); + announce_and_cleanup(); + kernel_entry(0, machid, gd->bd->bi_boot_params); +} + +/* Main Entry point for arm bootm implementation + * + * Modeled after the powerpc implementation + * DIFFERENCE: Instead of calling prep and go at the end + * they are called if subcommand is equal 0. + */ +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + /* No need for those on ARM */ + if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & BOOTM_STATE_OS_GO) { + boot_jump_linux(images); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images); + return 0; }

On Thu, Mar 15, 2012 at 03:01:45PM +0100, Stefano Babic wrote:
From: Simon Schwarz simonschwarzcor@googlemail.com
Adds prep subcommand to bootm implementation of ARM. When bootm is called with the subcommand prep the function stops right after ATAGS creation and before announce_and_cleanup.
This is used in command "cmd_spl export"
[snip]
+static void boot_jump_linux(bootm_headers_t *images) +{
- int machid = gd->bd->bi_arch_number;
[snip]
- if (s) {
strict_strtoul(s, 16, (long unsigned int *) &machid);
printf("Using machid 0x%x from environment\n", machid);
- }
This upsets gcc 4.2. bi_arch_number is an unsigned long so I'm applying the following to this patch as part of my commit:
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 03c25e9..fc73ca9 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -310,7 +310,7 @@ static void boot_prep_linux(bootm_headers_t *images) /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images) { - int machid = gd->bd->bi_arch_number; + unsigned long machid = gd->bd->bi_arch_number; char *s; void (*kernel_entry)(int zero, int arch, uint params);
@@ -318,8 +318,8 @@ static void boot_jump_linux(bootm_headers_t *images)
s = getenv("machid"); if (s) { - strict_strtoul(s, 16, (long unsigned int *) &machid); - printf("Using machid 0x%x from environment\n", machid); + strict_strtoul(s, 16, &machid); + printf("Using machid 0x%lx from environment\n", machid); }
debug("## Transferring control to Linux (at address %08lx)" \
The original code used simple_strtoul which doesn't cause a warning here and newer gcc decided the unpatched usage was fine.

From: Tom Rini trini@ti.com
To avoid a conflict with common/cmd_bootm.c's 'images' (which is exposed as part of the Linux SPL series), rename the board-specific 'images' to 'imgs'.
Cc: Heiko Schocher hs@denx.de Signed-off-by: Tom Rini trini@ti.com Acked-by: Heiko Schocher hs@denx.de Tested-by: Heiko Schocher hs@denx.de --- board/ait/cam_enc_4xx/cam_enc_4xx.c | 48 +++++++++++++++++----------------- 1 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c index 5586576..bb29cf3 100644 --- a/board/ait/cam_enc_4xx/cam_enc_4xx.c +++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c @@ -503,7 +503,7 @@ struct fit_images_info { size_t size; };
-static struct fit_images_info images[10]; +static struct fit_images_info imgs[10];
struct menu_display { char title[50]; @@ -688,14 +688,14 @@ static int ait_menu_install_images(void) * img_writeramdisk: write ramdisk to ubi volume */
- while (images[count].type != IH_TYPE_INVALID) { + while (imgs[count].type != IH_TYPE_INVALID) { printf("Installing %s\n", - genimg_get_type_name(images[count].type)); - sprintf(s, "%p", images[count].data); + genimg_get_type_name(imgs[count].type)); + sprintf(s, "%p", imgs[count].data); setenv("img_addr_r", s); - sprintf(s, "%lx", (unsigned long)images[count].size); + sprintf(s, "%lx", (unsigned long)imgs[count].size); setenv("filesize", s); - switch (images[count].subtype) { + switch (imgs[count].subtype) { case FIT_SUBTYPE_DF_ENV_IMAGE: ret = run_command2("run img_writedfenv", 0); break; @@ -865,7 +865,7 @@ static int ait_menu_check_image(void) int found_uboot = -1; int found_ramdisk = -1;
- memset(images, 0, sizeof(images)); + memset(imgs, 0, sizeof(imgs)); s = getenv("fit_addr_r"); fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \ CONFIG_BOARD_IMG_ADDR_R; @@ -911,7 +911,7 @@ static int ait_menu_check_image(void) fit_image_print(addr, noffset, "");
fit_image_get_type(addr, noffset, - &images[count].type); + &imgs[count].type); /* Mandatory properties */ ret = fit_get_desc(addr, noffset, &desc); printf("Description: "); @@ -925,33 +925,33 @@ static int ait_menu_check_image(void) if (ret) { printf("unavailable\n"); } else { - images[count].subtype = ait_subtype_nr(subtype); + imgs[count].subtype = ait_subtype_nr(subtype); printf("%s %d\n", subtype, - images[count].subtype); + imgs[count].subtype); }
- sprintf(images[count].desc, "%s", desc); + sprintf(imgs[count].desc, "%s", desc);
ret = fit_image_get_data(addr, noffset, - &images[count].data, - &images[count].size); + &imgs[count].data, + &imgs[count].size);
printf("Data Size: "); if (ret) printf("unavailable\n"); else - genimg_print_size(images[count].size); - printf("Data @ %p\n", images[count].data); + genimg_print_size(imgs[count].size); + printf("Data @ %p\n", imgs[count].data); count++; } }
for (i = 0; i < count; i++) { - if (images[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE) + if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE) found_uboot = i; - if (images[i].type == IH_TYPE_RAMDISK) { + if (imgs[i].type == IH_TYPE_RAMDISK) { found_ramdisk = i; - images[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE; + imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE; } }
@@ -959,31 +959,31 @@ static int ait_menu_check_image(void) if (found_uboot >= 0) { s = getenv("dvn_boot_vers"); if (s) { - ret = strcmp(s, images[found_uboot].desc); + ret = strcmp(s, imgs[found_uboot].desc); if (ret != 0) { setenv("dvn_boot_vers", - images[found_uboot].desc); + imgs[found_uboot].desc); } else { found_uboot = -1; printf("no new uboot version\n"); } } else { - setenv("dvn_boot_vers", images[found_uboot].desc); + setenv("dvn_boot_vers", imgs[found_uboot].desc); } } if (found_ramdisk >= 0) { s = getenv("dvn_app_vers"); if (s) { - ret = strcmp(s, images[found_ramdisk].desc); + ret = strcmp(s, imgs[found_ramdisk].desc); if (ret != 0) { setenv("dvn_app_vers", - images[found_ramdisk].desc); + imgs[found_ramdisk].desc); } else { found_ramdisk = -1; printf("no new ramdisk version\n"); } } else { - setenv("dvn_app_vers", images[found_ramdisk].desc); + setenv("dvn_app_vers", imgs[found_ramdisk].desc); } } if ((found_uboot == -1) && (found_ramdisk == -1))

On Thu, Mar 15, 2012 at 03:01:33PM +0100, Stefano Babic wrote:
Hi,
this should be the final version for the patchset introducing direct Linux booting from SPL.
Only Patch 1/14: "Add cmd_spl command" was modified. Patches 2/13 up to 12/13 are untouched from V13. Patch 13/13 fix a small issue by compiling the cam_enc_4xx board (Tom Rini)
My first question is, are we hoping to get this in for v2012.03 or push it off one more time, but really get it in (and put it in a /next branch now'ish) ?

Dear Tom Rini,
In message 20120316172653.GD4234@bill-the-cat you wrote:
Only Patch 1/14: "Add cmd_spl command" was modified. Patches 2/13 up to 12/13 are untouched from V13. Patch 13/13 fix a small issue by compiling the cam_enc_4xx board (Tom Rini)
My first question is, are we hoping to get this in for v2012.03 or push it off one more time, but really get it in (and put it in a /next branch now'ish) ?
I want to get this into the upcoming release. I rather delay the release then keeping thie queued even longer.
Best regards,
Wolfgang Denk

On Fri, Mar 16, 2012 at 08:24:55PM +0100, Wolfgang Denk wrote:
Dear Tom Rini,
In message 20120316172653.GD4234@bill-the-cat you wrote:
Only Patch 1/14: "Add cmd_spl command" was modified. Patches 2/13 up to 12/13 are untouched from V13. Patch 13/13 fix a small issue by compiling the cam_enc_4xx board (Tom Rini)
My first question is, are we hoping to get this in for v2012.03 or push it off one more time, but really get it in (and put it in a /next branch now'ish) ?
I want to get this into the upcoming release. I rather delay the release then keeping thie queued even longer.
OK, that said, I'm OK with everything so far and you had the last round of "please fix/change this" comments. Are you happy with it all now?

Dear Tom Rini,
In message 20120316193030.GC31661@bill-the-cat you wrote:
OK, that said, I'm OK with everything so far and you had the last round of "please fix/change this" comments. Are you happy with it all now?
We can iterate forever on improvements, or we can get it in now. Let's do the latter :-)
Best regards,
Wolfgang Denk

On Fri, Mar 16, 2012 at 09:38:10PM +0100, Wolfgang Denk wrote:
Dear Tom Rini,
In message 20120316193030.GC31661@bill-the-cat you wrote:
OK, that said, I'm OK with everything so far and you had the last round of "please fix/change this" comments. Are you happy with it all now?
We can iterate forever on improvements, or we can get it in now. Let's do the latter :-)
OK. But now we add to the ELDK 4.2 saga. This series adds not just a warning (well, 5 for CONFIG_OMAP I guess, 1 for everything else) for everything ARM but also breaks everything else over undefined reference to 'raise'. ELDK 5.1 is fine. Now what?

Dear Tom Rini,
In message 20120316212442.GE31661@bill-the-cat you wrote:
OK. But now we add to the ELDK 4.2 saga. This series adds not just a warning (well, 5 for CONFIG_OMAP I guess, 1 for everything else) for everything ARM but also breaks everything else over undefined reference to 'raise'. ELDK 5.1 is fine. Now what?
This raise issue is probably due to a misconfiguration.
See "arch/arm/config.mk", search for "For EABI, make sure to provide raise()".
Check why arch/arm/lib/eabi_compat.c does not get compiled / linked.
Best regards,
Wolfgang Denk

On Sat, Mar 17, 2012 at 8:16 AM, Wolfgang Denk wd@denx.de wrote:
Dear Tom Rini,
In message 20120316212442.GE31661@bill-the-cat you wrote:
OK. But now we add to the ELDK 4.2 saga. This series adds not just a warning (well, 5 for CONFIG_OMAP I guess, 1 for everything else) for everything ARM but also breaks everything else over undefined reference to 'raise'. ELDK 5.1 is fine. Now what?
This raise issue is probably due to a misconfiguration.
See "arch/arm/config.mk", search for "For EABI, make sure to provide raise()".
Check why arch/arm/lib/eabi_compat.c does not get compiled / linked.
Even if ELDK5.1 is totally fine? And other modern toolchains as well..

On 17/03/2012 16:24, Tom Rini wrote:
On Sat, Mar 17, 2012 at 8:16 AM, Wolfgang Denk wd@denx.de wrote:
Dear Tom Rini,
Hi Tom,
In message 20120316212442.GE31661@bill-the-cat you wrote:
OK. But now we add to the ELDK 4.2 saga. This series adds not just a warning (well, 5 for CONFIG_OMAP I guess, 1 for everything else) for everything ARM but also breaks everything else over undefined reference to 'raise'. ELDK 5.1 is fine. Now what?
This raise issue is probably due to a misconfiguration.
See "arch/arm/config.mk", search for "For EABI, make sure to provide raise()".
Check why arch/arm/lib/eabi_compat.c does not get compiled / linked.
Even if ELDK5.1 is totally fine? And other modern toolchains as well..
Compiling with ELDK-4.2, I see only a couple of warnings more. But wihout any problem with raise. Really I had to revert "Revert "config.mk: Check for -fstack-usage support", but this is another story.
Stefano

Dear Tom Rini,
In message CA+M6bXk90TfweArc-dtFo3f8RG5jBmi7iz+KXmXGcxymHzfohQ@mail.gmail.com you wrote:
See "arch/arm/config.mk", search for "For EABI, make sure to provide raise()".
Check why arch/arm/lib/eabi_compat.c does not get compiled / linked.
Even if ELDK5.1 is totally fine? And other modern toolchains as well..
Yes, this problem is supposed to be handled by the code I mentioned.
There must be an error somewhere, if it doesn;t work.
Does arch/arm/lib/eabi_compat.c get compiled and linked?
Best regards,
Wolfgang Denk

On Fri, Mar 16, 2012 at 02:24:42PM -0700, Tom Rini wrote:
On Fri, Mar 16, 2012 at 09:38:10PM +0100, Wolfgang Denk wrote:
Dear Tom Rini,
In message 20120316193030.GC31661@bill-the-cat you wrote:
OK, that said, I'm OK with everything so far and you had the last round of "please fix/change this" comments. Are you happy with it all now?
We can iterate forever on improvements, or we can get it in now. Let's do the latter :-)
OK. But now we add to the ELDK 4.2 saga. This series adds not just a warning (well, 5 for CONFIG_OMAP I guess, 1 for everything else) for everything ARM but also breaks everything else over undefined reference to 'raise'. ELDK 5.1 is fine. Now what?
Welp, now I don't get it. I saw this Friday, I don't see it today. I blame gremlins. MAKEALL -a arm is going along rather nicely, just the one warning Stefano also sees. I'll go fix that, post what I changed and get out an updated pull request for Albert.

Hello, On 03/15/2012 03:01 PM, Stefano Babic wrote:
Hi,
this should be the final version for the patchset introducing direct Linux booting from SPL.
Only Patch 1/14: "Add cmd_spl command" was modified. Patches 2/13 up to 12/13 are untouched from V13. Patch 13/13 fix a small issue by compiling the cam_enc_4xx board (Tom Rini)
Changelog
[PATCH V14 01/13] Add cmd_spl command [PATCH V14 02/13] devkit8000: add config for spl command [PATCH V14 03/13] omap-common: Add NAND SPL linux booting [PATCH V14 04/13] devkit8000/spl: init GPMC for dm9000 in SPL [PATCH V14 05/13] omap-common/spl: Add linux boot to SPL [PATCH V14 06/13] omap/spl: change output of spl_parse_image_header [PATCH V14 07/13] devkit8000: Implement and activate direct OS boot [PATCH V14 08/13] Add cache functions to SPL for armv7 [PATCH V14 09/13] OMAP3: SPL: do not call I2C init if no I2C is set. [PATCH V14 10/13] SPL: call cleanup_before_linux() before booting [PATCH V14 11/13] OMAP3: twister: add support to boot Linux from SPL [PATCH V14 12/13] arm: Add Prep subcommand support to bootm [PATCH V14 13/13] cam_enc_4xx: Rename 'images' to 'imgs' _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
It applies on TI-u-boot, but TI-u-boot is still broken for Devkit8000 (SOFT_ECC). After merging mainline-u-boot into TI-u-boot it works fine:
Tested-by: Thomas Weber weber@corscience.de on Devkit8000
Thanks,
Thomas

Am 17/03/2012 05:34, schrieb Thomas Weber:
Hello, On 03/15/2012 03:01 PM, Stefano Babic wrote:
Hi,
Hi Thomas,
It applies on TI-u-boot, but TI-u-boot is still broken for Devkit8000 (SOFT_ECC).
Yes, I have the same problem, too. The commit breaking TI boards is reverted in u-boot mainline.
After merging mainline-u-boot into TI-u-boot it works fine:
Tested-by: Thomas Weber weber@corscience.de on Devkit8000
Thanks for testing,
Stefano
participants (14)
-
Albert ARIBAUD
-
Andreas Bießmann
-
Aneesh V
-
Heiko Schocher
-
Mike Frysinger
-
Scott Wood
-
Sergei Shtylyov
-
Simon Schwarz
-
stefano babic
-
Stefano Babic
-
Thomas Weber
-
Tom Rini
-
Tom Rini
-
Wolfgang Denk