All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Schwarz <simonschwarzcor@googlemail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] arm: Add Prep subcommand support to bootm
Date: Mon, 29 Aug 2011 18:08:13 +0200	[thread overview]
Message-ID: <1314634093-8494-1-git-send-email-simonschwarzcor@gmail.com> (raw)

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

changes after slicing this from patch
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106422:
DEL Prototype declaration - not necessary if reordered
DEL Most #ifdefs - relying on -ffunction-sections and --gc-sections to handle unused
CHG reorganized bootm. powerpc implementation was the model
ADD get_board_serial fake implementation - this is needed if setup_serial_tag
	is compiled but the board doesn't support it - tradeoff for removing
	#ifdefs
---
 arch/arm/lib/bootm.c |  330 +++++++++++++++++++++++++------------------------
 1 files changed, 168 insertions(+), 162 deletions(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 802e833..5f112e2 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>
@@ -32,31 +36,16 @@
 
 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);
-
+static void (*kernel_entry)(int zero, int arch, uint params);
 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)
 {
@@ -80,85 +69,6 @@ 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 (&params);
-#endif
-#ifdef CONFIG_REVISION_TAG
-	setup_revision_tag (&params);
-#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;
@@ -174,54 +84,19 @@ 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 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_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
+	{
+		extern void udc_disconnect(void);
+		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)
 static void setup_start_tag (bd_t *bd)
 {
 	params = (struct tag *) bd->bi_boot_params;
@@ -237,7 +112,6 @@ static void setup_start_tag (bd_t *bd)
 }
 
 
-#ifdef CONFIG_SETUP_MEMORY_TAGS
 static void setup_memory_tags (bd_t *bd)
 {
 	int i;
@@ -252,8 +126,6 @@ static void setup_memory_tags (bd_t *bd)
 		params = tag_next (params);
 	}
 }
-#endif /* CONFIG_SETUP_MEMORY_TAGS */
-
 
 static void setup_commandline_tag (bd_t *bd, char *commandline)
 {
@@ -280,8 +152,6 @@ static void setup_commandline_tag (bd_t *bd, char *commandline)
 	params = tag_next (params);
 }
 
-
-#ifdef CONFIG_INITRD_TAG
 static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
 {
 	/* an ATAG_INITRD node tells the kernel where the compressed
@@ -295,9 +165,18 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
 
 	params = tag_next (params);
 }
-#endif /* CONFIG_INITRD_TAG */
 
-#ifdef CONFIG_SERIAL_TAG
+/* This is a workaround - if boards don't implement
+ * get_board_serial */
+__attribute__((weak))
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+	printf("This board does not implement get_board_serial() \
+		but calls it serialnr is filled with junk!\n");
+	serialnr->high = 0xABCDF;
+	serialnr->low = 0xABCDF;
+}
+
 void setup_serial_tag (struct tag **tmp)
 {
 	struct tag *params = *tmp;
@@ -312,9 +191,7 @@ void setup_serial_tag (struct tag **tmp)
 	params = tag_next (params);
 	*tmp = params;
 }
-#endif
 
-#ifdef CONFIG_REVISION_TAG
 void setup_revision_tag(struct tag **in_params)
 {
 	u32 rev = 0;
@@ -326,19 +203,148 @@ void setup_revision_tag(struct tag **in_params)
 	params->u.revision.rev = rev;
 	params = tag_next (params);
 }
-#endif  /* 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 */
 
-static ulong get_sp(void)
+static void create_atags(bootm_headers_t *images)
 {
-	ulong ret;
+	bd_t	*bd = gd->bd;
+	char *commandline = getenv("bootargs");
 
-	asm("mov %0, sp" : "=r"(ret) : );
-	return ret;
+	setup_start_tag(bd);
+#ifdef CONFIG_SERIAL_TAG
+	setup_serial_tag(&params);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+	setup_commandline_tag(gd->bd, commandline);
+#endif
+#ifdef CONFIG_REVISION_TAG
+	setup_revision_tag(&params);
+#endif
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+	setup_memory_tags(bd);
+#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);
+}
+
+static int create_fdt(bootm_headers_t *images)
+{
+	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;
+
+	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;
+}
+
+/* Subcommand: CMDLINE */
+static int boot_cmdline_linux(bootm_headers_t *images)
+{
+	return -1; /* not implemented */
+}
+
+/* Subcommand: BDT */
+static int boot_bd_t_linux(bootm_headers_t *images)
+{
+	return -1; /* not implemented */
+}
+
+/* Subcommand: PREP */
+static void boot_prep_linux(bootm_headers_t *images)
+{
+#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");
+		create_atags(images);
+#else
+	printf("FDT and ATAGS failed - hanging\n");
+	hang();
+#endif
+	}
+
+	kernel_entry = (void (*)(int, int, uint))images->ep;
+}
+
+/* Subcommand: GO */
+static void boot_jump_linux(bootm_headers_t *images)
+{
+	int	machid = gd->bd->bi_arch_number;
+	char	*s;
+	s = getenv("machid");
+	if (s) {
+		strict_strtoul(s, 16, (long unsigned int *) &machid);
+		debug("Using machid 0x%x from environment\n", machid);
+	}
+
+	debug("Using machid 0x%x from bd\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 subommand is equal 0.
+ */
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+	if (flag & BOOTM_STATE_OS_CMDLINE)
+		boot_cmdline_linux(images);
+
+	if (flag & BOOTM_STATE_OS_BD_T)
+		boot_bd_t_linux(images);
+
+	if (flag & BOOTM_STATE_OS_PREP || flag == 0)
+		boot_prep_linux(images);
+
+	if (flag & BOOTM_STATE_OS_GO || flag == 0)
+		boot_jump_linux(images);
+
+	return 0;
 }
-- 
1.7.4.1

             reply	other threads:[~2011-08-29 16:08 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-29 16:08 Simon Schwarz [this message]
2011-09-05 10:58 ` [U-Boot] [PATCH] arm: Add Prep subcommand support to bootm Andreas Bießmann
2011-09-05 14:06   ` Simon Schwarz
2011-09-05 15:25     ` Andreas Bießmann
2011-09-05 14:53 ` [U-Boot] [PATCH V2] " Simon Schwarz
2011-09-19 13:43   ` [U-Boot] [PATCH V3] " Simon Schwarz
2011-12-06 17:26     ` [U-Boot] [PATCH V4] " Simon Schwarz
2012-01-16  8:12       ` [U-Boot] [PATCH] " Simon Schwarz
2012-01-17 10:26         ` Stefano Babic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1314634093-8494-1-git-send-email-simonschwarzcor@gmail.com \
    --to=simonschwarzcor@googlemail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.