1 /* 2 * (c) Copyright 2012 by National Instruments, 3 * Joe Hershberger <joe.hershberger@ni.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 10 #include <command.h> 11 #include <environment.h> 12 #include <errno.h> 13 #include <malloc.h> 14 #include <memalign.h> 15 #include <search.h> 16 #include <ubi_uboot.h> 17 #undef crc32 18 19 env_t *env_ptr; 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #ifdef CONFIG_CMD_SAVEENV 24 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 25 static int env_ubi_save(void) 26 { 27 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); 28 int ret; 29 30 ret = env_export(env_new); 31 if (ret) 32 return ret; 33 34 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { 35 printf("\n** Cannot find mtd partition \"%s\"\n", 36 CONFIG_ENV_UBI_PART); 37 return 1; 38 } 39 40 if (gd->env_valid == ENV_VALID) { 41 puts("Writing to redundant UBI... "); 42 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND, 43 (void *)env_new, CONFIG_ENV_SIZE)) { 44 printf("\n** Unable to write env to %s:%s **\n", 45 CONFIG_ENV_UBI_PART, 46 CONFIG_ENV_UBI_VOLUME_REDUND); 47 return 1; 48 } 49 } else { 50 puts("Writing to UBI... "); 51 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, 52 (void *)env_new, CONFIG_ENV_SIZE)) { 53 printf("\n** Unable to write env to %s:%s **\n", 54 CONFIG_ENV_UBI_PART, 55 CONFIG_ENV_UBI_VOLUME); 56 return 1; 57 } 58 } 59 60 puts("done\n"); 61 62 gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND; 63 64 return 0; 65 } 66 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 67 static int env_ubi_save(void) 68 { 69 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); 70 int ret; 71 72 ret = env_export(env_new); 73 if (ret) 74 return ret; 75 76 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { 77 printf("\n** Cannot find mtd partition \"%s\"\n", 78 CONFIG_ENV_UBI_PART); 79 return 1; 80 } 81 82 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, 83 CONFIG_ENV_SIZE)) { 84 printf("\n** Unable to write env to %s:%s **\n", 85 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 86 return 1; 87 } 88 89 puts("done\n"); 90 return 0; 91 } 92 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 93 #endif /* CONFIG_CMD_SAVEENV */ 94 95 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 96 static void env_ubi_load(void) 97 { 98 ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE); 99 ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE); 100 env_t *tmp_env1, *tmp_env2; 101 102 /* 103 * In case we have restarted u-boot there is a chance that buffer 104 * contains old environment (from the previous boot). 105 * If UBI volume is zero size, ubi_volume_read() doesn't modify the 106 * buffer. 107 * We need to clear buffer manually here, so the invalid CRC will 108 * cause setting default environment as expected. 109 */ 110 memset(env1_buf, 0x0, CONFIG_ENV_SIZE); 111 memset(env2_buf, 0x0, CONFIG_ENV_SIZE); 112 113 tmp_env1 = (env_t *)env1_buf; 114 tmp_env2 = (env_t *)env2_buf; 115 116 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { 117 printf("\n** Cannot find mtd partition \"%s\"\n", 118 CONFIG_ENV_UBI_PART); 119 set_default_env(NULL); 120 return; 121 } 122 123 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, 124 CONFIG_ENV_SIZE)) { 125 printf("\n** Unable to read env from %s:%s **\n", 126 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 127 } 128 129 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2, 130 CONFIG_ENV_SIZE)) { 131 printf("\n** Unable to read redundant env from %s:%s **\n", 132 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); 133 } 134 135 env_import_redund((char *)tmp_env1, (char *)tmp_env2); 136 } 137 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 138 static void env_ubi_load(void) 139 { 140 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 141 142 /* 143 * In case we have restarted u-boot there is a chance that buffer 144 * contains old environment (from the previous boot). 145 * If UBI volume is zero size, ubi_volume_read() doesn't modify the 146 * buffer. 147 * We need to clear buffer manually here, so the invalid CRC will 148 * cause setting default environment as expected. 149 */ 150 memset(buf, 0x0, CONFIG_ENV_SIZE); 151 152 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { 153 printf("\n** Cannot find mtd partition \"%s\"\n", 154 CONFIG_ENV_UBI_PART); 155 set_default_env(NULL); 156 return; 157 } 158 159 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) { 160 printf("\n** Unable to read env from %s:%s **\n", 161 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 162 set_default_env(NULL); 163 return; 164 } 165 166 env_import(buf, 1); 167 } 168 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 169 170 U_BOOT_ENV_LOCATION(ubi) = { 171 .location = ENVL_UBI, 172 .load = env_ubi_load, 173 .save = env_save_ptr(env_ubi_save), 174 }; 175