[U-Boot] [V2 08/15] S3C6400: Adopt SPL framwork to support spl for nand flash
Zhong Hongbo
bocui107 at gmail.com
Fri Jul 13 18:11:46 CEST 2012
From: Zhong Hongbo <bocui107 at gmail.com>
Adopt the new SPL framework to implement the SPL booting of
the nand flash for S3C6400.
Signed-off-by: Zhong Hongbo <bocui107 at gmail.com>
---
Change for V2:
- seprate some code.
---
arch/arm/cpu/arm1176/start.S | 16 +---
board/samsung/smdk6400/Makefile | 29 +++++-
board/samsung/smdk6400/lowlevel_init.S | 18 ++--
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, 219 insertions(+), 47 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 848144a..26a3533 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
*/
@@ -356,21 +356,14 @@ clbss_l:str r2, [r0] /* clear loop... */
cmp r0, r1
bne clbss_l
-#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
@@ -383,7 +376,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
@@ -397,7 +389,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
@@ -575,4 +567,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 1142be1..6cc7567 100644
--- a/board/samsung/smdk6400/lowlevel_init.S
+++ b/board/samsung/smdk6400/lowlevel_init.S
@@ -83,18 +83,12 @@ lowlevel_init:
str r3, [r0, #oVECTADDR]
str r3, [r1, #oVECTADDR]
+#ifdef CONFIG_SPL_BUILD
/* init system clock */
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
/* Memory subsystem address 0x7e00f120 */
ldr r0, =ELFIN_MEM_SYS_CFG
@@ -104,6 +98,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)
@@ -243,7 +243,7 @@ wait_for_async:
mov pc, lr
-#ifndef CONFIG_NAND_SPL
+#ifndef CONFIG_SPL_BUILD
/*
* uart_asm_init: Initialize UART's pins
*/
@@ -255,7 +255,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 <mgroeger at sysgo.de>
- *
- * (C) Copyright 2002
- * David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
- *
- * (C) Copyright 2008
- * Guennadi Liakhovetki, DENX Software Engineering, <lg at denx.de>
+ * Copyright (C) 2012
+ * Zhong Hongbo <bocui107 at 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 06b85bf..632ecb7 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 0xd0020000
+#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
More information about the U-Boot
mailing list