cache.s 3.42 KB
#include <asm.h>
#include <regdef.h>
#include <R4300.h>

/*
 * invalICache(void *addr, int nbytes)
 */
LEAF(invalICache)
	.set	mips3
	blez	a1,2f			# If nbytes <= 0, bail
	li	t3,ICACHE_SIZE
	bgeu	a1,t3,3f		# Is nbytes >= I-Cache size?
	move	t0,a0
	addu	t1,a0,a1
	bgeu	t0,t1,2f		# (Check for address wrap)
	subu	t1,ICACHE_LINESIZE
	andi	t2,t0,ICACHE_LINEMASK
	subu	t0,t2
1:
	.set	noreorder
	cache	CACH_PI|C_HINV,0(t0)	# If not, use hit invalidate
	bltu	t0,t1,1b		#  only on given range
	addu	t0,ICACHE_LINESIZE
	.set	reorder
2:
	j	ra
3:
	li	t0,K0BASE
	addu	t1,t0,t3
	subu	t1,ICACHE_LINESIZE
4:
	.set	noreorder
	cache	CACH_PI|C_IINV,0(t0)	# If so, use index invalidate on
	bltu	t0,t1,4b		#  entire cache
	addu	t0,ICACHE_LINESIZE
	.set	reorder

	j	ra
	.set	mips0
END(invalICache)

/*
 * invalDCache(void *addr, int nbytes)
 */
LEAF(invalDCache)
	.set	mips3
	blez	a1,3f			# If nbytes <= 0, bail
	li	t3,DCACHE_SIZE
	bgeu	a1,t3,4f		# Is nbytes >= D-Cache size?
	move	t0,a0
	addu	t1,a0,a1
	bgeu	t0,t1,3f		# (Check for address wrap)
	subu	t1,DCACHE_LINESIZE
	andi	t2,t0,DCACHE_LINEMASK
	beq	t2,zero,1f		# Check if beginning address is aligned
	subu	t0,t2			# If not, back up to cache line address
	.set	noreorder
	cache	CACH_PD|C_HWBINV,0(t0)	# Use hit writeback invalidate on first
	.set	reorder
	bgeu	t0,t1,3f
	addu	t0,DCACHE_LINESIZE
1:
	and	t2,t1,DCACHE_LINEMASK
	beq	t2,zero,2f		# Check if ending address is aligned
	subu	t1,t2
	.set	noreorder
	cache	CACH_PD|C_HWBINV,DCACHE_LINESIZE(t1)
	.set	reorder
	bgtu	t0,t1,3f
2:
	.set	noreorder
	cache	CACH_PD|C_HINV,0(t0)	# If not, use hit invalidate
	bltu	t0,t1,2b		#  only on given range
	addu	t0,DCACHE_LINESIZE
	.set	reorder
3:
	j	ra
4:
	li	t0,K0BASE
	addu	t1,t0,t3
	subu	t1,DCACHE_LINESIZE
5:
	.set	noreorder
	cache	CACH_PD|C_IWBINV,0(t0)	# If so, use index writeback invalidate
	bltu	t0,t1,5b		#  on entire cache
	addu	t0,DCACHE_LINESIZE
	.set	reorder

	j	ra
	.set	mips0
END(invalDCache)

/*
 * writebackDCache(void *addr, int nbytes)
 */
LEAF(writebackDCache)
	.set	mips3
	blez	a1,2f			# If nbytes <= 0, bail
	li	t3,DCACHE_SIZE
	bgeu	a1,t3,3f		# Is nbytes >= D-Cache size?
	move	t0,a0
	addu	t1,a0,a1
	bgeu	t0,t1,2f		# (Check for address wrap)
	subu	t1,DCACHE_LINESIZE
	andi	t2,t0,DCACHE_LINEMASK
	subu	t0,t2
1:
	.set	noreorder
	cache	CACH_PD|C_HWB,0(t0)	# If not, use hit writeback
	bltu	t0,t1,1b		#  only on given range
	addu	t0,DCACHE_LINESIZE
	.set	reorder
2:
	j	ra
3:
	li	t0,K0BASE
	addu	t1,t0,t3
	subu	t1,DCACHE_LINESIZE
4:
	.set	noreorder
	cache	CACH_PD|C_IWBINV,0(t0)	# If so, use index writeback invalidate
	bltu	t0,t1,4b		#  on entire cache
	addu	t0,DCACHE_LINESIZE
	.set	reorder

	j	ra
	.set	mips0
END(writebackDCache)

	#*******<14 Initialize CPU cache>
	# Invalidate I cache

LEAF(initICache)
	.set	mips3
	.set	reorder
        la	t0,K0BASE    	
	addu	t1,t0,ICACHE_SIZE
	subu	t1,ICACHE_LINESIZE

        .set    noreorder
	mtc0	zero,C0_TAGLO
	mtc0	zero,C0_TAGHI
1:
        cache   CACH_PI|C_IST,0(t0) 	#  use index invalidate
        bltu    t0,t1,1b       		#  on entire cache
        addu    t0,ICACHE_LINESIZE
	jr	ra
	nop
	.set	reorder
	.set	mips0
END(initICache)

LEAF(initDCache)
	.set	mips3
        la	t0,K0BASE    	
	addu	t1,t0,DCACHE_SIZE
	subu	t1,DCACHE_LINESIZE
	
	# Invalidate D cache

	.set	noreorder
2:
        cache   CACH_PD|C_IST,0(t0)  #  use index store tag to invalidate
        bltu    t0,t1,2b       		#  cache.
	addu	t0,DCACHE_LINESIZE	# some cache data for NMI case
	jr 	ra
	nop
	.set	reorder
	.set	mips0
END(initDCache)