1// SPDX-License-Identifier: GPL-2.0+ 2 3#include <common.h> 4#include <env.h> 5#include <part.h> 6#include <spl.h> 7#include <spl_load.h> 8#include <asm/u-boot.h> 9#include <ext4fs.h> 10#include <errno.h> 11#include <image.h> 12 13static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, 14 ulong size, void *buf) 15{ 16 int ret; 17 loff_t actlen; 18 19 ret = ext4fs_read(buf, file_offset, size, &actlen); 20 if (ret) 21 return ret; 22 return actlen; 23} 24 25int spl_load_image_ext(struct spl_image_info *spl_image, 26 struct spl_boot_device *bootdev, 27 struct blk_desc *block_dev, int partition, 28 const char *filename) 29{ 30 s32 err; 31 loff_t filelen; 32 struct disk_partition part_info = {}; 33 struct spl_load_info load; 34 35 if (part_get_info(block_dev, partition, &part_info)) { 36 printf("spl: no partition table found\n"); 37 return -1; 38 } 39 40 ext4fs_set_blk_dev(block_dev, &part_info); 41 42 err = ext4fs_mount(); 43 if (!err) { 44#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 45 printf("%s: ext4fs mount err - %d\n", __func__, err); 46#endif 47 return -1; 48 } 49 50 err = ext4fs_open(filename, &filelen); 51 if (err < 0) { 52 puts("spl: ext4fs_open failed\n"); 53 goto end; 54 } 55 56 spl_set_bl_len(&load, 1); 57 load.read = spl_fit_read; 58 err = spl_load(spl_image, bootdev, &load, filelen, 0); 59 60end: 61#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 62 if (err < 0) 63 printf("%s: error reading image %s, err - %d\n", 64 __func__, filename, err); 65#endif 66 67 return err < 0; 68} 69 70#if CONFIG_IS_ENABLED(OS_BOOT) 71int spl_load_image_ext_os(struct spl_image_info *spl_image, 72 struct spl_boot_device *bootdev, 73 struct blk_desc *block_dev, int partition) 74{ 75 int err; 76 __maybe_unused loff_t filelen, actlen; 77 struct disk_partition part_info = {}; 78 __maybe_unused char *file; 79 80 if (part_get_info(block_dev, partition, &part_info)) { 81 printf("spl: no partition table found\n"); 82 return -1; 83 } 84 85 ext4fs_set_blk_dev(block_dev, &part_info); 86 87 err = ext4fs_mount(); 88 if (!err) { 89#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 90 printf("%s: ext4fs mount err - %d\n", __func__, err); 91#endif 92 return -1; 93 } 94#if defined(CONFIG_SPL_ENV_SUPPORT) 95 file = env_get("falcon_args_file"); 96 if (file) { 97 err = ext4fs_open(file, &filelen); 98 if (err < 0) { 99 puts("spl: ext4fs_open failed\n"); 100 goto defaults; 101 } 102 err = ext4fs_read((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0, filelen, &actlen); 103 if (err < 0) { 104 printf("spl: error reading image %s, err - %d, falling back to default\n", 105 file, err); 106 goto defaults; 107 } 108 file = env_get("falcon_image_file"); 109 if (file) { 110 err = spl_load_image_ext(spl_image, bootdev, block_dev, 111 partition, file); 112 if (err != 0) { 113 puts("spl: falling back to default\n"); 114 goto defaults; 115 } 116 117 return 0; 118 } else { 119 puts("spl: falcon_image_file not set in environment, falling back to default\n"); 120 } 121 } else { 122 puts("spl: falcon_args_file not set in environment, falling back to default\n"); 123 } 124 125defaults: 126#endif 127 128 err = ext4fs_open(CONFIG_SPL_FS_LOAD_ARGS_NAME, &filelen); 129 if (err < 0) 130 puts("spl: ext4fs_open failed\n"); 131 132 err = ext4fs_read((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0, filelen, &actlen); 133 if (err < 0) { 134#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 135 printf("%s: error reading image %s, err - %d\n", 136 __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err); 137#endif 138 return -1; 139 } 140 141 return spl_load_image_ext(spl_image, bootdev, block_dev, partition, 142 CONFIG_SPL_FS_LOAD_KERNEL_NAME); 143} 144#else 145int spl_load_image_ext_os(struct spl_image_info *spl_image, 146 struct spl_boot_device *bootdev, 147 struct blk_desc *block_dev, int partition) 148{ 149 return -ENOSYS; 150} 151#endif 152