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 574101f687SSimon Glass int spl_load_image_fat(struct blk_desc *block_dev, 58773b5940SDan Murphy 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 8597ca364fSLokesh Vutla return spl_load_simple_fit(&load, 0, header); 8697ca364fSLokesh Vutla } else { 877e0f2267SMarek Vasut err = spl_parse_image_header(header); 88d550e82eSTom Rini if (err) 897e0f2267SMarek Vasut goto end; 90773b5940SDan Murphy 91*1eefe14fSMichal Simek err = file_fat_read(filename, 92*1eefe14fSMichal Simek (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 1064101f687SSimon Glass int spl_load_image_fat_os(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) 116ae1590edSTom Rini file = getenv("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 } 124ae1590edSTom Rini file = getenv("falcon_image_file"); 125ae1590edSTom Rini if (file) { 126ae1590edSTom Rini err = spl_load_image_fat(block_dev, partition, file); 127ae1590edSTom Rini if (err != 0) { 128ae1590edSTom Rini puts("spl: falling back to default\n"); 129ae1590edSTom Rini goto defaults; 130ae1590edSTom Rini } 131ae1590edSTom Rini 132ae1590edSTom Rini return 0; 133ae1590edSTom Rini } else 134ae1590edSTom Rini puts("spl: falcon_image_file not set in environment, falling back to default\n"); 135ae1590edSTom Rini } else 136ae1590edSTom Rini puts("spl: falcon_args_file not set in environment, falling back to default\n"); 137ae1590edSTom Rini 138ae1590edSTom Rini defaults: 139ae1590edSTom Rini #endif 140ae1590edSTom Rini 141205b4f33SGuillaume GARDET err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME, 142773b5940SDan Murphy (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 143773b5940SDan Murphy if (err <= 0) { 144773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 1458cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n", 146205b4f33SGuillaume GARDET __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err); 147773b5940SDan Murphy #endif 148773b5940SDan Murphy return -1; 149773b5940SDan Murphy } 150773b5940SDan Murphy 151773b5940SDan Murphy return spl_load_image_fat(block_dev, partition, 152205b4f33SGuillaume GARDET CONFIG_SPL_FS_LOAD_KERNEL_NAME); 153773b5940SDan Murphy } 154339245b7SNikita Kiryanov #else 1554101f687SSimon Glass int spl_load_image_fat_os(struct blk_desc *block_dev, int partition) 156339245b7SNikita Kiryanov { 157339245b7SNikita Kiryanov return -ENOSYS; 158339245b7SNikita Kiryanov } 159773b5940SDan Murphy #endif 160773b5940SDan Murphy #endif 161