diff --git a/Makefile b/Makefile index 3b339ad17e..9225a2d350 100644 --- 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)) diff --git a/board/apollon/apollon.c b/board/apollon/apollon.c index 064d143ae4..383b0643f8 100644 --- a/board/apollon/apollon.c +++ b/board/apollon/apollon.c @@ -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 */ diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S index 17c7a83491..8b765f1e80 100644 --- a/cpu/arm1136/start.S +++ b/cpu/arm1136/start.S @@ -35,6 +35,25 @@ #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 index 0000000000..66a0959ee2 --- /dev/null +++ b/onenand_ipl/board/apollon/Makefile @@ -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 index 0000000000..acf5c2998f --- /dev/null +++ b/onenand_ipl/board/apollon/apollon.c @@ -0,0 +1,70 @@ +/* + * (C) Copyright 2005-2008 Samsung Electronics + * Kyungmin Park + * + * 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 + +#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 index 0000000000..fd9c506f7e --- /dev/null +++ b/onenand_ipl/board/apollon/config.mk @@ -0,0 +1,14 @@ +# +# (C) Copyright 2005-2008 Samsung Electronics +# Kyungmin Park +# +# 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 index 0000000000..417a5a7e0d --- /dev/null +++ b/onenand_ipl/board/apollon/low_levelinit.S @@ -0,0 +1,205 @@ +/* + * Board specific setup info + * + * (C) Copyright 2005-2008 Samsung Electronics + * Kyungmin Park + * + * 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 +#include +#include +#include + +#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 index 0000000000..559f9f2bef --- /dev/null +++ b/onenand_ipl/board/apollon/u-boot.onenand.lds @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2005-2008 Samsung Electronics + * Kyungmin Park + * + * 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 index 0000000000..f30deaeca7 --- /dev/null +++ b/onenand_ipl/onenand_boot.c @@ -0,0 +1,81 @@ +/* + * (C) Copyright 2005-2008 Samsung Electronics + * Kyungmin Park + * + * 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 +#include + +#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 index 0000000000..b9c6669a7b --- /dev/null +++ b/onenand_ipl/onenand_ipl.h @@ -0,0 +1,44 @@ +/* + * (C) Copyright 2005-2008 Samsung Electronics + * Kyungmin Park + * + * 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 + +#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 index 0000000000..f553220237 --- /dev/null +++ b/onenand_ipl/onenand_read.c @@ -0,0 +1,105 @@ +/* + * (C) Copyright 2005-2008 Samsung Electronis + * Kyungmin Park + * + * 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 "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; +}