cache.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
  3. * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18. * MA 02111-1307 USA
  19. */
  20. #include <common.h>
  21. #include <asm/system.h>
  22. void flush_dcache_range(unsigned long addr, unsigned long stop)
  23. {
  24. ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  25. while (addr < stop) {
  26. mtspr(SPR_DCBFR, addr);
  27. addr += block_size;
  28. }
  29. }
  30. void invalidate_dcache_range(unsigned long addr, unsigned long stop)
  31. {
  32. ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  33. while (addr < stop) {
  34. mtspr(SPR_DCBIR, addr);
  35. addr += block_size;
  36. }
  37. }
  38. static void invalidate_icache_range(unsigned long addr, unsigned long stop)
  39. {
  40. ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
  41. while (addr < stop) {
  42. mtspr(SPR_ICBIR, addr);
  43. addr += block_size;
  44. }
  45. }
  46. void flush_cache(unsigned long addr, unsigned long size)
  47. {
  48. flush_dcache_range(addr, addr + size);
  49. invalidate_icache_range(addr, addr + size);
  50. }
  51. int icache_status(void)
  52. {
  53. return mfspr(SPR_SR) & SPR_SR_ICE;
  54. }
  55. int checkicache(void)
  56. {
  57. unsigned long iccfgr;
  58. unsigned long cache_set_size;
  59. unsigned long cache_ways;
  60. unsigned long cache_block_size;
  61. iccfgr = mfspr(SPR_ICCFGR);
  62. cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
  63. cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
  64. cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
  65. return cache_set_size * cache_ways * cache_block_size;
  66. }
  67. int dcache_status(void)
  68. {
  69. return mfspr(SPR_SR) & SPR_SR_DCE;
  70. }
  71. int checkdcache(void)
  72. {
  73. unsigned long dccfgr;
  74. unsigned long cache_set_size;
  75. unsigned long cache_ways;
  76. unsigned long cache_block_size;
  77. dccfgr = mfspr(SPR_DCCFGR);
  78. cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
  79. cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
  80. cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
  81. return cache_set_size * cache_ways * cache_block_size;
  82. }
  83. void dcache_enable(void)
  84. {
  85. mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
  86. asm volatile("l.nop");
  87. asm volatile("l.nop");
  88. asm volatile("l.nop");
  89. asm volatile("l.nop");
  90. asm volatile("l.nop");
  91. asm volatile("l.nop");
  92. asm volatile("l.nop");
  93. asm volatile("l.nop");
  94. }
  95. void dcache_disable(void)
  96. {
  97. mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
  98. }
  99. void icache_enable(void)
  100. {
  101. mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
  102. asm volatile("l.nop");
  103. asm volatile("l.nop");
  104. asm volatile("l.nop");
  105. asm volatile("l.nop");
  106. asm volatile("l.nop");
  107. asm volatile("l.nop");
  108. asm volatile("l.nop");
  109. asm volatile("l.nop");
  110. }
  111. void icache_disable(void)
  112. {
  113. mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
  114. }
  115. int cache_init(void)
  116. {
  117. if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
  118. icache_disable();
  119. invalidate_icache_range(0, checkicache());
  120. icache_enable();
  121. }
  122. if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
  123. dcache_disable();
  124. invalidate_dcache_range(0, checkdcache());
  125. dcache_enable();
  126. }
  127. return 0;
  128. }