env_ubi.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. #include <common.h>
  8. #include <command.h>
  9. #include <environment.h>
  10. #include <errno.h>
  11. #include <malloc.h>
  12. #include <search.h>
  13. #include <ubi_uboot.h>
  14. #undef crc32
  15. char *env_name_spec = "UBI";
  16. env_t *env_ptr;
  17. DECLARE_GLOBAL_DATA_PTR;
  18. int env_init(void)
  19. {
  20. /* use default */
  21. gd->env_addr = (ulong)&default_environment[0];
  22. gd->env_valid = 1;
  23. return 0;
  24. }
  25. #ifdef CONFIG_CMD_SAVEENV
  26. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  27. static unsigned char env_flags;
  28. int saveenv(void)
  29. {
  30. ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  31. int ret;
  32. ret = env_export(env_new);
  33. if (ret)
  34. return ret;
  35. if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  36. printf("\n** Cannot find mtd partition \"%s\"\n",
  37. CONFIG_ENV_UBI_PART);
  38. return 1;
  39. }
  40. env_new->flags = ++env_flags; /* increase the serial */
  41. if (gd->env_valid == 1) {
  42. puts("Writing to redundant UBI... ");
  43. if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  44. (void *)env_new, CONFIG_ENV_SIZE)) {
  45. printf("\n** Unable to write env to %s:%s **\n",
  46. CONFIG_ENV_UBI_PART,
  47. CONFIG_ENV_UBI_VOLUME_REDUND);
  48. return 1;
  49. }
  50. } else {
  51. puts("Writing to UBI... ");
  52. if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  53. (void *)env_new, CONFIG_ENV_SIZE)) {
  54. printf("\n** Unable to write env to %s:%s **\n",
  55. CONFIG_ENV_UBI_PART,
  56. CONFIG_ENV_UBI_VOLUME);
  57. return 1;
  58. }
  59. }
  60. puts("done\n");
  61. gd->env_valid = gd->env_valid == 2 ? 1 : 2;
  62. return 0;
  63. }
  64. #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  65. int saveenv(void)
  66. {
  67. ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  68. int ret;
  69. ret = env_export(env_new);
  70. if (ret)
  71. return ret;
  72. if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  73. printf("\n** Cannot find mtd partition \"%s\"\n",
  74. CONFIG_ENV_UBI_PART);
  75. return 1;
  76. }
  77. if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
  78. CONFIG_ENV_SIZE)) {
  79. printf("\n** Unable to write env to %s:%s **\n",
  80. CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  81. return 1;
  82. }
  83. puts("done\n");
  84. return 0;
  85. }
  86. #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  87. #endif /* CONFIG_CMD_SAVEENV */
  88. #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  89. void env_relocate_spec(void)
  90. {
  91. ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
  92. ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
  93. int crc1_ok = 0, crc2_ok = 0;
  94. env_t *ep, *tmp_env1, *tmp_env2;
  95. tmp_env1 = (env_t *)env1_buf;
  96. tmp_env2 = (env_t *)env2_buf;
  97. if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  98. printf("\n** Cannot find mtd partition \"%s\"\n",
  99. CONFIG_ENV_UBI_PART);
  100. set_default_env(NULL);
  101. return;
  102. }
  103. if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
  104. CONFIG_ENV_SIZE)) {
  105. printf("\n** Unable to read env from %s:%s **\n",
  106. CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  107. }
  108. if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
  109. CONFIG_ENV_SIZE)) {
  110. printf("\n** Unable to read redundant env from %s:%s **\n",
  111. CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
  112. }
  113. crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
  114. crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
  115. if (!crc1_ok && !crc2_ok) {
  116. set_default_env("!bad CRC");
  117. return;
  118. } else if (crc1_ok && !crc2_ok) {
  119. gd->env_valid = 1;
  120. } else if (!crc1_ok && crc2_ok) {
  121. gd->env_valid = 2;
  122. } else {
  123. /* both ok - check serial */
  124. if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
  125. gd->env_valid = 2;
  126. else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
  127. gd->env_valid = 1;
  128. else if (tmp_env1->flags > tmp_env2->flags)
  129. gd->env_valid = 1;
  130. else if (tmp_env2->flags > tmp_env1->flags)
  131. gd->env_valid = 2;
  132. else /* flags are equal - almost impossible */
  133. gd->env_valid = 1;
  134. }
  135. if (gd->env_valid == 1)
  136. ep = tmp_env1;
  137. else
  138. ep = tmp_env2;
  139. env_flags = ep->flags;
  140. env_import((char *)ep, 0);
  141. }
  142. #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  143. void env_relocate_spec(void)
  144. {
  145. ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
  146. if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  147. printf("\n** Cannot find mtd partition \"%s\"\n",
  148. CONFIG_ENV_UBI_PART);
  149. set_default_env(NULL);
  150. return;
  151. }
  152. if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf,
  153. CONFIG_ENV_SIZE)) {
  154. printf("\n** Unable to read env from %s:%s **\n",
  155. CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  156. set_default_env(NULL);
  157. return;
  158. }
  159. env_import(buf, 1);
  160. }
  161. #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */