summaryrefslogtreecommitdiffstats
path: root/qemu/roms/u-boot/common/spl/spl_mmc.c
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/common/spl/spl_mmc.c
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/common/spl/spl_mmc.c')
-rw-r--r--qemu/roms/u-boot/common/spl/spl_mmc.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/common/spl/spl_mmc.c b/qemu/roms/u-boot/common/spl/spl_mmc.c
new file mode 100644
index 000000000..fa6f891bc
--- /dev/null
+++ b/qemu/roms/u-boot/common/spl/spl_mmc.c
@@ -0,0 +1,147 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <spl.h>
+#include <asm/u-boot.h>
+#include <mmc.h>
+#include <version.h>
+#include <image.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
+{
+ unsigned long err;
+ u32 image_size_sectors;
+ struct image_header *header;
+
+ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+ sizeof(struct image_header));
+
+ /* read image header to find the image size & load address */
+ err = mmc->block_dev.block_read(0, sector, 1, header);
+ if (err == 0)
+ goto end;
+
+ if (image_get_magic(header) != IH_MAGIC)
+ return -1;
+
+ spl_parse_image_header(header);
+
+ /* convert size to sectors - round up */
+ image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
+ mmc->read_bl_len;
+
+ /* Read the header too to avoid extra memcpy */
+ err = mmc->block_dev.block_read(0, sector, image_size_sectors,
+ (void *)spl_image.load_addr);
+
+end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ if (err == 0)
+ printf("spl: mmc blk read err - %lu\n", err);
+#endif
+
+ return (err == 0);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+static int mmc_load_image_raw_os(struct mmc *mmc)
+{
+ if (!mmc->block_dev.block_read(0,
+ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
+ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("mmc args blk read error\n");
+#endif
+ return -1;
+ }
+
+ return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
+}
+#endif
+
+void spl_mmc_load_image(void)
+{
+ struct mmc *mmc;
+ int err;
+ u32 boot_mode;
+
+ mmc_initialize(gd->bd);
+ /* We register only one device. So, the dev id is always 0 */
+ mmc = find_mmc_device(0);
+ if (!mmc) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("spl: mmc device not found!!\n");
+#endif
+ hang();
+ }
+
+ err = mmc_init(mmc);
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: mmc init failed: err - %d\n", err);
+#endif
+ hang();
+ }
+
+ boot_mode = spl_boot_mode();
+ if (boot_mode == MMCSD_MODE_RAW) {
+ debug("boot mode - RAW\n");
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
+#endif
+ err = mmc_load_image_raw(mmc,
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+#ifdef CONFIG_SPL_FAT_SUPPORT
+ } else if (boot_mode == MMCSD_MODE_FAT) {
+ debug("boot mode - FAT\n");
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev,
+ CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION))
+#endif
+ err = spl_load_image_fat(&mmc->block_dev,
+ CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION,
+ CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
+#endif
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ } else if (boot_mode == MMCSD_MODE_EMMCBOOT) {
+ /*
+ * We need to check what the partition is configured to.
+ * 1 and 2 match up to boot0 / boot1 and 7 is user data
+ * which is the first physical partition (0).
+ */
+ int part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
+
+ if (part == 7)
+ part = 0;
+
+ if (mmc_switch_part(0, part)) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("MMC partition switch failed\n");
+#endif
+ hang();
+ }
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
+#endif
+ err = mmc_load_image_raw(mmc,
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+#endif
+ } else {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("spl: wrong MMC boot mode\n");
+#endif
+ hang();
+ }
+
+ if (err)
+ hang();
+}