1 /* 2 * File : cache.c 3 * COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (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 along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Change Logs: 20 * Date Author Notes 21 */ 22 23 #include "../xburst/cache.h" 24 25 #include <board.h> 26 27 #define CACHE_SIZE 16*1024 28 #define CACHE_LINE_SIZE 32 29 #define KSEG0 0x80000000 30 31 #define K0_TO_K1() \ 32 do { \ 33 unsigned long __k0_addr; \ 34 \ 35 __asm__ __volatile__( \ 36 "la %0, 1f\n\t" \ 37 "or %0, %0, %1\n\t" \ 38 "jr %0\n\t" \ 39 "nop\n\t" \ 40 "1: nop\n" \ 41 : "=&r"(__k0_addr) \ 42 : "r" (0x20000000) ); \ 43 } while(0) 44 45 #define K1_TO_K0() \ 46 do { \ 47 unsigned long __k0_addr; \ 48 __asm__ __volatile__( \ 49 "nop;nop;nop;nop;nop;nop;nop\n\t" \ 50 "la %0, 1f\n\t" \ 51 "jr %0\n\t" \ 52 "nop\n\t" \ 53 "1: nop\n" \ 54 : "=&r" (__k0_addr)); \ 55 } while (0) 56 57 #define INVALIDATE_BTB() \ 58 do { \ 59 unsigned long tmp; \ 60 __asm__ __volatile__( \ 61 ".set mips32\n\t" \ 62 "mfc0 %0, $16, 7\n\t" \ 63 "nop\n\t" \ 64 "ori %0, 2\n\t" \ 65 "mtc0 %0, $16, 7\n\t" \ 66 "nop\n\t" \ 67 ".set mips2\n\t" \ 68 : "=&r" (tmp)); \ 69 } while (0) 70 71 #define SYNC_WB() __asm__ __volatile__ ("sync") 72 73 #define cache_op(op,addr) \ 74 __asm__ __volatile__( \ 75 " .set noreorder \n" \ 76 " .set mips32\n\t \n" \ 77 " cache %0, %1 \n" \ 78 " .set mips0 \n" \ 79 " .set reorder" \ 80 : \ 81 : "i" (op), "m" (*(unsigned char *)(addr))) 82 83 void __icache_invalidate_all(void) 84 { 85 unsigned int i; 86 87 K0_TO_K1(); 88 89 asm volatile (".set noreorder\n" 90 ".set mips32\n\t" 91 "mtc0\t$0,$28\n\t" 92 "mtc0\t$0,$29\n" 93 ".set mips0\n" 94 ".set reorder\n"); 95 for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE) 96 cache_op(Index_Store_Tag_I, i); 97 98 K1_TO_K0(); 99 100 INVALIDATE_BTB(); 101 } 102 103 void __dcache_writeback_all(void) 104 { 105 unsigned int i; 106 107 for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE) 108 cache_op(Index_Writeback_Inv_D, i); 109 110 SYNC_WB(); 111 } 112 113 void rt_hw_cache_init(void) 114 { 115 __dcache_writeback_all(); 116 __icache_invalidate_all(); 117 } 118 119