memsize.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * (C) Copyright 2004
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <config.h>
  8. #ifdef __PPC__
  9. /*
  10. * At least on G2 PowerPC cores, sequential accesses to non-existent
  11. * memory must be synchronized.
  12. */
  13. # include <asm/io.h> /* for sync() */
  14. #else
  15. # define sync() /* nothing */
  16. #endif
  17. /*
  18. * Check memory range for valid RAM. A simple memory test determines
  19. * the actually available RAM size between addresses `base' and
  20. * `base + maxsize'.
  21. */
  22. long get_ram_size(long *base, long maxsize)
  23. {
  24. volatile long *addr;
  25. long save[32];
  26. long cnt;
  27. long val;
  28. long size;
  29. int i = 0;
  30. for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
  31. addr = base + cnt; /* pointer arith! */
  32. sync ();
  33. save[i++] = *addr;
  34. sync ();
  35. *addr = ~cnt;
  36. }
  37. addr = base;
  38. sync ();
  39. save[i] = *addr;
  40. sync ();
  41. *addr = 0;
  42. sync ();
  43. if ((val = *addr) != 0) {
  44. /* Restore the original data before leaving the function.
  45. */
  46. sync ();
  47. *addr = save[i];
  48. for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
  49. addr = base + cnt;
  50. sync ();
  51. *addr = save[--i];
  52. }
  53. return (0);
  54. }
  55. for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
  56. addr = base + cnt; /* pointer arith! */
  57. val = *addr;
  58. *addr = save[--i];
  59. if (val != ~cnt) {
  60. size = cnt * sizeof (long);
  61. /* Restore the original data before leaving the function.
  62. */
  63. for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
  64. addr = base + cnt;
  65. *addr = save[--i];
  66. }
  67. return (size);
  68. }
  69. }
  70. return (maxsize);
  71. }