From: Zhong Hongbo <bocui...@gmail.com>

Adopt the new SPL framework to implement the SPL booting of
the nand flash for S3C6400.

Signed-off-by: Zhong Hongbo <bocui...@gmail.com>
---
Change for V4:
        - Adjust the patch's order.
Change for V3:
        - None.
Change for V2:
        - seprate some code.
---
 arch/arm/cpu/arm1176/start.S                    |   16 +---
 board/samsung/smdk6400/Makefile                 |   29 +++++-
 board/samsung/smdk6400/lowlevel_init.S          |   22 ++--
 board/samsung/smdk6400/smdk6400_nand_spl.c      |   61 ++++++++++--
 board/samsung/smdk6400/tools/mksmdk6400_image.c |  117 +++++++++++++++++++++++
 drivers/mtd/nand/s3c64xx.c                      |    4 +-
 include/configs/smdk6400.h                      |   21 +++--
 7 files changed, 221 insertions(+), 49 deletions(-)
 create mode 100644 board/samsung/smdk6400/tools/mksmdk6400_image.c

diff --git a/arch/arm/cpu/arm1176/start.S b/arch/arm/cpu/arm1176/start.S
index d613641..761b7fe 100644
--- a/arch/arm/cpu/arm1176/start.S
+++ b/arch/arm/cpu/arm1176/start.S
@@ -51,7 +51,7 @@
 
 .globl _start
 _start: b      reset
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
        ldr     pc, _undefined_instruction
        ldr     pc, _software_interrupt
        ldr     pc, _prefetch_abort
@@ -164,7 +164,7 @@ cpu_init_crit:
         * When booting from NAND - it has definitely been a reset, so, no need
         * to flush caches and disable the MMU
         */
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
        /*
         * flush v4 I/D caches
         */
@@ -357,21 +357,14 @@ clbss_l:cmp       r0, r1                  /* clear 
loop... */
        add     r0, r0, #4
        b       clbss_l
 clbss_e:
-#ifndef CONFIG_NAND_SPL
        bl coloured_LED_init
        bl red_led_on
 #endif
-#endif
 
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
  */
-#ifdef CONFIG_NAND_SPL
-       ldr     pc, _nand_boot
-
-_nand_boot: .word nand_boot
-#else
        ldr     r0, _board_init_r_ofs
        adr     r1, _start
        add     lr, r0, r1
@@ -384,7 +377,6 @@ _nand_boot: .word nand_boot
 
 _board_init_r_ofs:
        .word board_init_r - _start
-#endif
 
 _rel_dyn_start_ofs:
        .word __rel_dyn_start - _start
@@ -398,7 +390,7 @@ _mmu_table_base:
        .word mmu_table
 #endif
 
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
 /*
  * we assume that cache operation is done before. (eg. cleanup_before_linux())
  * actually, we don't need to do anything about cache if not use d-cache in
@@ -576,4 +568,4 @@ fiq:
        get_bad_stack
        bad_save_user_regs
        bl      do_fiq
-#endif /* CONFIG_NAND_SPL */
+#endif /* CONFIG_SPL_BUILD */
diff --git a/board/samsung/smdk6400/Makefile b/board/samsung/smdk6400/Makefile
index 645c8e2..f7fa667 100644
--- a/board/samsung/smdk6400/Makefile
+++ b/board/samsung/smdk6400/Makefile
@@ -28,15 +28,34 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(BOARD).o
 
+ifndef CONFIG_SPL_BUILD
 COBJS-y        := smdk6400.o
+endif
+
 SOBJS  := lowlevel_init.o mem_init.o
 
-SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
-OBJS   := $(addprefix $(obj),$(COBJS-y))
-SOBJS  := $(addprefix $(obj),$(SOBJS))
+ifdef CONFIG_SPL_BUILD
+COBJS-y += smdk6400_nand_spl.o
+endif
+
+SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
+
+ALL    :=       $(obj).depend $(LIB)
+
+ifdef CONFIG_SPL_BUILD
+ALL    += $(OBJTREE)/tools/mk$(BOARD)spl
+endif
+
+all:   $(ALL)
+
+$(LIB):        $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
 
-$(LIB):        $(obj).depend $(SOBJS) $(OBJS)
-       $(call cmd_link_o_target, $(SOBJS) $(OBJS))
+ifdef CONFIG_SPL_BUILD
+$(OBJTREE)/tools/mk$(BOARD)spl:        tools/mksmdk6400_image.c
+       $(HOSTCC) tools/mksmdk6400_image.c -o $(OBJTREE)/tools/mk$(BOARD)spl
+endif
 
 #########################################################################
 
diff --git a/board/samsung/smdk6400/lowlevel_init.S 
b/board/samsung/smdk6400/lowlevel_init.S
index 45887f3..93172e7 100644
--- a/board/samsung/smdk6400/lowlevel_init.S
+++ b/board/samsung/smdk6400/lowlevel_init.S
@@ -84,18 +84,12 @@ lowlevel_init:
        str     r3, [r0, #oVECTADDR]
        str     r3, [r1, #oVECTADDR]
 
+#ifdef CONFIG_SPL_BUILD
        /* init system clock */
-       bl system_clock_init
+       bl      system_clock_init
 
-#ifndef CONFIG_NAND_SPL
-       /* for UART */
-       bl uart_asm_init
-#endif
-
-#ifdef CONFIG_BOOT_NAND
        /* simple init for NAND */
-       bl nand_asm_init
-#endif
+       bl      nand_asm_init
 
        /* Memory subsystem address 0x7e00f120 */
        ldr     r0, =ELFIN_MEM_SYS_CFG
@@ -105,6 +99,12 @@ lowlevel_init:
        str     r1, [r0]
 
        bl      mem_ctrl_asm_init
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+       /* for UART */
+       bl      uart_asm_init
+#endif
 
 /* Wakeup support. Don't know if it's going to be used, untested. */
        ldr     r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)
@@ -244,7 +244,7 @@ wait_for_async:
        mov     pc, lr
 
 
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
 /*
  * uart_asm_init: Initialize UART's pins
  */
@@ -256,7 +256,7 @@ uart_asm_init:
        mov     pc, lr
 #endif
 
-#ifdef CONFIG_BOOT_NAND
+#ifdef CONFIG_SPL_BUILD
 /*
  * NAND Interface init for SMDK6400
  */
diff --git a/board/samsung/smdk6400/smdk6400_nand_spl.c 
b/board/samsung/smdk6400/smdk6400_nand_spl.c
index a023284..34649a2 100644
--- a/board/samsung/smdk6400/smdk6400_nand_spl.c
+++ b/board/samsung/smdk6400/smdk6400_nand_spl.c
@@ -1,13 +1,6 @@
 /*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroe...@sysgo.de>
- *
- * (C) Copyright 2002
- * David Mueller, ELSOFT AG, <d.muel...@elsoft.ch>
- *
- * (C) Copyright 2008
- * Guennadi Liakhovetki, DENX Software Engineering, <l...@denx.de>
+ * Copyright (C) 2012
+ * Zhong Hongbo <bocui...@gmail.com>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -29,9 +22,55 @@
  */
 
 #include <common.h>
+#include <config.h>
+#include <nand.h>
 
 void board_init_f(unsigned long bootflag)
 {
-       relocate_code(CONFIG_SYS_TEXT_BASE - TOTAL_MALLOC_LEN, NULL,
-                       CONFIG_SYS_TEXT_BASE);
+       /*
+        * We call relocate_code() with relocation target same as the
+        * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting
+        * skipped. Instead, only .bss initialization will happen. That's
+        * all we need
+        */
+       relocate_code(CONFIG_SPL_STACK, NULL, CONFIG_SPL_TEXT_BASE);
+}
+
+void board_init_r(gd_t *id, ulong dest_addr)
+{
+       __attribute__((noreturn)) void (*uboot)(void);
+
+       spl_nand_copy();
+       /*
+        * Jump to U-Boot image
+        */
+       uboot = (void *)CONFIG_SYS_UBOOT_BASE;
+       (*uboot)();
+       /* Never returns Here */
+}
+
+void spl_nand_copy(void)
+{
+       /*
+        * Init board specific nand support
+        */
+       nand_init();
+       /*
+        * Load U-Boot image from NAND into RAM
+        */
+       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                       CONFIG_SYS_NAND_U_BOOT_SIZE,
+                       (void *)CONFIG_SYS_UBOOT_BASE);
+
+#ifdef CONFIG_NAND_ENV_DST
+       nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
+                       (void *)CONFIG_NAND_ENV_DST);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+       nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE,
+                       (void *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE);
+#endif
+#endif
+
+       nand_deselect();
 }
diff --git a/board/samsung/smdk6400/tools/mksmdk6400_image.c 
b/board/samsung/smdk6400/tools/mksmdk6400_image.c
new file mode 100644
index 0000000..1a51913
--- /dev/null
+++ b/board/samsung/smdk6400/tools/mksmdk6400_image.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define CHECKSUM_OFFSET                (14*1024-4)
+#define BUFSIZE                        (16*1024)
+#define FILE_PERM              (S_IRUSR | S_IWUSR | S_IRGRP \
+                               | S_IWGRP | S_IROTH | S_IWOTH)
+/*
+* Requirement:
+* IROM code reads first 14K bytes from boot device.
+* It then calculates the checksum of 14K-4 bytes and compare with data at
+* 14K-4 offset.
+*
+* This function takes two filenames:
+* IN  "u-boot-spl.bin" and
+* OUT "u-boot-mmc-spl.bin" as filenames.
+* It reads the "u-boot-spl.bin" in 16K buffer.
+* It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer.
+* It writes the buffer to "u-boot-mmc-spl.bin" file.
+*/
+
+int main(int argc, char **argv)
+{
+       int i, len;
+       unsigned char buffer[BUFSIZE] = {0};
+       int ifd, ofd;
+       unsigned int checksum = 0, count;
+
+       if (argc != 3) {
+               printf(" %d Wrong number of arguments\n", argc);
+               exit(EXIT_FAILURE);
+       }
+
+       ifd = open(argv[1], O_RDONLY);
+       if (ifd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       argv[0], argv[1], strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);
+       if (ifd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       argv[0], argv[2], strerror(errno));
+               if (ifd)
+                       close(ifd);
+               exit(EXIT_FAILURE);
+       }
+
+       len = lseek(ifd, 0, SEEK_END);
+       lseek(ifd, 0, SEEK_SET);
+
+       count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET;
+
+       if (read(ifd, buffer, count) != count) {
+               fprintf(stderr, "%s: Can't read %s: %s\n",
+                       argv[0], argv[1], strerror(errno));
+
+               if (ifd)
+                       close(ifd);
+               if (ofd)
+                       close(ofd);
+
+               exit(EXIT_FAILURE);
+       }
+
+       for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++)
+               checksum += buffer[i];
+
+       memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum));
+
+       if (write(ofd, buffer, BUFSIZE) != BUFSIZE) {
+               fprintf(stderr, "%s: Can't write %s: %s\n",
+                       argv[0], argv[2], strerror(errno));
+
+               if (ifd)
+                       close(ifd);
+               if (ofd)
+                       close(ofd);
+
+               exit(EXIT_FAILURE);
+       }
+
+       if (ifd)
+               close(ifd);
+       if (ofd)
+               close(ofd);
+
+       return EXIT_SUCCESS;
+}
diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c
index 3199bf1..b85b641 100644
--- a/drivers/mtd/nand/s3c64xx.c
+++ b/drivers/mtd/nand/s3c64xx.c
@@ -39,7 +39,7 @@
 #define MAX_CHIPS      2
 static int nand_cs[MAX_CHIPS] = {0, 1};
 
-#ifdef CONFIG_NAND_SPL
+#ifdef CONFIG_SPL_BUILD
 #define printf(arg...) do {} while (0)
 #endif
 
@@ -285,7 +285,7 @@ int board_nand_init(struct nand_chip *nand)
        nand->dev_ready         = s3c_nand_device_ready;
        nand->select_chip       = s3c_nand_select_chip;
        nand->options           = 0;
-#ifdef CONFIG_NAND_SPL
+#ifdef CONFIG_SPL_BUILD
        nand->read_byte         = nand_read_byte;
        nand->write_buf         = nand_write_buf;
        nand->read_buf          = nand_read_buf;
diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h
index d85ddeb..c63aef8 100644
--- a/include/configs/smdk6400.h
+++ b/include/configs/smdk6400.h
@@ -238,11 +238,10 @@
 #define CONFIG_SYS_NAND_YAFFS_WRITE    1  /* support yaffs write               
      */
 #define CONFIG_SYS_NAND_BBT_2NDPAGE    1  /* bad-block markers in 1st and 2nd 
pages  */
 
-#define CONFIG_SYS_NAND_U_BOOT_DST     CONFIG_SYS_PHY_UBOOT_BASE       /* NUB 
load-addr      */
-#define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_NAND_U_BOOT_DST      /* NUB 
start-addr     */
-
-#define CONFIG_SYS_NAND_U_BOOT_OFFS    (4 * 1024)      /* Offset to RAM U-Boot 
image */
-#define CONFIG_SYS_NAND_U_BOOT_SIZE    (252 * 1024)    /* Size of RAM U-Boot 
image   */
+/* Offset to RAM U-Boot image */
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    (16 * 1024)
+/* Size of RAM U-Boot image   */
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    (252 * 1024)
 
 /* NAND chip page size         */
 #define CONFIG_SYS_NAND_PAGE_SIZE      2048
@@ -266,8 +265,6 @@
                                 48, 49, 50, 51, 52, 53, 54, 55, \
                                 56, 57, 58, 59, 60, 61, 62, 63}
 
-/* Boot configuration (define only one of next 3) */
-#define CONFIG_BOOT_NAND
 /* None of these are currently implemented. Left from the original Samsung
  * version for reference
 #define CONFIG_BOOT_NOR
@@ -275,7 +272,15 @@
 #define CONFIG_BOOT_ONENAND
 */
 
-#define CONFIG_NAND
+#define CONFIG_SPL
+#define CONFIG_SPL_NAND
+#define CONFIG_SPL_NAND_SIMPLE
+#define CONFIG_SPL_NAND_SUPPORT
+
+#define CONFIG_SPL_TEXT_BASE   0x0
+#define CONFIG_SPL_STACK  CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_MALLOC_LEN
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+
 #define CONFIG_NAND_S3C64XX
 /* Unimplemented or unsupported. See comment above.
 #define CONFIG_ONENAND
-- 
1.7.5.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to