219 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
		
		
			
		
	
	
			219 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
|  | /* | ||
|  |  * File      : cache_gcc.S | ||
|  |  * This file is part of RT-Thread RTOS | ||
|  |  * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team | ||
|  |  * | ||
|  |  * The license and distribution terms for this file may be | ||
|  |  * found in the file LICENSE in this distribution or at | ||
|  |  * http://www.rt-thread.org/license/LICENSE | ||
|  |  * | ||
|  |  * Change Logs: | ||
|  |  * Date           Author       Notes | ||
|  |  * 2010-05-17     swkyer       first version | ||
|  |  * 2010-09-11     bernard      port to Loongson SoC3210 | ||
|  |  * 2011-08-08     lgnq         port to Loongson LS1B | ||
|  |  * 2015-07-08     chinesebear  port to Loongson LS1C | ||
|  |  */ | ||
|  | #include "../common/mipsregs.h" | ||
|  | #include "../common/mips.inc" | ||
|  | #include "../common/asm.h" | ||
|  | #include "cache.h" | ||
|  | 
 | ||
|  | 	.ent	cache_init
 | ||
|  |     .global cache_init
 | ||
|  |     .set noreorder
 | ||
|  | cache_init: | ||
|  |         move t1,ra | ||
|  | ####part 2#### | ||
|  | cache_detect_4way: | ||
|  |         mfc0    t4, CP0_CONFIG | ||
|  |         andi    t5, t4, 0x0e00 | ||
|  |         srl     t5, t5, 9     #ic | ||
|  |         andi    t6, t4, 0x01c0 | ||
|  |         srl     t6, t6, 6     #dc | ||
|  |         addiu   t8, $0, 1 | ||
|  |         addiu   t9, $0, 2 | ||
|  |                                 #set dcache way | ||
|  |         beq     t6, $0,  cache_d1way | ||
|  |         addiu   t7, $0, 1       #1 way | ||
|  |         beq     t6, t8,  cache_d2way | ||
|  |         addiu   t7, $0, 2       #2 way | ||
|  |         beq     $0, $0, cache_d4way | ||
|  |         addiu   t7, $0, 4       #4 way | ||
|  | cache_d1way: | ||
|  |         beq     $0, $0, 1f | ||
|  |         addiu   t6, t6, 12      #1 way | ||
|  | cache_d2way: | ||
|  |         beq     $0, $0, 1f | ||
|  |         addiu   t6, t6, 11      #2 way | ||
|  | cache_d4way: | ||
|  |         addiu   t6, t6, 10      #4 way (10), 2 way(11), 1 way(12) | ||
|  | 1:                              #set icache way | ||
|  |         beq     t5, $0,  cache_i1way | ||
|  |         addiu   t3, $0, 1       #1 way | ||
|  |         beq     t5, t8,  cache_i2way | ||
|  |         addiu   t3, $0, 2       #2 way | ||
|  |         beq     $0, $0, cache_i4way | ||
|  |         addiu   t3, $0, 4       #4 way | ||
|  | cache_i1way: | ||
|  |         beq     $0, $0, 1f | ||
|  |         addiu   t5, t5, 12 | ||
|  | cache_i2way: | ||
|  |         beq     $0, $0, 1f | ||
|  |         addiu   t5, t5, 11 | ||
|  | cache_i4way: | ||
|  |         addiu   t5, t5, 10      #4 way (10), 2 way(11), 1 way(12) | ||
|  | 
 | ||
|  | 1:      addiu   t4, $0, 1 | ||
|  |         sllv    t6, t4, t6 | ||
|  |         sllv    t5, t4, t5 | ||
|  | #if 0 | ||
|  |     la	t0, memvar | ||
|  | 	sw	t7, 0x0(t0) #ways | ||
|  | 	sw	t5, 0x4(t0) #icache size | ||
|  | 	sw	t6, 0x8(t0) #dcache size | ||
|  | #endif | ||
|  | ####part 3#### | ||
|  | 	.set	mips3
 | ||
|  | 	lui	a0, 0x8000 | ||
|  | 	addu	a1, $0, t5 | ||
|  | 	addu	a2, $0, t6 | ||
|  | cache_init_d2way: | ||
|  | #a0=0x80000000, a1=icache_size, a2=dcache_size | ||
|  | #a3, v0 and v1 used as local registers | ||
|  | 	mtc0	$0, CP0_TAGHI | ||
|  | 	addu	v0, $0, a0 | ||
|  | 	addu	v1, a0, a2 | ||
|  | 1:	slt	a3, v0, v1 | ||
|  | 	beq	a3, $0, 1f | ||
|  | 	nop | ||
|  | 	mtc0	$0, CP0_TAGLO | ||
|  | 	beq	t7, 1, 4f | ||
|  | 	cache	Index_Store_Tag_D, 0x0(v0)	# 1 way | ||
|  | 	beq	t7, 2 ,4f | ||
|  | 	cache	Index_Store_Tag_D, 0x1(v0)	# 2 way | ||
|  | 	cache	Index_Store_Tag_D, 0x2(v0)	# 4 way | ||
|  | 	cache	Index_Store_Tag_D, 0x3(v0) | ||
|  | 4:	beq	$0, $0, 1b | ||
|  | 	addiu	v0, v0, 0x20 | ||
|  | 1: | ||
|  | cache_flush_i2way: | ||
|  | 	addu	v0, $0, a0 | ||
|  | 	addu	v1, a0, a1 | ||
|  | 1:	slt	a3, v0, v1 | ||
|  | 	beq	a3, $0, 1f | ||
|  | 	nop | ||
|  | 	beq	t3, 1, 4f | ||
|  | 	cache	Index_Invalidate_I, 0x0(v0)	# 1 way | ||
|  | 	beq	t3, 2, 4f | ||
|  | 	cache	Index_Invalidate_I, 0x1(v0)	# 2 way | ||
|  | 	cache	Index_Invalidate_I, 0x2(v0) | ||
|  | 	cache	Index_Invalidate_I, 0x3(v0)	# 4 way | ||
|  | 4:	beq	$0, $0, 1b | ||
|  | 	addiu	v0, v0, 0x20 | ||
|  | 1: | ||
|  | cache_flush_d2way: | ||
|  | 	addu	v0, $0, a0 | ||
|  | 	addu	v1, a0, a2 | ||
|  | 1:	slt	a3, v0, v1 | ||
|  | 	beq	a3, $0, 1f | ||
|  | 	nop | ||
|  | 	beq	t7, 1, 4f | ||
|  | 	cache	Index_Writeback_Inv_D, 0x0(v0) 	#1 way | ||
|  | 	beq	t7, 2, 4f | ||
|  | 	cache	Index_Writeback_Inv_D, 0x1(v0)	# 2 way | ||
|  | 	cache	Index_Writeback_Inv_D, 0x2(v0) | ||
|  | 	cache	Index_Writeback_Inv_D, 0x3(v0)	# 4 way | ||
|  | 4:	beq	$0, $0, 1b | ||
|  | 	addiu	v0, v0, 0x20 | ||
|  | 1: | ||
|  | cache_init_finish: | ||
|  | 	jr	t1 | ||
|  |     nop | ||
|  |     .set reorder
 | ||
|  | 	.end cache_init
 | ||
|  | 
 | ||
|  | ########################### | ||
|  | #  Enable CPU cache       # | ||
|  | ########################### | ||
|  | 
 | ||
|  | LEAF(enable_cpu_cache) | ||
|  | 	.set noreorder
 | ||
|  | 	mfc0	t0, CP0_CONFIG | ||
|  | 	nop | ||
|  | 	and		t0, ~0x03 | ||
|  | 	or		t0, 0x03 | ||
|  | 	mtc0	t0, CP0_CONFIG | ||
|  | 	nop | ||
|  | 	.set reorder
 | ||
|  | 	j	ra | ||
|  | END (enable_cpu_cache) | ||
|  |      | ||
|  | ########################### | ||
|  | #  disable CPU cache      # | ||
|  | ########################### | ||
|  | 
 | ||
|  | LEAF(disable_cpu_cache) | ||
|  | 	.set noreorder
 | ||
|  | 	mfc0	t0, CP0_CONFIG | ||
|  | 	nop | ||
|  | 	and		t0, ~0x03 | ||
|  | 	or 		t0, 0x2 | ||
|  | 	mtc0	t0, CP0_CONFIG | ||
|  | 	nop | ||
|  | 	.set reorder
 | ||
|  | 	j	ra | ||
|  | END (disable_cpu_cache) | ||
|  | 
 | ||
|  | /**********************************/ | ||
|  | /* Invalidate Instruction Cache	  */ | ||
|  | /**********************************/ | ||
|  | LEAF(Clear_TagLo) | ||
|  | 	.set 	noreorder
 | ||
|  | 	mtc0	zero, CP0_TAGLO | ||
|  | 	nop | ||
|  | 	.set 	reorder
 | ||
|  | 	j		ra | ||
|  | END(Clear_TagLo) | ||
|  | 
 | ||
|  |     .set mips3
 | ||
|  | /**********************************/ | ||
|  | /* Invalidate Instruction Cache	  */ | ||
|  | /**********************************/ | ||
|  | LEAF(Invalidate_Icache_Ls1c) | ||
|  | 	.set	noreorder
 | ||
|  | 	cache	Index_Invalidate_I,0(a0) | ||
|  | 	cache	Index_Invalidate_I,1(a0) | ||
|  | 	cache	Index_Invalidate_I,2(a0) | ||
|  | 	cache	Index_Invalidate_I,3(a0) | ||
|  | 	.set	reorder
 | ||
|  | 	j		ra | ||
|  | END(Invalidate_Icache_Ls1c) | ||
|  | 
 | ||
|  | /**********************************/ | ||
|  | /* Invalidate Data Cache		  */ | ||
|  | /**********************************/ | ||
|  | LEAF(Invalidate_Dcache_ClearTag_Ls1c) | ||
|  | 	.set	noreorder
 | ||
|  | 	cache	Index_Store_Tag_D, 0(a0)	# BDSLOT: clear tag | ||
|  | 	cache	Index_Store_Tag_D, 1(a0)	# BDSLOT: clear tag | ||
|  | 	.set	reorder
 | ||
|  | 	j		ra | ||
|  | END(Invalidate_Dcache_ClearTag_Ls1c) | ||
|  | 
 | ||
|  | LEAF(Invalidate_Dcache_Fill_Ls1c) | ||
|  | 	.set	noreorder
 | ||
|  | 	cache	Index_Writeback_Inv_D, 0(a0)	# BDSLOT: clear tag | ||
|  | 	cache	Index_Writeback_Inv_D, 1(a0)	# BDSLOT: clear tag | ||
|  | 	.set	reorder
 | ||
|  | 	j		ra | ||
|  | END(Invalidate_Dcache_Fill_Ls1c) | ||
|  | 
 | ||
|  | LEAF(Writeback_Invalidate_Dcache) | ||
|  | 	.set noreorder
 | ||
|  | 	cache	Hit_Writeback_Inv_D, (a0) | ||
|  | 	.set reorder
 | ||
|  | 	j	ra | ||
|  | END(Writeback_Invalidate_Dcache) | ||
|  |     .set mips0
 |