Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2011 OMICRON electronics GmbH * * based on drivers/mtd/nand/raw/nand_spl_load.c * * Copyright (C) 2011 * Heiko Schocher, DENX Software Engineering, hs@denx.de. */ #include <common.h> #include <image.h> #include <log.h> #include <spi.h> #include <spi_flash.h> #include <errno.h> #include <spl.h> DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_SPL_OS_BOOT /* * Load the kernel, check for a valid header we can parse, and if found load * the kernel and then device tree. */ static int spi_load_image_os(struct spl_image_info *spl_image, struct spi_flash *flash, struct image_header *header) { int err; /* Read for a header, parse or error out. */ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, sizeof(*header), (void *)header); if (image_get_magic(header) != IH_MAGIC) return -1; err = spl_parse_image_header(spl_image, header); if (err) return err; spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, spl_image->size, (void *)spl_image->load_addr); /* Read device tree. */ spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS, CONFIG_SYS_SPI_ARGS_SIZE, (void *)CONFIG_SYS_SPL_ARGS_ADDR); return 0; } #endif static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { struct spi_flash *flash = load->dev; ulong ret; ret = spi_flash_read(flash, sector, count, buf); if (!ret) return count; else return 0; } unsigned int __weak spl_spi_get_uboot_offs(struct spi_flash *flash) { return CONFIG_SYS_SPI_U_BOOT_OFFS; } /* * The main entry for SPI booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image * from SPI into SDRAM and starts it from there. */ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int err = 0; unsigned int payload_offs; struct spi_flash *flash; struct image_header *header; /* * Load U-Boot image from SPI flash into RAM * In DM mode: defaults speed and mode will be * taken from DT when available */ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { puts("SPI probe failed.\n"); return -ENODEV; } payload_offs = spl_spi_get_uboot_offs(flash); header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) payload_offs = fdtdec_get_config_int(gd->fdt_blob, "u-boot,spl-payload-offset", payload_offs); #endif #ifdef CONFIG_SPL_OS_BOOT if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header)) #endif { /* Load u-boot, mkimage header is 64 bytes. */ err = spi_flash_read(flash, payload_offs, sizeof(*header), (void *)header); if (err) { debug("%s: Failed to read from SPI flash (err=%d)\n", __func__, err); return err; } if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && image_get_magic(header) == FDT_MAGIC) { err = spi_flash_read(flash, payload_offs, roundup(fdt_totalsize(header), 4), (void *)CONFIG_SYS_LOAD_ADDR); if (err) return err; err = spl_parse_image_header(spl_image, (struct image_header *)CONFIG_SYS_LOAD_ADDR); } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.dev = flash; load.priv = NULL; load.filename = NULL; load.bl_len = 1; load.read = spl_spi_fit_read; err = spl_load_simple_fit(spl_image, &load, payload_offs, header); } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { struct spl_load_info load; load.dev = flash; load.priv = NULL; load.filename = NULL; load.bl_len = 1; load.read = spl_spi_fit_read; err = spl_load_imx_container(spl_image, &load, payload_offs); } else { err = spl_parse_image_header(spl_image, header); if (err) return err; err = spi_flash_read(flash, payload_offs, spl_image->size, (void *)spl_image->load_addr); } } return err; } /* Use priorty 1 so that boards can override this */ SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image); |