.text
	.align 3



spuutil_WaitForDMATagGroups:

	########################################################################
	#	A very simple helper function that will not return until the _all_ of
	#	the DMA trasactions for the groups passed in r3 have completed.
	#Params:
	#	r3 is the tag group mask
	#	r4 is the blocking bahavior
	#Clobber:
	#	r2
	#	r3
	#	r4
	#	r5
	#Expects:
	#
	#	input register to have [0:95] set to 0
	########################################################################

	hbr		.WaitForDMATagGroups_end, $lr

	andc	$5, $5, $5
	cwd		$6, 0($sp)

	andc	$2, $2, $2
	wrch	$mfc_wr_tag_update, $2
	rdch	$2, $mfc_rd_tag_status

.WaitForDMATagGroups_loop:
	rchcnt	$2, $mfc_wr_tag_update
	ceqi	$2, $2, 1
	brz		$2, .WaitForDMATagGroups_loop

	shufb	$3, $3, $5, $6
	shufb	$4, $4, $5, $6
	wrch	$mfc_wr_tag_mask, $3
	wrch	$mfc_wr_tag_update, $4
	rdch	$2, $mfc_rd_tag_status

.WaitForDMATagGroups_end:

	bi		$lr
	
	.type	spuutil_WaitForDMATagGroups, @function
	.size	spuutil_WaitForDMATagGroups, .-spuutil_WaitForDMATagGroups
	.global spuutil_WaitForDMATagGroups









spuutil_SendPUEvent:
	
	########################################################################
	#	A very simple helper function that will write the value in r3
	#	to the pu intr mb
	# Params:
	#	r3 event value
	# Clobber:
	#	r2
	#	r4
	#	r5
	# Expects:
	########################################################################
	
	hbr		.spuutil_SendPUEvent_end, $lr

	andc	$4, $4, $4
	cwd		$5, 0($sp)

	ila		$2, 0x1

	shli	$2, $2, 0x1c

	or		$2, $2, $3
	
	shufb	$2, $2, $4, $5

	wrch	$mfc_wr_intr_mailbox, $2

.spuutil_SendPUEvent_end:
	bi		$lr

	.type	spuutil_SendPUEvent, @function
	.size	spuutil_SendPUEvent, .-spuutil_SendPUEvent
	.global spuutil_SendPUEvent








spuutil_QueueMFCCommand:
	########################################################################
	#	Add the passed DMA params to the queue
	# Params:
	#	r3 DMA command
	#	r4 ea high
	#	r5 ea low
	#	r6 LS address
	#	r7 transfers/list size
	#	r8 tag
	#
	# Clobber:
	#	r3
	#	r4
	#	r5
	#	r6
	#	r7
	#	r8
	#	r9
	#	r10
	# Expects:
	########################################################################

	hbr		.spuutil_QueueMFCCommand_end, $lr

	andc 	$9, $9, $9
	cwd		$10, 0($sp)

	shufb	$6, $6, $9, $10
	wrch	$mfc_ls_addr, $6

	shufb	$4, $4, $9, $10
	wrch	$mfc_ea_hi, $4

	shufb	$5, $5, $9, $10
	wrch	$mfc_ea_low, $5

	shufb	$7, $7, $9, $10
	wrch	$mfc_dma_size, $7

	shufb	$8, $8, $9, $10
	wrch	$mfc_tag_id, $8

	shufb	$3, $3, $9, $10
	wrch	$mfc_cmd_queue, $3

.spuutil_QueueMFCCommand_end:
	bi		$lr

	.type	spuutil_QueueMFCCommand, @function
	.size	spuutil_QueueMFCCommand, .-spuutil_QueueMFCCommand
	.global spuutil_QueueMFCCommand



spuutil_QueueMFCTransfer:

	########################################################################
	#	Similar to spuutil_QueueDMACommand except this functions handles
	#	
	# Params:
	#	r3 DMA command
	#	r4 ea high
	#	r5 ea low
	#	r6 LS address
	#	r7 transfers/list size
	#	r8 tag
	#
	# Clobber:
	#	r3
	#	r4
	#	r5
	#	r6
	#	r7
	#	r8
	#	r9
	#	r10
	#	r11
	#	r12
	#	r13
	#	r14
	# Expects:
	########################################################################

	andc 	$9, $9, $9
	cwd		$10, 0($sp)

	shufb	$3, $3, $9, $10
	shufb	$4, $4, $9, $10
	shufb	$5, $5, $9, $10
	shufb	$6, $6, $9, $10
	shufb	$7, $7, $9, $10
	shufb	$8, $8, $9, $10

	ila		$12, 0x3fff
	andc	$11, $7, $12		#get the number of 4k chunks
	and		$7, $7, $12			#get the 4k remainder
	andc	$13, $13, $13
	ai		$12, $12, 1			#r12 = 0x4000
	shufb	$12, $12, $9, $10

.spuutil_QueueMFCTransfer_TransferStart:
	brz		$11, .spuutil_QueueMFCTransfer_TransferCleanup 


.spuutil_QueueMFCTransfer_16kTop:

	wrch	$mfc_ls_addr, $6
	wrch	$mfc_ea_hi, $4
	wrch	$mfc_ea_low, $5
	wrch	$mfc_dma_size, $12
	wrch	$mfc_tag_id, $8
	wrch	$mfc_cmd_queue, $3

	a		$6, $6, $12
	cg		$14, $5, $12
	a		$4, $4, $14
	a		$5, $5, $12

	a		$13, $13, $12
	ceq		$14, $11, $13
	brz		$14, .spuutil_QueueMFCTransfer_16kTop


.spuutil_QueueMFCTransfer_TransferCleanup:
	
	wrch	$mfc_ls_addr, $6
	wrch	$mfc_ea_hi, $4
	wrch	$mfc_ea_low, $5
	wrch	$mfc_dma_size, $7
	wrch	$mfc_tag_id, $8
	wrch	$mfc_cmd_queue, $3

.spuutil_QueueMFCTransfer_end:
	bi		$lr

	.type	spuutil_QueueMFCTransfer, @function
	.size	spuutil_QueueMFCTransfer, .-spuutil_QueueMFCTransfer
	.global spuutil_QueueMFCTransfer




spuutil_SetDecrementer:
	
	########################################################################
	#	A very simple helper function to reset the decrementer counter
	# Params:
	#	r3 value
	# Clobber:
	#	r2
	#	r3
	#	r4
	#	r5
	# Expects:
	########################################################################
	
	hbr		.spuutil_SetDecrementer_end, $lr

	andc	$4, $4, $4
	cwd		$5, 0($sp)

	il		$2, ~0x20
	wrch	$spu_wr_event_mask, $2

	il		$2, 0x20
	wrch	$spu_wr_event_ack, $2

	shufb	$3, $3, $4, $5

	wrch	$spu_wr_decr_count, $3

.spuutil_SetDecrementer_end:
	bi		$lr

	.type	spuutil_SetDecrementer, @function
	.size	spuutil_SetDecrementer, .-spuutil_SetDecrementer
	.global spuutil_SetDecrementer


