memsize.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2004
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. */
  6. #include <common.h>
  7. DECLARE_GLOBAL_DATA_PTR;
  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[BITS_PER_LONG - 1];
  26. long save_base;
  27. long cnt;
  28. long val;
  29. long size;
  30. int i = 0;
  31. for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
  32. addr = base + cnt; /* pointer arith! */
  33. sync();
  34. save[i++] = *addr;
  35. sync();
  36. *addr = ~cnt;
  37. }
  38. addr = base;
  39. sync();
  40. save_base = *addr;
  41. sync();
  42. *addr = 0;
  43. sync();
  44. if ((val = *addr) != 0) {
  45. /* Restore the original data before leaving the function. */
  46. sync();
  47. *base = save_base;
  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. /*
  62. * Restore the original data
  63. * before leaving the function.
  64. */
  65. for (cnt <<= 1;
  66. cnt < maxsize / sizeof(long);
  67. cnt <<= 1) {
  68. addr = base + cnt;
  69. *addr = save[--i];
  70. }
  71. /* warning: don't restore save_base in this case,
  72. * it is already done in the loop because
  73. * base and base+size share the same physical memory
  74. * and *base is saved after *(base+size) modification
  75. * in first loop
  76. */
  77. return (size);
  78. }
  79. }
  80. *base = save_base;
  81. return (maxsize);
  82. }
  83. phys_size_t __weak get_effective_memsize(void)
  84. {
  85. #ifndef CONFIG_VERY_BIG_RAM
  86. return gd->ram_size;
  87. #else
  88. /* limit stack to what we can reasonable map */
  89. return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
  90. CONFIG_MAX_MEM_MAPPED : gd->ram_size);
  91. #endif
  92. }