⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r4300cfl.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 S
字号:
/*************************************************************
 * File: lib/r4300cfl.s
 * Purpose: Part of C runtime library
 * Author: Phil Bunce (pjb@carmel.com)
 * Revision History:
 *	980304	Created
 */

#include <mips.h>

#ifdef flush_icache
#undef flush_icache
#endif
#ifdef wb_dcache
#undef wb_dcache
#endif

#ifdef ALGOR
#define flush_icache(o,r)	.set nowarn; \
			.word	(0xbc000000|((r)<<21)|((o)<<18)); \
			.set warn; 42:
#define hitinv_dcache(o,r)	.set nowarn; \
			.word	(0xbc110000|((r)<<21)|((o)<<18)); \
			.set warn; 42:
#define isttag_dcache(o,r)	.set nowarn; \
			.word	(0xbc090000|((r)<<21)|((o)<<18)); \
			.set warn; 42:
#define wb_dcache(o,r)	.set nowarn; \
			.word	(0xbc010000|((r)<<21)|((o)<<18)); \
			.set warn; 42:
#define read_dtag(o,r)	.set nowarn; \
			.word	(0xbc050000|((r)<<21)|((o)<<18)); \
			.set warn; 42:
#else
#define flush_icache(o,r)	.word	(0xbc000000|((r)<<21)|((o)<<18))
#define hitinv_dcache(o,r)	.word	(0xbc110000|((r)<<21)|((o)<<18))
#define isttag_dcache(o,r)	.word	(0xbc090000|((r)<<21)|((o)<<18))
#define wb_dcache(o,r)	.word	(0xbc010000|((r)<<21)|((o)<<18))
#define	read_dtag(o,r)	.word	(0xbc050000|((r)<<21)|((o)<<18))
#endif

#define Index_Invalidate 0	/* I */
#define Index_Writeback_Invalidate 0	/* D */
#define Index_Store_Tag	2	/* I & D */
#define Hit_Invalidate	4	/* I & D */

#define C0_TAGLO	$28
#define C0_TAGHI	$29
#define SR_DE		(1<<16)

/*************************************************************
*  r4300_flush(type,adr)
*	Flush the designated VR4300 cache.
*	Note that this isn't a real subroutine, it just transfers
*	control to the appropriate flush routine.
*
*	The VR4300 has a 16KB direct-mapped icache that has 8 words 
*	per line. It has a 8KB direct-mapped write-back dcache that 
*	has 4 words per line.
*
*	To flush the Icache, issue the instruction 0xbc010000.
*	To flush the Dcache, issue the instruction 0xbc020000.
*	To flush both caches, issue the instruction 0xbc030000.
*	To write-back a Dcache line, issue the instruction 0xbc040000
*		specifying offset and base.
*/
	.globl r4300_flush
	.ent r4300_flush
r4300_flush:
	bne	a0,ICACHEI,1f
	j	r4300_iflush

1:	bne	a0,ICACHE,1f
	j	r4300_iflush

1:	bne	a0,DCACHE,1f
	j	r4300_dflush

1:	bne	a0,DCACHEI,1f
	j	r4300_dflushi

1:	move	a0,a1
	j	r4300_iflush
	.end r4300_flush


/*************************************************************
*  r4300_iflush()
*	Flush the VR4300 Instruction cache.
*/
	.globl r4300_iflush
	.ent r4300_iflush
r4300_iflush:
	# disable ints
	.set noreorder
	mfc0	t7,C0_SR
	nop
	and	t0,t7,~SR_IEC
	or	t0,SR_DE
	mtc0	t0,C0_SR
	.set reorder

	# switch to Kseg1
	la	t0,1f
	li	t1,K1BASE
	or	t0,t1
	j	t0

1:	
	# save taglo
	.set noreorder
	mfc0	t6,C0_TAGLO

	li	t1,0x80000000
	addu	t0,t1,(16*1024)	# cache size

1: 	
	# set taglo
	mtc0	zero,C0_TAGLO
	nop
	flush_icache(0,r_t1)
	nop
	bne	t0,t1,1b
	addu	t1,16		# line size

	# restore taglo
	mtc0	t6,C0_TAGLO
	nop

	nop
	mtc0	t7,C0_SR	# restore SR
	nop
	nop
	.set reorder
	j	ra
	.end r4300_iflush

/*************************************************************
*  r4300_dflushi()
*	Initial flush of the VR4300 Data cache.
*/
	.globl r4300_dflushi
	.ent r4300_dflushi
r4300_dflushi:
	# disable ints
	.set noreorder
	mfc0	t7,C0_SR
	nop
	and	t0,t7,~SR_IEC
	or	t0,SR_DE
	mtc0	t0,C0_SR
	.set reorder

	# switch to Kseg1
	la	t0,1f
	li	t1,K1BASE
	or	t0,t1
	j	t0

1:	
	# save taglo & taghi
	.set noreorder
	mfc0	t6,C0_TAGHI
	mfc0	t5,C0_TAGLO

	# load valid virtual addresses into the cache tags
	li	t1,0x80000000
	addu	t0,t1,(8*1024)	# cache size
	mtc0	zero,C0_TAGHI
	mtc0	zero,C0_TAGLO
	nop
	nop

1:
	isttag_dcache(0,r_t1)
	nop
	bne	t0,t1,1b
	addu	t1,16		# line size
	.set reorder

	# now Hit_Invalidate all entries
	li	t1,0x80000000
	addu	t0,t1,(8*1024)	# cache size

	.set noreorder
1: 	
	mtc0	zero,C0_TAGLO
	nop
	nop
	hitinv_dcache(0,r_t1)
	nop
	bne	t0,t1,1b
	addu	t1,16		# line size

	# restore taglo & taghi
	mtc0	t5,C0_TAGLO
	mtc0	t6,C0_TAGHI
	nop
	mtc0	t7,C0_SR	# restore SR
	nop
	nop
	.set reorder
	j	ra
	.end r4300_dflushi

/*************************************************************
*  r4300_dflush()
*	Flush the VR4300 Data cache.
*	o disable ints
*	o switch to kseg1
*	o write-back the cache
*	o invalidate the cache
*/
	.globl r4300_dflush
	.ent r4300_dflush
r4300_dflush:
	# disable ints
	.set noreorder
	mfc0	t7,C0_SR
	nop
	and	t0,t7,~SR_IEC
	or	t0,SR_DE
	mtc0	t0,C0_SR
	.set reorder

	# switch to Kseg1
	la	t0,1f
	li	t1,K1BASE
	or	t0,t1
	j	t0
1:
	# save taglo
	.set noreorder
	mfc0	t6,C0_TAGLO

	# write-back and invalidate the Dcache
	li	t0,0x80000000
	addu	t1,t0,(8*1024)		# 8KB cache

1:	
	# set taglo
	mtc0	zero,C0_TAGLO
	nop
	wb_dcache(0,r_t0)
	nop
	bne	t0,t1,1b
	addu	t0,16		# line size

	mtc0	t6,C0_TAGLO	# restore taglo
	nop
	mtc0	t7,C0_SR	# restore SR
	nop
	.set reorder

	j	ra
	.end r4300_dflush


/*************************************************************
*  r4300_readdtag()
*	Read the VR4300 Dcache tag.
*/
	.globl r4300_readdtag
	.ent r4300_readdtag
r4300_readdtag:
	# disable ints
	.set noreorder
	mfc0	t7,C0_SR
	nop
	and	t0,t7,~SR_IEC
	or	t0,SR_DE
	mtc0	t0,C0_SR
	.set reorder

	# switch to Kseg1
	la	t0,1f
	li	t1,K1BASE
	or	t0,t1
	j	t0

1:	
	# save taglo & taghi
	.set noreorder
	mfc0	t5,C0_TAGLO
	mfc0	t6,C0_TAGHI
	move	t1,a0

	read_dtag(0,r_t1)
	nop
	nop

	# store result
	mfc0	t0,C0_TAGLO
	nop
	sw	t0,(a1)
	mfc0	t0,C0_TAGHI
	nop
	sw	t0,(a2)

	# restore taglo & taghi
	mtc0	t5,C0_TAGLO
	mtc0	t6,C0_TAGHI
	nop

	nop
	mtc0	t7,C0_SR	# restore SR
	nop
	nop
	.set reorder
	j	ra
	.end r4300_readdtag

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -