env_dataflash.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * LowLevel function for DataFlash environment support
  3. * Author : Gilles Gastaldi (Atmel)
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <command.h>
  9. #include <environment.h>
  10. #include <linux/stddef.h>
  11. #include <dataflash.h>
  12. #include <search.h>
  13. #include <errno.h>
  14. DECLARE_GLOBAL_DATA_PTR;
  15. env_t *env_ptr;
  16. char *env_name_spec = "dataflash";
  17. uchar env_get_char_spec(int index)
  18. {
  19. uchar c;
  20. read_dataflash(CONFIG_ENV_ADDR + index + offsetof(env_t, data),
  21. 1, (char *)&c);
  22. return c;
  23. }
  24. void env_relocate_spec(void)
  25. {
  26. char buf[CONFIG_ENV_SIZE];
  27. read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf);
  28. env_import(buf, 1);
  29. }
  30. #ifdef CONFIG_ENV_OFFSET_REDUND
  31. #error No support for redundant environment on dataflash yet!
  32. #endif
  33. int saveenv(void)
  34. {
  35. env_t env_new;
  36. ssize_t len;
  37. char *res;
  38. res = (char *)&env_new.data;
  39. len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
  40. if (len < 0) {
  41. error("Cannot export environment: errno = %d\n", errno);
  42. return 1;
  43. }
  44. env_new.crc = crc32(0, env_new.data, ENV_SIZE);
  45. return write_dataflash(CONFIG_ENV_ADDR,
  46. (unsigned long)&env_new,
  47. CONFIG_ENV_SIZE);
  48. }
  49. /*
  50. * Initialize environment use
  51. *
  52. * We are still running from ROM, so data use is limited.
  53. * Use a (moderately small) buffer on the stack
  54. */
  55. int env_init(void)
  56. {
  57. ulong crc, len = ENV_SIZE, new = 0;
  58. unsigned off;
  59. uchar buf[64];
  60. if (gd->env_valid)
  61. return 0;
  62. AT91F_DataflashInit(); /* prepare for DATAFLASH read/write */
  63. /* read old CRC */
  64. read_dataflash(CONFIG_ENV_ADDR + offsetof(env_t, crc),
  65. sizeof(ulong), (char *)&crc);
  66. off = offsetof(env_t, data);
  67. while (len > 0) {
  68. int n = (len > sizeof(buf)) ? sizeof(buf) : len;
  69. read_dataflash(CONFIG_ENV_ADDR + off, n, (char *)buf);
  70. new = crc32(new, buf, n);
  71. len -= n;
  72. off += n;
  73. }
  74. if (crc == new) {
  75. gd->env_addr = offsetof(env_t, data);
  76. gd->env_valid = 1;
  77. } else {
  78. gd->env_addr = (ulong)&default_environment[0];
  79. gd->env_valid = 0;
  80. }
  81. return 0;
  82. }