memsize.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #include <init.h>
  8. DECLARE_GLOBAL_DATA_PTR;
  9. #ifdef __PPC__
  10. /*
  11. * At least on G2 PowerPC cores, sequential accesses to non-existent
  12. * memory must be synchronized.
  13. */
  14. # include <asm/io.h> /* for sync() */
  15. #else
  16. # define sync() /* nothing */
  17. #endif
  18. /*
  19. * Check memory range for valid RAM. A simple memory test determines
  20. * the actually available RAM size between addresses `base' and
  21. * `base + maxsize'.
  22. */
  23. long get_ram_size(long *base, long maxsize)
  24. {
  25. volatile long *addr;
  26. long save[BITS_PER_LONG - 1];
  27. long save_base;
  28. long cnt;
  29. long val;
  30. long size;
  31. int i = 0;
  32. for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
  33. addr = base + cnt; /* pointer arith! */
  34. sync();
  35. save[i++] = *addr;
  36. sync();
  37. *addr = ~cnt;
  38. }
  39. addr = base;
  40. sync();
  41. save_base = *addr;
  42. sync();
  43. *addr = 0;
  44. sync();
  45. if ((val = *addr) != 0) {
  46. /* Restore the original data before leaving the function. */
  47. sync();
  48. *base = save_base;
  49. for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
  50. addr = base + cnt;
  51. sync();
  52. *addr = save[--i];
  53. }
  54. return (0);
  55. }
  56. for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
  57. addr = base + cnt; /* pointer arith! */
  58. val = *addr;
  59. *addr = save[--i];
  60. if (val != ~cnt) {
  61. size = cnt * sizeof(long);
  62. /*
  63. * Restore the original data
  64. * before leaving the function.
  65. */
  66. for (cnt <<= 1;
  67. cnt < maxsize / sizeof(long);
  68. cnt <<= 1) {
  69. addr = base + cnt;
  70. *addr = save[--i];
  71. }
  72. /* warning: don't restore save_base in this case,
  73. * it is already done in the loop because
  74. * base and base+size share the same physical memory
  75. * and *base is saved after *(base+size) modification
  76. * in first loop
  77. */
  78. return (size);
  79. }
  80. }
  81. *base = save_base;
  82. return (maxsize);
  83. }
  84. phys_size_t __weak get_effective_memsize(void)
  85. {
  86. #ifndef CONFIG_VERY_BIG_RAM
  87. return gd->ram_size;
  88. #else
  89. /* limit stack to what we can reasonable map */
  90. return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
  91. CONFIG_MAX_MEM_MAPPED : gd->ram_size);
  92. #endif
  93. }