10649cd0dSSimon Glass /* 20649cd0dSSimon Glass * (c) Copyright 2011 by Tigris Elektronik GmbH 30649cd0dSSimon Glass * 40649cd0dSSimon Glass * Author: 50649cd0dSSimon Glass * Maximilian Schwerin <mvs@tigris.de> 60649cd0dSSimon Glass * 70649cd0dSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 80649cd0dSSimon Glass */ 90649cd0dSSimon Glass 100649cd0dSSimon Glass #include <common.h> 110649cd0dSSimon Glass 120649cd0dSSimon Glass #include <command.h> 130649cd0dSSimon Glass #include <environment.h> 140649cd0dSSimon Glass #include <linux/stddef.h> 150649cd0dSSimon Glass #include <malloc.h> 160649cd0dSSimon Glass #include <memalign.h> 170649cd0dSSimon Glass #include <search.h> 180649cd0dSSimon Glass #include <errno.h> 190649cd0dSSimon Glass #include <fat.h> 200649cd0dSSimon Glass #include <mmc.h> 210649cd0dSSimon Glass 224415f1d1SSimon Glass #ifdef CONFIG_SPL_BUILD 234415f1d1SSimon Glass /* TODO(sjg@chromium.org): Figure out why this is needed */ 244415f1d1SSimon Glass # if !defined(CONFIG_TARGET_AM335X_EVM) || defined(CONFIG_SPL_OS_BOOT) 254415f1d1SSimon Glass # define LOADENV 264415f1d1SSimon Glass # endif 274415f1d1SSimon Glass #else 284415f1d1SSimon Glass # define LOADENV 294415f1d1SSimon Glass # if defined(CONFIG_CMD_SAVEENV) 304415f1d1SSimon Glass # define CMD_SAVEENV 314415f1d1SSimon Glass # endif 324415f1d1SSimon Glass #endif 334415f1d1SSimon Glass 340649cd0dSSimon Glass DECLARE_GLOBAL_DATA_PTR; 350649cd0dSSimon Glass 364415f1d1SSimon Glass #ifdef CMD_SAVEENV 37e5bce247SSimon Glass static int env_fat_save(void) 380649cd0dSSimon Glass { 39cda87ec5SAlex Kiernan env_t __aligned(ARCH_DMA_MINALIGN) env_new; 400649cd0dSSimon Glass struct blk_desc *dev_desc = NULL; 410649cd0dSSimon Glass disk_partition_t info; 420649cd0dSSimon Glass int dev, part; 430649cd0dSSimon Glass int err; 440649cd0dSSimon Glass loff_t size; 450649cd0dSSimon Glass 460649cd0dSSimon Glass err = env_export(&env_new); 470649cd0dSSimon Glass if (err) 480649cd0dSSimon Glass return err; 490649cd0dSSimon Glass 500649cd0dSSimon Glass part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE, 510649cd0dSSimon Glass CONFIG_ENV_FAT_DEVICE_AND_PART, 520649cd0dSSimon Glass &dev_desc, &info, 1); 530649cd0dSSimon Glass if (part < 0) 540649cd0dSSimon Glass return 1; 550649cd0dSSimon Glass 560649cd0dSSimon Glass dev = dev_desc->devnum; 570649cd0dSSimon Glass if (fat_set_blk_dev(dev_desc, &info) != 0) { 58d0816da5SMaxime Ripard /* 59d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 60d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 61d0816da5SMaxime Ripard */ 62d0816da5SMaxime Ripard printf("Unable to use %s %d:%d... ", 630649cd0dSSimon Glass CONFIG_ENV_FAT_INTERFACE, dev, part); 640649cd0dSSimon Glass return 1; 650649cd0dSSimon Glass } 660649cd0dSSimon Glass 670649cd0dSSimon Glass err = file_fat_write(CONFIG_ENV_FAT_FILE, (void *)&env_new, 0, sizeof(env_t), 680649cd0dSSimon Glass &size); 690649cd0dSSimon Glass if (err == -1) { 70d0816da5SMaxime Ripard /* 71d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 72d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 73d0816da5SMaxime Ripard */ 74d0816da5SMaxime Ripard printf("Unable to write \"%s\" from %s%d:%d... ", 750649cd0dSSimon Glass CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part); 760649cd0dSSimon Glass return 1; 770649cd0dSSimon Glass } 780649cd0dSSimon Glass 790649cd0dSSimon Glass return 0; 800649cd0dSSimon Glass } 814415f1d1SSimon Glass #endif /* CMD_SAVEENV */ 820649cd0dSSimon Glass 834415f1d1SSimon Glass #ifdef LOADENV 84c5951991SSimon Glass static int env_fat_load(void) 850649cd0dSSimon Glass { 860649cd0dSSimon Glass ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 870649cd0dSSimon Glass struct blk_desc *dev_desc = NULL; 880649cd0dSSimon Glass disk_partition_t info; 890649cd0dSSimon Glass int dev, part; 900649cd0dSSimon Glass int err; 910649cd0dSSimon Glass 92*26862b4aSFaiz Abbas if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc")) 93*26862b4aSFaiz Abbas mmc_initialize(NULL); 94*26862b4aSFaiz Abbas 950649cd0dSSimon Glass part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE, 960649cd0dSSimon Glass CONFIG_ENV_FAT_DEVICE_AND_PART, 970649cd0dSSimon Glass &dev_desc, &info, 1); 980649cd0dSSimon Glass if (part < 0) 990649cd0dSSimon Glass goto err_env_relocate; 1000649cd0dSSimon Glass 1010649cd0dSSimon Glass dev = dev_desc->devnum; 1020649cd0dSSimon Glass if (fat_set_blk_dev(dev_desc, &info) != 0) { 103d0816da5SMaxime Ripard /* 104d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 105d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 106d0816da5SMaxime Ripard */ 107d0816da5SMaxime Ripard printf("Unable to use %s %d:%d... ", 1080649cd0dSSimon Glass CONFIG_ENV_FAT_INTERFACE, dev, part); 1090649cd0dSSimon Glass goto err_env_relocate; 1100649cd0dSSimon Glass } 1110649cd0dSSimon Glass 1120649cd0dSSimon Glass err = file_fat_read(CONFIG_ENV_FAT_FILE, buf, CONFIG_ENV_SIZE); 1130649cd0dSSimon Glass if (err == -1) { 114d0816da5SMaxime Ripard /* 115d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 116d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 117d0816da5SMaxime Ripard */ 118d0816da5SMaxime Ripard printf("Unable to read \"%s\" from %s%d:%d... ", 1190649cd0dSSimon Glass CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part); 1200649cd0dSSimon Glass goto err_env_relocate; 1210649cd0dSSimon Glass } 1220649cd0dSSimon Glass 1232166ebf7SSimon Goldschmidt return env_import(buf, 1); 1240649cd0dSSimon Glass 1250649cd0dSSimon Glass err_env_relocate: 1260649cd0dSSimon Glass set_default_env(NULL); 127c5951991SSimon Glass 128c5951991SSimon Glass return -EIO; 1290649cd0dSSimon Glass } 1304415f1d1SSimon Glass #endif /* LOADENV */ 1314415f1d1SSimon Glass 1324415f1d1SSimon Glass U_BOOT_ENV_LOCATION(fat) = { 1334415f1d1SSimon Glass .location = ENVL_FAT, 134ac358bebSSimon Glass ENV_NAME("FAT") 1354415f1d1SSimon Glass #ifdef LOADENV 136e5bce247SSimon Glass .load = env_fat_load, 1374415f1d1SSimon Glass #endif 1384415f1d1SSimon Glass #ifdef CMD_SAVEENV 139e5bce247SSimon Glass .save = env_save_ptr(env_fat_save), 1404415f1d1SSimon Glass #endif 1414415f1d1SSimon Glass }; 142