[U-Boot] [PATCH v3 0/8] SPL: Port SPL framework to powerpc

This patchset ports the SPL framework to powerpc. Its based on the SPL generalization lately done by Tom Rini. The patches can be applied on top of his 7th version located here:
http://github.com/trini/u-boot WIP/spl-improvements
Additionally, a new MPC5200 board port is included, the a3m071 board port. This board port uses this SPL framework mainly to speed up booting into the OS (Linux of course). Detection of Linux vs. U-Boot booting is done here by checking the environment variable "boot_os". If "boot_os" is set to "yes", then the OS (Linux) is booted. Otherwise the "real" U-Boot is booted. For this env checking in the SPL, a small restructuring of the env code has been done.
Comments welcome!
Thanks, Stefan
Changes in v2: - Rebased on Tom's SPL framework patches v4 - Add option to skip copying of the mkimage header - Rebased on Tom's SPL framework patches v4 - Rebased on Tom's SPL framework patches v4 - a3m071 build: Concat SPL binary and u-boot.img directly (no padding)
Changes in v3: - Rebased on current master plus SPL framework v7 - Don't use special MPC5xxx memcpy in SPL - Move linker symbols to header spl.h (checkpatch)
Stefan Roese (8): powerpc: Extract EPAPR_MAGIC constants into processor.h SPL: Port SPL framework to powerpc env: Extract getenv_f() into separate source file mpc5200: Add SPL support mpc5200: Add a3m071 board support fdt: cmd_fdt: Call fdt_chosen() from "fdt boardsetup" Makefile: Add possibility to set entry-point for u-boot.img Makefile: Add target for combined spl/u-boot.bin & u-boot.img
MAINTAINERS | 2 + Makefile | 14 +- arch/powerpc/cpu/mpc5xxx/Makefile | 4 + arch/powerpc/cpu/mpc5xxx/spl_boot.c | 79 +++++++ arch/powerpc/cpu/mpc5xxx/start.S | 22 ++ arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds | 57 +++++ arch/powerpc/include/asm/processor.h | 6 + arch/powerpc/include/asm/spl.h | 31 +++ arch/powerpc/lib/Makefile | 11 + arch/powerpc/lib/bootm.c | 6 - arch/powerpc/lib/spl.c | 42 ++++ board/a3m071/Makefile | 36 +++ board/a3m071/README | 79 +++++++ board/a3m071/a3m071.c | 335 +++++++++++++++++++++++++++ board/a3m071/mt46v16m16-75.h | 32 +++ boards.cfg | 1 + common/Makefile | 4 + common/cmd_fdt.c | 4 +- common/cmd_nvedit.c | 58 ----- common/env_getenv_f.c | 82 +++++++ common/spl/spl.c | 10 + include/configs/a3m071.h | 385 ++++++++++++++++++++++++++++++++ 22 files changed, 1234 insertions(+), 66 deletions(-) create mode 100644 arch/powerpc/cpu/mpc5xxx/spl_boot.c create mode 100644 arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds create mode 100644 arch/powerpc/include/asm/spl.h create mode 100644 arch/powerpc/lib/spl.c create mode 100644 board/a3m071/Makefile create mode 100644 board/a3m071/README create mode 100644 board/a3m071/a3m071.c create mode 100644 board/a3m071/mt46v16m16-75.h create mode 100644 common/env_getenv_f.c create mode 100644 include/configs/a3m071.h

By extracting these defines into a header, they can be re-used by other C sources as well. This will be done by the SPL framework OS boot support.
Signed-off-by: Stefan Roese sr@denx.de ---
arch/powerpc/include/asm/processor.h | 6 ++++++ arch/powerpc/lib/bootm.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index dc009d6..daa670b 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1329,4 +1329,10 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #endif #endif /* CONFIG_MACH_SPECIFIC */
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_440) + #define EPAPR_MAGIC (0x45504150) +#else + #define EPAPR_MAGIC (0x65504150) +#endif + #endif /* __ASM_PPC_PROCESSOR_H */ diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 53dc4df..e3fee0b 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -87,12 +87,6 @@ static void boot_jump_linux(bootm_headers_t *images) * r8: 0 * r9: 0 */ -#if defined(CONFIG_MPC85xx) || defined(CONFIG_440) - #define EPAPR_MAGIC (0x45504150) -#else - #define EPAPR_MAGIC (0x65504150) -#endif - debug (" Booting using OF flat tree...\n"); WATCHDOG_RESET (); (*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,

This patch enables the SPL framework to be used on powerpc platforms and not only ARM.
Signed-off-by: Stefan Roese sr@denx.de --- Changes in v2: - Rebased on Tom's SPL framework patches v4 - Add option to skip copying of the mkimage header
arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/spl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/spl/spl.c | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/powerpc/lib/spl.c
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 965f9ea..9bcbdde 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -50,6 +50,7 @@ COBJS-y += cache.o COBJS-y += extable.o COBJS-y += interrupts.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
# Workaround for local bus unaligned access problems diff --git a/arch/powerpc/lib/spl.c b/arch/powerpc/lib/spl.c new file mode 100644 index 0000000..502c93b --- /dev/null +++ b/arch/powerpc/lib/spl.c @@ -0,0 +1,42 @@ +/* + * Copyright 2012 Stefan Roese sr@denx.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. + */ +#include <common.h> +#include <config.h> +#include <spl.h> +#include <image.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * 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 __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5, ulong r6, + ulong r7, ulong r8, ulong r9) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t)spl_image.entry_point; + + image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0); +} +#endif /* CONFIG_SPL_OS_BOOT */ diff --git a/common/spl/spl.c b/common/spl/spl.c index c640f87..e568c49 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -74,6 +74,16 @@ __weak int spl_start_uboot(void) } #endif
+/* + * Weak default function for board specific cleanup/preparation before + * Linux boot. Some boards/platforms might now need it, so just provide + * an empty stub here. + */ +__weak void spl_board_prepare_for_linux(void) +{ + /* Nothing to do! */ +} + void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header);

On 09/26/2012 04:01:08 AM, Stefan Roese wrote:
This patch enables the SPL framework to be used on powerpc platforms and not only ARM.
Signed-off-by: Stefan Roese sr@denx.de
Changes in v2:
- Rebased on Tom's SPL framework patches v4
- Add option to skip copying of the mkimage header
arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/spl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/spl/spl.c | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/powerpc/lib/spl.c
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 965f9ea..9bcbdde 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -50,6 +50,7 @@ COBJS-y += cache.o COBJS-y += extable.o COBJS-y += interrupts.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
Won't this build spl.o into the main U-Boot as well?
+/*
- 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 __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5,
ulong r6,
ulong r7, ulong r8, ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
-Scott

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 09/28/12 16:13, Scott Wood wrote:
On 09/26/2012 04:01:08 AM, Stefan Roese wrote:
This patch enables the SPL framework to be used on powerpc platforms and not only ARM.
Signed-off-by: Stefan Roese sr@denx.de --- Changes in v2: - Rebased on Tom's SPL framework patches v4 - Add option to skip copying of the mkimage header
arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/spl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/spl/spl.c | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/powerpc/lib/spl.c
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 965f9ea..9bcbdde 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -50,6 +50,7 @@ COBJS-y += cache.o COBJS-y += extable.o COBJS-y += interrupts.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
Won't this build spl.o into the main U-Boot as well?
True and probably uncaught as PowerPC uses -ffunction-sections / - --gc-sections on main U-Boot.
- -- Tom

On 09/29/2012 01:13 AM, Scott Wood wrote:
On 09/26/2012 04:01:08 AM, Stefan Roese wrote:
This patch enables the SPL framework to be used on powerpc platforms and not only ARM.
Signed-off-by: Stefan Roese sr@denx.de
Changes in v2:
- Rebased on Tom's SPL framework patches v4
- Add option to skip copying of the mkimage header
arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/spl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/spl/spl.c | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/powerpc/lib/spl.c
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 965f9ea..9bcbdde 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -50,6 +50,7 @@ COBJS-y += cache.o COBJS-y += extable.o COBJS-y += interrupts.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
Won't this build spl.o into the main U-Boot as well?
Yes. I'll fix it in the next patchset version.
+/*
- 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 __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5,
ulong r6,
ulong r7, ulong r8, ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed at some time. Okay?
Thanks, Stefan

On 10/02/2012 05:20:54 AM, Stefan Roese wrote:
On 09/29/2012 01:13 AM, Scott Wood wrote:
On 09/26/2012 04:01:08 AM, Stefan Roese wrote:
This patch enables the SPL framework to be used on powerpc
platforms
and not only ARM.
Signed-off-by: Stefan Roese sr@denx.de
Changes in v2:
- Rebased on Tom's SPL framework patches v4
- Add option to skip copying of the mkimage header
arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/spl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/spl/spl.c | 10 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 arch/powerpc/lib/spl.c
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 965f9ea..9bcbdde 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -50,6 +50,7 @@ COBJS-y += cache.o COBJS-y += extable.o COBJS-y += interrupts.o COBJS-$(CONFIG_CMD_KGDB) += kgdb.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
Won't this build spl.o into the main U-Boot as well?
Yes. I'll fix it in the next patchset version.
+/*
- 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 __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5,
ulong r6,
ulong r7, ulong r8, ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed at some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does this in common code, not even PPC-specific.
-Scott

On 10/02/2012 10:08 PM, Scott Wood wrote:
+void __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5,
ulong r6,
ulong r7, ulong r8, ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed at some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does this in common code, not even PPC-specific.
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Tom? Should I prepare a patch adding this cache flushing to common/spl/spl.c?
Thanks, Stefan

On 10/04/2012 02:36:34 AM, Stefan Roese wrote:
On 10/02/2012 10:08 PM, Scott Wood wrote:
+void __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4,
ulong r5,
ulong r6,
ulong r7, ulong r8,
ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC,
CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed
at
some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does
this in
common code, not even PPC-specific.
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
-Scott

On 10/04/2012 07:14 PM, Scott Wood wrote:
On 10/04/2012 02:36:34 AM, Stefan Roese wrote:
On 10/02/2012 10:08 PM, Scott Wood wrote:
+void __noreturn jump_to_image_linux(void *arg) +{
- debug("Entering kernel arg pointer: 0x%p\n", arg);
- typedef void (*image_entry_arg_t)(void *, ulong r4,
ulong r5,
ulong r6,
ulong r7, ulong r8,
ulong r9)
__attribute__ ((noreturn));
- image_entry_arg_t image_entry =
(image_entry_arg_t)spl_image.entry_point;
- image_entry(arg, 0, 0, EPAPR_MAGIC,
CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed
at
some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does
this in
common code, not even PPC-specific.
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
I see.
Tom, whats your input on this? Do you see any problems about putting a flush_cache() into the common SPL framework code? Are any of the ARM platforms currently using this framework already running with d-cache enabled?
Should I post a patch?
Thanks, Stefan

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/05/12 06:15, Stefan Roese wrote:
On 10/04/2012 07:14 PM, Scott Wood wrote:
On 10/04/2012 02:36:34 AM, Stefan Roese wrote:
On 10/02/2012 10:08 PM, Scott Wood wrote:
> +void __noreturn jump_to_image_linux(void *arg) +{ + > debug("Entering kernel arg pointer: 0x%p\n", arg); + > typedef void (*image_entry_arg_t)(void *, ulong r4,
ulong r5,
> ulong r6, + ulong r7, ulong r8,
ulong r9)
> + __attribute__ ((noreturn)); + image_entry_arg_t > image_entry = + > (image_entry_arg_t)spl_image.entry_point; + + > image_entry(arg, 0, 0, EPAPR_MAGIC,
CONFIG_SYS_BOOTMAPSZ, 0, 0);
> +}
At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed
at
some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does
this in
common code, not even PPC-specific.
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
I see.
Tom, whats your input on this? Do you see any problems about putting a flush_cache() into the common SPL framework code? Are any of the ARM platforms currently using this framework already running with d-cache enabled?
On ARM, jump_to_image_linux() calls cleanup_before_linux() to take care of flushing, etc. So the PowerPC jump_to_image_linux should take care of what it needs to take care of.
- -- Tom

On 10/05/2012 10:22:40 AM, Tom Rini wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/05/12 06:15, Stefan Roese wrote:
On 10/04/2012 07:14 PM, Scott Wood wrote:
On 10/04/2012 02:36:34 AM, Stefan Roese wrote:
On 10/02/2012 10:08 PM, Scott Wood wrote:
>> +void __noreturn jump_to_image_linux(void *arg) +{ + >> debug("Entering kernel arg pointer: 0x%p\n", arg); + >> typedef void (*image_entry_arg_t)(void *, ulong r4,
ulong r5,
>> ulong r6, + ulong r7,
ulong r8,
ulong r9)
>> + __attribute__ ((noreturn)); +
image_entry_arg_t
>> image_entry = + >> (image_entry_arg_t)spl_image.entry_point; + + >> image_entry(arg, 0, 0, EPAPR_MAGIC,
CONFIG_SYS_BOOTMAPSZ, 0, 0);
>> +} > > At what point does the image get cache-flushed?
Not at all right now. MPC5200 has dcache disabled, at least in the SPL. Other PowerPC architectures might add a cache flush here if needed
at
some time. Okay?
Or they might forget to do so and have weird bugs.
Why not just call flush_cache() on the image now? Non-SPL does
this in
common code, not even PPC-specific.
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
I see.
Tom, whats your input on this? Do you see any problems about putting a flush_cache() into the common SPL framework code? Are any of the ARM platforms currently using this framework already running with d-cache enabled?
On ARM, jump_to_image_linux() calls cleanup_before_linux() to take care of flushing, etc. So the PowerPC jump_to_image_linux should take care of what it needs to take care of.
It seems that most implementations of cleanup_before_linux() -- which is quite misnamed as we need to do this stuff no matter what we're loading -- disable and flush the entire cache. Are there any implementations that just flush the range that the image was loaded into? Is that information available at that point?
What if we're loading main U-Boot and not Linux? Does cleanup_before_linux() still get called?
Normal U-Boot does this from generic code, why not SPL? It should become a no-op on platforms that don't need it.
-Scott

On 10/05/2012 05:22 PM, Tom Rini wrote:
<snip>
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
I see.
Tom, whats your input on this? Do you see any problems about putting a flush_cache() into the common SPL framework code? Are any of the ARM platforms currently using this framework already running with d-cache enabled?
On ARM, jump_to_image_linux() calls cleanup_before_linux() to take care of flushing, etc. So the PowerPC jump_to_image_linux should take care of what it needs to take care of.
Hmmm. Why not move this cleanup_xxx stuff into the common code as well? Is it really that platform specific? Cache flushing is a common problem.
So basically a "+1" for Scotts comments. But I would suggest to address this in a follow up patch, to consolidate all this cleanup/cache_flush stuff. Okay?
Thanks, Stefan

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/05/12 10:03, Stefan Roese wrote:
On 10/05/2012 05:22 PM, Tom Rini wrote:
<snip>
Okay, probably better to add this code now. But shouldn't we add this code to the common SPL framework code then? Right before calling jump_to_image_linux()?
Sure, I didn't mean it should go here (it needs to be somewhere that knows the image start/end, not just the entry point). This is just the patch that prompted me to ask the question.
I see.
Tom, whats your input on this? Do you see any problems about putting a flush_cache() into the common SPL framework code? Are any of the ARM platforms currently using this framework already running with d-cache enabled?
On ARM, jump_to_image_linux() calls cleanup_before_linux() to take care of flushing, etc. So the PowerPC jump_to_image_linux should take care of what it needs to take care of.
Hmmm. Why not move this cleanup_xxx stuff into the common code as well? Is it really that platform specific? Cache flushing is a common problem.
So basically a "+1" for Scotts comments. But I would suggest to address this in a follow up patch, to consolidate all this cleanup/cache_flush stuff. Okay?
OK, so my quick check of things shows that in SPL, arm isn't ever enabling the dcache (at least CONFIG_SPL_FRAMEWORK), we just make sure that yes, really, we're good to go for Linux kernel booting. That's why we haven't had this as a general issue yet. So in sum, yes, please come up with patches to get things in a more consistent state. It should probably be re-naming cleanup_before_linux as well and calling that as in some cases we need to do a little more than i/d_disable, flush (see the v7 one). Thanks!
- -- Tom

By extracting getenv_f and envmatch() from cmd_nvedit.c into a separate file, getenv_f() can be included easily into the SPL binary. With this, SPL boards can now use getenv_f() to read environment variables (e.g. to detect if the OS or U-Boot shall be executed).
In the approach this is done for env stored in NOR flash, as this will be used by an upcoming MPC5200 board port.
Signed-off-by: Stefan Roese sr@denx.de --- Changes in v3: - Rebased on current master plus SPL framework v7
common/Makefile | 4 +++ common/cmd_nvedit.c | 58 ------------------------------------ common/env_getenv_f.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 58 deletions(-) create mode 100644 common/env_getenv_f.c
diff --git a/common/Makefile b/common/Makefile index 22e8a6f..c30099d 100644 --- a/common/Makefile +++ b/common/Makefile @@ -50,6 +50,7 @@ XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o XCOBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o +COBJS-y += env_getenv_f.o COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o @@ -194,6 +195,9 @@ COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o endif
ifdef CONFIG_SPL_BUILD +COBJS-y += env_common.o +COBJS-y += env_getenv_f.o +COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o endif COBJS-y += console.o diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 3474bc6..725e082 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -563,44 +563,6 @@ char *getenv(const char *name) return NULL; }
-/* - * Look up variable from environment for restricted C runtime env. - */ -int getenv_f(const char *name, char *buf, unsigned len) -{ - int i, nxt; - - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - int val, n; - - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) { - if (nxt >= CONFIG_ENV_SIZE) - return -1; - } - - val = envmatch((uchar *)name, i); - if (val < 0) - continue; - - /* found; copy out */ - for (n = 0; n < len; ++n, ++buf) { - *buf = env_get_char(val++); - if (*buf == '\0') - return n; - } - - if (n) - *--buf = '\0'; - - printf("env_buf [%d bytes] too small for value of "%s"\n", - len, name); - - return n; - } - - return -1; -} - /** * Decode the integer value of an environment variable and return it. * @@ -636,26 +598,6 @@ U_BOOT_CMD( ); #endif
- -/* - * Match a name / name=value pair - * - * s1 is either a simple 'name', or a 'name=value' pair. - * i2 is the environment index for a 'name2=value2' pair. - * If the names match, return the index for the value2, else -1. - */ -int envmatch(uchar *s1, int i2) -{ - while (*s1 == env_get_char(i2++)) - if (*s1++ == '=') - return i2; - - if (*s1 == '\0' && env_get_char(i2-1) == '=') - return i2; - - return -1; -} - static int do_env_default(cmd_tbl_t *cmdtp, int __flag, int argc, char * const argv[]) { diff --git a/common/env_getenv_f.c b/common/env_getenv_f.c new file mode 100644 index 0000000..7dfbfe0 --- /dev/null +++ b/common/env_getenv_f.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2000-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Andreas Heppel aheppel@sysgo.de + * + * Copyright 2011 Freescale Semiconductor, Inc. + * + * 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. + */ + +#include <common.h> +#include <environment.h> + +/* + * Match a name / name=value pair + * + * s1 is either a simple 'name', or a 'name=value' pair. + * i2 is the environment index for a 'name2=value2' pair. + * If the names match, return the index for the value2, else -1. + */ +int envmatch(uchar *s1, int i2) +{ + while (*s1 == env_get_char(i2++)) + if (*s1++ == '=') + return i2; + + if (*s1 == '\0' && env_get_char(i2-1) == '=') + return i2; + + return -1; +} + +/* + * Look up variable from environment for restricted C runtime env. + */ +int getenv_f(const char *name, char *buf, unsigned len) +{ + int i, nxt; + + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + int val, n; + + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) { + if (nxt >= CONFIG_ENV_SIZE) + return -1; + } + + val = envmatch((uchar *)name, i); + if (val < 0) + continue; + + /* found; copy out */ + for (n = 0; n < len; ++n, ++buf) { + *buf = env_get_char(val++); + if (*buf == '\0') + return n; + } + + if (n) + *--buf = '\0'; + + printf("env_buf [%d bytes] too small for value of "%s"\n", + len, name); + + return n; + } + + return -1; +}

On 09/26/2012 11:01 AM, Stefan Roese wrote:
By extracting getenv_f and envmatch() from cmd_nvedit.c into a separate file, getenv_f() can be included easily into the SPL binary. With this, SPL boards can now use getenv_f() to read environment variables (e.g. to detect if the OS or U-Boot shall be executed).
In the approach this is done for env stored in NOR flash, as this will be used by an upcoming MPC5200 board port.
This patch is not needed as it seems. I'll post a new version in a short while that only enables the needed files for SPL_BUILD.
Thanks, Stefan

This patch adds SPL booting support (NOR flash) for the MPC5200 platforms.
Signed-off-by: Stefan Roese sr@denx.de --- Changes in v2: - Rebased on Tom's SPL framework patches v4
Changes in v3: - Don't use special MPC5xxx memcpy in SPL - Move linker symbols to header spl.h (checkpatch)
arch/powerpc/cpu/mpc5xxx/Makefile | 4 ++ arch/powerpc/cpu/mpc5xxx/spl_boot.c | 79 +++++++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc5xxx/start.S | 22 +++++++++ arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds | 57 ++++++++++++++++++++++++ arch/powerpc/include/asm/spl.h | 31 +++++++++++++ arch/powerpc/lib/Makefile | 10 +++++ 6 files changed, 203 insertions(+) create mode 100644 arch/powerpc/cpu/mpc5xxx/spl_boot.c create mode 100644 arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds create mode 100644 arch/powerpc/include/asm/spl.h
diff --git a/arch/powerpc/cpu/mpc5xxx/Makefile b/arch/powerpc/cpu/mpc5xxx/Makefile index 1a088b7..8de2c13 100644 --- a/arch/powerpc/cpu/mpc5xxx/Makefile +++ b/arch/powerpc/cpu/mpc5xxx/Makefile @@ -41,6 +41,10 @@ COBJS-y += speed.o COBJS-$(CONFIG_CMD_USB) += usb_ohci.o COBJS-$(CONFIG_CMD_USB) += usb.o
+ifdef CONFIG_SPL_BUILD +COBJS-y += spl_boot.o +endif + SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) START := $(addprefix $(obj),$(SSTART) $(CSTART)) diff --git a/arch/powerpc/cpu/mpc5xxx/spl_boot.c b/arch/powerpc/cpu/mpc5xxx/spl_boot.c new file mode 100644 index 0000000..9f14127 --- /dev/null +++ b/arch/powerpc/cpu/mpc5xxx/spl_boot.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012 Stefan Roese sr@denx.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. + */ + +#include <common.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Needed to align size SPL image to a 4-byte length + */ +u32 end_align __attribute__ ((section(".end_align"))); + +/* + * Return selected boot device. On MPC5200 its only NOR flash right now. + */ +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_NOR; +} + +/* + * SPL version of board_init_f() + */ +void board_init_f(ulong bootflag) +{ + end_align = (u32)__spl_flash_end; + + /* + * First we need to initialize the SDRAM, so that the real + * U-Boot or the OS (Linux) can be loaded + */ + initdram(0); + + /* Clear bss */ + memset(__bss_start, '\0', __bss_end__ - __bss_start); + + /* + * Init global_data pointer. Has to be done before calling + * get_clocks(), as it stores some clock values into gd needed + * later on in the serial driver. + */ + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); + /* Clear initial global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + /* + * get_clocks() needs to be called so that the serial driver + * works correctly + */ + get_clocks(); + + /* + * Do rudimental console / serial setup + */ + preloader_console_init(); + + /* + * Call board_init_r() (SPL framework version) to load and boot + * real U-Boot or OS + */ + board_init_r(NULL, 0); + /* Does not return!!! */ +} diff --git a/arch/powerpc/cpu/mpc5xxx/start.S b/arch/powerpc/cpu/mpc5xxx/start.S index 51cc4e2..ad5bc0a 100644 --- a/arch/powerpc/cpu/mpc5xxx/start.S +++ b/arch/powerpc/cpu/mpc5xxx/start.S @@ -50,6 +50,7 @@ #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) #endif
+#ifndef CONFIG_SPL_BUILD /* * Set up GOT: Global Offset Table * @@ -68,6 +69,7 @@ GOT_ENTRY(__bss_end__) GOT_ENTRY(__bss_start) END_GOT +#endif
/* * Version string @@ -84,6 +86,18 @@ version_string: . = EXC_OFF_SYS_RESET .globl _start _start: + +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + /* + * This is the entry of the real U-Boot from a board port + * that supports SPL booting on the MPC5200. We only need + * to call board_init_f() here. Everything else has already + * been done in the SPL u-boot version. + */ + GET_GOT /* initialize GOT access */ + bl board_init_f /* run 1st part of board init code (in Flash)*/ + /* NOTREACHED - board_init_f() does not return */ +#else mfmsr r5 /* save msr contents */
/* Move CSBoot and adjust instruction pointer */ @@ -152,7 +166,9 @@ lowboot_reentry: /* Be careful to keep code relocatable ! */ /*--------------------------------------------------------------*/
+#ifndef CONFIG_SPL_BUILD GET_GOT /* initialize GOT access */ +#endif
/* r3: IMMR */ bl cpu_init_f /* run low-level CPU init code (in Flash)*/ @@ -160,7 +176,9 @@ lowboot_reentry: bl board_init_f /* run 1st part of board init code (in Flash)*/
/* NOTREACHED - board_init_f() does not return */ +#endif
+#ifndef CONFIG_SPL_BUILD /* * Vector Table */ @@ -333,6 +351,7 @@ int_return: lwz r1,GPR1(r1) SYNC rfi +#endif /* CONFIG_SPL_BUILD */
/* * This code initialises the MPC5xxx processor core @@ -522,6 +541,7 @@ get_pvr: mfspr r3, PVR blr
+#ifndef CONFIG_SPL_BUILD /*------------------------------------------------------------------------------*/
/* @@ -759,3 +779,5 @@ trap_init:
mtlr r4 /* restore link register */ blr + +#endif /* CONFIG_SPL_BUILD */ diff --git a/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds new file mode 100644 index 0000000..cab9b92 --- /dev/null +++ b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds @@ -0,0 +1,57 @@ +/* + * Copyright 2012 Stefan Roese sr@denx.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 + */ + +MEMORY +{ + sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, + LENGTH = CONFIG_SPL_BSS_MAX_SIZE + flash : ORIGIN = CONFIG_SPL_TEXT_BASE, + LENGTH = CONFIG_SYS_SPL_MAX_LEN +} + +OUTPUT_ARCH(powerpc) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + arch/powerpc/cpu/mpc5xxx/start.o (.text) + *(.text*) + } > flash + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash + + . = ALIGN(4); + .end_align : { *(.end_align*) } > flash + __spl_flash_end = .; + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end__ = .; + } > sdram +} diff --git a/arch/powerpc/include/asm/spl.h b/arch/powerpc/include/asm/spl.h new file mode 100644 index 0000000..f43bc23 --- /dev/null +++ b/arch/powerpc/include/asm/spl.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.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 _ASM_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NOR 1 + +/* Linker symbols */ +extern char __bss_start[], __bss_end__[]; + +#endif diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 9bcbdde..cdb7a31 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -44,7 +44,9 @@ SOBJS-y += ticks.o SOBJS-y += reloc.o
COBJS-$(CONFIG_BAT_RW) += bat_rw.o +ifndef CONFIG_SPL_BUILD COBJS-y += board.o +endif COBJS-y += bootm.o COBJS-y += cache.o COBJS-y += extable.o @@ -53,6 +55,11 @@ COBJS-$(CONFIG_CMD_KGDB) += kgdb.o COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-y += time.o
+# Don't include the MPC5xxx special memcpy into the +# SPL U-Boot image. memcpy is used in the SPL NOR +# flash driver. And we need the real, fast memcpy +# here. We have no problems with unaligned access. +ifndef CONFIG_SPL_BUILD # Workaround for local bus unaligned access problems # on MPC512x and MPC5200 ifdef CONFIG_MPC512X @@ -63,6 +70,7 @@ ifdef CONFIG_MPC5200 $(obj)ppcstring.o: AFLAGS += -Dmemcpy=__memcpy COBJS-y += memcpy_mpc5200.o endif +endif
COBJS += $(sort $(COBJS-y))
@@ -75,12 +83,14 @@ TARGETS += $(LIB) all: $(TARGETS)
$(LIB): $(obj).depend $(OBJS) +ifndef CONFIG_SPL_BUILD @if ! $(CROSS_COMPILE)readelf -S $(OBJS) | grep -q '.fixup.*PROGBITS';\ then \ echo "ERROR: Your compiler doesn't generate .fixup sections!";\ echo " Upgrade to a recent toolchain."; \ exit 1; \ fi; +endif $(call cmd_link_o_target, $(OBJS))
$(LIBGCC): $(obj).depend $(LGOBJS)
participants (3)
-
Scott Wood
-
Stefan Roese
-
Tom Rini