diff mbox

[U-Boot,PATCHv3,4/4] igep00x0: UBIize

Message ID 20160112232405.GA23708@localhost.localdomain
State Superseded
Headers show

Commit Message

Ladislav Michl Jan. 12, 2016, 11:24 p.m. UTC
Hi Heiko,

just one more thing I forgot to mention...

On Tue, Jan 12, 2016 at 10:08:21AM +0100, Heiko Schocher wrote:
> Am 11.01.2016 um 13:58 schrieb Ladislav Michl:
[...]
> >All that ubispl_info structure is board specific and there is not much left
> >besides initializing it. Also volumes can differ per board basis, so
> >providing common function is somewhat questionable. However here it is,
> >just to show how does it look like. Suggestions are very welcome as silence
> >around this part of patch is a bit suspicious ;-)
> 
> Questions are coming if there are users ;-)
> 
> I vote for bringing this in, and we will see, where we have to make
> things more configurable ... some nitpicks below ...

I wouldn't make payload loading function completely board specific as we
would face danger of copying similar pattern over and over for every board
wanting to support ubispl without anyone even considering consolidation.
History of U-Boot proves that happens :) So lets's make payload loading
function decently generic which will force users to improve it and
eventuelly provide their own as a last option. Also let's not pretend
code works on anything but NAND, so patch would boil down to something
like this:

commit 9fd0671cb68e14d3238867173a8ecdaf0f4695af
Author: Ladislav Michl <ladis@linux-mips.org>
Date:   Mon Jan 11 13:08:10 2016 +0100

    spl: support loading from UBI volumes
    
    Add support for loading from UBI volumes on the top of NAND.
    
    Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
diff mbox

Patch

diff --git a/common/spl/Makefile b/common/spl/Makefile
index 10a4589..36e5338 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -12,8 +12,11 @@  ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
 obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o
+ifndef CONFIG_SPL_UBI
 obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o
+endif
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o
+obj-$(CONFIG_SPL_UBI) += spl_ubi.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o
 obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o
 obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 6e6dee7..7665105 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -288,8 +288,12 @@  static int spl_load_image(u32 boot_device)
 #endif
 #ifdef CONFIG_SPL_NAND_SUPPORT
 	case BOOT_DEVICE_NAND:
+#ifdef CONFIG_SPL_UBI
+		return spl_ubi_load_image(boot_device);
+#else
 		return spl_nand_load_image();
 #endif
+#endif
 #ifdef CONFIG_SPL_ONENAND_SUPPORT
 	case BOOT_DEVICE_ONENAND:
 		return spl_onenand_load_image();
diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c
new file mode 100644
index 0000000..7b6eb31
--- /dev/null
+++ b/common/spl/spl_ubi.c
@@ -0,0 +1,71 @@ 
+/*
+ * Copyright (C) 2016
+ * Ladislav Michl <ladis@linux-mips.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <config.h>
+#include <nand.h>
+#include <ubispl.h>
+#include <spl.h>
+
+int spl_ubi_load_image(u32 boot_device)
+{
+	int ret;
+	struct image_header *header;
+	struct ubispl_info info;
+	struct ubispl_load volumes[2];
+
+#ifdef CONFIG_SPL_NAND_SUPPORT
+	if (boot_device == BOOT_DEVICE_NAND)
+		nand_init();
+#endif
+	info.ubi = (struct ubi_scan_info *) CONFIG_SPL_UBI_INFO_ADDR;
+	info.fastmap = 1;
+	info.read = nand_spl_read_block;
+
+	info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET;
+	info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE;
+	info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET;
+	info.leb_start = CONFIG_SPL_UBI_LEB_START;
+	info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset;
+
+#ifdef CONFIG_SPL_OS_BOOT
+	if (!spl_start_uboot()) {
+		volumes[0].name = "kernel";
+		volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID;
+		volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR;
+		volumes[1].name = "args";
+		volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID;
+		volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+
+		ret = ubispl_load_volumes(&info, volumes, 2);
+		if (!ret) {
+			header = (struct image_header *) volumes[0].load_addr;
+			spl_parse_image_header(header);
+			puts("Linux loaded.\n");
+			goto out;
+		}
+		puts("Loading Linux failed, falling back to U-Boot.\n");
+	}
+#endif
+	header = (struct image_header *)
+		(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header));
+	volumes[0].name = "monitor";
+	volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID;
+	volumes[0].load_addr = (void *)header;
+
+	ret = ubispl_load_volumes(&info, volumes, 1);
+	if (!ret)
+		spl_parse_image_header(header);
+#ifdef CONFIG_SPL_OS_BOOT
+out:
+#endif
+#ifdef CONFIG_SPL_NAND_SUPPORT
+	if (boot_device == BOOT_DEVICE_NAND)
+		nand_deselect();
+#endif
+	return ret;
+}
diff --git a/include/spl.h b/include/spl.h
index 92cdc04..1ab9295 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -40,6 +40,7 @@  u32 spl_boot_mode(void);
 void spl_set_header_raw_uboot(void);
 void spl_parse_image_header(const struct image_header *header);
 void spl_board_prepare_for_linux(void);
+int spl_board_ubi_load_image(u32 boot_device);
 void __noreturn jump_to_image_linux(void *arg);
 int spl_start_uboot(void);
 void spl_display_print(void);
@@ -53,6 +54,9 @@  int spl_onenand_load_image(void);
 /* NOR SPL functions */
 int spl_nor_load_image(void);
 
+/* UBI SPL functions */
+int spl_ubi_load_image(u32 boot_device);
+
 /* MMC SPL functions */
 int spl_mmc_load_image(u32 boot_device);