OneNAND Initial Program Loader (IPL) support
authorKyungmin Park <kmpark@infradead.org>
Thu, 17 Jan 2008 07:43:25 +0000 (16:43 +0900)
committerWolfgang Denk <wd@denx.de>
Thu, 14 Feb 2008 21:08:13 +0000 (22:08 +0100)
This patch enables the OneNAND boot within U-Boot.
Before this work, we used another OneNAND IPL called X-Loader based
on open source. With this work, we can build the oneboot.bin image
without other program.

The build sequence is simple.
First, it compiles the u-boot.bin
Second, it compiles OneNAND IPL
Finally, it becomes the oneboot.bin from OneNAND IPL and u-boot.bin
The mechanism is similar with NAND boot except it boots from itself.

Another thing is that you can only use the OneNAND IPL only to work
other bootloader such as RedBoot and so on.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Makefile
board/apollon/apollon.c
cpu/arm1136/start.S
onenand_ipl/board/apollon/Makefile [new file with mode: 0644]
onenand_ipl/board/apollon/apollon.c [new file with mode: 0644]
onenand_ipl/board/apollon/config.mk [new file with mode: 0644]
onenand_ipl/board/apollon/low_levelinit.S [new file with mode: 0644]
onenand_ipl/board/apollon/u-boot.onenand.lds [new file with mode: 0644]
onenand_ipl/onenand_boot.c [new file with mode: 0644]
onenand_ipl/onenand_ipl.h [new file with mode: 0644]
onenand_ipl/onenand_read.c [new file with mode: 0644]

index 3b339ad17e66ca976914ad1d45bd6d90e8f5c07e..9225a2d3503506d1c783f94c248dc0958977de18 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -274,13 +274,18 @@ NAND_SPL = nand_spl
 U_BOOT_NAND = $(obj)u-boot-nand.bin
 endif
 
+ifeq ($(CONFIG_ONENAND_U_BOOT),y)
+ONENAND_IPL = onenand_ipl
+U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
+endif
+
 __OBJS := $(subst $(obj),,$(OBJS))
 __LIBS := $(subst $(obj),,$(LIBS))
 
 #########################################################################
 #########################################################################
 
-ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
+ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
 
 all:           $(ALL)
 
@@ -327,6 +332,12 @@ $(NAND_SPL):       $(VERSION_FILE) $(obj)include/autoconf.mk
 $(U_BOOT_NAND):        $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
                cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
 
+$(ONENAND_IPL):        $(VERSION_FILE) $(obj)include/autoconf.mk
+               $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
+
+$(U_BOOT_ONENAND):     $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
+               cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
+
 $(VERSION_FILE):
                @( echo -n "#define U_BOOT_VERSION \"U-Boot " ; \
                echo -n "$(U_BOOT_VERSION)" ; \
@@ -2597,7 +2608,9 @@ omap2420h4_config : unconfig
        @$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4
 
 apollon_config         : unconfig
+       @echo "#define CONFIG_ONENAND_U_BOOT" > $(obj)include/config.h
        @$(MKCONFIG) $(@:_config=) arm arm1136 apollon
+       @echo "CONFIG_ONENAND_U_BOOT = y" >> $(obj)include/config.mk
 
 #========================================================================
 # i386
@@ -2898,6 +2911,8 @@ clean:
        @rm -f $(obj)board/bf537-stamp/u-boot.lds $(obj)board/bf561-ezkit/u-boot.lds
        @rm -f $(obj)include/bmp_logo.h
        @rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
+       @rm -f $(obj)onenand_ipl/onenand-ipl $(obj)onenand_ipl/onenand-ipl.bin \
+               $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)onenand_ipl/onenand-ipl.map
        @rm -f $(obj)api_examples/demo $(VERSION_FILE)
 
 clobber:       clean
@@ -2912,6 +2927,7 @@ clobber:  clean
        @rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
        @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
        @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
+       @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
        @[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
 
 ifeq ($(OBJTREE),$(SRCTREE))
index 064d143ae485d5dff82774376546f328112e20c7..383b0643f87ddc73c450333b66988671d5303cd4 100644 (file)
@@ -440,7 +440,8 @@ void muxSetupTouchScreen(void)
 void muxSetupGPMC(void)
 {
        /* gpmc_io_dir, MCR */
-       writel(0x4800008C, 0x19000000);
+       volatile unsigned int *MCR = (unsigned int *) 0x4800008C;
+       *MCR = 0x19000000;
 
        /* NOR FLASH CS0 */
        /* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode 0; Byte-3 */
index 17c7a834919b54a4b02fc929df958dcb0abac0bb..8b765f1e806d0c5418214c924c9930941cb9bed6 100644 (file)
 #endif
 .globl _start
 _start: b      reset
+#ifdef CONFIG_ONENAND_IPL
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+       ldr     pc, _hang
+
+_hang:
+       .word   do_hang
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678
+       .word   0x12345678      /* now 16*4=64 */
+#else
        ldr     pc, _undefined_instruction
        ldr     pc, _software_interrupt
        ldr     pc, _prefetch_abort
@@ -51,6 +70,7 @@ _not_used:            .word not_used
 _irq:                  .word irq
 _fiq:                  .word fiq
 _pad:                  .word 0x12345678 /* now 16*4=64 */
+#endif /* CONFIG_ONENAND_IPL */
 .global _end_vect
 _end_vect:
 
@@ -139,7 +159,9 @@ relocate:                           /* relocate U-Boot to RAM           */
        adr     r0, _start              /* r0 <- current position of code   */
        ldr     r1, _TEXT_BASE          /* test if we run from flash or RAM */
        cmp     r0, r1                  /* don't reloc during debug         */
+#ifndef CONFIG_ONENAND_IPL
        beq     stack_setup
+#endif /* CONFIG_ONENAND_IPL */
 
        ldr     r2, _armboot_start
        ldr     r3, _bss_start
@@ -156,26 +178,36 @@ copy_loop:
        /* Set up the stack                                                 */
 stack_setup:
        ldr     r0, _TEXT_BASE          /* upper 128 KiB: relocated uboot   */
+#ifdef CONFIG_ONENAND_IPL
+       sub     sp, r0, #128            /* leave 32 words for abort-stack   */
+#else
        sub     r0, r0, #CFG_MALLOC_LEN /* malloc area                      */
        sub     r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
 #ifdef CONFIG_USE_IRQ
        sub     r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif
        sub     sp, r0, #12             /* leave 3 words for abort-stack    */
+#endif /* CONFIG_ONENAND_IPL */
 
 clear_bss:
        ldr     r0, _bss_start          /* find start of bss segment        */
        ldr     r1, _bss_end            /* stop here                        */
        mov     r2, #0x00000000         /* clear                            */
 
+#ifndef CONFIG_ONENAND_IPL
 clbss_l:str    r2, [r0]                /* clear loop...                    */
        add     r0, r0, #4
        cmp     r0, r1
        bne     clbss_l
+#endif
 
        ldr     pc, _start_armboot
 
+#ifdef CONFIG_ONENAND_IPL
+_start_armboot: .word start_oneboot
+#else
 _start_armboot: .word start_armboot
+#endif
 
 
 /*
@@ -214,6 +246,8 @@ cpu_init_crit:
        bl      lowlevel_init   /* go setup pll,mux,memory */
        mov     lr, ip          /* restore link */
        mov     pc, lr          /* back to my caller */
+
+#ifndef CONFIG_ONENAND_IPL
 /*
  *************************************************************************
  *
@@ -326,10 +360,17 @@ cpu_init_crit:
        .macro get_fiq_stack                    @ setup FIQ stack
        ldr     sp, FIQ_STACK_START
        .endm
+#endif /* CONFIG_ONENAND_IPL */
 
 /*
  * exception handlers
  */
+#ifdef CONFIG_ONENAND_IPL
+       .align  5
+do_hang:
+       ldr     sp, _TEXT_BASE                  /* use 32 words about stack */
+       bl      hang                            /* hang and never return */
+#else  /* !CONFIG_ONENAND IPL */
        .align  5
 undefined_instruction:
        get_bad_stack
@@ -415,3 +456,4 @@ rstctl:
        .word   PM_RSTCTRL_WKUP
 
 #endif
+#endif /* CONFIG_ONENAND_IPL */
diff --git a/onenand_ipl/board/apollon/Makefile b/onenand_ipl/board/apollon/Makefile
new file mode 100644 (file)
index 0000000..66a0959
--- /dev/null
@@ -0,0 +1,65 @@
+
+include $(TOPDIR)/config.mk
+include $(TOPDIR)/include/config.mk
+include $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds
+LDFLAGS        = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS += -DCONFIG_ONENAND_IPL
+CFLAGS += -DCONFIG_ONENAND_IPL
+OBJCLFAGS += --gap-fill=0x00
+
+SOBJS  = start.o low_levelinit.o # _memcpy32.o
+COBJS  = apollon.o onenand_read.o onenand_boot.o
+
+SRCS   := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS := $(SOBJS) $(COBJS)
+LNDIR  := $(OBJTREE)/onenand_ipl/board/$(BOARDDIR)
+
+onenandobj     := $(OBJTREE)/onenand_ipl/
+
+ALL    = $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin
+
+all:   $(obj).depend $(ALL)
+
+$(onenandobj)onenand-ipl-2k.bin:       $(onenandobj)onenand-ipl
+       $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x800 -O binary $< $@
+
+$(onenandobj)onenand-ipl.bin:  $(onenandobj)onenand-ipl
+       $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(onenandobj)onenand-ipl:      $(OBJS)
+       cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
+               -Map $(onenandobj)onenand-ipl.map \
+               -o $(onenandobj)onenand-ipl
+
+# create symbolic links from common files
+
+# from cpu directory
+$(obj)start.S:
+       rm -f $(obj)start.S
+       ln -s $(SRCTREE)/cpu/$(CPU)/start.S $(obj)start.S
+
+# from onenand_ipl directory
+$(obj)onenand_ipl.h:
+       rm -f $(obj)onenand_ipl.h
+       ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $(obj)onenand_ipl.h
+
+$(obj)onenand_boot.c:  $(obj)onenand_ipl.h
+       rm -f $(obj)onenand_boot.c
+       ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $(obj)onenand_boot.c
+
+$(obj)onenand_read.c:  $(obj)onenand_ipl.h
+       rm -f $(obj)onenand_read.c
+       ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $(obj)onenand_read.c
+
+$(obj)%.o:     $(obj)%.S
+       $(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o:     $(obj)$.c
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
diff --git a/onenand_ipl/board/apollon/apollon.c b/onenand_ipl/board/apollon/apollon.c
new file mode 100644 (file)
index 0000000..acf5c29
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.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
+ */
+#include <common.h>
+#include <asm/arch/mux.h>
+
+#define write_config_reg(reg, value)                                    \
+do {                                                                    \
+       writeb(value, reg);                                             \
+} while (0)
+
+/*****************************************
+ * Routine: board_init
+ * Description: Early hardware init.
+ *****************************************/
+int board_init(void)
+{
+       return 0;
+}
+
+#ifdef CFG_PRINTF
+/* Pin Muxing registers used for UART1 */
+/****************************************
+ * Routine: muxSetupUART1  (ostboot)
+ * Description: Set up uart1 muxing
+ *****************************************/
+static void muxSetupUART1(void)
+{
+       /* UART1_CTS pin configuration, PIN = D21 */
+       write_config_reg(CONTROL_PADCONF_UART1_CTS, 0);
+       /* UART1_RTS pin configuration, PIN = H21 */
+       write_config_reg(CONTROL_PADCONF_UART1_RTS, 0);
+       /* UART1_TX pin configuration, PIN = L20 */
+       write_config_reg(CONTROL_PADCONF_UART1_TX, 0);
+       /* UART1_RX pin configuration, PIN = T21 */
+       write_config_reg(CONTROL_PADCONF_UART1_RX, 0);
+}
+#endif
+
+/**********************************************************
+ * Routine: s_init
+ * Description: Does early system init of muxing and clocks.
+ * - Called at time when only stack is available.
+ **********************************************************/
+int s_init(int skip)
+{
+#ifdef CFG_PRINTF
+       muxSetupUART1();
+#endif
+       return 0;
+}
diff --git a/onenand_ipl/board/apollon/config.mk b/onenand_ipl/board/apollon/config.mk
new file mode 100644 (file)
index 0000000..fd9c506
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# (C) Copyright 2005-2008 Samsung Electronics
+# Kyungmin Park <kyungmin.park@samsung.com>
+#
+# Samsung Apollon board with OMAP2420 (ARM1136) cpu
+#
+# Apollon has 1 bank of 128MB mDDR-SDRAM on CS0
+# Physical Address:
+# 8000'0000 (bank0)
+# 8800'0000 (bank1)
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+
+TEXT_BASE = 0x00000000
diff --git a/onenand_ipl/board/apollon/low_levelinit.S b/onenand_ipl/board/apollon/low_levelinit.S
new file mode 100644 (file)
index 0000000..417a5a7
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from board/omap2420h4/platform.S
+ *
+ * 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 <config.h>
+#include <asm/arch/omap2420.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/clocks.h>
+
+#define APOLLON_CS0_BASE       0x00000000
+
+#ifdef PRCM_CONFIG_I
+#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907
+#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013
+#define SDRC_RFR_CTRL_0_VAL    0x00044C01
+
+/* GPMC */
+#define APOLLON_GPMC_CONFIG1_0 0xe30d1201
+#define APOLLON_GPMC_CONFIG2_0 0x000c1000
+#define APOLLON_GPMC_CONFIG3_0 0x00030400
+#define APOLLON_GPMC_CONFIG4_0 0x0B841006
+#define APOLLON_GPMC_CONFIG5_0 0x020F0C11
+#define APOLLON_GPMC_CONFIG6_0 0x00000000
+#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24))
+
+#elif defined(PRCM_CONFIG_II)
+#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485
+#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C
+#define SDRC_RFR_CTRL_0_VAL    0x00030001
+
+/* GPMC */
+#define APOLLON_GPMC_CONFIG1_0 0xe30d1201
+#define APOLLON_GPMC_CONFIG2_0 0x00080E81
+#define APOLLON_GPMC_CONFIG3_0 0x00030400
+#define APOLLON_GPMC_CONFIG4_0 0x08041586
+#define APOLLON_GPMC_CONFIG5_0 0x020C090E
+#define APOLLON_GPMC_CONFIG6_0 0x00000000
+#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24))
+
+#else
+#error "Please configure PRCM schecm"
+#endif
+
+_TEXT_BASE:
+       .word   TEXT_BASE       /* sdram load addr from config.mk */
+
+.globl lowlevel_init
+lowlevel_init:
+       mov r3, r0     /* save skip information */
+
+       /* Disable watchdog */
+       ldr     r0, =WD2_BASE
+       ldr     r1, =WD_UNLOCK1
+       str     r1, [r0, #WSPR]
+
+       ldr     r1, =WD_UNLOCK2
+       str     r1, [r0, #WSPR]
+
+#ifdef DEBUG_LED
+       /* LED0 OFF */
+       ldr     r0, =0x480000E5         /* ball AA10, mode 3 */
+       mov     r1, #0x0b
+       strb    r1, [r0]
+#endif
+
+       /* Pin muxing for SDRC */
+       mov     r1, #0x00
+       ldr     r0, =0x480000A1         /* ball C12, mode 0 */
+       strb    r1, [r0]
+
+       ldr     r0, =0x48000032         /* ball D11, mode 0 */
+       strb    r1, [r0]
+
+       ldr     r0, =0x480000A3         /* ball B13, mode 0 */
+       strb    r1, [r0]
+
+       /* SDRC setting */
+       ldr     r0, =OMAP2420_SDRC_BASE
+       ldr     r1, =0x00000010
+       str     r1, [r0, #0x10]
+
+       ldr     r1, =0x00000100
+       str     r1, [r0, #0x44]
+
+       /* SDRC CS0 configuration */
+#ifdef CONFIG_APOLLON_PLUS
+       ldr     r1, =0x01702011
+#else
+       ldr     r1, =0x00d04011
+#endif
+       str     r1, [r0, #0x80]
+
+       ldr     r1, =SDRC_ACTIM_CTRLA_0_VAL
+       str     r1, [r0, #0x9C]
+
+       ldr     r1, =SDRC_ACTIM_CTRLB_0_VAL
+       str     r1, [r0, #0xA0]
+
+       ldr     r1, =SDRC_RFR_CTRL_0_VAL
+       str     r1, [r0, #0xA4]
+
+       ldr     r1, =0x00000041
+       str     r1, [r0, #0x70]
+
+       /* Manual command sequence */
+       ldr     r1, =0x00000007
+       str     r1, [r0, #0xA8]
+
+       ldr     r1, =0x00000000
+       str     r1, [r0, #0xA8]
+
+       ldr     r1, =0x00000001
+       str     r1, [r0, #0xA8]
+
+       ldr     r1, =0x00000002
+       str     r1, [r0, #0xA8]
+       str     r1, [r0, #0xA8]
+
+       /*
+        * CS0 SDRC Mode register
+        *   Burst length = 4 - DDR memory
+        *   Serial mode
+        *   CAS latency = 3
+        */
+       ldr     r1, =0x00000032
+       str     r1, [r0, #0x84]
+
+       /* Note: You MUST set EMR values */
+       /* EMR1 & EMR2 */
+       ldr     r1, =0x00000000
+       str     r1, [r0, #0x88]
+       str     r1, [r0, #0x8C]
+
+#ifdef OLD_SDRC_DLLA_CTRL
+       /* SDRC_DLLA_CTRL */
+       ldr     r1, =0x00007306
+       str     r1, [r0, #0x60]
+
+       ldr     r1, =0x00007303
+       str     r1, [r0, #0x60]
+#else
+       /* SDRC_DLLA_CTRL */
+       ldr     r1, =0x00000506
+       str     r1, [r0, #0x60]
+
+       ldr     r1, =0x00000503
+       str     r1, [r0, #0x60]
+#endif
+
+#ifdef __BROKEN_FEATURE__
+       /* SDRC_DLLB_CTRL */
+       ldr     r1, =0x00000506
+       str     r1, [r0, #0x68]
+
+       ldr     r1, =0x00000503
+       str     r1, [r0, #0x68]
+#endif
+
+       /* little delay after init */
+       mov     r2, #0x1800
+1:
+       subs    r2, r2, #0x1
+        bne    1b
+
+       ldr     sp, SRAM_STACK
+        str     ip, [sp]       /* stash old link register */
+       mov     ip, lr          /* save link reg across call */
+        mov     r0, r3         /* pass skip info to s_init */
+
+        bl      s_init         /* go setup pll,mux,memory */
+
+        ldr     ip, [sp]       /* restore save ip */
+       mov     lr, ip          /* restore link reg */
+
+       /* back to arch calling code */
+       mov     pc,     lr
+
+       /* the literal pools origin */
+       .ltorg
+
+SRAM_STACK:
+       .word LOW_LEVEL_SRAM_STACK
diff --git a/onenand_ipl/board/apollon/u-boot.onenand.lds b/onenand_ipl/board/apollon/u-boot.onenand.lds
new file mode 100644 (file)
index 0000000..559f9f2
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from X-loader
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+
+       . = ALIGN(4);
+       .text      :
+       {
+         start.o       (.text)
+         *(.text)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(.rodata) }
+
+       . = ALIGN(4);
+       .data : { *(.data) }
+
+       . = ALIGN(4);
+       .got : { *(.got) }
+
+       . = ALIGN(4);
+       __bss_start = .;
+       .bss : { *(.bss) }
+       _end = .;
+}
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c
new file mode 100644 (file)
index 0000000..f30deae
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from x-loader
+ *
+ * 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 <common.h>
+#include <version.h>
+
+#include "onenand_ipl.h"
+
+#ifdef CFG_PRINTF
+int print_info(void)
+{
+       printf(XLOADER_VERSION);
+
+       return 0;
+}
+#endif
+
+typedef int (init_fnc_t)(void);
+
+init_fnc_t *init_sequence[] = {
+       board_init,             /* basic board dependent setup */
+#ifdef CFG_PRINTF
+       serial_init,            /* serial communications setup */
+       print_info,
+#endif
+       NULL,
+};
+
+void start_oneboot(void)
+{
+       init_fnc_t **init_fnc_ptr;
+       uchar *buf;
+
+       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+               if ((*init_fnc_ptr)() != 0)
+                       hang();
+       }
+
+       buf = (uchar *) CFG_LOAD_ADDR;
+
+       if (!onenand_read_block(buf, ONENAND_START_BLOCK))
+               buf += ONENAND_BLOCK_SIZE;
+
+       if (buf == (uchar *)CFG_LOAD_ADDR)
+               hang();
+
+       /* go run U-Boot and never return */
+       printf("Starting OS Bootloader...\n");
+       ((init_fnc_t *)CFG_LOAD_ADDR)();
+
+       /* should never come here */
+}
+
+void hang(void)
+{
+       /* if board_hang() returns, hange here */
+       printf("X-Loader hangs\n");
+       for (;;);
+}
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h
new file mode 100644 (file)
index 0000000..b9c6669
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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 _ONENAND_IPL_H
+#define _ONENAND_IPL_H
+
+#include <linux/mtd/onenand_regs.h>
+
+#define ONENAND_START_BLOCK             0
+#define ONENAND_BLOCK_SIZE              2048
+
+#ifndef CFG_PRINTF
+#define printf(format, args...)
+#endif
+
+#define onenand_readw(a)        readw(a)
+#define onenand_writew(v, a)    writew(v, a)
+
+#define THIS_ONENAND(a)         (CFG_ONENAND_BASE + (a))
+
+#define READ_INTERRUPT()                                                \
+       onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
+
+#define ONENAND_PAGE_SIZE                       2048
+
+extern int onenand_read_block(unsigned char *buf, ulong block);
+#endif
diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c
new file mode 100644 (file)
index 0000000..f553220
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronis
+ * Kyungmin Park <kyungmin.park@samsung.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
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include "onenand_ipl.h"
+
+#define onenand_block_address(block)           (block)
+#define onenand_sector_address(page)           (page << 2)
+#define onenand_buffer_address()               ((1 << 3) << 8)
+#define onenand_bufferram_address(block)       (0)
+
+/* read a page with ECC */
+static inline int onenand_read_page(ulong block, ulong page, u_char *buf)
+{
+       unsigned long *base;
+
+#ifndef __HAVE_ARCH_MEMCPY32
+       unsigned int offset, value;
+       unsigned long *p;
+#endif
+
+       onenand_writew(onenand_block_address(block),
+               THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
+
+       onenand_writew(onenand_sector_address(page),
+               THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
+
+       onenand_writew(onenand_buffer_address(),
+               THIS_ONENAND(ONENAND_REG_START_BUFFER));
+
+       onenand_writew(onenand_bufferram_address(block),
+               THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
+
+       onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
+
+       onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
+
+#ifndef __HAVE_ARCH_MEMCPY32
+       p = (unsigned long *) buf;
+#endif
+       base = (unsigned long *) (CFG_ONENAND_BASE + ONENAND_DATARAM);
+
+       while (!(READ_INTERRUPT() & ONENAND_INT_READ))
+               continue;
+
+#ifdef __HAVE_ARCH_MEMCPY32
+       /* 32 bytes boundary memory copy */
+       memcpy32(buf, base, ONENAND_PAGE_SIZE);
+#else
+       for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) {
+               value = *(base + offset);
+               *p++ = value;
+       }
+#endif
+
+       return 0;
+}
+
+#define ONENAND_START_PAGE             1
+#define ONENAND_PAGES_PER_BLOCK                64
+
+/**
+ * onenand_read_block - Read a block data to buf
+ * @return 0 on success
+ */
+int onenand_read_block(unsigned char *buf, ulong block)
+{
+       int page, offset = 0;
+
+       /* NOTE: you must read page from page 1 of block 0 */
+       /* read the block page by page*/
+       for (page = ONENAND_START_PAGE;
+           page < ONENAND_PAGES_PER_BLOCK; page++) {
+
+               onenand_read_page(block, page, buf + offset);
+
+               offset += ONENAND_PAGE_SIZE;
+       }
+
+       return 0;
+}