1 /* 2 * (C) Copyright 2010-2016 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* #define DEBUG */ 8 9 #include <common.h> 10 11 #include <command.h> 12 #include <environment.h> 13 #include <linux/stddef.h> 14 #include <errno.h> 15 #include <memalign.h> 16 #include <sata.h> 17 #include <search.h> 18 19 #if defined(CONFIG_ENV_SIZE_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND) 20 #error ENV REDUND not supported 21 #endif 22 23 #if !defined(CONFIG_ENV_OFFSET) || !defined(CONFIG_ENV_SIZE) 24 #error CONFIG_ENV_OFFSET or CONFIG_ENV_SIZE not defined 25 #endif 26 27 DECLARE_GLOBAL_DATA_PTR; 28 29 __weak int sata_get_env_dev(void) 30 { 31 return CONFIG_SYS_SATA_ENV_DEV; 32 } 33 34 #ifdef CONFIG_CMD_SAVEENV 35 static inline int write_env(struct blk_desc *sata, unsigned long size, 36 unsigned long offset, void *buffer) 37 { 38 uint blk_start, blk_cnt, n; 39 40 blk_start = ALIGN(offset, sata->blksz) / sata->blksz; 41 blk_cnt = ALIGN(size, sata->blksz) / sata->blksz; 42 43 n = blk_dwrite(sata, blk_start, blk_cnt, buffer); 44 45 return (n == blk_cnt) ? 0 : -1; 46 } 47 48 static int env_sata_save(void) 49 { 50 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); 51 struct blk_desc *sata = NULL; 52 int env_sata, ret; 53 54 if (sata_initialize()) 55 return 1; 56 57 env_sata = sata_get_env_dev(); 58 59 sata = sata_get_dev(env_sata); 60 if (sata == NULL) { 61 printf("Unknown SATA(%d) device for environment!\n", 62 env_sata); 63 return 1; 64 } 65 66 ret = env_export(env_new); 67 if (ret) 68 return 1; 69 70 printf("Writing to SATA(%d)...", env_sata); 71 if (write_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, &env_new)) { 72 puts("failed\n"); 73 return 1; 74 } 75 76 puts("done\n"); 77 return 0; 78 } 79 #endif /* CONFIG_CMD_SAVEENV */ 80 81 static inline int read_env(struct blk_desc *sata, unsigned long size, 82 unsigned long offset, void *buffer) 83 { 84 uint blk_start, blk_cnt, n; 85 86 blk_start = ALIGN(offset, sata->blksz) / sata->blksz; 87 blk_cnt = ALIGN(size, sata->blksz) / sata->blksz; 88 89 n = blk_dread(sata, blk_start, blk_cnt, buffer); 90 91 return (n == blk_cnt) ? 0 : -1; 92 } 93 94 static void env_sata_load(void) 95 { 96 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 97 struct blk_desc *sata = NULL; 98 int env_sata; 99 100 if (sata_initialize()) 101 return -EIO; 102 103 env_sata = sata_get_env_dev(); 104 105 sata = sata_get_dev(env_sata); 106 if (sata == NULL) { 107 printf("Unknown SATA(%d) device for environment!\n", env_sata); 108 return -EIO; 109 } 110 111 if (read_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf)) { 112 set_default_env(NULL); 113 return -EIO; 114 } 115 116 return env_import(buf, 1); 117 } 118 119 U_BOOT_ENV_LOCATION(sata) = { 120 .location = ENVL_ESATA, 121 ENV_NAME("SATA") 122 .load = env_sata_load, 123 .save = env_save_ptr(env_sata_save), 124 }; 125