invaldcache.s 1.19 KB
#include <asm.h>
#include <regdef.h>
#include <PR/R4300.h>

/*
 * skInvalDCache(void *addr, int nbytes)
 */
LEAF(skInvalDCache)
	.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(skInvalDCache)