1 // SPDX-License-Identifier: GPL-2.0+
3 * (c) Copyright 2011 by Tigris Elektronik GmbH
6 * Maximilian Schwerin <mvs@tigris.de>
12 #include <env_internal.h>
20 #include <asm/cache.h>
21 #include <asm/global_data.h>
22 #include <linux/stddef.h>
24 #ifdef CONFIG_SPL_BUILD
25 /* TODO(sjg@chromium.org): Figure out why this is needed */
26 # if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT)
33 DECLARE_GLOBAL_DATA_PTR;
35 static char *env_fat_device_and_part(void)
38 static char *part_str;
41 part_str = CONFIG_ENV_FAT_DEVICE_AND_PART;
42 if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
43 part_str = "0" CONFIG_ENV_FAT_DEVICE_AND_PART;
44 part_str[0] += mmc_get_env_dev();
50 return CONFIG_ENV_FAT_DEVICE_AND_PART;
54 static int env_fat_save(void)
56 env_t __aligned(ARCH_DMA_MINALIGN) env_new;
57 struct blk_desc *dev_desc = NULL;
58 struct disk_partition info;
59 const char *file = CONFIG_ENV_FAT_FILE;
64 err = env_export(&env_new);
68 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
69 env_fat_device_and_part(),
74 dev = dev_desc->devnum;
75 if (fat_set_blk_dev(dev_desc, &info) != 0) {
77 * This printf is embedded in the messages from env_save that
78 * will calling it. The missing \n is intentional.
80 printf("Unable to use %s %d:%d... \n",
81 CONFIG_ENV_FAT_INTERFACE, dev, part);
85 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
86 if (gd->env_valid == ENV_VALID)
87 file = CONFIG_ENV_FAT_FILE_REDUND;
90 err = file_fat_write(file, (void *)&env_new, 0, sizeof(env_t), &size);
93 * This printf is embedded in the messages from env_save that
94 * will calling it. The missing \n is intentional.
96 printf("Unable to write \"%s\" from %s%d:%d... \n",
97 file, CONFIG_ENV_FAT_INTERFACE, dev, part);
101 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
102 gd->env_valid = (gd->env_valid == ENV_REDUND) ? ENV_VALID : ENV_REDUND;
109 static int env_fat_load(void)
111 ALLOC_CACHE_ALIGN_BUFFER(char, buf1, CONFIG_ENV_SIZE);
112 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
113 ALLOC_CACHE_ALIGN_BUFFER(char, buf2, CONFIG_ENV_SIZE);
116 struct blk_desc *dev_desc = NULL;
117 struct disk_partition info;
122 if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc"))
123 mmc_initialize(NULL);
126 part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
127 env_fat_device_and_part(),
128 &dev_desc, &info, 1);
130 goto err_env_relocate;
132 dev = dev_desc->devnum;
133 if (fat_set_blk_dev(dev_desc, &info) != 0) {
135 * This printf is embedded in the messages from env_save that
136 * will calling it. The missing \n is intentional.
138 printf("Unable to use %s %d:%d... \n",
139 CONFIG_ENV_FAT_INTERFACE, dev, part);
140 goto err_env_relocate;
143 err1 = file_fat_read(CONFIG_ENV_FAT_FILE, buf1, CONFIG_ENV_SIZE);
144 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
145 err2 = file_fat_read(CONFIG_ENV_FAT_FILE_REDUND, buf2, CONFIG_ENV_SIZE);
147 err1 = (err1 >= 0) ? 0 : -1;
148 err2 = (err2 >= 0) ? 0 : -1;
149 return env_import_redund(buf1, err1, buf2, err2, H_EXTERNAL);
153 * This printf is embedded in the messages from env_save that
154 * will calling it. The missing \n is intentional.
156 printf("Unable to read \"%s\" from %s%d:%d... \n",
157 CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part);
158 goto err_env_relocate;
161 return env_import(buf1, 1, H_EXTERNAL);
165 env_set_default(NULL, 0);
171 U_BOOT_ENV_LOCATION(fat) = {
172 .location = ENVL_FAT,
175 .load = env_fat_load,
177 .save = ENV_SAVE_PTR(env_fat_save),