cpu.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * (C) Copyright 2004 Texas Insturments
  3. *
  4. * (C) Copyright 2002
  5. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  6. * Marius Groeger <mgroeger@sysgo.de>
  7. *
  8. * (C) Copyright 2002
  9. * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
  10. *
  11. * SPDX-License-Identifier: GPL-2.0+
  12. */
  13. /*
  14. * CPU specific code
  15. */
  16. #include <common.h>
  17. #include <command.h>
  18. #include <asm/system.h>
  19. static void cache_flush(void);
  20. int cleanup_before_linux (void)
  21. {
  22. /*
  23. * this function is called just before we call linux
  24. * it prepares the processor for linux
  25. *
  26. * we turn off caches etc ...
  27. */
  28. disable_interrupts ();
  29. /* turn off I/D-cache */
  30. icache_disable();
  31. dcache_disable();
  32. /* flush I/D-cache */
  33. cache_flush();
  34. return 0;
  35. }
  36. static void cache_flush(void)
  37. {
  38. unsigned long i = 0;
  39. /* clean entire data cache */
  40. asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
  41. /* invalidate both caches and flush btb */
  42. asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
  43. /* mem barrier to sync things */
  44. asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
  45. }
  46. #ifndef CONFIG_SYS_DCACHE_OFF
  47. #ifndef CONFIG_SYS_CACHELINE_SIZE
  48. #define CONFIG_SYS_CACHELINE_SIZE 32
  49. #endif
  50. void invalidate_dcache_all(void)
  51. {
  52. asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
  53. }
  54. void flush_dcache_all(void)
  55. {
  56. asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
  57. asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
  58. }
  59. static int check_cache_range(unsigned long start, unsigned long stop)
  60. {
  61. int ok = 1;
  62. if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
  63. ok = 0;
  64. if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
  65. ok = 0;
  66. if (!ok)
  67. debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
  68. start, stop);
  69. return ok;
  70. }
  71. void invalidate_dcache_range(unsigned long start, unsigned long stop)
  72. {
  73. if (!check_cache_range(start, stop))
  74. return;
  75. while (start < stop) {
  76. asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
  77. start += CONFIG_SYS_CACHELINE_SIZE;
  78. }
  79. }
  80. void flush_dcache_range(unsigned long start, unsigned long stop)
  81. {
  82. if (!check_cache_range(start, stop))
  83. return;
  84. while (start < stop) {
  85. asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
  86. start += CONFIG_SYS_CACHELINE_SIZE;
  87. }
  88. asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
  89. }
  90. void flush_cache(unsigned long start, unsigned long size)
  91. {
  92. flush_dcache_range(start, start + size);
  93. }
  94. #else /* #ifndef CONFIG_SYS_DCACHE_OFF */
  95. void invalidate_dcache_all(void)
  96. {
  97. }
  98. void flush_dcache_all(void)
  99. {
  100. }
  101. void invalidate_dcache_range(unsigned long start, unsigned long stop)
  102. {
  103. }
  104. void flush_dcache_range(unsigned long start, unsigned long stop)
  105. {
  106. }
  107. void flush_cache(unsigned long start, unsigned long size)
  108. {
  109. }
  110. #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
  111. #if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF)
  112. void enable_caches(void)
  113. {
  114. #ifndef CONFIG_SYS_ICACHE_OFF
  115. icache_enable();
  116. #endif
  117. #ifndef CONFIG_SYS_DCACHE_OFF
  118. dcache_enable();
  119. #endif
  120. }
  121. #endif