cache.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
  4. * Copyright (C) 2009, Wind River Systems Inc
  5. * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
  6. */
  7. #include <common.h>
  8. #include <cpu_func.h>
  9. #include <asm/cache.h>
  10. DECLARE_GLOBAL_DATA_PTR;
  11. static void __flush_dcache(unsigned long start, unsigned long end)
  12. {
  13. unsigned long addr;
  14. start &= ~(gd->arch.dcache_line_size - 1);
  15. end += (gd->arch.dcache_line_size - 1);
  16. end &= ~(gd->arch.dcache_line_size - 1);
  17. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  18. __asm__ __volatile__ (" flushda 0(%0)\n"
  19. : /* Outputs */
  20. : /* Inputs */ "r"(addr)
  21. /* : No clobber */);
  22. }
  23. }
  24. static void __flush_dcache_all(unsigned long start, unsigned long end)
  25. {
  26. unsigned long addr;
  27. start &= ~(gd->arch.dcache_line_size - 1);
  28. end += (gd->arch.dcache_line_size - 1);
  29. end &= ~(gd->arch.dcache_line_size - 1);
  30. if (end > start + gd->arch.dcache_size)
  31. end = start + gd->arch.dcache_size;
  32. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  33. __asm__ __volatile__ (" flushd 0(%0)\n"
  34. : /* Outputs */
  35. : /* Inputs */ "r"(addr)
  36. /* : No clobber */);
  37. }
  38. }
  39. static void __invalidate_dcache(unsigned long start, unsigned long end)
  40. {
  41. unsigned long addr;
  42. start &= ~(gd->arch.dcache_line_size - 1);
  43. end += (gd->arch.dcache_line_size - 1);
  44. end &= ~(gd->arch.dcache_line_size - 1);
  45. for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
  46. __asm__ __volatile__ (" initda 0(%0)\n"
  47. : /* Outputs */
  48. : /* Inputs */ "r"(addr)
  49. /* : No clobber */);
  50. }
  51. }
  52. static void __flush_icache(unsigned long start, unsigned long end)
  53. {
  54. unsigned long addr;
  55. start &= ~(gd->arch.icache_line_size - 1);
  56. end += (gd->arch.icache_line_size - 1);
  57. end &= ~(gd->arch.icache_line_size - 1);
  58. if (end > start + gd->arch.icache_size)
  59. end = start + gd->arch.icache_size;
  60. for (addr = start; addr < end; addr += gd->arch.icache_line_size) {
  61. __asm__ __volatile__ (" flushi %0\n"
  62. : /* Outputs */
  63. : /* Inputs */ "r"(addr)
  64. /* : No clobber */);
  65. }
  66. __asm__ __volatile(" flushp\n");
  67. }
  68. void flush_dcache_all(void)
  69. {
  70. __flush_dcache_all(0, gd->arch.dcache_size);
  71. __flush_icache(0, gd->arch.icache_size);
  72. }
  73. void flush_dcache_range(unsigned long start, unsigned long end)
  74. {
  75. if (gd->arch.has_initda)
  76. __flush_dcache(start, end);
  77. else
  78. __flush_dcache_all(start, end);
  79. }
  80. void flush_cache(unsigned long start, unsigned long size)
  81. {
  82. if (gd->arch.has_initda)
  83. __flush_dcache(start, start + size);
  84. else
  85. __flush_dcache_all(start, start + size);
  86. __flush_icache(start, start + size);
  87. }
  88. void invalidate_dcache_range(unsigned long start, unsigned long end)
  89. {
  90. if (gd->arch.has_initda)
  91. __invalidate_dcache(start, end);
  92. else
  93. __flush_dcache_all(start, end);
  94. }
  95. int dcache_status(void)
  96. {
  97. return 1;
  98. }
  99. void dcache_enable(void)
  100. {
  101. flush_dcache_all();
  102. }
  103. void dcache_disable(void)
  104. {
  105. flush_dcache_all();
  106. }