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