From: Tien Fong Chee <tien.fong.c...@intel.com>

Generic firmware loader framework contains some common functionality
which is reusable by any specific file system firmware loader.

Signed-off-by: Tien Fong Chee <tien.fong.c...@intel.com>
---
 common/Makefile   |   2 +
 common/load_fs.c  | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/load_fs.h |  40 ++++++++++++++
 3 files changed, 205 insertions(+)
 create mode 100644 common/load_fs.c
 create mode 100644 include/load_fs.h

diff --git a/common/Makefile b/common/Makefile
index 801ea31..0e591c0 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -130,3 +130,5 @@ obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-y += command.o
 obj-y += s_record.o
 obj-y += xyzModem.o
+
+obj-y += load_fs.o
diff --git a/common/load_fs.c b/common/load_fs.c
new file mode 100644
index 0000000..9f9ca88
--- /dev/null
+++ b/common/load_fs.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fs.h>
+#include <fdt_support.h>
+#include <load_fs.h>
+#include <nand.h>
+#include <sata.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <usb.h>
+
+int flash_select_fs_dev(struct flash_location *location)
+{
+       int res;
+
+       switch (location->storage) {
+       case FLASH_STORAGE_MMC:
+               res = fs_set_blk_dev("mmc", location->devpart, FS_TYPE_ANY);
+               break;
+       case FLASH_STORAGE_USB:
+               res = fs_set_blk_dev("usb", location->devpart, FS_TYPE_ANY);
+               break;
+       case FLASH_STORAGE_SATA:
+               res = fs_set_blk_dev("sata", location->devpart, FS_TYPE_ANY);
+               break;
+       case FLASH_STORAGE_NAND:
+               if (location->ubivol != NULL)
+                       res = fs_set_blk_dev("ubi", NULL, FS_TYPE_UBIFS);
+               else
+                       res = -ENODEV;
+               break;
+       default:
+               printf("Error: unsupported location storage.\n");
+               return -ENODEV;
+       }
+
+       if (res)
+               printf("Error: could not access storage.\n");
+
+       return res;
+}
+#ifndef CONFIG_SPL_BUILD
+#ifdef CONFIG_USB_STORAGE
+static int flash_init_usb(void)
+{
+       int err;
+
+       err = usb_init();
+       if (err)
+               return err;
+
+#ifndef CONFIG_DM_USB
+       err = usb_stor_scan(1) < 0 ? -ENODEV : 0;
+#endif
+
+       return err;
+}
+#else
+static inline int flash_init_usb(void)
+{
+       printf("Cannot load flash image: no USB support\n");
+       return -ENOSYS;
+}
+#endif
+#endif
+
+#ifdef CONFIG_SATA
+static int flash_init_sata(void)
+{
+       return sata_probe(0);
+}
+#else
+static inline int flash_init_sata(void)
+{
+       printf("Cannot load flash image: no SATA support\n");
+       return -ENOSYS;
+}
+#endif
+
+#ifdef CONFIG_CMD_UBIFS
+static int flash_mount_ubifs(struct flash_location *location)
+{
+       int res;
+       char cmd[32];
+
+       sprintf(cmd, "ubi part %s", location->mtdpart);
+       res = run_command(cmd, 0);
+       if (res)
+               return res;
+
+       sprintf(cmd, "ubifsmount %s", location->ubivol);
+       res = run_command(cmd, 0);
+
+       return res;
+}
+
+static inline int flash_umount_ubifs(void)
+{
+       return run_command("ubifsumount", 0);
+}
+#else
+static inline int flash_mount_ubifs(struct flash_location *location)
+{
+       printf("Cannot load flash image: no UBIFS support\n");
+       return -ENOSYS;
+}
+
+static inline int flash_umount_ubifs(void)
+{
+       printf("Cannot unmount UBIFS: no UBIFS support\n");
+       return -ENOSYS;
+}
+#endif
+
+__weak char *get_file(void *file_info)
+{
+       return NULL;
+}
+
+__weak int fs_loading(void *file_info, const void *load_addr, size_t bsize)
+{
+       return 0;
+}
+
+int load_fs(struct flash_location *location, void *file_info,
+               const void *load_addr, size_t bsize)
+{
+       int res = 0;
+       char *flash_file;
+
+       flash_file = get_file(file_info);
+       if (!flash_file) {
+               printf("no filename specified.\n");
+               return -EINVAL;
+       }
+
+#ifndef CONFIG_SPL_BUILD
+       if (location->storage == FLASH_STORAGE_USB)
+               res = flash_init_usb();
+#endif
+
+       if (location->storage == FLASH_STORAGE_SATA)
+               res = flash_init_sata();
+
+       if (location->ubivol != NULL)
+               res = flash_mount_ubifs(location);
+
+       if (res)
+               return res;
+
+       res = fs_loading(file_info, load_addr, bsize);
+
+       if (location->ubivol != NULL)
+               flash_umount_ubifs();
+
+       return res;
+}
diff --git a/include/load_fs.h b/include/load_fs.h
new file mode 100644
index 0000000..a26d630
--- /dev/null
+++ b/include/load_fs.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+
+#ifndef _LOAD_FS_H_
+#define _LOAD_FS_H_
+
+#include <errno.h>
+
+enum flash_storage {
+       FLASH_STORAGE_NAND,
+       FLASH_STORAGE_SF,
+       FLASH_STORAGE_MMC,
+       FLASH_STORAGE_USB,
+       FLASH_STORAGE_SATA,
+};
+
+enum flash_flags {
+       FLASH_STORAGE_RAW, /* Stored in raw memory */
+       FLASH_STORAGE_FS,  /* Stored within a file system */
+       FLASH_STORAGE_FIT, /* Stored inside a FIT image */
+};
+
+struct flash_location {
+       char *name;
+       enum flash_storage storage;
+       enum flash_flags flags;
+       u32 offset;     /* offset from start of storage */
+       char *devpart;  /* Use the load command dev:part conventions */
+       char *mtdpart;  /* MTD partition for ubi part */
+       char *ubivol;   /* UBI volume-name for ubifsmount */
+};
+
+int load_fs(struct flash_location *location, void *file_info,
+                               const void *load_addr, size_t bsize);
+int flash_select_fs_dev(struct flash_location *location);
+#endif
-- 
2.2.0

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

Reply via email to