From patchwork Tue Nov 30 10:30:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: luigi.mantellini@idf-hit.com X-Patchwork-Id: 73591 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 749A31007D1 for ; Tue, 30 Nov 2010 21:31:40 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EDDDB283D4; Tue, 30 Nov 2010 11:31:32 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hoaz284sZtZx; Tue, 30 Nov 2010 11:31:32 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3E798283CC; Tue, 30 Nov 2010 11:31:22 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0E4A6283CC for ; Tue, 30 Nov 2010 11:31:15 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XCpb33CJVGCr for ; Tue, 30 Nov 2010 11:31:10 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx101.fabbricadigitale.it (mx2.fabbricadigitale.it [217.169.111.37]) by theia.denx.de (Postfix) with ESMTPS id C0D8D283BE for ; Tue, 30 Nov 2010 11:31:09 +0100 (CET) Received: from localhost (mxnew.fabbricadigitale.it [127.0.0.1]) by mx101.fabbricadigitale.it (MM4Csmtpd) with ESMTP id ED12EE0003B9 for ; Tue, 30 Nov 2010 11:31:08 +0100 (CET) X-Virus-Scanned: amavisd-new at fabbricadigitale.it Received: from mx101.fabbricadigitale.it ([127.0.0.1]) by localhost (mx101.fabbricadigitale.it [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id f0DIGsCYmCtI for ; Tue, 30 Nov 2010 11:31:08 +0100 (CET) Received: from PMF-EX01P-SHARZ.fdmsha.local (unknown [172.16.26.20]) by mx101.fabbricadigitale.it (MM4Csmtpd) with ESMTPS id B255EE0003B6 for ; Tue, 30 Nov 2010 11:31:08 +0100 (CET) Received: from abel.dialface.net (85.46.108.250) by PMF-EX01P-SHARZ.fdmsha.local (172.16.26.20) with Microsoft SMTP Server id 8.1.340.0; Tue, 30 Nov 2010 11:31:05 +0100 From: To: "u-boot@lists.denx.de" , Date: Tue, 30 Nov 2010 11:30:47 +0100 Message-ID: <1291113049-4176-2-git-send-email-luigi.mantellini@idf-hit.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1291113049-4176-1-git-send-email-luigi.mantellini@idf-hit.com> References: <1291113049-4176-1-git-send-email-luigi.mantellini@idf-hit.com> MIME-Version: 1.0 Cc: Luigi 'Comio' Mantellini Subject: [U-Boot] [RFC 1/2] Add support for bootstrap stage that allows to have a compressed U-Boot image. The final image will named "u-boot-bootstrap". X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Luigi 'Comio' Mantellini The following symbols are allowed: CONFIG_BOOTSTRAP Enable the bootstrap stage. A minimal code is added to uncompress or copy the payload (a full U-Boot image). CONFIG_BOOTSTRAP_TEXT_BASE TEXT_BASE of the bootstrap code. CONFIG_BOOTSTRAP_SKIP_LOWLEVEL_INIT Skip the lowlevel initialization. CONFIG_BOOTSTRAP_BAUDRATE Initial and hardcoded serial boudrate CONFIG_BOOTSTRAP_BZIP2 Enable BZIP2 compression of the U-Boot image. CONFIG_BOOTSTRAP_GZIP Enable GZIP compression of the U-Boot image. CONFIG_BOOTSTRAP_LZMA Enable LZMA compression of the U-Boot image. CONFIG_BOOTSTRAP_LZO Enable LZO compression of the U-Boot image. The board should define the following functions: phys_size_t bootstrap_initdram(int board_type); int bootstrap_checkboard(void); int bootstrap_misc_init_r(void); void lowlevel_init(void); Signed-off-by: Luigi 'Comio' Mantellini --- .gitignore | 24 ++- Makefile | 172 +++++++++++++++- arch/mips/config.mk | 2 +- arch/mips/cpu/Makefile | 28 ++- arch/mips/cpu/cpu.c | 12 - arch/mips/cpu/reset.c | 39 ++++ arch/mips/cpu/reset_bootstrap.c | 39 ++++ arch/mips/cpu/start_bootstrap.S | 452 +++++++++++++++++++++++++++++++++++++++ arch/mips/lib/Makefile | 15 ++- arch/mips/lib/board_bootstrap.c | 261 ++++++++++++++++++++++ common/Makefile | 15 ++- common/console_bootstrap.c | 85 ++++++++ config.mk | 19 ++- include/common.h | 21 ++ lib/Makefile | 28 +++- lib/bootstrap.c | 89 ++++++++ lib/lzma/Makefile | 4 +- lib/lzo/Makefile | 4 +- 18 files changed, 1281 insertions(+), 28 deletions(-) create mode 100644 arch/mips/cpu/reset.c create mode 100644 arch/mips/cpu/reset_bootstrap.c create mode 100644 arch/mips/cpu/start_bootstrap.S create mode 100644 arch/mips/lib/board_bootstrap.c create mode 100644 common/console_bootstrap.c create mode 100644 lib/bootstrap.c diff --git a/.gitignore b/.gitignore index e71f6ac..9cfba4c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ /u-boot.hex /u-boot.map /u-boot.bin +/u-boot.bin.bz2 +/u-boot.bin.gz +/u-boot.bin.lzma +/u-boot.bin.lzo +/u-boot.dis /u-boot.srec /u-boot.ldr /u-boot.ldr.hex @@ -30,6 +35,20 @@ /u-boot.lds /u-boot-onenand.bin /u-boot-flexonenand.bin +/u-boot-bootstrap +/u-boot-bootstrap.hex +/u-boot-bootstrap.map +/u-boot-bootstrap.bin +/u-boot-bootstrap.bin.bz2 +/u-boot-bootstrap.bin.gz +/u-boot-bootstrap.bin.lzma +/u-boot-bootstrap.bin.lzo +/u-boot-bootstrap.dis +/u-boot-bootstrap.srec +/u-boot-bootstrap.ldr +/u-boot-bootstrap.ldr.hex +/u-boot-bootstrap.ldr.srec +/u-boot-bootstrap.lds # # Generated files @@ -39,7 +58,7 @@ /LOG /errlog /reloc_off - +/.payload.s /include/generated/ /lib/asm-offsets.s @@ -66,3 +85,6 @@ cscope.* /onenand_ipl/onenand-ipl* /onenand_ipl/board/*/onenand* /onenand_ipl/board/*/*.S +examples/standalone/ + +setvars diff --git a/Makefile b/Makefile index 87a383d..fa159c7 100644 --- a/Makefile +++ b/Makefile @@ -180,6 +180,13 @@ endif OBJS := $(addprefix $(obj),$(OBJS)) +ifeq ($(CONFIG_BOOTSTRAP),y) +BOOTSTRAP_OBJS = $(CPUDIR)/start_bootstrap.o + +BOOTSTRAP_OBJS := $(addprefix $(obj),$(BOOTSTRAP_OBJS)) +endif + + LIBS = lib/libgeneric.o LIBS += lib/lzma/liblzma.o LIBS += lib/lzo/liblzo.o @@ -263,12 +270,29 @@ ifeq ($(SOC),s5pc2xx) LIBS += $(CPUDIR)/s5p-common/libs5p-common.o endif -LIBS := $(addprefix $(obj),$(sort $(LIBS))) +LIBS := $(addprefix $(obj),$(LIBS)) .PHONY : $(LIBS) $(TIMESTAMP_FILE) $(VERSION_FILE) LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) +ifeq ($(CONFIG_BOOTSTRAP),y) +BOOTSTRAP_LIBS = lib/libgeneric_bootstrap.o +BOOTSTRAP_LIBS += arch/$(ARCH)/cpu/lib$(ARCH)_bootstrap.o +BOOTSTRAP_LIBS += arch/$(ARCH)/lib/lib$(ARCH)_bootstrap.o +BOOTSTRAP_LIBS += common/libcommon_bootstrap.o +BOOTSTRAP_LIBS += drivers/serial/libserial.o + +BOOTSTRAP_LIBS-$(CONFIG_BOOTSTRAP_LZMA) += lib/lzma/liblzma.o +BOOTSTRAP_LIBS-$(CONFIG_BOOTSTRAP_LZO) += lib/lzo/liblzo.o +BOOTSTRAP_LIBS += $(BOOTSTRAP_LIBS-y) + +.PHONY : $(BOOTSTRAP_LIBS) + +BOOTSTRAP_LIBBOARD = board/$(BOARDDIR)/lib$(BOARD)_bootstrap.o +BOOTSTRAP_LIBBOARD := $(addprefix $(obj),$(BOOTSTRAP_LIBBOARD)) +endif + # Add GCC lib ifdef USE_PRIVATE_LIBGCC ifeq ("$(USE_PRIVATE_LIBGCC)", "yes") @@ -282,6 +306,9 @@ endif PLATFORM_LIBS += $(PLATFORM_LIBGCC) export PLATFORM_LIBS +BOOTSTRAP_PLATFORM_LIBS += $(PLATFORM_LIBGCC) +export BOOTSTRAP_PLATFORM_LIBS + # Special flags for CPP when processing the linker script. # Pass the version down so we can handle backwards compatibility # on the fly. @@ -304,6 +331,9 @@ endif __OBJS := $(subst $(obj),,$(OBJS)) __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD)) +__BOOTSTRAP_OBJS := $(subst $(obj),,$(BOOTSTRAP_OBJS)) +__BOOTSTRAP_LIBS := $(subst $(obj),,$(BOOTSTRAP_LIBS)) $(subst $(obj),,$(BOOTSTRAP_LIBBOARD)) + ######################################################################### ######################################################################### @@ -325,6 +355,10 @@ endif # Always append ALL so that arch config.mk's can add custom ones ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) +ifeq ($(CONFIG_BOOTSTRAP),y) +ALL += $(obj)u-boot-bootstrap.srec $(obj)u-boot-bootstrap.bin +endif + all: $(ALL) $(obj)u-boot.hex: $(obj)u-boot @@ -337,6 +371,18 @@ $(obj)u-boot.bin: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ $(BOARD_SIZE_CHECK) +$(obj)u-boot.bin.gz: $(obj)u-boot.bin + gzip -c $< > $@ + +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin + lzma -e -z -c $< > $@ + +$(obj)u-boot.bin.lzo: $(obj)u-boot.bin + lzop -9 -c $< > $@ + +$(obj)u-boot.bin.bz2: $(obj)u-boot.bin + bzip2 --best -z -c $< > $@ + $(obj)u-boot.ldr: $(obj)u-boot $(CREATE_LDR_ENV) $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS) @@ -367,12 +413,12 @@ $(obj)u-boot.sha1: $(obj)u-boot.bin $(obj)tools/ubsha1 $(obj)u-boot.bin $(obj)u-boot.dis: $(obj)u-boot - $(OBJDUMP) -d $< > $@ + $(OBJDUMP) -S -d $< > $@ GEN_UBOOT = \ UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \ sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ - cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ + cd $(LNDIR) && $(LD) --gc-sections $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot.map -o u-boot $(obj)u-boot: depend \ @@ -395,6 +441,116 @@ $(LIBS): depend $(SUBDIRS) $(LIBBOARD): depend $(LIBS) $(MAKE) -C $(dir $(subst $(obj),,$@)) +# Bootstrap targets + +ifeq ($(CONFIG_BOOTSTRAP),y) +$(obj)u-boot-bootstrap.hex: $(obj)u-boot-bootstrap + $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ + +$(obj)u-boot-bootstrap.srec: $(obj)u-boot-bootstrap + $(OBJCOPY) -O srec $< $@ + +$(obj)u-boot-bootstrap.bin: $(obj)u-boot-bootstrap + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + $(BOARD_SIZE_CHECK) + +$(obj)u-boot-bootstrap.bin.gz: $(obj)u-boot-bootstrap.bin + gzip -c $< > $@ + +$(obj)u-boot-bootstrap.bin.lzma: $(obj)u-boot-bootstrap.bin + lzma -e -z -c $< > $@ + +$(obj)u-boot.bin-bootstrap.lzo: $(obj)u-boot-bootstrap.bin + lzop -9 -c $< > $@ + +$(obj)u-boot.bin-bootstrap.bz2: $(obj)u-boot-bootstrap.bin + bzip2 --best -z -c $< > $@ + +$(obj)u-boot-bootstrap.ldr: $(obj)u-boot-bootstrap + $(CREATE_LDR_ENV) + $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS) + $(BOARD_SIZE_CHECK) + +$(obj)u-boot-bootstrap.ldr.hex: $(obj)u-boot-bootstrap.ldr + $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary + +$(obj)u-boot-bootstrap.ldr.srec: $(obj)u-boot-bootstrap.ldr + $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary + +$(obj)u-boot-bootstrap.img: $(obj)u-boot-bootstrap.bin + $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \ + -a $(CONFIG_BOOTSTRAP_BASE) -e 0 \ + -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \ + sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \ + -d $< $@ + +$(obj)u-boot-bootstrap.imx: $(obj)u-boot-bootstrap.bin + $(obj)tools/mkimage -n $(IMX_CONFIG) -T imximage \ + -e $(CONFIG_BOOTSTRAP_BASE) -d $< $@ + +$(obj)u-boot-bootstrap.kwb: $(obj)u-boot-bootstrap.bin + $(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@ + +$(obj)u-boot-bootstrap.sha1: $(obj)u-boot-bootstrap.bin + $(obj)tools/ubsha1 $(obj)u-boot-bootstrap.bin + +$(obj)u-boot-bootstrap.dis: $(obj)u-boot-bootstrap + $(OBJDUMP) -S -d $< > $@ + +PAYLOAD_FILE_BASE=$(obj)u-boot.bin +ifeq ($(CONFIG_BOOTSTRAP_GZIP),y) +PAYLOAD_FILE_EXT:=.gz +endif +ifeq ($(CONFIG_BOOTSTRAP_LZMA),y) +PAYLOAD_FILE_EXT:=.lzma +endif +ifeq ($(CONFIG_BOOTSTRAP_LZO),y) +PAYLOAD_FILE_EXT:=.lzo +endif +ifeq ($(CONFIG_BOOTSTRAP_BZIP2),y) +PAYLOAD_FILE_EXT:=.bz2 +endif + +PAYLOAD_FILE := $(PAYLOAD_FILE_BASE)$(PAYLOAD_FILE_EXT) + +$(obj).payload.s: $(PAYLOAD_FILE) + echo ".globl payload_start" > $@ + echo ".globl payload_end" >> $@ + echo ".globl payload_size" >> $@ + echo ".globl payload_uncsize" >> $@ + echo .section .payload,\"a\",@progbits >> $@ + echo "payload_size:" >> $@ + echo -n ".word " >> $@ + wc -c $(PAYLOAD_FILE) | cut -f1 -d' ' >> $@ + echo "payload_uncsize:" >> $@ + echo -n ".word " >> $@ + wc -c $(obj)u-boot.bin | cut -f1 -d' ' >> $@ + echo "payload_start:" >> $@ + echo .incbin \"$(PAYLOAD_FILE)\" >> $@ + echo "payload_end:" >> $@ + + +GEN_UBOOT_BOOTSTRAP = \ + UNDEF_SYM=`$(OBJDUMP) -x $(BOOTSTRAP_LIBBOARD) $(BOOTSTRAP_LIBS) | \ + sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ + cd $(LNDIR) && $(LD) --gc-sections $(BOOTSTRAP_LDFLAGS) $$UNDEF_SYM $(obj).payload.o $(__BOOTSTRAP_OBJS) \ + --start-group $(__BOOTSTRAP_LIBS) --end-group $(BOOTSTRAP_PLATFORM_LIBS) \ + -Map u-boot-bootstrap.map -o u-boot-bootstrap +$(obj)u-boot-bootstrap: depend $(SUBDIRS) $(BOOTSTRAP_OBJS) $(BOOTSTRAP_LIBBOARD) $(BOOTSTRAP_LIBS) $(BOOTSTRAP_LDSCRIPT) $(obj)u-boot-bootstrap.lds $(obj).payload.o + $(GEN_UBOOT_BOOTSTRAP) +ifeq ($(CONFIG_KALLSYMS),y) + smap=`$(call SYSTEM_MAP,u-boot-bootstrap) | \ + awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \ + $(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \ + -c common/system_map.c -o $(obj)common/system_map.o + $(GEN_UBOOT_BOOTSTRAP) $(obj)common/system_map.o +endif + +$(BOOTSTRAP_LIBBOARD): depend $(BOOTSTRAP_LIBS) + $(MAKE) -C $(dir $(subst $(obj),,$@)) $(notdir $@) +endif + $(SUBDIRS): depend $(MAKE) -C $@ all @@ -404,6 +560,9 @@ $(LDSCRIPT): depend $(obj)u-boot.lds: $(LDSCRIPT) $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ +$(obj)u-boot-bootstrap.lds: $(BOOTSTRAP_LDSCRIPT) + $(CPP) $(CPPFLAGS) $(BOOTSTRAP_LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ + $(NAND_SPL): $(TIMESTAMP_FILE) $(VERSION_FILE) depend $(MAKE) -C nand_spl/board/$(BOARDDIR) all @@ -1221,6 +1380,7 @@ clean: $(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom \ $(obj)board/armltd/{integratorap,integratorcp}/u-boot.lds \ $(obj)u-boot.lds \ + $(obj)u-boot-bootstrap.lds \ $(obj)arch/blackfin/cpu/bootrom-asm-offsets.[chs] @rm -f $(obj)include/bmp_logo.h @rm -f $(obj)lib/asm-offsets.s @@ -1244,6 +1404,12 @@ clobber: clean @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) @rm -f $(obj)u-boot.kwb @rm -f $(obj)u-boot.imx + @rm -f $(obj)u-boot.bin{.gz,.lzma,.lzo,.bz2} + @rm -f $(obj)u-boot-bootstrap $(obj)u-boot-bootstrap.map $(obj)u-boot-bootstrap.hex + @rm -f $(obj)u-boot-bootstrap.kwb + @rm -f $(obj)u-boot-bootstrap.imx + @rm -f $(obj)u-boot-bootstrap.bin{.gz,.lzma,.lzo,.bz2} + @rm -f $(obj).payload.s @rm -f $(obj)tools/{env/crc32.c,inca-swap-bytes} @rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm diff --git a/arch/mips/config.mk b/arch/mips/config.mk index aa06761..4655169 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -47,6 +47,6 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM # to RAM. $28 is always used as gp. # -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic -g PLATFORM_CPPFLAGS += -msoft-float PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib diff --git a/arch/mips/cpu/Makefile b/arch/mips/cpu/Makefile index 06df8d1..6a9a2af 100644 --- a/arch/mips/cpu/Makefile +++ b/arch/mips/cpu/Makefile @@ -24,25 +24,45 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).o +BOOTSTRAP_LIB = $(obj)lib$(CPU)_bootstrap.o + +BOOTSTRAP_LIB-$(CONFIG_BOOTSTRAP) = $(BOOTSTRAP_LIB) START = start.o SOBJS-y = cache.o -COBJS-y = cpu.o interrupts.o +COBJS-y = cpu.o reset.o interrupts.o SOBJS-$(CONFIG_INCA_IP) += incaip_wdt.o COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o +COBJS-$(CONFIG_IFX_ASC) += ifx_asc.o COBJS-$(CONFIG_PURPLE) += asc_serial.o COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o -SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +BOOTSTRAP_START = start_bootstrap.o +BOOTSTRAP_START-$(CONFIG_BOOTSTRAP) += $(BOOTSTRAP_START) +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += cpu.o interrupts.o reset_bootstrap.o +BOOTSTRAP_SOBJS-$(CONFIG_BOOTSTRAP) += cache.o +BOOTSTRAP_COBJS-$(CONFIG_IFX_ASC) += ifx_asc.o + +BOOTSTRAP_OBJS := $(addprefix $(obj),$(BOOTSTRAP_SOBJS-y) $(BOOTSTRAP_COBJS-y)) +BOOTSTRAP_START := $(addprefix $(obj),$(BOOTSTRAP_START-y)) + +SRCS := $(sort $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) $(BOOTSTRAP_START-y:.o=.S) $(BOOTSTRAP_SOBJS-y:.o=.S) $(BOOTSTRAP_COBJS-y:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) START := $(addprefix $(obj),$(START)) -all: $(obj).depend $(START) $(LIB) +all: $(START) $(LIB) $(BOOTSTRAP_START-y) $(BOOTSTRAP_LIB-y) -$(LIB): $(OBJS) +$(START): $(obj).depend + +$(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(BOOTSTRAP_START): $(obj).depend + +$(BOOTSTRAP_LIB): $(obj).depend $(BOOTSTRAP_OBJS) + $(call cmd_link_o_target, $(BOOTSTRAP_OBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c index 3ae397c..45bf07c 100644 --- a/arch/mips/cpu/cpu.c +++ b/arch/mips/cpu/cpu.c @@ -38,18 +38,6 @@ : \ : "i" (op), "R" (*(unsigned char *)(addr))) -void __attribute__((weak)) _machine_restart(void) -{ -} - -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - _machine_restart(); - - fprintf(stderr, "*** reset failed ***\n"); - return 0; -} - void flush_cache(ulong start_addr, ulong size) { unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; diff --git a/arch/mips/cpu/reset.c b/arch/mips/cpu/reset.c new file mode 100644 index 0000000..397fb62 --- /dev/null +++ b/arch/mips/cpu/reset.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * 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 + */ + +#include +#include +#include +#include + +void __attribute__((weak)) _machine_restart(void) +{ +} + +int __attribute__((weak)) do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + _machine_restart(); + + fprintf(stderr, "*** reset failed ***\n"); + return 0; +} diff --git a/arch/mips/cpu/reset_bootstrap.c b/arch/mips/cpu/reset_bootstrap.c new file mode 100644 index 0000000..0bef625 --- /dev/null +++ b/arch/mips/cpu/reset_bootstrap.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * 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 + */ + +#include +#include +#include +#include + +void __attribute__((weak)) _machine_restart(void) +{ +} + +int __attribute__((weak)) do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + _machine_restart(); + + printf("*** reset failed ***\n"); + return 0; +} diff --git a/arch/mips/cpu/start_bootstrap.S b/arch/mips/cpu/start_bootstrap.S new file mode 100644 index 0000000..def1fde --- /dev/null +++ b/arch/mips/cpu/start_bootstrap.S @@ -0,0 +1,452 @@ +/* + * Startup Code for MIPS32 CPU-core base on start.S source + * + * Copyright (c) 2010 Industrie Dial Face S.p.A. + * Luigi 'Comio' Mantellini + * + * Copyright (c) 2003 Wolfgang Denk + * + * 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 + */ + +#include +#include +#include +#include + + /* + * For the moment disable interrupts, mark the kernel mode and + * set ST0_KX so that the CPU does not spit fire when using + * 64-bit addresses. + */ + .macro setup_c0_status set clr + .set push + mfc0 t0, CP0_STATUS + or t0, ST0_CU0 | \set | 0x1f | \clr + xor t0, 0x1f | \clr + mtc0 t0, CP0_STATUS + .set noreorder + sll zero, 3 # ehb + .set pop + .endm + + .macro setup_c0_status_reset +#ifdef CONFIG_64BIT + setup_c0_status ST0_KX 0 +#else + setup_c0_status 0 0 +#endif + .endm + +#define RVECENT(f,n) \ + b f; nop +#define XVECENT(f,bev) \ + b f ; \ + li k0,bev + + .set noreorder + + .globl _start + .text +_start: + RVECENT(reset,0) /* U-boot entry point */ + RVECENT(reset,1) /* software reboot */ +#if defined(CONFIG_INCA_IP) + .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */ + .word 0x00000000 /* phase of the flash */ +#elif defined(CONFIG_PURPLE) + .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */ + .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */ +#else + RVECENT(romReserved,2) +#endif + RVECENT(romReserved,3) + RVECENT(romReserved,4) + RVECENT(romReserved,5) + RVECENT(romReserved,6) + RVECENT(romReserved,7) + RVECENT(romReserved,8) + RVECENT(romReserved,9) + RVECENT(romReserved,10) + RVECENT(romReserved,11) + RVECENT(romReserved,12) + RVECENT(romReserved,13) + RVECENT(romReserved,14) + RVECENT(romReserved,15) + RVECENT(romReserved,16) + RVECENT(romReserved,17) + RVECENT(romReserved,18) + RVECENT(romReserved,19) + RVECENT(romReserved,20) + RVECENT(romReserved,21) + RVECENT(romReserved,22) + RVECENT(romReserved,23) + RVECENT(romReserved,24) + RVECENT(romReserved,25) + RVECENT(romReserved,26) + RVECENT(romReserved,27) + RVECENT(romReserved,28) + RVECENT(romReserved,29) + RVECENT(romReserved,30) + RVECENT(romReserved,31) + RVECENT(romReserved,32) + RVECENT(romReserved,33) + RVECENT(romReserved,34) + RVECENT(romReserved,35) + RVECENT(romReserved,36) + RVECENT(romReserved,37) + RVECENT(romReserved,38) + RVECENT(romReserved,39) + RVECENT(romReserved,40) + RVECENT(romReserved,41) + RVECENT(romReserved,42) + RVECENT(romReserved,43) + RVECENT(romReserved,44) + RVECENT(romReserved,45) + RVECENT(romReserved,46) + RVECENT(romReserved,47) + RVECENT(romReserved,48) + RVECENT(romReserved,49) + RVECENT(romReserved,50) + RVECENT(romReserved,51) + RVECENT(romReserved,52) + RVECENT(romReserved,53) + RVECENT(romReserved,54) + RVECENT(romReserved,55) + RVECENT(romReserved,56) + RVECENT(romReserved,57) + RVECENT(romReserved,58) + RVECENT(romReserved,59) + RVECENT(romReserved,60) + RVECENT(romReserved,61) + RVECENT(romReserved,62) + RVECENT(romReserved,63) + XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */ + RVECENT(romReserved,65) + RVECENT(romReserved,66) + RVECENT(romReserved,67) + RVECENT(romReserved,68) + RVECENT(romReserved,69) + RVECENT(romReserved,70) + RVECENT(romReserved,71) + RVECENT(romReserved,72) + RVECENT(romReserved,73) + RVECENT(romReserved,74) + RVECENT(romReserved,75) + RVECENT(romReserved,76) + RVECENT(romReserved,77) + RVECENT(romReserved,78) + RVECENT(romReserved,79) + XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */ + RVECENT(romReserved,81) + RVECENT(romReserved,82) + RVECENT(romReserved,83) + RVECENT(romReserved,84) + RVECENT(romReserved,85) + RVECENT(romReserved,86) + RVECENT(romReserved,87) + RVECENT(romReserved,88) + RVECENT(romReserved,89) + RVECENT(romReserved,90) + RVECENT(romReserved,91) + RVECENT(romReserved,92) + RVECENT(romReserved,93) + RVECENT(romReserved,94) + RVECENT(romReserved,95) + XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */ + RVECENT(romReserved,97) + RVECENT(romReserved,98) + RVECENT(romReserved,99) + RVECENT(romReserved,100) + RVECENT(romReserved,101) + RVECENT(romReserved,102) + RVECENT(romReserved,103) + RVECENT(romReserved,104) + RVECENT(romReserved,105) + RVECENT(romReserved,106) + RVECENT(romReserved,107) + RVECENT(romReserved,108) + RVECENT(romReserved,109) + RVECENT(romReserved,110) + RVECENT(romReserved,111) + XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */ + RVECENT(romReserved,113) + RVECENT(romReserved,114) + RVECENT(romReserved,115) + RVECENT(romReserved,116) + RVECENT(romReserved,116) + RVECENT(romReserved,118) + RVECENT(romReserved,119) + RVECENT(romReserved,120) + RVECENT(romReserved,121) + RVECENT(romReserved,122) + RVECENT(romReserved,123) + RVECENT(romReserved,124) + RVECENT(romReserved,125) + RVECENT(romReserved,126) + RVECENT(romReserved,127) + + /* We hope there are no more reserved vectors! + * 128 * 8 == 1024 == 0x400 + * so this is address R_VEC+0x400 == 0xbfc00400 + */ +#ifdef CONFIG_PURPLE +/* 0xbfc00400 */ + .word 0xdc870000 + .word 0xfca70000 + .word 0x20840008 + .word 0x20a50008 + .word 0x20c6ffff + .word 0x14c0fffa + .word 0x00000000 + .word 0x03e00008 + .word 0x00000000 + .word 0x00000000 +/* 0xbfc00428 */ + .word 0xdc870000 + .word 0xfca70000 + .word 0x20840008 + .word 0x20a50008 + .word 0x20c6ffff + .word 0x14c0fffa + .word 0x00000000 + .word 0x03e00008 + .word 0x00000000 + .word 0x00000000 +#endif /* CONFIG_PURPLE */ + .align 4 +reset: + + /* Clear watch registers. + */ + mtc0 zero, CP0_WATCHLO + mtc0 zero, CP0_WATCHHI + + /* WP(Watch Pending), SW0/1 should be cleared. */ + mtc0 zero, CP0_CAUSE + + setup_c0_status_reset + + /* Init Timer */ + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + +#if !defined(CONFIG_BOOTSTRAP_SKIP_LOWLEVEL_INIT) + /* CONFIG0 register */ + li t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ + + /* Initialize $gp. + */ + bal 1f + nop + .word _gp +1: + lw gp, 0(ra) + +#if !defined(CONFIG_BOOTSTRAP_SKIP_LOWLEVEL_INIT) + /* Initialize any external memory. + */ + la t9, lowlevel_init + jalr t9 + nop + + /* Initialize caches... + */ + la t9, mips_cache_reset + jalr t9 + nop + + /* ... and enable them. + */ + li t0, CONF_CM_CACHABLE_NONCOHERENT + mtc0 t0, CP0_CONFIG +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ + + /* Set up temporary stack. + */ +#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS + li a0, CONFIG_SYS_INIT_SP_OFFSET + la t9, mips_cache_lock + jalr t9 + nop +#endif + + li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET + la sp, 0(t0) + + la t9, bootstrap_board_init_f + jr t9 + nop + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * a0 = addr_sp + * a1 = gd + * a2 = destination address + */ + .globl relocate_code + .ent relocate_code +relocate_code: + move sp, a0 /* Set new stack pointer */ + + li t0, CONFIG_BOOTSTRAP_TEXT_BASE + la t3, in_ram + lw t2, -12(t3) /* t2 <-- uboot_end_data */ + move t1, a2 + move s2, a2 /* s2 <-- destination address */ + + /* + * Fix $gp: + * + * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address + */ + move t6, gp + sub gp, CONFIG_BOOTSTRAP_TEXT_BASE + add gp, a2 /* gp now adjusted */ + sub s1, gp, t6 /* s1 <-- relocation offset */ + + /* + * t0 = source address + * t1 = target address + * t2 = source end address + */ + + /* + * Save destination address and size for later usage in flush_cache() + */ + move s0, a1 /* save gd in s0 */ + move a0, t1 /* a0 <-- destination addr */ + sub a1, t2, t0 /* a1 <-- size */ + + /* On the purple board we copy the code earlier in a special way + * in order to solve flash problems + */ +#ifndef CONFIG_PURPLE +1: + lw t3, 0(t0) + sw t3, 0(t1) + addu t0, 4 + ble t0, t2, 1b + addu t1, 4 /* delay slot */ +#endif + + /* If caches were enabled, we would have to flush them here. + */ + + /* a0 & a1 are already set up for flush_cache(start, size) */ + la t9, flush_cache + jalr t9 + nop + + /* Jump to where we've relocated ourselves. + */ + addi t0, s2, in_ram - _start + jr t0 + nop + + .word _gp + .word _GLOBAL_OFFSET_TABLE_ + .word uboot_end_data + .word uboot_end + .word num_got_entries + +in_ram: + /* + * Now we want to update GOT. + * + * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object + * generated by GNU ld. Skip these reserved entries from relocation. + */ + lw t3, -4(t0) /* t3 <-- num_got_entries */ + lw t4, -16(t0) /* t4 <-- _GLOBAL_OFFSET_TABLE_ */ + lw t5, -20(t0) /* t5 <-- _gp */ + sub t4, t5 /* compute offset*/ + add t4, t4, gp /* t4 now holds relocated _GLOBAL_OFFSET_TABLE_ */ + addi t4, t4, 8 /* Skipping first two entries. */ + li t2, 2 +1: + lw t1, 0(t4) + beqz t1, 2f + add t1, s1 + sw t1, 0(t4) +2: + addi t2, 1 + blt t2, t3, 1b + addi t4, 4 /* delay slot */ + + /* Clear BSS. + */ + lw t1, -12(t0) /* t1 <-- uboot_end_data */ + lw t2, -8(t0) /* t2 <-- uboot_end */ + add t1, s1 /* adjust pointers */ + add t2, s1 + + sub t1, 4 +1: + addi t1, 4 + bltl t1, t2, 1b + sw zero, 0(t1) /* delay slot */ + + move a0, s0 /* a0 <-- gd */ + la t9, bootstrap_board_init_r + jr t9 + move a1, s2 /* delay slot */ + + .end relocate_code + +/* + * void copy_and_jump (void) + * + * This function copies/unzips the u-boot image and runs it. + * This "function" does not return + * +*/ + .globl copy_and_jump + .ent copy_and_jump +copy_and_jump: + + /* copy_uboot(CONFIG_SYS_MONITOR_BASE, payload_uncsize, payload_start, payload_size) */ + li a0, CONFIG_SYS_MONITOR_BASE + la a1, payload_uncsize + lw a1, 0(a1) + la a2, payload_start + la a3, payload_size + la t9, copy_uboot + jalr t9 + lw a3, 0(a3) /* delay slot */ + + li t9, CONFIG_SYS_MONITOR_BASE + jr t9 + nop + + .end copy_and_jump + + /* Exception handlers. + */ +romReserved: + b romReserved + +romExcHandle: + b romExcHandle diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 4e90704..3570581 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -24,6 +24,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o +BOOTSTRAP_LIB = $(obj)lib$(ARCH)_bootstrap.o + +BOOTSTRAP_LIB-$(CONFIG_BOOTSTRAP) = $(BOOTSTRAP_LIB) SOBJS-y += @@ -35,12 +38,22 @@ COBJS-y += bootm.o endif COBJS-y += time.o -SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += board_bootstrap.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += time.o + +BOOTSTRAP_OBJS := $(addprefix $(obj),$(BOOTSTRAP_SOBJS-y) $(BOOTSTRAP_COBJS-y)) + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) $(BOOTSTRAP_SOBJS-y:.o=.S) $(BOOTSTRAP_COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +all: $(LIB) $(BOOTSTRAP_LIB-y) + $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(BOOTSTRAP_LIB): $(obj).depend $(BOOTSTRAP_OBJS) + $(call cmd_link_o_target, $(BOOTSTRAP_OBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/arch/mips/lib/board_bootstrap.c b/arch/mips/lib/board_bootstrap.c new file mode 100644 index 0000000..1d548d6 --- /dev/null +++ b/arch/mips/lib/board_bootstrap.c @@ -0,0 +1,261 @@ +/* + * (C) Copyright 2010 Industrie Dial Face S.p.A. + * Luigi 'Comio' Mantellini, luigi.mantellini@idf-hit.com + * + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@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. + * + * 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 + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern int timer_init(void); + +extern int incaip_set_cpuclk(void); + +extern ulong uboot_end_data; +extern ulong uboot_end; + +static char *failed = "*** failed ***\n"; + +/* + * mips_io_port_base is the begin of the address space to which x86 style + * I/O ports are mapped. + */ +unsigned long mips_io_port_base = -1; + +int __board_early_init_f(void) +{ + /* + * Nothing to do in this dummy implementation + */ + return 0; +} + +int board_early_init_f(void) __attribute__((weak, alias("__board_early_init_f"))); +int bootstrap_board_early_init_f(void) __attribute__((weak, alias("board_early_init_f"))); + +static int bootstrap_init_func_ram (void) +{ + if ((gd->ram_size = bootstrap_initdram (0)) > 0) { + return (0); + } + puts (failed); + return (1); +} + +static int bootstrap_display_banner(void) +{ + puts ("bootstrap..."); + return (0); +} + +static int bootstrap_init_baudrate (void) +{ +#if defined(CONFIG_BOOTSTRAP_BAUDRATE) + gd->baudrate = CONFIG_BOOTSTRAP_BAUDRATE; +#else + gd->baudrate = CONFIG_BAUDRATE; +#endif + return 0; +} + +/* + * Breath some life into the board... + * + * The first part of initialization is running from Flash memory; + * its main purpose is to initialize the RAM so that we + * can relocate the monitor code to RAM. + */ + +/* + * All attempts to come up with a "common" initialization sequence + * that works for all boards and architectures failed: some of the + * requirements are just _too_ different. To get rid of the resulting + * mess of board dependend #ifdef'ed code we now make the whole + * initialization sequence configurable to the user. + * + * The requirements for any new initalization function is simple: it + * receives a pointer to the "global data" structure as it's only + * argument, and returns an integer return code, where 0 means + * "continue" and != 0 means "fatal error, hang the system". + */ +typedef int (init_fnc_t) (void); + +static init_fnc_t *init_sequence[] = { + bootstrap_board_early_init_f, + timer_init, + bootstrap_init_baudrate,/* initialze baudrate settings */ + serial_init, /* serial communications setup */ + bootstrap_display_banner, /* say that we are here */ + bootstrap_checkboard, + bootstrap_init_func_ram, + NULL, +}; + + +void bootstrap_board_init_f(ulong bootflag) +{ + gd_t gd_data, *id; + bd_t *bd; + init_fnc_t **init_fnc_ptr; + ulong addr, addr_sp, len = (ulong)&uboot_end - CONFIG_BOOTSTRAP_TEXT_BASE; + ulong *s; + + /* Pointer is writable since we allocated a register for it. + */ + gd = &gd_data; + /* compiler optimization barrier needed for GCC >= 3.4 */ + __asm__ __volatile__("": : :"memory"); + + memset ((void *)gd, 0, sizeof (gd_t)); + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr)() != 0) { + bootstrap_hang (); + } + } + + /* + * Now that we have DRAM mapped and working, we can + * relocate the code and continue running from DRAM. + */ + addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; + + /* We can reserve some RAM "on top" here. + */ + + /* round down to next 4 kB limit. + */ + addr &= ~(4096 - 1); + debug ("Top of RAM usable for U-Boot at: %08lx\n", addr); + + /* Reserve memory for U-Boot code, data & bss + * round down to next 16 kB limit + */ + addr -= len; + addr &= ~(16 * 1024 - 1); + + debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr); + + /* Reserve memory for malloc() arena. + */ + addr_sp = addr - TOTAL_MALLOC_LEN; + debug ("Reserving %dk for malloc() at: %08lx\n", + TOTAL_MALLOC_LEN >> 10, addr_sp); + + /* + * (permanently) allocate a Board Info struct + * and a permanent copy of the "global" data + */ + addr_sp -= sizeof(bd_t); + bd = (bd_t *)addr_sp; + gd->bd = bd; + debug ("Reserving %zu Bytes for Board Info at: %08lx\n", + sizeof(bd_t), addr_sp); + + addr_sp -= sizeof(gd_t); + id = (gd_t *)addr_sp; + debug ("Reserving %zu Bytes for Global Data at: %08lx\n", + sizeof (gd_t), addr_sp); + + /* Reserve memory for boot params. + */ + addr_sp -= CONFIG_SYS_BOOTPARAMS_LEN; + bd->bi_boot_params = addr_sp; + debug ("Reserving %dk for boot params() at: %08lx\n", + CONFIG_SYS_BOOTPARAMS_LEN >> 10, addr_sp); + + /* + * Finally, we set up a new (bigger) stack. + * + * Leave some safety gap for SP, force alignment on 16 byte boundary + * Clear initial stack frame + */ + addr_sp -= 16; + addr_sp &= ~0xF; + s = (ulong *)addr_sp; + *s-- = 0; + *s-- = 0; + addr_sp = (ulong)s; + debug ("Stack Pointer at: %08lx\n", addr_sp); + + /* + * Save local variables to board info struct + */ + bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; /* start of DRAM memory */ + bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */ + bd->bi_baudrate = gd->baudrate; /* Console Baudrate */ + + memcpy (id, (void *)gd, sizeof (gd_t)); + + /* On the purple board we copy the code in a special way + * in order to solve flash problems + */ + relocate_code (addr_sp, id, addr); + + /* NOTREACHED - relocate_code() does not return */ +} +/************************************************************************ + * + * This is the next part if the initialization sequence: we are now + * running from RAM and have a "normal" C environment, i. e. global + * data can be written, BSS has been cleared, the stack size in not + * that critical any more, etc. + * + ************************************************************************ + */ + +void bootstrap_board_init_r (gd_t *id, ulong dest_addr) +{ + extern void malloc_bin_reloc (void); + extern void copy_and_jump(void); + + bd_t *bd; + + gd = id; + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + + debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr); + + gd->reloc_off = dest_addr - CONFIG_BOOTSTRAP_TEXT_BASE; + + bd = gd->bd; + + /* The Malloc area is immediately below the monitor copy in DRAM */ + mem_malloc_init(CONFIG_BOOTSTRAP_BASE + gd->reloc_off - + TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); + malloc_bin_reloc(); + + copy_and_jump(); + + /* NOTREACHED - no way out of command loop except booting */ +} + +void bootstrap_hang (void) +{ + puts ("### ERROR ### Please RESET the board ###\n"); + for (;;); +} diff --git a/common/Makefile b/common/Makefile index abea91c..5662506 100644 --- a/common/Makefile +++ b/common/Makefile @@ -24,6 +24,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)libcommon.o +BOOTSTRAP_LIB = $(obj)libcommon_bootstrap.o + +BOOTSTRAP_LIB-$(CONFIG_BOOTSTRAP) = $(BOOTSTRAP_LIB) # core COBJS-y += main.o @@ -165,20 +168,28 @@ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += dlmalloc.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += console_bootstrap.o + +BOOTSTRAP_COBJS := $(sort $(BOOTSTRAP_COBJS-y)) +BOOTSTRAP_OBJS := $(addprefix $(obj),$(BOOTSTRAP_COBJS)) COBJS := $(sort $(COBJS-y)) XCOBJS := $(sort $(XCOBJS-y)) -SRCS := $(COBJS:.o=.c) $(XCOBJS:.o=.c) +SRCS := $(sort $(COBJS:.o=.c) $(XCOBJS:.o=.c) $(BOOTSTRAP_COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(COBJS)) XOBJS := $(addprefix $(obj),$(XCOBJS)) CPPFLAGS += -I.. -all: $(LIB) $(XOBJS) +all: $(LIB) $(BOOTSTRAP_LIB-y) $(XOBJS) $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(BOOTSTRAP_LIB): $(obj).depend $(BOOTSTRAP_OBJS) + $(call cmd_link_o_target, $(BOOTSTRAP_OBJS)) + $(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc $(CC) $(AFLAGS) -Wa,--no-warn \ -DENV_CRC=$(shell $(obj)../tools/envcrc) \ diff --git a/common/console_bootstrap.c b/common/console_bootstrap.c new file mode 100644 index 0000000..cdd4a62 --- /dev/null +++ b/common/console_bootstrap.c @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2000 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * + * 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 + */ + +#include +#include +#include + +/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ + +int getc(void) +{ + /* Send directly to the handler */ + return serial_getc(); +} + +int tstc(void) +{ + /* Send directly to the handler */ + return serial_tstc(); +} + +void putc(const char c) +{ + /* Send directly to the handler */ + serial_putc(c); +} + +void puts(const char *s) +{ + serial_puts(s); +} + +int printf(const char *fmt, ...) +{ + va_list args; + uint i; + char printbuffer[CONFIG_SYS_PBSIZE]; + + va_start(args, fmt); + + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsprintf(printbuffer, fmt, args); + va_end(args); + + /* Print the string */ + puts(printbuffer); + return i; +} + +int vprintf(const char *fmt, va_list args) +{ + uint i; + char printbuffer[CONFIG_SYS_PBSIZE]; + + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsprintf(printbuffer, fmt, args); + + /* Print the string */ + puts(printbuffer); + return i; +} diff --git a/config.mk b/config.mk index c6d6f7b..103bdce 100644 --- a/config.mk +++ b/config.mk @@ -150,7 +150,7 @@ else ARFLAGS = crv endif RELFLAGS= $(PLATFORM_RELFLAGS) -DBGFLAGS= -g # -DDEBUG +DBGFLAGS= -g OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug @@ -160,6 +160,11 @@ else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif endif +ifeq ($(CONFIG_BOOTSTRAP),y) +ifndef BOOTSTRAP_LDSCRIPT +BOOTSTRAP_LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-bootstrap.lds +endif +endif OBJCFLAGS += --gap-fill=0xff gccincdir := $(shell $(CC) -print-file-name=include) @@ -170,6 +175,10 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),) CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) endif +ifneq ($(CONFIG_BOOTSTRAP_TEXT_BASE),) +CPPFLAGS += -DCONFIG_BOOTSTRAP_TEXT_BASE=$(CONFIG_BOOTSTRAP_TEXT_BASE) +endif + ifneq ($(RESET_VECTOR_ADDRESS),) CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS) endif @@ -190,6 +199,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes endif CFLAGS += $(call cc-option,-fno-stack-protector) +CFLAGS += $(call cc-option,-ffunction-sections) # $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g # option to the assembler. @@ -209,6 +219,13 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),) LDFLAGS += -Ttext $(CONFIG_SYS_TEXT_BASE) endif +ifeq ($(CONFIG_BOOTSTRAP),y) +BOOTSTRAP_LDFLAGS += -Bstatic -T $(obj)u-boot-bootstrap.lds $(PLATFORM_LDFLAGS) +ifneq ($(CONFIG_BOOTSTRAP_TEXT_BASE),) +BOOTSTRAP_LDFLAGS += -Ttext $(CONFIG_BOOTSTRAP_TEXT_BASE) +endif +endif + # Location of a usable BFD library, where we define "usable" as # "built for ${HOST}, supports ${TARGET}". Sensible values are # - When cross-compiling: the root of the cross-environment diff --git a/include/common.h b/include/common.h index 189ad81..690cba2 100644 --- a/include/common.h +++ b/include/common.h @@ -723,6 +723,27 @@ int cpu_disable(int nr); int cpu_release(int nr, int argc, char * const argv[]); #endif +/* Bootstrap specific code */ +#ifdef CONFIG_BOOTSTRAP +void bootstrap_hang(void) __attribute__ ((noreturn)); +void bootstrap_board_init_f(ulong) __attribute__ ((noreturn)); +void bootstrap_board_init_r(gd_t *, ulong) __attribute__ ((noreturn)); +int bootstrap_checkboard(void); + +int bootstrap_serial_init(void); +void bootstrap_serial_exit(void); +void bootstrap_serial_setbrg(void); +void bootstrap_serial_putc(const char); +void bootstrap_serial_putc_raw(const char); +void bootstrap_serial_puts(const char *); +int bootstrap_serial_getc(void); +int bootstrap_serial_tstc(void); + +phys_size_t bootstrap_initdram (int); + +int copy_uboot(void *dst, size_t unc_size, void *src, size_t size); +#endif + #endif /* __ASSEMBLY__ */ /* Put only stuff here that the assembler can digest */ diff --git a/lib/Makefile b/lib/Makefile index ffdee7d..e6ac700 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -24,6 +24,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)libgeneric.o +BOOTSTRAP_LIB = $(obj)libgeneric_bootstrap.o + +BOOTSTRAP_LIB-$(CONFIG_BOOTSTRAP) = $(BOOTSTRAP_LIB) COBJS-$(CONFIG_ADDR_MAP) += addr_map.o COBJS-$(CONFIG_BZIP2) += bzlib.o @@ -54,13 +57,36 @@ COBJS-y += vsprintf.o COBJS-$(CONFIG_ZLIB) += zlib.o COBJS-$(CONFIG_RBTREE) += rbtree.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += string.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += vsprintf.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += div64.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += ctype.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += time.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP) += bootstrap.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_GZIP) += zlib.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_GZIP) += gunzip.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_GZIP) += crc32.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_BZIP2) += bzlib.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_BZIP2) += bzlib_crctable.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_BZIP2) += bzlib_decompress.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_BZIP2) += bzlib_randtable.o +BOOTSTRAP_COBJS-$(CONFIG_BOOTSTRAP_BZIP2) += bzlib_huffman.o + +BOOTSTRAP_COBJS := $(BOOTSTRAP_COBJS-y) +BOOTSTRAP_OBJS := $(addprefix $(obj),$(BOOTSTRAP_COBJS)) + COBJS := $(COBJS-y) -SRCS := $(COBJS:.o=.c) +SRCS := $(COBJS:.o=.c) $(BOOTSTRAP_COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) +all: $(LIB) $(BOOTSTRAP_LIB-y) + $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(BOOTSTRAP_LIB): $(obj).depend $(BOOTSTRAP_OBJS) + $(call cmd_link_o_target, $(BOOTSTRAP_OBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/lib/bootstrap.c b/lib/bootstrap.c new file mode 100644 index 0000000..50d3461 --- /dev/null +++ b/lib/bootstrap.c @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2010 Industrie Dial Face S.p.A. + * Luigi 'Comio' Mantellini, luigi.mantellini@idf-hit.com + * + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@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. + * + * 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 + */ + +#include +#include +#include + +#ifdef CONFIG_BOOTSTRAP_LZMA +#include +#include +#include +#endif /* CONFIG_BOOTSTRAP_LZMA */ + +#ifdef CONFIG_BOOTSTRAP_LZO +#include +#endif /* CONFIG_BOOTSTRAP_LZO */ + +#ifdef CONFIG_BOOTSTRAP_BZIP2 +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static const char *algo = +#if defined(CONFIG_BOOTSTRAP_GZIP) + "gzip"; +#elif defined(CONFIG_BOOTSTRAP_LZMA) + "lzma"; +#elif defined(CONFIG_BOOTSTRAP_LZO) + "lzo"; +#elif defined(CONFIG_BOOTSTRAP_BZIP2) + "bzip2"; +#else + "flat"; +#endif + + +int copy_uboot(void *dst, size_t unc_size, void *src, size_t size) +{ + int ret; + debug("copy from %p (%d) to %p (%d)\n", src, size, dst, unc_size); + + printf("Uncompressing payload (%s)...", algo); +#if defined(CONFIG_BOOTSTRAP_GZIP) + ret = gunzip(dst, unc_size, src, &size); +#elif defined(CONFIG_BOOTSTRAP_LZMA) + SizeT outsize = unc_size; + ret = lzmaBuffToBuffDecompress(dst, &outsize, src, size); +#elif defined(CONFIG_BOOTSTRAP_LZO) + uint unc_len = unc_size; + ret = lzop_decompress(src, size, dst, &unc_len); +#elif defined(CONFIG_BOOTSTRAP_BZIP2) + uint unc_len = unc_size; + ret = BZ2_bzBuffToBuffDecompress ((char*)dst, &unc_len, (char *)src, size, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); +#else + memcpy(dst, src, size); + ret = 0; +#endif + if (ret) { + printf("failed with error %d.\n", ret); + bootstrap_hang(); + } else { + puts("done.\n"); + } + return ret; +} \ No newline at end of file diff --git a/lib/lzma/Makefile b/lib/lzma/Makefile index 4d3401d..395b8dc 100644 --- a/lib/lzma/Makefile +++ b/lib/lzma/Makefile @@ -32,7 +32,9 @@ SOBJS = CFLAGS += -D_LZMA_PROB32 -COBJS-$(CONFIG_LZMA) += LzmaDec.o LzmaTools.o +COBJS-$(CONFIG_LZMA)$(CONFIG_BOOTSTRAP_LZMA) += LzmaDec.o LzmaTools.o + +COBJS-y += $(COBJS-yy) COBJS = $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile index 69bc839..c8d7fa5 100644 --- a/lib/lzo/Makefile +++ b/lib/lzo/Makefile @@ -27,7 +27,9 @@ LIB = $(obj)liblzo.o SOBJS = -COBJS-$(CONFIG_LZO) += lzo1x_decompress.o +COBJS-$(CONFIG_LZO)$(CONFIG_BOOTSTRAP_LZO) += lzo1x_decompress.o + +COBJS-y += $(OBJS-yy) COBJS = $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)