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 { 390649cd0dSSimon Glass env_t 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) { 58*d0816da5SMaxime Ripard /* 59*d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 60*d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 61*d0816da5SMaxime Ripard */ 62*d0816da5SMaxime 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) { 70*d0816da5SMaxime Ripard /* 71*d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 72*d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 73*d0816da5SMaxime Ripard */ 74*d0816da5SMaxime 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 920649cd0dSSimon Glass part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE, 930649cd0dSSimon Glass CONFIG_ENV_FAT_DEVICE_AND_PART, 940649cd0dSSimon Glass &dev_desc, &info, 1); 950649cd0dSSimon Glass if (part < 0) 960649cd0dSSimon Glass goto err_env_relocate; 970649cd0dSSimon Glass 980649cd0dSSimon Glass dev = dev_desc->devnum; 990649cd0dSSimon Glass if (fat_set_blk_dev(dev_desc, &info) != 0) { 100*d0816da5SMaxime Ripard /* 101*d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 102*d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 103*d0816da5SMaxime Ripard */ 104*d0816da5SMaxime Ripard printf("Unable to use %s %d:%d... ", 1050649cd0dSSimon Glass CONFIG_ENV_FAT_INTERFACE, dev, part); 1060649cd0dSSimon Glass goto err_env_relocate; 1070649cd0dSSimon Glass } 1080649cd0dSSimon Glass 1090649cd0dSSimon Glass err = file_fat_read(CONFIG_ENV_FAT_FILE, buf, CONFIG_ENV_SIZE); 1100649cd0dSSimon Glass if (err == -1) { 111*d0816da5SMaxime Ripard /* 112*d0816da5SMaxime Ripard * This printf is embedded in the messages from env_save that 113*d0816da5SMaxime Ripard * will calling it. The missing \n is intentional. 114*d0816da5SMaxime Ripard */ 115*d0816da5SMaxime Ripard printf("Unable to read \"%s\" from %s%d:%d... ", 1160649cd0dSSimon Glass CONFIG_ENV_FAT_FILE, CONFIG_ENV_FAT_INTERFACE, dev, part); 1170649cd0dSSimon Glass goto err_env_relocate; 1180649cd0dSSimon Glass } 1190649cd0dSSimon Glass 1200649cd0dSSimon Glass env_import(buf, 1); 121c5951991SSimon Glass return 0; 1220649cd0dSSimon Glass 1230649cd0dSSimon Glass err_env_relocate: 1240649cd0dSSimon Glass set_default_env(NULL); 125c5951991SSimon Glass 126c5951991SSimon Glass return -EIO; 1270649cd0dSSimon Glass } 1284415f1d1SSimon Glass #endif /* LOADENV */ 1294415f1d1SSimon Glass 1304415f1d1SSimon Glass U_BOOT_ENV_LOCATION(fat) = { 1314415f1d1SSimon Glass .location = ENVL_FAT, 132ac358bebSSimon Glass ENV_NAME("FAT") 1334415f1d1SSimon Glass #ifdef LOADENV 134e5bce247SSimon Glass .load = env_fat_load, 1354415f1d1SSimon Glass #endif 1364415f1d1SSimon Glass #ifdef CMD_SAVEENV 137e5bce247SSimon Glass .save = env_save_ptr(env_fat_save), 1384415f1d1SSimon Glass #endif 1394415f1d1SSimon Glass }; 140