Patchwork [U-Boot,6/7,v6] nand: tpl : introduce the TPL based on the SPL

login
register
mail settings
Submitter ying.zhang@freescale.com
Date June 26, 2013, 7:18 a.m.
Message ID <1372231112-25185-6-git-send-email-ying.zhang@freescale.com>
Download mbox | patch
Permalink /patch/254607/
State Superseded
Delegated to: Andy Fleming
Headers show

Comments

ying.zhang@freescale.com - June 26, 2013, 7:18 a.m.
From: Ying Zhang <b40530@freescale.com>

Due to the nand SPL on some board(e.g. P1022DS)has a size limit, it can
not be more than 4K. So, the SPL cannot initialize the DDR with the SPD
code. This patch introduces TPL to enable a loader stub that runs in the
L2 SRAM, after being loaded by the code from the SPL. It initializes the
DDR with the SPD or other operations.

The TPL's size is sizeable, the maximum size must not exceed the size of L2
SRAM. It initializes the DDR through SPD code, and copys final uboot image
to DDR. So there are three stage uboot images:
	* spl_boot, * tpl_boot, * final uboot image,

This patch is on top of the patch:
SPL : spi flash : support to start from eSPI with SPL

Signed-off-by: Ying Zhang <b40530@freescale.com>
---
Compared with the original version, Changed as below:
1. Split from "powerpc/p1022ds: nand: introduce the TPL based on the SPL".
2. No change.
3. No change.
4. No change.
5. Use ifdef to define "nand_load_image" to non-static for non-SPL

 Makefile                                           |   21 +++-
 README                                             |   57 +++++++-
 arch/powerpc/config.mk                             |    2 +
 .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c        |    4 +-
 arch/powerpc/lib/Makefile                          |    2 +
 common/Makefile                                    |    9 +
 common/cmd_nvedit.c                                |    8 +-
 config.mk                                          |   32 ++++
 doc/README.TPL                                     |   69 +++++++++
 drivers/mtd/nand/Makefile                          |    7 +
 drivers/mtd/nand/fsl_elbc_spl.c                    |    5 +-
 drivers/serial/serial.c                            |    2 +-
 include/bootstage.h                                |    3 +-
 tpl/Makefile                                       |  161 ++++++++++++++++++++
 14 files changed, 368 insertions(+), 14 deletions(-)
 create mode 100644 doc/README.TPL
 create mode 100644 tpl/Makefile
Zhang Ying-B40530 - June 28, 2013, 7:57 a.m.
-----Original Message-----
From: Wood Scott-B07421 
Sent: Thursday, June 27, 2013 6:33 AM
To: Zhang Ying-B40530
Cc: u-boot@lists.denx.de; afleming@gmail.com; Xie Xiaobo-R63061; Zhang Ying-B40530
Subject: Re: [PATCH 6/7 v6] nand: tpl : introduce the TPL based on the SPL

On 06/26/2013 02:18:31 AM, ying.zhang@freescale.com wrote:
> From: Ying Zhang <b40530@freescale.com>
> 
> Due to the nand SPL on some board(e.g. P1022DS)has a size limit, it  
> can
> not be more than 4K. So, the SPL cannot initialize the DDR with the  
> SPD
> code. This patch introduces TPL to enable a loader stub that runs in  
> the
> L2 SRAM, after being loaded by the code from the SPL. It initializes  
> the
> DDR with the SPD or other operations.
> 
> The TPL's size is sizeable, the maximum size must not exceed the size  
> of L2
> SRAM.

Using L2 SRAM for this is an implementation detail, and not appropriate  
for a description of the generic TPL infrastructure.  For example, on  
newer QorIQ chips you'd be using CPC (L3) SRAM.

> It initializes the DDR through SPD code, and copys final uboot image
> to DDR. So there are three stage uboot images:
> 	* spl_boot, * tpl_boot, * final uboot image,
> 
> This patch is on top of the patch:
> SPL : spi flash : support to start from eSPI with SPL

You don't need to mention a dependency on an earlier patch in the same  
patchset (and when you do need to mention a dependency, it should be  
below the --- line so it doesn't go into the git history).  OTOH, you  
do need to mention the dependency on the patch to have a separate  
autoconf.mk.
[Zhang Ying] 
I want to know when the patch that creates a separate autoconf.mk can
be merged?
My patch need to be verified on the basis of it.
Scott Wood - June 28, 2013, 7:39 p.m.
On 06/28/2013 02:57:55 AM, Zhang Ying-B40530 wrote:
> You don't need to mention a dependency on an earlier patch in the same
> patchset (and when you do need to mention a dependency, it should be
> below the --- line so it doesn't go into the git history).  OTOH, you
> do need to mention the dependency on the patch to have a separate
> autoconf.mk.
> [Zhang Ying]
> I want to know when the patch that creates a separate autoconf.mk can
> be merged?
> My patch need to be verified on the basis of it.

You could include it as the first patch in your series (be sure to  
leave the authorship intact).

-Scott
Zhang Ying-B40530 - July 1, 2013, 8:48 a.m.
I haven't subscribe the mail list and I didn't find the patch 
"creates a separate autoconf.mk". Can you tell me where I can
find it? Thanks.

-----Original Message-----
From: Wood Scott-B07421 
Sent: Saturday, June 29, 2013 3:40 AM
To: Zhang Ying-B40530
Cc: Wood Scott-B07421; u-boot@lists.denx.de; afleming@gmail.com; Xie Xiaobo-R63061
Subject: Re: [PATCH 6/7 v6] nand: tpl : introduce the TPL based on the SPL

On 06/28/2013 02:57:55 AM, Zhang Ying-B40530 wrote:
> You don't need to mention a dependency on an earlier patch in the same 
> patchset (and when you do need to mention a dependency, it should be 
> below the --- line so it doesn't go into the git history).  OTOH, you 
> do need to mention the dependency on the patch to have a separate 
> autoconf.mk.
> [Zhang Ying]
> I want to know when the patch that creates a separate autoconf.mk can 
> be merged?
> My patch need to be verified on the basis of it.

You could include it as the first patch in your series (be sure to leave the authorship intact).

-Scott
Scott Wood - July 1, 2013, 4:57 p.m.
On 07/01/2013 03:48:16 AM, Zhang Ying-B40530 wrote:
> I haven't subscribe the mail list and I didn't find the patch
> "creates a separate autoconf.mk". Can you tell me where I can
> find it? Thanks.

Search in http://patchwork.ozlabs.org/project/uboot/list/

-Scott

Patch

diff --git a/Makefile b/Makefile
index fdaddb9..0513e4d 100644
--- a/Makefile
+++ b/Makefile
@@ -118,10 +118,11 @@  endif # ifneq ($(BUILD_DIR),)
 
 OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
 SPLTREE		:= $(OBJTREE)/spl
+TPLTREE		:= $(OBJTREE)/tpl
 SRCTREE		:= $(CURDIR)
 TOPDIR		:= $(SRCTREE)
 LNDIR		:= $(OBJTREE)
-export	TOPDIR SRCTREE OBJTREE SPLTREE
+export	TOPDIR SRCTREE OBJTREE SPLTREE TPLTREE
 
 MKCONFIG	:= $(SRCTREE)/mkconfig
 export MKCONFIG
@@ -412,6 +413,7 @@  ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map
 ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin
 ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin
 ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
+ALL-$(CONFIG_TPL) += $(obj)tpl/u-boot-tpl.bin
 ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
 ifneq ($(CONFIG_SPL_TARGET),)
 ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
@@ -498,6 +500,18 @@  $(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 		cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
 		rm $(obj)spl/u-boot-spl-pad.bin
 
+$(obj)u-boot-with-tpl.bin: $(obj)spl/u-boot-spl.bin $(obj)tpl/u-boot-tpl.bin \
+		$(obj)u-boot.bin
+		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SPL_PAD_TO) \
+			-I binary -O binary \
+			$(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl-pad.bin
+		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_PAD_TO) \
+			-I binary -O binary \
+			$(obj)tpl/u-boot-tpl.bin $(obj)tpl/u-boot-tpl-pad.bin
+		cat $(obj)spl/u-boot-spl-pad.bin $(obj)tpl/u-boot-tpl-pad.bin \
+			$(obj)u-boot.bin > $@
+		rm $(obj)spl/u-boot-spl-pad.bin $(obj)tpl/u-boot-tpl-pad.bin
+
 $(obj)u-boot-with-spl.imx: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 		$(MAKE) -C $(SRCTREE)/arch/arm/imx-common \
 			$(OBJTREE)/u-boot-with-spl.imx
@@ -622,6 +636,9 @@  $(obj)u-boot-nand.bin:	nand_spl $(obj)u-boot.bin
 $(obj)spl/u-boot-spl.bin:	$(SUBDIR_TOOLS) depend
 		$(MAKE) -C spl all
 
+$(obj)tpl/u-boot-tpl.bin:	$(SUBDIR_TOOLS) depend
+		$(MAKE) -C tpl all
+
 updater:
 		$(MAKE) -C tools/updater all
 
@@ -877,6 +894,8 @@  clobber:	tidy
 	@rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map}
 	@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map}
 	@rm -f $(obj)spl/u-boot-spl.lds
+	@rm -f $(obj)tpl/{u-boot-tpl,u-boot-tpl.bin,u-boot-tpl.map}
+	@rm -f $(obj)tpl/u-boot-tpl.lds
 	@rm -f $(obj)MLO MLO.byteswap
 	@rm -f $(obj)SPL
 	@rm -f $(obj)tools/xway-swap-bytes
diff --git a/README b/README
index b941a56..0c20253 100644
--- a/README
+++ b/README
@@ -2999,9 +2999,10 @@  FIT uImage format:
 		Set for the SPL on PPC mpc8xxx targets, support for
 		arch/powerpc/cpu/mpc8xxx/ddr/libddr.o in SPL binary.
 
-		CONFIG_SPL_COMMON_INIT_DDR
+		CONFIG_COMMON_INIT_DDR
 		Set for common ddr init with serial presence detect in
-		SPL binary.
+		SPL binary or TPL binary.
+
 		CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
 		CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
 		CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS,
@@ -3050,8 +3051,9 @@  FIT uImage format:
 
 		CONFIG_SPL_NET_SUPPORT
 		Support for the net/libnet.o in SPL binary.
-		It conflicts with SPL env from storage medium specified by
-		CONFIG_ENV_IS_xxx but CONFIG_ENV_IS_NOWHERE
+		It only co-exist with CONFIG_ENV_IS_NOWHERE in the SPL. it
+		conflicts with SPL env from storage medium specified by
+		CONFIG_ENV_IS_xxx.
 
 		CONFIG_SPL_ENV_IMPORT
 		Support for importing the environment in SPL.
@@ -3074,6 +3076,13 @@  FIT uImage format:
 		option to re-enable it. This will affect the output of the
 		bootm command when booting a FIT image.
 
+- TPL framework
+		CONFIG_TPL
+		Enable building of TPL globally.
+
+		CONFIG_TPL_TEXT_BASE
+		TEXT_BASE for linking the TPL binary.
+
 Modem Support:
 --------------
 
@@ -4111,11 +4120,51 @@  Low Level (hardware related) configuration options:
 		that is executed before the actual U-Boot. E.g. when
 		compiling a NAND SPL.
 
+- CONFIG_TPL_BUILD
+		Modifies the behaviour of start.S when compiling a loader
+		that is executed after the SPL and before the actual U-Boot.
+		It is loaded by the SPL.
+
 - CONFIG_SYS_MPC85XX_NO_RESETVEC
 		Only for 85xx systems. If this variable is specified, the section
 		.resetvec is not kept and the section .bootpg is placed in the
 		previous 4k of the .text section.
 
+- CONFIG_SYS_MPC8XXX_INIT_DDR_SUPPORT
+		Set for the SPL on PPC mpc8xxx targets, support for
+		arch/powerpc/cpu/mpc8xxx/ddr/libddr.o.
+
+- CONFIG_SYS_ENV_SUPPORT
+		Support for the environment operating.
+
+- CONFIG_SYS_SERIAL_SUPPORT
+		Support for drivers/serial/libserial.o.
+
+- CONFIG_SYS_LIBGENERIC_SUPPORT
+		Support for lib/libgeneric.o.
+
+- CONFIG_SYS_LIBCOMMON_SUPPORT
+		Support for common/libcommon.o.
+
+- CONFIG_SYS_I2C_SUPPORT
+		Support for drivers/i2c/libi2c.o.
+
+- CONFIG_SYS_NAND_SUPPORT
+		Support for drivers/mtd/nand/libnand.o.
+
+- CONFIG_SYS_MAX_SIZE
+		Maximum size of the image (text, data, rodata, and
+		linker lists sections), BSS excluded.
+		When defined, the linker checks that the actual size does
+		not exceed it.
+
+- CONFIG_SYS_PAD_TO
+		Image offset to which the image should be padded before appending
+		the image payload. By default, this is defined as
+		CONFIG_SYS_MAX_SIZE, or 0 if CONFIG_SYS_MAX_SIZE is undefined.
+		CONFIG_SYS_PAD_TO must be either 0, meaning to append the image
+		payload without any padding, or >= CONFIG_SYS_MAX_SIZE.
+
 - CONFIG_ARCH_MAP_SYSMEM
 		Generally U-Boot (and in particular the md command) uses
 		effective address. It is therefore not necessary to regard
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk
index e32d2bf..aebb0aa 100644
--- a/arch/powerpc/config.mk
+++ b/arch/powerpc/config.mk
@@ -48,5 +48,7 @@  endif
 
 # Only test once
 ifneq ($(CONFIG_SPL_BUILD),y)
+ifneq ($(CONFIG_TPL_BUILD),y)
 ALL-y += checkgcc4
 endif
+endif
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
index 56128a7..e46100a 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c
@@ -218,13 +218,13 @@  compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
 		if (dimm_params[i].n_ranks) {
 			if (dimm_params[i].registered_dimm) {
 				temp1 = 1;
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 				printf("Detected RDIMM %s\n",
 					dimm_params[i].mpart);
 #endif
 			} else {
 				temp2 = 1;
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 				printf("Detected UDIMM %s\n",
 					dimm_params[i].mpart);
 #endif
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 59c723b..c61eb06 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -59,10 +59,12 @@  SOBJS-y	+= reloc.o
 
 COBJS-$(CONFIG_BAT_RW) += bat_rw.o
 ifndef CONFIG_SPL_BUILD
+ifndef CONFIG_TPL_BUILD
 ifndef CONFIG_SYS_GENERIC_BOARD
 COBJS-y	+= board.o
 endif
 endif
+endif
 COBJS-y	+= bootm.o
 COBJS-y	+= cache.o
 COBJS-y	+= extable.o
diff --git a/common/Makefile b/common/Makefile
index 3581603..b797e0c 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -27,6 +27,7 @@  LIB	= $(obj)libcommon.o
 
 # core
 ifndef CONFIG_SPL_BUILD
+ifndef CONFIG_TPL_BUILD
 COBJS-y += main.o
 COBJS-y += command.o
 COBJS-y += exports.o
@@ -204,6 +205,7 @@  COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
 COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 endif
+endif
 
 ifdef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
@@ -223,6 +225,13 @@  else
 COBJS-y += env_nowhere.o
 endif
 endif
+
+ifdef CONFIG_TPL_BUILD
+COBJS-$(CONFIG_SYS_ENV_SUPPORT) += env_attr.o
+COBJS-$(CONFIG_SYS_ENV_SUPPORT) += env_flags.o
+COBJS-$(CONFIG_SYS_ENV_SUPPORT) += env_callback.o
+endif
+
 # core command
 COBJS-y += cmd_nvedit.o
 #environment
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 2478c95..d91a2ef 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -87,7 +87,7 @@  int get_env_id(void)
 	return env_id;
 }
 
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 /*
  * Command interface: print one or all environment variables
  *
@@ -356,7 +356,7 @@  ulong getenv_hex(const char *varname, ulong default_val)
 	return value;
 }
 
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	if (argc < 2)
@@ -700,7 +700,7 @@  ulong getenv_ulong(const char *name, int base, ulong default_val)
 	return str ? simple_strtoul(str, NULL, base) : default_val;
 }
 
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
 static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
 		       char * const argv[])
@@ -741,7 +741,7 @@  int envmatch(uchar *s1, int i2)
 	return -1;
 }
 
-#ifndef CONFIG_SPL_BUILD
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
 static int do_env_default(cmd_tbl_t *cmdtp, int __flag,
 			  int argc, char * const argv[])
 {
diff --git a/config.mk b/config.mk
index ddf350e..f2938f1 100644
--- a/config.mk
+++ b/config.mk
@@ -41,8 +41,12 @@  ifneq ($(OBJTREE),$(SRCTREE))
 ifeq ($(CONFIG_SPL_BUILD),y)
 obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
 else
+ifeq ($(CONFIG_TPL_BUILD),y)
+obj := $(if $(dir),$(TPLTREE)/$(dir)/,$(TPLTREE)/)
+else
 obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
 endif
+endif
 src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)
 
 $(shell mkdir -p $(obj))
@@ -53,8 +57,14 @@  obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
 
 $(shell mkdir -p $(obj))
 else
+ifeq ($(CONFIG_TPL_BUILD),y)
+obj := $(if $(dir),$(TPLTREE)/$(dir)/,$(TPLTREE)/)
+
+$(shell mkdir -p $(obj))
+else
 obj :=
 endif
+endif
 src :=
 endif
 
@@ -210,6 +220,11 @@  CPPFLAGS += -ffunction-sections -fdata-sections
 LDFLAGS_FINAL += --gc-sections
 endif
 
+ifeq ($(CONFIG_TPL_BUILD),y)
+CPPFLAGS += -ffunction-sections -fdata-sections
+LDFLAGS_FINAL += --gc-sections
+endif
+
 ifneq ($(CONFIG_SYS_TEXT_BASE),)
 CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
 endif
@@ -218,10 +233,18 @@  ifneq ($(CONFIG_SPL_TEXT_BASE),)
 CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)
 endif
 
+ifneq ($(CONFIG_TPL_TEXT_BASE),)
+CPPFLAGS += -DCONFIG_TPL_TEXT_BASE=$(CONFIG_TPL_TEXT_BASE)
+endif
+
 ifneq ($(CONFIG_SPL_PAD_TO),)
 CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
 endif
 
+ifneq ($(CONFIG_SYS_PAD_TO),)
+CPPFLAGS += -DCONFIG_SYS_PAD_TO=$(CONFIG_SYS_PAD_TO)
+endif
+
 ifneq ($(CONFIG_UBOOT_PAD_TO),)
 CPPFLAGS += -DCONFIG_UBOOT_PAD_TO=$(CONFIG_UBOOT_PAD_TO)
 endif
@@ -230,6 +253,10 @@  ifeq ($(CONFIG_SPL_BUILD),y)
 CPPFLAGS += -DCONFIG_SPL_BUILD
 endif
 
+ifeq ($(CONFIG_TPL_BUILD),y)
+CPPFLAGS += -DCONFIG_TPL_BUILD
+endif
+
 # Does this architecture support generic board init?
 ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)
 ifneq ($(CONFIG_SYS_GENERIC_BOARD),)
@@ -294,6 +321,11 @@  ifneq ($(CONFIG_SPL_TEXT_BASE),)
 LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
 endif
 
+LDFLAGS_u-boot-tpl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
+ifneq ($(CONFIG_TPL_TEXT_BASE),)
+LDFLAGS_u-boot-tpl += -Ttext $(CONFIG_TPL_TEXT_BASE)
+endif
+
 # Linus' kernel sanity checking tool
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
                   -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__ $(CF)
diff --git a/doc/README.TPL b/doc/README.TPL
new file mode 100644
index 0000000..dc135af
--- /dev/null
+++ b/doc/README.TPL
@@ -0,0 +1,69 @@ 
+Generic TPL framework
+=====================
+
+Overview
+--------
+
+Due to the SPL on some boards(powerpc mpc85xx) has a size limit and cannot
+be compatible with all the external device(e.g. DDR). So add a tertiary
+program loader (TPL) to enable a loader stub that runs in the L2 SRAM,
+after being loaded by the code from the SPL. It loads the final uboot image
+into DDR, then jump to it to begin execution. Now, only the powerpc mpc85xx
+has this requirement and will implemente it.
+
+Keep consistent with SPL, with this framework almost all source files for a
+board can be reused. No code duplication or symlinking is necessary anymore.
+
+How it works
+------------
+
+There is a new directory TOPDIR/tpl which contains only a Makefile.
+The object files are built separately for TPL and placed in this directory.
+The final binaries which are generated are u-boot-tpl, u-boot-tpl.bin and
+u-boot-tpl.map.
+
+During the TPL build a variable named CONFIG_TPL_BUILD is exported
+in the make environment and also appended to CPPFLAGS with -DCONFIG_TPL_BUILD.
+Source files can therefore be compiled for TPL with different settings.
+
+For example:
+
+ifeq ($(CONFIG_TPL_BUILD),y)
+COBJS-y += board_tpl.o
+else
+COBJS-y += board.o
+endif
+
+COBJS-$(CONFIG_TPL_BUILD) += foo.o
+
+#ifdef CONFIG_TPL_BUILD
+	foo();
+#endif
+
+
+The building of TPL images can be with:
+
+#define CONFIG_TPL
+
+Because TPL images normally have a different text base, one has to be
+configured by defining CONFIG_TPL_TEXT_BASE. The linker script has to be
+defined with CONFIG_TPL_LDSCRIPT.
+
+To support generic U-Boot libraries and drivers in the TPL binary one can
+optionally define CONFIG_SYS_XXX_SUPPORT. Currently following options
+are supported:
+
+CONFIG_SYS_LIBCOMMON_SUPPORT (common/libcommon.o)
+CONFIG_SYS_LIBDISK_SUPPORT (disk/libdisk.o)
+CONFIG_SYS_I2C_SUPPORT (drivers/i2c/libi2c.o)
+CONFIG_SYS_GPIO_SUPPORT (drivers/gpio/libgpio.o)
+CONFIG_SYS_MMC_SUPPORT (drivers/mmc/libmmc.o)
+CONFIG_SYS_SERIAL_SUPPORT (drivers/serial/libserial.o)
+CONFIG_SYS_SPI_FLASH_SUPPORT (drivers/mtd/spi/libspi_flash.o)
+CONFIG_SYS_SPI_SUPPORT (drivers/spi/libspi.o)
+CONFIG_SYS_FAT_SUPPORT (fs/fat/libfat.o)
+CONFIG_SYS_LIBGENERIC_SUPPORT (lib/libgeneric.o)
+CONFIG_SYS_POWER_SUPPORT (drivers/power/libpower.o)
+CONFIG_SYS_NAND_SUPPORT (drivers/mtd/nand/libnand.o)
+CONFIG_SYS_DMA_SUPPORT (drivers/dma/libdma.o)
+CONFIG_SYS_POST_MEM_SUPPORT (post/drivers/memory.o)
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index bb81e84..5113642 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -42,6 +42,7 @@  COBJS-$(CONFIG_SPL_NAND_BASE) += nand_base.o
 
 else # not spl
 
+ifndef CONFIG_TPL_BUILD
 NORMAL_DRIVERS=y
 
 COBJS-y += nand.o
@@ -51,6 +52,7 @@  COBJS-y += nand_util.o
 COBJS-y += nand_ecc.o
 COBJS-y += nand_base.o
 
+endif
 endif # not spl
 
 ifdef NORMAL_DRIVERS
@@ -82,9 +84,14 @@  COBJS-$(CONFIG_NAND_DOCG4) += docg4.o
 
 else  # minimal SPL drivers
 
+ifdef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
 COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
 COBJS-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
+endif
+ifdef CONFIG_TPL_BUILD
+COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
+endif
 
 endif # drivers
 endif # nand
diff --git a/drivers/mtd/nand/fsl_elbc_spl.c b/drivers/mtd/nand/fsl_elbc_spl.c
index 50ff4fe..ab208fd 100644
--- a/drivers/mtd/nand/fsl_elbc_spl.c
+++ b/drivers/mtd/nand/fsl_elbc_spl.c
@@ -47,7 +47,10 @@  static void nand_wait(void)
 	}
 }
 
-static int nand_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
+#ifdef CONFIG_SPL_BUILD
+static
+#endif
+int nand_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
 {
 	fsl_lbc_t *regs = LBC_BASE_ADDR;
 	uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index daa8003..81aca81 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -371,7 +371,7 @@  static struct serial_device *get_current(void)
 
 	/* We must have a console device */
 	if (!dev) {
-#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
 		puts("Cannot find console\n");
 		hang();
 #else
diff --git a/include/bootstage.h b/include/bootstage.h
index ef07a87..1e8c492 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -220,7 +220,8 @@  enum bootstage_id {
  */
 ulong timer_get_boot_us(void);
 
-#if !defined(CONFIG_SPL_BUILD) && !defined(USE_HOSTCC)
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD) && \
+	!defined(USE_HOSTCC)
 /*
  * Board code can implement show_boot_progress() if needed.
  *
diff --git a/tpl/Makefile b/tpl/Makefile
new file mode 100644
index 0000000..bb947e5
--- /dev/null
+++ b/tpl/Makefile
@@ -0,0 +1,161 @@ 
+#
+# Copyright 2013 Freescale Semiconductor, Inc.
+#
+# 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.
+#
+
+CONFIG_TPL_BUILD := y
+export CONFIG_TPL_BUILD
+
+include $(TOPDIR)/config.mk
+
+# We want the final binaries in this directory
+obj := $(OBJTREE)/tpl/
+
+HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(SRCTREE)/board/$(VENDOR)/common/Makefile),y,n)
+
+ifdef	CONFIG_TPL_START_S_PATH
+START_PATH := $(subst ",,$(CONFIG_TPL_START_S_PATH))
+else
+START_PATH := $(CPUDIR)
+endif
+
+START := $(START_PATH)/start.o
+ifeq ($(CPU),x86)
+START += $(START_PATH)/start16.o
+START += $(START_PATH)/resetvec.o
+endif
+ifeq ($(CPU),ppc4xx)
+START += $(START_PATH)/resetvec.o
+endif
+ifeq ($(CPU),mpc85xx)
+START += $(START_PATH)/resetvec.o
+endif
+
+LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o
+
+LIBS-y += $(CPUDIR)/lib$(CPU).o
+ifeq ($(CPU),mpc83xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+endif
+ifeq ($(CPU),mpc85xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+ifdef CONFIG_SYS_MPC8XXX_INIT_DDR_SUPPORT
+LIBS-y += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
+endif
+endif
+ifeq ($(CPU),mpc86xx)
+LIBS-y += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
+endif
+
+ifdef SOC
+LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
+endif
+LIBS-y += board/$(BOARDDIR)/lib$(BOARD).o
+LIBS-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/lib$(VENDOR).o
+
+LIBS-$(CONFIG_SYS_LIBCOMMON_SUPPORT) += common/libcommon.o
+LIBS-$(CONFIG_SYS_LIBDISK_SUPPORT) += disk/libdisk.o
+LIBS-$(CONFIG_SYS_I2C_SUPPORT) += drivers/i2c/libi2c.o
+LIBS-$(CONFIG_SYS_GPIO_SUPPORT) += drivers/gpio/libgpio.o
+LIBS-$(CONFIG_SYS_MMC_SUPPORT) += drivers/mmc/libmmc.o
+LIBS-$(CONFIG_SYS_SERIAL_SUPPORT) += drivers/serial/libserial.o
+LIBS-$(CONFIG_SYS_SPI_FLASH_SUPPORT) += drivers/mtd/spi/libspi_flash.o
+LIBS-$(CONFIG_SYS_SPI_SUPPORT) += drivers/spi/libspi.o
+LIBS-$(CONFIG_SYS_FAT_SUPPORT) += fs/fat/libfat.o
+LIBS-$(CONFIG_SYS_LIBGENERIC_SUPPORT) += lib/libgeneric.o
+LIBS-$(CONFIG_SYS_POWER_SUPPORT) += drivers/power/libpower.o
+LIBS-$(CONFIG_SYS_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
+LIBS-$(CONFIG_SYS_ONENAND_SUPPORT) += drivers/mtd/onenand/libonenand.o
+LIBS-$(CONFIG_SYS_DMA_SUPPORT) += drivers/dma/libdma.o
+LIBS-$(CONFIG_SYS_POST_MEM_SUPPORT) += post/drivers/memory.o
+LIBS-$(CONFIG_SYS_NET_SUPPORT) += net/libnet.o
+LIBS-$(CONFIG_SYS_ETH_SUPPORT) += drivers/net/libnet.o
+LIBS-$(CONFIG_SYS_ETH_SUPPORT) += drivers/net/phy/libphy.o
+LIBS-$(CONFIG_SYS_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
+LIBS-$(CONFIG_SYS_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
+
+# Add GCC lib
+ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")
+PLATFORM_LIBGCC = $(TPLTREE)/arch/$(ARCH)/lib/libgcc.o
+PLATFORM_LIBS := $(filter-out %/libgcc.o, $(filter-out -lgcc, $(PLATFORM_LIBS))) $(PLATFORM_LIBGCC)
+endif
+
+START := $(addprefix $(TPLTREE)/,$(START))
+LIBS := $(addprefix $(TPLTREE)/,$(sort $(LIBS-y)))
+
+__START := $(subst $(obj),,$(START))
+__LIBS := $(subst $(obj),,$(LIBS))
+
+# Linker Script
+ifdef CONFIG_SPL_LDSCRIPT
+# need to strip off double quotes
+LDSCRIPT := $(addprefix $(SRCTREE)/,$(subst ",,$(CONFIG_SPL_LDSCRIPT)))
+endif
+
+ifeq ($(wildcard $(LDSCRIPT)),)
+	LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds
+endif
+ifeq ($(wildcard $(LDSCRIPT)),)
+	LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-spl.lds
+endif
+ifeq ($(wildcard $(LDSCRIPT)),)
+	LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot-spl.lds
+endif
+ifeq ($(wildcard $(LDSCRIPT)),)
+$(error could not find linker script)
+endif
+
+# Special flags for CPP when processing the linker script.
+# Pass the version down so we can handle backwards compatibility
+# on the fly.
+LDPPFLAGS += \
+	-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
+	-include $(OBJTREE)/include/config.h \
+	-DCPUDIR=$(CPUDIR) \
+	$(shell $(LD) --version | \
+	  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
+
+$(OBJTREE)/MLO:	$(obj)u-boot-tpl.bin
+	$(OBJTREE)/tools/mkimage -T omapimage \
+		-a $(CONFIG_TPL_TEXT_BASE) -d $< $@
+
+$(OBJTREE)/MLO.byteswap: $(obj)u-boot-tpl.bin
+	$(OBJTREE)/tools/mkimage -T omapimage -n byteswap \
+		-a $(CONFIG_TPL_TEXT_BASE) -d $< $@
+
+$(OBJTREE)/TPL : $(obj)u-boot-tpl.bin depend
+		$(MAKE) -C $(SRCTREE)/arch/arm/imx-common $@
+
+ALL-y	+= $(obj)u-boot-tpl.bin
+
+all:	$(ALL-y)
+
+$(obj)u-boot-tpl.bin:	$(obj)u-boot-tpl
+	$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
+
+GEN_UBOOT = \
+	cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $(__START) \
+		--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
+		-Map u-boot-tpl.map -o u-boot-tpl
+
+$(obj)u-boot-tpl:	depend $(START) $(LIBS) $(obj)u-boot-spl.lds
+	$(GEN_UBOOT)
+
+$(START):	depend
+	$(MAKE) -C $(SRCTREE)/$(START_PATH) $@
+
+$(LIBS):	depend
+	$(MAKE) -C $(SRCTREE)$(dir $(subst $(TPLTREE),,$@))
+
+$(obj)u-boot-spl.lds: $(LDSCRIPT) depend
+	$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -I$(obj). -ansi -D__ASSEMBLY__ -P - < $< > $@
+
+depend:	$(obj).depend
+.PHONY: depend
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk