cpu.c 2.3 KB

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