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> 1897ca364fSLokesh Vutla #include <libfdt.h> 19773b5940SDan Murphy 20773b5940SDan Murphy static int fat_registered; 21773b5940SDan Murphy 22773b5940SDan Murphy #ifdef CONFIG_SPL_FAT_SUPPORT 234101f687SSimon Glass static int spl_register_fat_device(struct blk_desc *block_dev, int partition) 24773b5940SDan Murphy { 25773b5940SDan Murphy int err = 0; 26773b5940SDan Murphy 27773b5940SDan Murphy if (fat_registered) 28773b5940SDan Murphy return err; 29773b5940SDan Murphy 30773b5940SDan Murphy err = fat_register_device(block_dev, partition); 31773b5940SDan Murphy if (err) { 32773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 338cffe5bdSDan Murphy printf("%s: fat register err - %d\n", __func__, err); 34773b5940SDan Murphy #endif 357d2b4e77SGuillaume GARDET return err; 36773b5940SDan Murphy } 37773b5940SDan Murphy 38773b5940SDan Murphy fat_registered = 1; 39773b5940SDan Murphy 40773b5940SDan Murphy return err; 41773b5940SDan Murphy } 42773b5940SDan Murphy 4397ca364fSLokesh Vutla static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, 4497ca364fSLokesh Vutla ulong size, void *buf) 4597ca364fSLokesh Vutla { 4697ca364fSLokesh Vutla loff_t actread; 4797ca364fSLokesh Vutla int ret; 4897ca364fSLokesh Vutla char *filename = (char *)load->filename; 4997ca364fSLokesh Vutla 5097ca364fSLokesh Vutla ret = fat_read_file(filename, buf, file_offset, size, &actread); 5197ca364fSLokesh Vutla if (ret) 5297ca364fSLokesh Vutla return ret; 5397ca364fSLokesh Vutla 5497ca364fSLokesh Vutla return actread; 5597ca364fSLokesh Vutla } 5697ca364fSLokesh Vutla 57710e9ca5SSimon Glass int spl_load_image_fat(struct spl_image_info *spl_image, 58710e9ca5SSimon Glass struct blk_desc *block_dev, int partition, 59773b5940SDan Murphy const char *filename) 60773b5940SDan Murphy { 61773b5940SDan Murphy int err; 62773b5940SDan Murphy struct image_header *header; 63773b5940SDan Murphy 64773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition); 658cffe5bdSDan Murphy if (err) 66773b5940SDan Murphy goto end; 67773b5940SDan Murphy 68773b5940SDan Murphy header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 69773b5940SDan Murphy sizeof(struct image_header)); 70773b5940SDan Murphy 71773b5940SDan Murphy err = file_fat_read(filename, header, sizeof(struct image_header)); 72773b5940SDan Murphy if (err <= 0) 73773b5940SDan Murphy goto end; 74773b5940SDan Murphy 7597ca364fSLokesh Vutla if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 7697ca364fSLokesh Vutla image_get_magic(header) == FDT_MAGIC) { 7797ca364fSLokesh Vutla struct spl_load_info load; 7897ca364fSLokesh Vutla 7997ca364fSLokesh Vutla debug("Found FIT\n"); 8097ca364fSLokesh Vutla load.read = spl_fit_read; 8197ca364fSLokesh Vutla load.bl_len = 1; 8297ca364fSLokesh Vutla load.filename = (void *)filename; 8397ca364fSLokesh Vutla load.priv = NULL; 8497ca364fSLokesh Vutla 85*f4d7d859SSimon Glass return spl_load_simple_fit(spl_image, &load, 0, header); 8697ca364fSLokesh Vutla } else { 87710e9ca5SSimon Glass err = spl_parse_image_header(spl_image, header); 88d550e82eSTom Rini if (err) 897e0f2267SMarek Vasut goto end; 90773b5940SDan Murphy 911eefe14fSMichal Simek err = file_fat_read(filename, 92710e9ca5SSimon Glass (u8 *)(uintptr_t)spl_image->load_addr, 0); 9397ca364fSLokesh Vutla } 94773b5940SDan Murphy 95773b5940SDan Murphy end: 96773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 97773b5940SDan Murphy if (err <= 0) 988cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n", 998cffe5bdSDan Murphy __func__, filename, err); 100773b5940SDan Murphy #endif 101773b5940SDan Murphy 102773b5940SDan Murphy return (err <= 0); 103773b5940SDan Murphy } 104773b5940SDan Murphy 105773b5940SDan Murphy #ifdef CONFIG_SPL_OS_BOOT 106710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image, 107710e9ca5SSimon Glass struct blk_desc *block_dev, int partition) 108773b5940SDan Murphy { 109773b5940SDan Murphy int err; 110ae1590edSTom Rini __maybe_unused char *file; 111773b5940SDan Murphy 112773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition); 1138cffe5bdSDan Murphy if (err) 1148cffe5bdSDan Murphy return err; 115773b5940SDan Murphy 116ae1590edSTom Rini #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT) 117ae1590edSTom Rini file = getenv("falcon_args_file"); 118ae1590edSTom Rini if (file) { 119ae1590edSTom Rini err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 120ae1590edSTom Rini if (err <= 0) { 121ae1590edSTom Rini printf("spl: error reading image %s, err - %d, falling back to default\n", 122ae1590edSTom Rini file, err); 123ae1590edSTom Rini goto defaults; 124ae1590edSTom Rini } 125ae1590edSTom Rini file = getenv("falcon_image_file"); 126ae1590edSTom Rini if (file) { 127710e9ca5SSimon Glass err = spl_load_image_fat(spl_image, block_dev, 128710e9ca5SSimon Glass partition, file); 129ae1590edSTom Rini if (err != 0) { 130ae1590edSTom Rini puts("spl: falling back to default\n"); 131ae1590edSTom Rini goto defaults; 132ae1590edSTom Rini } 133ae1590edSTom Rini 134ae1590edSTom Rini return 0; 135ae1590edSTom Rini } else 136ae1590edSTom Rini puts("spl: falcon_image_file not set in environment, falling back to default\n"); 137ae1590edSTom Rini } else 138ae1590edSTom Rini puts("spl: falcon_args_file not set in environment, falling back to default\n"); 139ae1590edSTom Rini 140ae1590edSTom Rini defaults: 141ae1590edSTom Rini #endif 142ae1590edSTom Rini 143205b4f33SGuillaume GARDET err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME, 144773b5940SDan Murphy (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 145773b5940SDan Murphy if (err <= 0) { 146773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 1478cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n", 148205b4f33SGuillaume GARDET __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err); 149773b5940SDan Murphy #endif 150773b5940SDan Murphy return -1; 151773b5940SDan Murphy } 152773b5940SDan Murphy 153710e9ca5SSimon Glass return spl_load_image_fat(spl_image, block_dev, partition, 154205b4f33SGuillaume GARDET CONFIG_SPL_FS_LOAD_KERNEL_NAME); 155773b5940SDan Murphy } 156339245b7SNikita Kiryanov #else 157710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image, 158710e9ca5SSimon Glass struct blk_desc *block_dev, int partition) 159339245b7SNikita Kiryanov { 160339245b7SNikita Kiryanov return -ENOSYS; 161339245b7SNikita Kiryanov } 162773b5940SDan Murphy #endif 163773b5940SDan Murphy #endif 164