1*10465441SEvalZero/* 2*10465441SEvalZero * File : cache_gcc.S 3*10465441SEvalZero * This file is part of RT-Thread RTOS 4*10465441SEvalZero * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team 5*10465441SEvalZero * 6*10465441SEvalZero * The license and distribution terms for this file may be 7*10465441SEvalZero * found in the file LICENSE in this distribution or at 8*10465441SEvalZero * http://www.rt-thread.org/license/LICENSE 9*10465441SEvalZero * 10*10465441SEvalZero * Change Logs: 11*10465441SEvalZero * Date Author Notes 12*10465441SEvalZero * 2010-05-17 swkyer first version 13*10465441SEvalZero * 2010-09-11 bernard port to Loongson SoC3210 14*10465441SEvalZero * 2011-08-08 lgnq port to Loongson LS1B 15*10465441SEvalZero * 2015-07-08 chinesebear port to Loongson LS1C 16*10465441SEvalZero */ 17*10465441SEvalZero#include "../common/mipsregs.h" 18*10465441SEvalZero#include "../common/mips.inc" 19*10465441SEvalZero#include "../common/asm.h" 20*10465441SEvalZero#include "cache.h" 21*10465441SEvalZero 22*10465441SEvalZero .ent cache_init 23*10465441SEvalZero .global cache_init 24*10465441SEvalZero .set noreorder 25*10465441SEvalZerocache_init: 26*10465441SEvalZero move t1,ra 27*10465441SEvalZero####part 2#### 28*10465441SEvalZerocache_detect_4way: 29*10465441SEvalZero mfc0 t4, CP0_CONFIG 30*10465441SEvalZero andi t5, t4, 0x0e00 31*10465441SEvalZero srl t5, t5, 9 #ic 32*10465441SEvalZero andi t6, t4, 0x01c0 33*10465441SEvalZero srl t6, t6, 6 #dc 34*10465441SEvalZero addiu t8, $0, 1 35*10465441SEvalZero addiu t9, $0, 2 36*10465441SEvalZero #set dcache way 37*10465441SEvalZero beq t6, $0, cache_d1way 38*10465441SEvalZero addiu t7, $0, 1 #1 way 39*10465441SEvalZero beq t6, t8, cache_d2way 40*10465441SEvalZero addiu t7, $0, 2 #2 way 41*10465441SEvalZero beq $0, $0, cache_d4way 42*10465441SEvalZero addiu t7, $0, 4 #4 way 43*10465441SEvalZerocache_d1way: 44*10465441SEvalZero beq $0, $0, 1f 45*10465441SEvalZero addiu t6, t6, 12 #1 way 46*10465441SEvalZerocache_d2way: 47*10465441SEvalZero beq $0, $0, 1f 48*10465441SEvalZero addiu t6, t6, 11 #2 way 49*10465441SEvalZerocache_d4way: 50*10465441SEvalZero addiu t6, t6, 10 #4 way (10), 2 way(11), 1 way(12) 51*10465441SEvalZero1: #set icache way 52*10465441SEvalZero beq t5, $0, cache_i1way 53*10465441SEvalZero addiu t3, $0, 1 #1 way 54*10465441SEvalZero beq t5, t8, cache_i2way 55*10465441SEvalZero addiu t3, $0, 2 #2 way 56*10465441SEvalZero beq $0, $0, cache_i4way 57*10465441SEvalZero addiu t3, $0, 4 #4 way 58*10465441SEvalZerocache_i1way: 59*10465441SEvalZero beq $0, $0, 1f 60*10465441SEvalZero addiu t5, t5, 12 61*10465441SEvalZerocache_i2way: 62*10465441SEvalZero beq $0, $0, 1f 63*10465441SEvalZero addiu t5, t5, 11 64*10465441SEvalZerocache_i4way: 65*10465441SEvalZero addiu t5, t5, 10 #4 way (10), 2 way(11), 1 way(12) 66*10465441SEvalZero 67*10465441SEvalZero1: addiu t4, $0, 1 68*10465441SEvalZero sllv t6, t4, t6 69*10465441SEvalZero sllv t5, t4, t5 70*10465441SEvalZero#if 0 71*10465441SEvalZero la t0, memvar 72*10465441SEvalZero sw t7, 0x0(t0) #ways 73*10465441SEvalZero sw t5, 0x4(t0) #icache size 74*10465441SEvalZero sw t6, 0x8(t0) #dcache size 75*10465441SEvalZero#endif 76*10465441SEvalZero####part 3#### 77*10465441SEvalZero .set mips3 78*10465441SEvalZero lui a0, 0x8000 79*10465441SEvalZero addu a1, $0, t5 80*10465441SEvalZero addu a2, $0, t6 81*10465441SEvalZerocache_init_d2way: 82*10465441SEvalZero#a0=0x80000000, a1=icache_size, a2=dcache_size 83*10465441SEvalZero#a3, v0 and v1 used as local registers 84*10465441SEvalZero mtc0 $0, CP0_TAGHI 85*10465441SEvalZero addu v0, $0, a0 86*10465441SEvalZero addu v1, a0, a2 87*10465441SEvalZero1: slt a3, v0, v1 88*10465441SEvalZero beq a3, $0, 1f 89*10465441SEvalZero nop 90*10465441SEvalZero mtc0 $0, CP0_TAGLO 91*10465441SEvalZero beq t7, 1, 4f 92*10465441SEvalZero cache Index_Store_Tag_D, 0x0(v0) # 1 way 93*10465441SEvalZero beq t7, 2 ,4f 94*10465441SEvalZero cache Index_Store_Tag_D, 0x1(v0) # 2 way 95*10465441SEvalZero cache Index_Store_Tag_D, 0x2(v0) # 4 way 96*10465441SEvalZero cache Index_Store_Tag_D, 0x3(v0) 97*10465441SEvalZero4: beq $0, $0, 1b 98*10465441SEvalZero addiu v0, v0, 0x20 99*10465441SEvalZero1: 100*10465441SEvalZerocache_flush_i2way: 101*10465441SEvalZero addu v0, $0, a0 102*10465441SEvalZero addu v1, a0, a1 103*10465441SEvalZero1: slt a3, v0, v1 104*10465441SEvalZero beq a3, $0, 1f 105*10465441SEvalZero nop 106*10465441SEvalZero beq t3, 1, 4f 107*10465441SEvalZero cache Index_Invalidate_I, 0x0(v0) # 1 way 108*10465441SEvalZero beq t3, 2, 4f 109*10465441SEvalZero cache Index_Invalidate_I, 0x1(v0) # 2 way 110*10465441SEvalZero cache Index_Invalidate_I, 0x2(v0) 111*10465441SEvalZero cache Index_Invalidate_I, 0x3(v0) # 4 way 112*10465441SEvalZero4: beq $0, $0, 1b 113*10465441SEvalZero addiu v0, v0, 0x20 114*10465441SEvalZero1: 115*10465441SEvalZerocache_flush_d2way: 116*10465441SEvalZero addu v0, $0, a0 117*10465441SEvalZero addu v1, a0, a2 118*10465441SEvalZero1: slt a3, v0, v1 119*10465441SEvalZero beq a3, $0, 1f 120*10465441SEvalZero nop 121*10465441SEvalZero beq t7, 1, 4f 122*10465441SEvalZero cache Index_Writeback_Inv_D, 0x0(v0) #1 way 123*10465441SEvalZero beq t7, 2, 4f 124*10465441SEvalZero cache Index_Writeback_Inv_D, 0x1(v0) # 2 way 125*10465441SEvalZero cache Index_Writeback_Inv_D, 0x2(v0) 126*10465441SEvalZero cache Index_Writeback_Inv_D, 0x3(v0) # 4 way 127*10465441SEvalZero4: beq $0, $0, 1b 128*10465441SEvalZero addiu v0, v0, 0x20 129*10465441SEvalZero1: 130*10465441SEvalZerocache_init_finish: 131*10465441SEvalZero jr t1 132*10465441SEvalZero nop 133*10465441SEvalZero .set reorder 134*10465441SEvalZero .end cache_init 135*10465441SEvalZero 136*10465441SEvalZero########################### 137*10465441SEvalZero# Enable CPU cache # 138*10465441SEvalZero########################### 139*10465441SEvalZero 140*10465441SEvalZeroLEAF(enable_cpu_cache) 141*10465441SEvalZero .set noreorder 142*10465441SEvalZero mfc0 t0, CP0_CONFIG 143*10465441SEvalZero nop 144*10465441SEvalZero and t0, ~0x03 145*10465441SEvalZero or t0, 0x03 146*10465441SEvalZero mtc0 t0, CP0_CONFIG 147*10465441SEvalZero nop 148*10465441SEvalZero .set reorder 149*10465441SEvalZero j ra 150*10465441SEvalZeroEND (enable_cpu_cache) 151*10465441SEvalZero 152*10465441SEvalZero########################### 153*10465441SEvalZero# disable CPU cache # 154*10465441SEvalZero########################### 155*10465441SEvalZero 156*10465441SEvalZeroLEAF(disable_cpu_cache) 157*10465441SEvalZero .set noreorder 158*10465441SEvalZero mfc0 t0, CP0_CONFIG 159*10465441SEvalZero nop 160*10465441SEvalZero and t0, ~0x03 161*10465441SEvalZero or t0, 0x2 162*10465441SEvalZero mtc0 t0, CP0_CONFIG 163*10465441SEvalZero nop 164*10465441SEvalZero .set reorder 165*10465441SEvalZero j ra 166*10465441SEvalZeroEND (disable_cpu_cache) 167*10465441SEvalZero 168*10465441SEvalZero/**********************************/ 169*10465441SEvalZero/* Invalidate Instruction Cache */ 170*10465441SEvalZero/**********************************/ 171*10465441SEvalZeroLEAF(Clear_TagLo) 172*10465441SEvalZero .set noreorder 173*10465441SEvalZero mtc0 zero, CP0_TAGLO 174*10465441SEvalZero nop 175*10465441SEvalZero .set reorder 176*10465441SEvalZero j ra 177*10465441SEvalZeroEND(Clear_TagLo) 178*10465441SEvalZero 179*10465441SEvalZero .set mips3 180*10465441SEvalZero/**********************************/ 181*10465441SEvalZero/* Invalidate Instruction Cache */ 182*10465441SEvalZero/**********************************/ 183*10465441SEvalZeroLEAF(Invalidate_Icache_Ls1c) 184*10465441SEvalZero .set noreorder 185*10465441SEvalZero cache Index_Invalidate_I,0(a0) 186*10465441SEvalZero cache Index_Invalidate_I,1(a0) 187*10465441SEvalZero cache Index_Invalidate_I,2(a0) 188*10465441SEvalZero cache Index_Invalidate_I,3(a0) 189*10465441SEvalZero .set reorder 190*10465441SEvalZero j ra 191*10465441SEvalZeroEND(Invalidate_Icache_Ls1c) 192*10465441SEvalZero 193*10465441SEvalZero/**********************************/ 194*10465441SEvalZero/* Invalidate Data Cache */ 195*10465441SEvalZero/**********************************/ 196*10465441SEvalZeroLEAF(Invalidate_Dcache_ClearTag_Ls1c) 197*10465441SEvalZero .set noreorder 198*10465441SEvalZero cache Index_Store_Tag_D, 0(a0) # BDSLOT: clear tag 199*10465441SEvalZero cache Index_Store_Tag_D, 1(a0) # BDSLOT: clear tag 200*10465441SEvalZero .set reorder 201*10465441SEvalZero j ra 202*10465441SEvalZeroEND(Invalidate_Dcache_ClearTag_Ls1c) 203*10465441SEvalZero 204*10465441SEvalZeroLEAF(Invalidate_Dcache_Fill_Ls1c) 205*10465441SEvalZero .set noreorder 206*10465441SEvalZero cache Index_Writeback_Inv_D, 0(a0) # BDSLOT: clear tag 207*10465441SEvalZero cache Index_Writeback_Inv_D, 1(a0) # BDSLOT: clear tag 208*10465441SEvalZero .set reorder 209*10465441SEvalZero j ra 210*10465441SEvalZeroEND(Invalidate_Dcache_Fill_Ls1c) 211*10465441SEvalZero 212*10465441SEvalZeroLEAF(Writeback_Invalidate_Dcache) 213*10465441SEvalZero .set noreorder 214*10465441SEvalZero cache Hit_Writeback_Inv_D, (a0) 215*10465441SEvalZero .set reorder 216*10465441SEvalZero j ra 217*10465441SEvalZeroEND(Writeback_Invalidate_Dcache) 218*10465441SEvalZero .set mips0 219