1 /* 2 * File : mips_cache.c 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Change Logs: 21 * Date Author Notes 22 * 2016��9��7�� Urey the first version 23 */ 24 25 #include <rtthread.h> 26 #include "mips.h" 27 28 extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size); 29 void r4k_cache_init(void) 30 { 31 // cache_init(dcache_size, cpu_dcache_line_size); 32 } 33 34 void r4k_cache_flush_all(void) 35 { 36 blast_dcache16(); 37 blast_icache16(); 38 } 39 40 41 void r4k_icache_flush_all(void) 42 { 43 blast_icache16(); 44 } 45 46 void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size) 47 { 48 rt_ubase_t end, a; 49 50 if (size > g_mips_core.icache_size) 51 { 52 blast_icache16(); 53 } 54 else 55 { 56 rt_ubase_t ic_lsize = g_mips_core.icache_line_size; 57 58 a = addr & ~(ic_lsize - 1); 59 end = ((addr + size) - 1) & ~(ic_lsize - 1); 60 while (1) 61 { 62 flush_icache_line(a); 63 if (a == end) 64 break; 65 a += ic_lsize; 66 } 67 } 68 } 69 70 void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size) 71 { 72 rt_ubase_t end, a; 73 rt_ubase_t ic_lsize = g_mips_core.icache_line_size; 74 75 a = addr & ~(ic_lsize - 1); 76 end = ((addr + size) - 1) & ~(ic_lsize - 1); 77 while (1) 78 { 79 lock_icache_line(a); 80 if (a == end) 81 break; 82 a += ic_lsize; 83 } 84 } 85 86 void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size) 87 { 88 rt_ubase_t end, a; 89 rt_ubase_t dc_lsize = g_mips_core.dcache_line_size; 90 91 a = addr & ~(dc_lsize - 1); 92 end = ((addr + size) - 1) & ~(dc_lsize - 1); 93 while (1) 94 { 95 invalidate_dcache_line(a); 96 if (a == end) 97 break; 98 a += dc_lsize; 99 } 100 } 101 102 void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size) 103 { 104 rt_ubase_t end, a; 105 106 if (size >= g_mips_core.dcache_size) 107 { 108 blast_dcache16(); 109 } 110 else 111 { 112 rt_ubase_t dc_lsize = g_mips_core.dcache_line_size; 113 114 a = addr & ~(dc_lsize - 1); 115 end = ((addr + size) - 1) & ~(dc_lsize - 1); 116 while (1) 117 { 118 flush_dcache_line(a); 119 if (a == end) 120 break; 121 a += dc_lsize; 122 } 123 } 124 } 125 126 #define dma_cache_wback_inv(start,size) \ 127 do { (void) (start); (void) (size); } while (0) 128 #define dma_cache_wback(start,size) \ 129 do { (void) (start); (void) (size); } while (0) 130 #define dma_cache_inv(start,size) \ 131 do { (void) (start); (void) (size); } while (0) 132 133 134 void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction) 135 { 136 switch (direction) 137 { 138 case DMA_TO_DEVICE: 139 r4k_dcache_wback_inv(addr, size); 140 break; 141 142 case DMA_FROM_DEVICE: 143 r4k_dcache_wback_inv(addr, size); 144 break; 145 146 case DMA_BIDIRECTIONAL: 147 dma_cache_wback_inv(addr, size); 148 break; 149 default: 150 RT_ASSERT(0) ; 151 } 152 } 153 154