1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (c) Copyright 2011 by Tigris Elektronik GmbH 4 * 5 * Author: 6 * Maximilian Schwerin <mvs (at) tigris.de> 7 */ 8 9 #include <common.h> 10 11 #include <command.h> 12 #include <environment.h> 13 #include <linux/stddef.h> 14 #include <malloc.h> 15 #include <memalign.h> 16 #include <search.h> 17 #include <errno.h> 18 #include <fat.h> 19 #include <mmc.h> 20 21 #ifdef CONFIG_SPL_BUILD 22 /* TODO(sjg (at) chromium.org): Figure out why this is needed */ 23 # if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT) 24 # define LOADENV 25 # endif 26 #else 27 # define LOADENV 28 # if defined(CONFIG_CMD_SAVEENV) 29 # define CMD_SAVEENV 30 # endif 31 #endif 32 33 #ifdef CMD_SAVEENV 34 static int env_fat_save(void) 35 { 36 env_t __aligned(ARCH_DMA_MINALIGN) env_new; 37 struct blk_desc *dev_desc = NULL; 38 disk_partition_t info; 39 int dev, part; 40 int err; 41 loff_t size; 42 43 err = env_export(&env_new); 44 if (err) 45 return err; 46 47 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE, 48 CONFIG_ENV_FAT_DEVICE_AND_PART, 49 &dev_desc, &info, 1); 50 if (part < 0) 51 return 1; 52 53 dev = dev_desc->devnum; 54 if (fat_set_blk_dev(dev_desc, &info) != 0) { 55 /* 56 * This printf is embedded in the messages from env_save that 57 * will calling it. The missing \n is intentional. 58 */ 59 printf("Unable to use %s %d:%d... ", 60 CONFIG_ENV_FAT_INTERFACE, dev, part); 61 return 1; 62 } 63 64 err = file_fat_write(CONFIG_ENV_FAT_FILE, (void *)&env_new, 0, sizeof(env_t), 65 &size); 66 if (err == -1) { 67 /* 68 * This printf is embedded in the messages from env_save that 69 * will calling it. The missing \n is intentional. 70 */ 71 printf("Unable to write \"%s\" from %s%d:%d... ", 72 CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part); 73 return 1; 74 } 75 76 return 0; 77 } 78 #endif /* CMD_SAVEENV */ 79 80 #ifdef LOADENV 81 static int env_fat_load(void) 82 { 83 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 84 struct blk_desc *dev_desc = NULL; 85 disk_partition_t info; 86 int dev, part; 87 int err; 88 89 #ifdef CONFIG_MMC 90 if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc")) 91 mmc_initialize(NULL); 92 #endif 93 94 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE, 95 CONFIG_ENV_FAT_DEVICE_AND_PART, 96 &dev_desc, &info, 1); 97 if (part < 0) 98 goto err_env_relocate; 99 100 dev = dev_desc->devnum; 101 if (fat_set_blk_dev(dev_desc, &info) != 0) { 102 /* 103 * This printf is embedded in the messages from env_save that 104 * will calling it. The missing \n is intentional. 105 */ 106 printf("Unable to use %s %d:%d... ", 107 CONFIG_ENV_FAT_INTERFACE, dev, part); 108 goto err_env_relocate; 109 } 110 111 err = file_fat_read(CONFIG_ENV_FAT_FILE, buf, CONFIG_ENV_SIZE); 112 if (err == -1) { 113 /* 114 * This printf is embedded in the messages from env_save that 115 * will calling it. The missing \n is intentional. 116 */ 117 printf("Unable to read \"%s\" from %s%d:%d... ", 118 CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part); 119 goto err_env_relocate; 120 } 121 122 return env_import(buf, 1); 123 124 err_env_relocate: 125 set_default_env(NULL); 126 127 return -EIO; 128 } 129 #endif /* LOADENV */ 130 131 U_BOOT_ENV_LOCATION(fat) = { 132 .location = ENVL_FAT, 133 ENV_NAME("FAT") 134 #ifdef LOADENV 135 .load = env_fat_load, 136 #endif 137 #ifdef CMD_SAVEENV 138 .save = env_save_ptr(env_fat_save), 139 #endif 140 }; 141