cache.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2012 Andes Technology Corporation
  3. * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
  4. * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache)
  10. {
  11. if (cache == ICACHE)
  12. return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \
  13. >> ICM_CFG_OFF_ISZ) - 1);
  14. else
  15. return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \
  16. >> DCM_CFG_OFF_DSZ) - 1);
  17. }
  18. void flush_dcache_range(unsigned long start, unsigned long end)
  19. {
  20. unsigned long line_size;
  21. line_size = CACHE_LINE_SIZE(DCACHE);
  22. while (end > start) {
  23. asm volatile (
  24. "\n\tcctl %0, L1D_VA_WB"
  25. "\n\tcctl %0, L1D_VA_INVAL"
  26. :
  27. : "r" (start)
  28. );
  29. start += line_size;
  30. }
  31. }
  32. void invalidate_icache_range(unsigned long start, unsigned long end)
  33. {
  34. unsigned long line_size;
  35. line_size = CACHE_LINE_SIZE(ICACHE);
  36. while (end > start) {
  37. asm volatile (
  38. "\n\tcctl %0, L1I_VA_INVAL"
  39. :
  40. : "r"(start)
  41. );
  42. start += line_size;
  43. }
  44. }
  45. void invalidate_dcache_range(unsigned long start, unsigned long end)
  46. {
  47. unsigned long line_size;
  48. line_size = CACHE_LINE_SIZE(DCACHE);
  49. while (end > start) {
  50. asm volatile (
  51. "\n\tcctl %0, L1D_VA_INVAL"
  52. :
  53. : "r"(start)
  54. );
  55. start += line_size;
  56. }
  57. }
  58. void flush_cache(unsigned long addr, unsigned long size)
  59. {
  60. flush_dcache_range(addr, addr + size);
  61. invalidate_icache_range(addr, addr + size);
  62. }
  63. void icache_enable(void)
  64. {
  65. asm volatile (
  66. "mfsr $p0, $mr8\n\t"
  67. "ori $p0, $p0, 0x01\n\t"
  68. "mtsr $p0, $mr8\n\t"
  69. "isb\n\t"
  70. );
  71. }
  72. void icache_disable(void)
  73. {
  74. asm volatile (
  75. "mfsr $p0, $mr8\n\t"
  76. "li $p1, ~0x01\n\t"
  77. "and $p0, $p0, $p1\n\t"
  78. "mtsr $p0, $mr8\n\t"
  79. "isb\n\t"
  80. );
  81. }
  82. int icache_status(void)
  83. {
  84. int ret;
  85. asm volatile (
  86. "mfsr $p0, $mr8\n\t"
  87. "andi %0, $p0, 0x01\n\t"
  88. : "=r" (ret)
  89. :
  90. : "memory"
  91. );
  92. return ret;
  93. }
  94. void dcache_enable(void)
  95. {
  96. asm volatile (
  97. "mfsr $p0, $mr8\n\t"
  98. "ori $p0, $p0, 0x02\n\t"
  99. "mtsr $p0, $mr8\n\t"
  100. "isb\n\t"
  101. );
  102. }
  103. void dcache_disable(void)
  104. {
  105. asm volatile (
  106. "mfsr $p0, $mr8\n\t"
  107. "li $p1, ~0x02\n\t"
  108. "and $p0, $p0, $p1\n\t"
  109. "mtsr $p0, $mr8\n\t"
  110. "isb\n\t"
  111. );
  112. }
  113. int dcache_status(void)
  114. {
  115. int ret;
  116. asm volatile (
  117. "mfsr $p0, $mr8\n\t"
  118. "andi %0, $p0, 0x02\n\t"
  119. : "=r" (ret)
  120. :
  121. : "memory"
  122. );
  123. return ret;
  124. }