memsize.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 <common.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[32];
  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[i] = *addr;
  41. sync ();
  42. *addr = 0;
  43. sync ();
  44. if ((val = *addr) != 0) {
  45. /* Restore the original data before leaving the function.
  46. */
  47. sync ();
  48. *addr = save[i];
  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. /* Restore the original data before leaving the function.
  63. */
  64. for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
  65. addr = base + cnt;
  66. *addr = save[--i];
  67. }
  68. return (size);
  69. }
  70. }
  71. return (maxsize);
  72. }
  73. phys_size_t __weak get_effective_memsize(void)
  74. {
  75. #ifndef CONFIG_VERY_BIG_RAM
  76. return gd->ram_size;
  77. #else
  78. /* limit stack to what we can reasonable map */
  79. return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
  80. CONFIG_MAX_MEM_MAPPED : gd->ram_size);
  81. #endif
  82. }