Blame view
common/splash_source.c
9.79 KB
f4a40f05f omap3: cm-t35: ex... |
1 2 3 4 5 6 7 8 9 |
/* * (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il> * * Authors: Igor Grinberg <grinberg@compulab.co.il> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> |
7583f1f57 splash: sort incl... |
10 |
#include <bmp_layout.h> |
6947e3f56 compulab: splash:... |
11 |
#include <errno.h> |
7583f1f57 splash: sort incl... |
12 |
#include <fs.h> |
db1b79b88 splash: add suppo... |
13 |
#include <fdt_support.h> |
7583f1f57 splash: sort incl... |
14 15 16 |
#include <image.h> #include <nand.h> #include <sata.h> |
7e8d7f2ac compulab: splash:... |
17 |
#include <spi.h> |
7583f1f57 splash: sort incl... |
18 19 |
#include <spi_flash.h> #include <splash.h> |
9bb4e9474 splash_source: ad... |
20 |
#include <usb.h> |
f4a40f05f omap3: cm-t35: ex... |
21 22 |
DECLARE_GLOBAL_DATA_PTR; |
7e8d7f2ac compulab: splash:... |
23 24 |
#ifdef CONFIG_SPI_FLASH static struct spi_flash *sf; |
bcbb6448b splash_source: re... |
25 |
static int splash_sf_read_raw(u32 bmp_load_addr, int offset, size_t read_size) |
7e8d7f2ac compulab: splash:... |
26 27 28 29 30 31 32 33 34 35 36 37 38 |
{ if (!sf) { sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!sf) return -ENODEV; } return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr); } #else |
bcbb6448b splash_source: re... |
39 |
static int splash_sf_read_raw(u32 bmp_load_addr, int offset, size_t read_size) |
7e8d7f2ac compulab: splash:... |
40 41 42 43 44 45 |
{ debug("%s: sf support not available ", __func__); return -ENOSYS; } #endif |
f4a40f05f omap3: cm-t35: ex... |
46 |
#ifdef CONFIG_CMD_NAND |
bcbb6448b splash_source: re... |
47 |
static int splash_nand_read_raw(u32 bmp_load_addr, int offset, size_t read_size) |
7be4cd2cc compulab: splash:... |
48 |
{ |
edba8cc4f common: use get_n... |
49 50 |
struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device); return nand_read_skip_bad(mtd, offset, |
7be4cd2cc compulab: splash:... |
51 |
&read_size, NULL, |
edba8cc4f common: use get_n... |
52 |
mtd->size, |
7be4cd2cc compulab: splash:... |
53 54 55 |
(u_char *)bmp_load_addr); } #else |
bcbb6448b splash_source: re... |
56 |
static int splash_nand_read_raw(u32 bmp_load_addr, int offset, size_t read_size) |
7be4cd2cc compulab: splash:... |
57 58 59 60 61 62 |
{ debug("%s: nand support not available ", __func__); return -ENOSYS; } #endif |
bcbb6448b splash_source: re... |
63 |
static int splash_storage_read_raw(struct splash_location *location, |
fd29dd554 compulab: splash:... |
64 |
u32 bmp_load_addr, size_t read_size) |
7be4cd2cc compulab: splash:... |
65 |
{ |
fd29dd554 compulab: splash:... |
66 67 68 69 70 71 72 73 |
u32 offset; if (!location) return -EINVAL; offset = location->offset; switch (location->storage) { case SPLASH_STORAGE_NAND: |
bcbb6448b splash_source: re... |
74 |
return splash_nand_read_raw(bmp_load_addr, offset, read_size); |
7e8d7f2ac compulab: splash:... |
75 |
case SPLASH_STORAGE_SF: |
bcbb6448b splash_source: re... |
76 |
return splash_sf_read_raw(bmp_load_addr, offset, read_size); |
fd29dd554 compulab: splash:... |
77 78 79 80 81 82 |
default: printf("Unknown splash location "); } return -EINVAL; |
7be4cd2cc compulab: splash:... |
83 |
} |
fd29dd554 compulab: splash:... |
84 |
static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr) |
f4a40f05f omap3: cm-t35: ex... |
85 86 87 88 89 90 91 |
{ struct bmp_header *bmp_hdr; int res; size_t bmp_size, bmp_header_size = sizeof(struct bmp_header); if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) goto splash_address_too_high; |
bcbb6448b splash_source: re... |
92 |
res = splash_storage_read_raw(location, bmp_load_addr, bmp_header_size); |
f4a40f05f omap3: cm-t35: ex... |
93 94 95 96 97 98 99 100 |
if (res < 0) return res; bmp_hdr = (struct bmp_header *)bmp_load_addr; bmp_size = le32_to_cpu(bmp_hdr->file_size); if (bmp_load_addr + bmp_size >= gd->start_addr_sp) goto splash_address_too_high; |
bcbb6448b splash_source: re... |
101 |
return splash_storage_read_raw(location, bmp_load_addr, bmp_size); |
f4a40f05f omap3: cm-t35: ex... |
102 103 |
splash_address_too_high: |
f82eb2fa5 common: convert c... |
104 105 |
printf("Error: splashimage address too high. Data overwrites U-Boot and/or placed beyond DRAM boundaries. "); |
f4a40f05f omap3: cm-t35: ex... |
106 |
|
6947e3f56 compulab: splash:... |
107 |
return -EFAULT; |
f4a40f05f omap3: cm-t35: ex... |
108 |
} |
f4a40f05f omap3: cm-t35: ex... |
109 |
|
870dd3095 splash_source: ad... |
110 111 112 113 114 115 116 117 |
static int splash_select_fs_dev(struct splash_location *location) { int res; switch (location->storage) { case SPLASH_STORAGE_MMC: res = fs_set_blk_dev("mmc", location->devpart, FS_TYPE_ANY); break; |
9bb4e9474 splash_source: ad... |
118 119 120 |
case SPLASH_STORAGE_USB: res = fs_set_blk_dev("usb", location->devpart, FS_TYPE_ANY); break; |
50c2d2e12 splash_source: ad... |
121 122 123 |
case SPLASH_STORAGE_SATA: res = fs_set_blk_dev("sata", location->devpart, FS_TYPE_ANY); break; |
1cb075c6c splash_source: ad... |
124 125 126 127 128 129 |
case SPLASH_STORAGE_NAND: if (location->ubivol != NULL) res = fs_set_blk_dev("ubi", NULL, FS_TYPE_UBIFS); else res = -ENODEV; break; |
870dd3095 splash_source: ad... |
130 131 132 133 134 135 136 137 138 139 140 141 |
default: printf("Error: unsupported location storage. "); return -ENODEV; } if (res) printf("Error: could not access storage. "); return res; } |
9bb4e9474 splash_source: ad... |
142 143 144 145 146 147 148 149 |
#ifdef CONFIG_USB_STORAGE static int splash_init_usb(void) { int err; err = usb_init(); if (err) return err; |
d7b60fbfa splash: Accommoda... |
150 151 152 153 154 |
#ifndef CONFIG_DM_USB err = usb_stor_scan(1) < 0 ? -ENODEV : 0; #endif return err; |
9bb4e9474 splash_source: ad... |
155 156 157 158 159 160 161 162 163 |
} #else static inline int splash_init_usb(void) { printf("Cannot load splash image: no USB support "); return -ENOSYS; } #endif |
10e40d54b Kconfig: Add CONF... |
164 |
#ifdef CONFIG_SATA |
50c2d2e12 splash_source: ad... |
165 166 |
static int splash_init_sata(void) { |
f19f1ecb6 dm: sata: Support... |
167 |
return sata_probe(0); |
50c2d2e12 splash_source: ad... |
168 169 170 171 172 173 174 175 176 |
} #else static inline int splash_init_sata(void) { printf("Cannot load splash image: no SATA support "); return -ENOSYS; } #endif |
1cb075c6c splash_source: ad... |
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
#ifdef CONFIG_CMD_UBIFS static int splash_mount_ubifs(struct splash_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 splash_umount_ubifs(void) { return run_command("ubifsumount", 0); } #else static inline int splash_mount_ubifs(struct splash_location *location) { printf("Cannot load splash image: no UBIFS support "); return -ENOSYS; } static inline int splash_umount_ubifs(void) { printf("Cannot unmount UBIFS: no UBIFS support "); return -ENOSYS; } #endif |
870dd3095 splash_source: ad... |
213 214 215 216 |
#define SPLASH_SOURCE_DEFAULT_FILE_NAME "splash.bmp" static int splash_load_fs(struct splash_location *location, u32 bmp_load_addr) { |
9bb4e9474 splash_source: ad... |
217 |
int res = 0; |
870dd3095 splash_source: ad... |
218 |
loff_t bmp_size; |
3cc6e7070 splash: Prevent s... |
219 |
loff_t actread; |
870dd3095 splash_source: ad... |
220 |
char *splash_file; |
00caae6d4 env: Rename geten... |
221 |
splash_file = env_get("splashfile"); |
870dd3095 splash_source: ad... |
222 223 |
if (!splash_file) splash_file = SPLASH_SOURCE_DEFAULT_FILE_NAME; |
9bb4e9474 splash_source: ad... |
224 225 |
if (location->storage == SPLASH_STORAGE_USB) res = splash_init_usb(); |
50c2d2e12 splash_source: ad... |
226 227 |
if (location->storage == SPLASH_STORAGE_SATA) res = splash_init_sata(); |
1cb075c6c splash_source: ad... |
228 229 |
if (location->ubivol != NULL) res = splash_mount_ubifs(location); |
9bb4e9474 splash_source: ad... |
230 231 |
if (res) return res; |
870dd3095 splash_source: ad... |
232 233 |
res = splash_select_fs_dev(location); if (res) |
1cb075c6c splash_source: ad... |
234 |
goto out; |
870dd3095 splash_source: ad... |
235 236 237 238 239 |
res = fs_size(splash_file, &bmp_size); if (res) { printf("Error (%d): cannot determine file size ", res); |
1cb075c6c splash_source: ad... |
240 |
goto out; |
870dd3095 splash_source: ad... |
241 242 243 244 245 |
} if (bmp_load_addr + bmp_size >= gd->start_addr_sp) { printf("Error: splashimage address too high. Data overwrites U-Boot and/or placed beyond DRAM boundaries. "); |
1cb075c6c splash_source: ad... |
246 247 |
res = -EFAULT; goto out; |
870dd3095 splash_source: ad... |
248 249 250 |
} splash_select_fs_dev(location); |
3cc6e7070 splash: Prevent s... |
251 |
res = fs_read(splash_file, bmp_load_addr, 0, 0, &actread); |
1cb075c6c splash_source: ad... |
252 253 254 255 256 257 |
out: if (location->ubivol != NULL) splash_umount_ubifs(); return res; |
870dd3095 splash_source: ad... |
258 |
} |
fd29dd554 compulab: splash:... |
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
/** * select_splash_location - return the splash location based on board support * and env variable "splashsource". * * @locations: An array of supported splash locations. * @size: Size of splash_locations array. * * @return: If a null set of splash locations is given, or * splashsource env variable is set to unsupported value * return NULL. * If splashsource env variable is not defined * return the first entry in splash_locations as default. * If splashsource env variable contains a supported value * return the location selected by splashsource. */ static struct splash_location *select_splash_location( struct splash_location *locations, uint size) { int i; char *env_splashsource; if (!locations || size == 0) return NULL; |
00caae6d4 env: Rename geten... |
282 |
env_splashsource = env_get("splashsource"); |
fd29dd554 compulab: splash:... |
283 284 285 286 287 288 289 290 291 292 293 294 |
if (env_splashsource == NULL) return &locations[0]; for (i = 0; i < size; i++) { if (!strcmp(locations[i].name, env_splashsource)) return &locations[i]; } printf("splashsource env variable set to unsupported value "); return NULL; } |
db1b79b88 splash: add suppo... |
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
#ifdef CONFIG_FIT static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) { int res; int node_offset; int splash_offset; int splash_size; struct image_header *img_header; const u32 *fit_header; u32 fit_size; const size_t header_size = sizeof(struct image_header); /* Read in image header */ res = splash_storage_read_raw(location, bmp_load_addr, header_size); if (res < 0) return res; img_header = (struct image_header *)bmp_load_addr; |
a7126edcb splash_source: Ve... |
313 314 315 316 317 |
if (image_get_magic(img_header) != FDT_MAGIC) { printf("Could not find FDT magic "); return -EINVAL; } |
db1b79b88 splash: add suppo... |
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
fit_size = fdt_totalsize(img_header); /* Read in entire FIT */ fit_header = (const u32 *)(bmp_load_addr + header_size); res = splash_storage_read_raw(location, (u32)fit_header, fit_size); if (res < 0) return res; res = fit_check_format(fit_header); if (!res) { debug("Could not find valid FIT image "); return -EINVAL; } node_offset = fit_image_get_node(fit_header, location->name); if (node_offset < 0) { debug("Could not find splash image '%s' in FIT ", location->name); return -ENOENT; } res = fit_image_get_data_offset(fit_header, node_offset, &splash_offset); if (res < 0) { printf("Failed to load splash image (err=%d) ", res); return res; } res = fit_image_get_data_size(fit_header, node_offset, &splash_size); if (res < 0) { printf("Failed to load splash image (err=%d) ", res); return res; } /* Align data offset to 4-byte boundrary */ fit_size = fdt_totalsize(fit_header); fit_size = (fit_size + 3) & ~3; /* Read in the splash data */ location->offset = (location->offset + fit_size + splash_offset); res = splash_storage_read_raw(location, bmp_load_addr , splash_size); if (res < 0) return res; return 0; } #endif /* CONFIG_FIT */ |
f82eb2fa5 common: convert c... |
369 370 371 372 373 374 375 376 377 378 379 380 381 |
/** * splash_source_load - load splash image from a supported location. * * Select a splash image location based on the value of splashsource environment * variable and the board supported splash source locations, and load a * splashimage to the address pointed to by splashimage environment variable. * * @locations: An array of supported splash locations. * @size: Size of splash_locations array. * * @return: 0 on success, negative value on failure. */ int splash_source_load(struct splash_location *locations, uint size) |
f4a40f05f omap3: cm-t35: ex... |
382 |
{ |
fd29dd554 compulab: splash:... |
383 |
struct splash_location *splash_location; |
f4a40f05f omap3: cm-t35: ex... |
384 385 |
char *env_splashimage_value; u32 bmp_load_addr; |
00caae6d4 env: Rename geten... |
386 |
env_splashimage_value = env_get("splashimage"); |
f4a40f05f omap3: cm-t35: ex... |
387 |
if (env_splashimage_value == NULL) |
6947e3f56 compulab: splash:... |
388 |
return -ENOENT; |
f4a40f05f omap3: cm-t35: ex... |
389 390 391 392 393 |
bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16); if (bmp_load_addr == 0) { printf("Error: bad splashimage address specified "); |
6947e3f56 compulab: splash:... |
394 |
return -EFAULT; |
f4a40f05f omap3: cm-t35: ex... |
395 |
} |
fd29dd554 compulab: splash:... |
396 397 398 |
splash_location = select_splash_location(locations, size); if (!splash_location) return -EINVAL; |
3b593f903 splash: fix splas... |
399 |
if (splash_location->flags == SPLASH_STORAGE_RAW) |
870dd3095 splash_source: ad... |
400 |
return splash_load_raw(splash_location, bmp_load_addr); |
3b593f903 splash: fix splas... |
401 |
else if (splash_location->flags == SPLASH_STORAGE_FS) |
870dd3095 splash_source: ad... |
402 |
return splash_load_fs(splash_location, bmp_load_addr); |
db1b79b88 splash: add suppo... |
403 404 405 406 |
#ifdef CONFIG_FIT else if (splash_location->flags == SPLASH_STORAGE_FIT) return splash_load_fit(splash_location, bmp_load_addr); #endif |
870dd3095 splash_source: ad... |
407 |
return -EINVAL; |
f4a40f05f omap3: cm-t35: ex... |
408 |
} |