summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Schwarz <simonschwarzcor@googlemail.com>2012-03-15 04:01:38 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2012-03-27 22:05:28 +0200
commit379c19ab701dba85072f3d238a32c77611bc1284 (patch)
tree2d3cff92f75adc1e479c2e06af72936307e6d174
parent9e70c08b6fb7632385d59827e005569e5ddfd31d (diff)
downloadtalos-obmc-uboot-379c19ab701dba85072f3d238a32c77611bc1284.tar.gz
talos-obmc-uboot-379c19ab701dba85072f3d238a32c77611bc1284.zip
omap-common/spl: Add linux boot to SPL
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>
-rw-r--r--arch/arm/cpu/armv7/omap-common/spl.c44
-rw-r--r--arch/arm/cpu/armv7/omap-common/spl_nand.c53
-rw-r--r--arch/arm/include/asm/omap_common.h1
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 99bb382750..6b54ac7f01 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 2a6621492e..1295e88752 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 85eac7db59..6f25948e20 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);
OpenPOWER on IntegriCloud