1773b5940SDan Murphy /* 2773b5940SDan Murphy * (C) Copyright 2014 3773b5940SDan Murphy * Texas Instruments, <www.ti.com> 4773b5940SDan Murphy * 5773b5940SDan Murphy * Dan Murphy <dmurphy@ti.com> 6773b5940SDan Murphy * 7773b5940SDan Murphy * SPDX-License-Identifier: GPL-2.0+ 8773b5940SDan Murphy * 9773b5940SDan Murphy * FAT Image Functions copied from spl_mmc.c 10773b5940SDan Murphy */ 11773b5940SDan Murphy 12773b5940SDan Murphy #include <common.h> 13773b5940SDan Murphy #include <spl.h> 14773b5940SDan Murphy #include <asm/u-boot.h> 15773b5940SDan Murphy #include <fat.h> 16339245b7SNikita Kiryanov #include <errno.h> 17773b5940SDan Murphy #include <image.h> 18*0e00a84cSMasahiro Yamada #include <linux/libfdt.h> 19773b5940SDan Murphy 20773b5940SDan Murphy static int fat_registered; 21773b5940SDan Murphy 224101f687SSimon Glass static int spl_register_fat_device(struct blk_desc *block_dev, int partition) 23773b5940SDan Murphy { 24773b5940SDan Murphy int err = 0; 25773b5940SDan Murphy 26773b5940SDan Murphy if (fat_registered) 27773b5940SDan Murphy return err; 28773b5940SDan Murphy 29773b5940SDan Murphy err = fat_register_device(block_dev, partition); 30773b5940SDan Murphy if (err) { 31773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 328cffe5bdSDan Murphy printf("%s: fat register err - %d\n", __func__, err); 33773b5940SDan Murphy #endif 347d2b4e77SGuillaume GARDET return err; 35773b5940SDan Murphy } 36773b5940SDan Murphy 37773b5940SDan Murphy fat_registered = 1; 38773b5940SDan Murphy 39773b5940SDan Murphy return err; 40773b5940SDan Murphy } 41773b5940SDan Murphy 4297ca364fSLokesh Vutla static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, 4397ca364fSLokesh Vutla ulong size, void *buf) 4497ca364fSLokesh Vutla { 4597ca364fSLokesh Vutla loff_t actread; 4697ca364fSLokesh Vutla int ret; 4797ca364fSLokesh Vutla char *filename = (char *)load->filename; 4897ca364fSLokesh Vutla 4997ca364fSLokesh Vutla ret = fat_read_file(filename, buf, file_offset, size, &actread); 5097ca364fSLokesh Vutla if (ret) 5197ca364fSLokesh Vutla return ret; 5297ca364fSLokesh Vutla 5397ca364fSLokesh Vutla return actread; 5497ca364fSLokesh Vutla } 5597ca364fSLokesh Vutla 56710e9ca5SSimon Glass int spl_load_image_fat(struct spl_image_info *spl_image, 57710e9ca5SSimon Glass struct blk_desc *block_dev, int partition, 58773b5940SDan Murphy const char *filename) 59773b5940SDan Murphy { 60773b5940SDan Murphy int err; 61773b5940SDan Murphy struct image_header *header; 62773b5940SDan Murphy 63773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition); 648cffe5bdSDan Murphy if (err) 65773b5940SDan Murphy goto end; 66773b5940SDan Murphy 67773b5940SDan Murphy header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 68773b5940SDan Murphy sizeof(struct image_header)); 69773b5940SDan Murphy 70773b5940SDan Murphy err = file_fat_read(filename, header, sizeof(struct image_header)); 71773b5940SDan Murphy if (err <= 0) 72773b5940SDan Murphy goto end; 73773b5940SDan Murphy 7497ca364fSLokesh Vutla if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 7597ca364fSLokesh Vutla image_get_magic(header) == FDT_MAGIC) { 7697ca364fSLokesh Vutla struct spl_load_info load; 7797ca364fSLokesh Vutla 7897ca364fSLokesh Vutla debug("Found FIT\n"); 7997ca364fSLokesh Vutla load.read = spl_fit_read; 8097ca364fSLokesh Vutla load.bl_len = 1; 8197ca364fSLokesh Vutla load.filename = (void *)filename; 8297ca364fSLokesh Vutla load.priv = NULL; 8397ca364fSLokesh Vutla 84f4d7d859SSimon Glass return spl_load_simple_fit(spl_image, &load, 0, header); 8597ca364fSLokesh Vutla } else { 86710e9ca5SSimon Glass err = spl_parse_image_header(spl_image, header); 87d550e82eSTom Rini if (err) 887e0f2267SMarek Vasut goto end; 89773b5940SDan Murphy 901eefe14fSMichal Simek err = file_fat_read(filename, 91710e9ca5SSimon Glass (u8 *)(uintptr_t)spl_image->load_addr, 0); 9297ca364fSLokesh Vutla } 93773b5940SDan Murphy 94773b5940SDan Murphy end: 95773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 96773b5940SDan Murphy if (err <= 0) 978cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n", 988cffe5bdSDan Murphy __func__, filename, err); 99773b5940SDan Murphy #endif 100773b5940SDan Murphy 101773b5940SDan Murphy return (err <= 0); 102773b5940SDan Murphy } 103773b5940SDan Murphy 104773b5940SDan Murphy #ifdef CONFIG_SPL_OS_BOOT 105710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image, 106710e9ca5SSimon Glass struct blk_desc *block_dev, int partition) 107773b5940SDan Murphy { 108773b5940SDan Murphy int err; 109ae1590edSTom Rini __maybe_unused char *file; 110773b5940SDan Murphy 111773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition); 1128cffe5bdSDan Murphy if (err) 1138cffe5bdSDan Murphy return err; 114773b5940SDan Murphy 115ae1590edSTom Rini #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT) 11600caae6dSSimon Glass file = env_get("falcon_args_file"); 117ae1590edSTom Rini if (file) { 118ae1590edSTom Rini err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 119ae1590edSTom Rini if (err <= 0) { 120ae1590edSTom Rini printf("spl: error reading image %s, err - %d, falling back to default\n", 121ae1590edSTom Rini file, err); 122ae1590edSTom Rini goto defaults; 123ae1590edSTom Rini } 12400caae6dSSimon Glass file = env_get("falcon_image_file"); 125ae1590edSTom Rini if (file) { 126710e9ca5SSimon Glass err = spl_load_image_fat(spl_image, block_dev, 127710e9ca5SSimon Glass partition, file); 128ae1590edSTom Rini if (err != 0) { 129ae1590edSTom Rini puts("spl: falling back to default\n"); 130ae1590edSTom Rini goto defaults; 131ae1590edSTom Rini } 132ae1590edSTom Rini 133ae1590edSTom Rini return 0; 134ae1590edSTom Rini } else 135ae1590edSTom Rini puts("spl: falcon_image_file not set in environment, falling back to default\n"); 136ae1590edSTom Rini } else 137ae1590edSTom Rini puts("spl: falcon_args_file not set in environment, falling back to default\n"); 138ae1590edSTom Rini 139ae1590edSTom Rini defaults: 140ae1590edSTom Rini #endif 141ae1590edSTom Rini 142205b4f33SGuillaume GARDET err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME, 143773b5940SDan Murphy (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 144773b5940SDan Murphy if (err <= 0) { 145773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 1468cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n", 147205b4f33SGuillaume GARDET __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err); 148773b5940SDan Murphy #endif 149773b5940SDan Murphy return -1; 150773b5940SDan Murphy } 151773b5940SDan Murphy 152710e9ca5SSimon Glass return spl_load_image_fat(spl_image, block_dev, partition, 153205b4f33SGuillaume GARDET CONFIG_SPL_FS_LOAD_KERNEL_NAME); 154773b5940SDan Murphy } 155339245b7SNikita Kiryanov #else 156710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image, 157710e9ca5SSimon Glass struct blk_desc *block_dev, int partition) 158339245b7SNikita Kiryanov { 159339245b7SNikita Kiryanov return -ENOSYS; 160339245b7SNikita Kiryanov } 161773b5940SDan Murphy #endif 162