diff mbox

[U-Boot] powerpc/bootm: Flush ramdisk and device tree image when booting on MP

Message ID 1323268978-26973-1-git-send-email-galak@kernel.crashing.org
State Accepted
Headers show

Commit Message

Kumar Gala Dec. 7, 2011, 2:42 p.m. UTC
We already flush the kernel image after we've loaded it to ensure
visiblity to the other cores.  We need to do the same thing for the
ramdisk and device tree images.  In AMP boot scenarios we might not be
HW cache coherent with the secondary core that we are loading and
setting the ramdisk and device tree up for.  Thus we need to ensure
we've flushed the regions of memory utilized by ramdisk and device tree
so the loadding and any modifications (from decompression or fdt updates)
are made visible to the secondary cores.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/lib/bootm.c |   22 ++++++++++++++++------
 common/image.c           |    8 ++++++++
 2 files changed, 24 insertions(+), 6 deletions(-)

Comments

Tabi Timur-B04825 Dec. 7, 2011, 4:17 p.m. UTC | #1
On Wed, Dec 7, 2011 at 8:42 AM, Kumar Gala <galak@kernel.crashing.org> wrote:

> +       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);

Why are we calling boot_prep_linux(images) when "flag &
BOOTM_STATE_OS_PREP" is zero? If we don't want the OS to be PREPped,
then why call a function named boot_prep_linux()?
Kumar Gala Dec. 7, 2011, 7:30 p.m. UTC | #2
On Dec 7, 2011, at 10:17 AM, Tabi Timur-B04825 wrote:

> On Wed, Dec 7, 2011 at 8:42 AM, Kumar Gala <galak@kernel.crashing.org> wrote:
> 
>> +       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);
> 
> Why are we calling boot_prep_linux(images) when "flag &
> BOOTM_STATE_OS_PREP" is zero? If we don't want the OS to be PREPped,
> then why call a function named boot_prep_linux()?

We call it in both cases, one is for 'normal' bootm command the other is for 'bootm subcommand'.

- k
Wolfgang Denk Dec. 12, 2011, 7:18 a.m. UTC | #3
Dear Kumar Gala,

In message <1323268978-26973-1-git-send-email-galak@kernel.crashing.org> you wrote:
> We already flush the kernel image after we've loaded it to ensure
> visiblity to the other cores.  We need to do the same thing for the
> ramdisk and device tree images.  In AMP boot scenarios we might not be
> HW cache coherent with the secondary core that we are loading and
> setting the ramdisk and device tree up for.  Thus we need to ensure
> we've flushed the regions of memory utilized by ramdisk and device tree
> so the loadding and any modifications (from decompression or fdt updates)
> are made visible to the secondary cores.
> 
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
>  arch/powerpc/lib/bootm.c |   22 ++++++++++++++++------
>  common/image.c           |    8 ++++++++
>  2 files changed, 24 insertions(+), 6 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index 8233f1f..efcfe84 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -174,6 +174,18 @@  void arch_lmb_reserve(struct lmb *lmb)
 	return ;
 }
 
+static void boot_prep_linux(bootm_headers_t *images)
+{
+#ifdef CONFIG_MP
+	/*
+	 * if we are MP make sure to flush the device tree so any changes are
+	 * made visibile to all other cores.  In AMP boot scenarios the cores
+	 * might not be HW cache coherent with each other.
+	 */
+	flush_cache((unsigned long)images->ft_addr, images->ft_len);
+#endif
+}
+
 static int boot_cmdline_linux(bootm_headers_t *images)
 {
 	ulong of_size = images->ft_len;
@@ -329,19 +341,17 @@  int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
 		return 0;
 	}
 
-	/*
-	 * We do nothing & report success to retain compatiablity with older
-	 * versions of u-boot in which this use to flush the dcache on MP
-	 * systems
-	 */
-	if (flag & BOOTM_STATE_OS_PREP)
+	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);
 	ret = boot_body_linux(images);
 	if (ret)
 		return ret;
diff --git a/common/image.c b/common/image.c
index aacae5a..77ca6e4 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1104,6 +1104,14 @@  int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
 			memmove_wd((void *)*initrd_start,
 					(void *)rd_data, rd_len, CHUNKSZ);
 
+#ifdef CONFIG_MP
+			/*
+			 * Ensure the image is flushed to memory to handle
+			 * AMP boot scenarios in which we might not be
+			 * HW cache coherent
+			 */
+			flush_cache((unsigned long)*initrd_start, rd_len);
+#endif
 			puts("OK\n");
 		}
 	} else {