112115Sdyson/*
212115Sdyson *  fuc microcode for g98 sec engine
312115Sdyson *  Copyright (C) 2010  Marcin Ko��cielnicki
412115Sdyson *
512115Sdyson *  This program is free software; you can redistribute it and/or modify
612115Sdyson *  it under the terms of the GNU General Public License as published by
712115Sdyson *  the Free Software Foundation; either version 2 of the License, or
812115Sdyson *  (at your option) any later version.
912115Sdyson *
1012115Sdyson *  This program is distributed in the hope that it will be useful,
1112115Sdyson *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1212115Sdyson *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1312115Sdyson *  GNU General Public License for more details.
1412115Sdyson *
1512115Sdyson *  You should have received a copy of the GNU General Public License
1612115Sdyson *  along with this program; if not, write to the Free Software
1712115Sdyson *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1812115Sdyson */
1912115Sdyson
2012115Sdyson.section #g98_sec_data
2112115Sdyson
2212115Sdysonctx_dma:
2312115Sdysonctx_dma_query:		.b32 0
2412115Sdysonctx_dma_src:		.b32 0
2512115Sdysonctx_dma_dst:		.b32 0
2612115Sdyson.equ #dma_count 3
2712115Sdysonctx_query_address_high:	.b32 0
2812115Sdysonctx_query_address_low:	.b32 0
2912115Sdysonctx_query_counter:	.b32 0
3012115Sdysonctx_cond_address_high:	.b32 0
3112115Sdysonctx_cond_address_low:	.b32 0
3212115Sdysonctx_cond_off:		.b32 0
3312115Sdysonctx_src_address_high:	.b32 0
3412115Sdysonctx_src_address_low:	.b32 0
3512115Sdysonctx_dst_address_high:	.b32 0
3612115Sdysonctx_dst_address_low:	.b32 0
3712115Sdysonctx_mode:		.b32 0
3812115Sdyson.align 16
3912115Sdysonctx_key:		.skip 16
4012115Sdysonctx_iv:			.skip 16
4112115Sdyson
4213260Swollman.align 0x80
4312115Sdysonswap:
4412115Sdyson.skip 32
4512115Sdyson
4612115Sdyson.align 8
4712115Sdysoncommon_cmd_dtable:
4812115Sdyson.b32 #ctx_query_address_high + 0x20000 ~0xff
4912115Sdyson.b32 #ctx_query_address_low + 0x20000 ~0xfffffff0
5012115Sdyson.b32 #ctx_query_counter + 0x20000 ~0xffffffff
5112115Sdyson.b32 #cmd_query_get + 0x00000 ~1
5229906Skato.b32 #ctx_cond_address_high + 0x20000 ~0xff
5324131Sbde.b32 #ctx_cond_address_low + 0x20000 ~0xfffffff0
5412115Sdyson.b32 #cmd_cond_mode + 0x00000 ~7
5512115Sdyson.b32 #cmd_wrcache_flush + 0x00000 ~0
5612115Sdyson.equ #common_cmd_max 0x88
5712115Sdyson
5812115Sdyson
5912115Sdyson.align 8
6012115Sdysonengine_cmd_dtable:
6112115Sdyson.b32 #ctx_key + 0x0 + 0x20000 ~0xffffffff
6212115Sdyson.b32 #ctx_key + 0x4 + 0x20000 ~0xffffffff
6312115Sdyson.b32 #ctx_key + 0x8 + 0x20000 ~0xffffffff
6412115Sdyson.b32 #ctx_key + 0xc + 0x20000 ~0xffffffff
6512115Sdyson.b32 #ctx_iv + 0x0 + 0x20000 ~0xffffffff
6612115Sdyson.b32 #ctx_iv + 0x4 + 0x20000 ~0xffffffff
6712115Sdyson.b32 #ctx_iv + 0x8 + 0x20000 ~0xffffffff
6812115Sdyson.b32 #ctx_iv + 0xc + 0x20000 ~0xffffffff
6912115Sdyson.b32 #ctx_src_address_high + 0x20000 ~0xff
7028270Swollman.b32 #ctx_src_address_low + 0x20000 ~0xfffffff0
7112911Sphk.b32 #ctx_dst_address_high + 0x20000 ~0xff
7212911Sphk.b32 #ctx_dst_address_low + 0x20000 ~0xfffffff0
7312911Sphk.b32 #sec_cmd_mode + 0x00000 ~0xf
7412911Sphk.b32 #sec_cmd_length + 0x10000 ~0x0ffffff0
7512911Sphk.equ #engine_cmd_max 0xce
7612911Sphk
7712911Sphk.align 4
7812911Sphksec_dtable:
7912911Sphk.b16 #sec_copy_prep #sec_do_inout
8012911Sphk.b16 #sec_store_prep #sec_do_out
8112911Sphk.b16 #sec_ecb_e_prep #sec_do_inout
8212911Sphk.b16 #sec_ecb_d_prep #sec_do_inout
8312911Sphk.b16 #sec_cbc_e_prep #sec_do_inout
8412115Sdyson.b16 #sec_cbc_d_prep #sec_do_inout
8531315Sbde.b16 #sec_pcbc_e_prep #sec_do_inout
8630280Sphk.b16 #sec_pcbc_d_prep #sec_do_inout
8712911Sphk.b16 #sec_cfb_e_prep #sec_do_inout
8812115Sdyson.b16 #sec_cfb_d_prep #sec_do_inout
8912115Sdyson.b16 #sec_ofb_prep #sec_do_inout
9012115Sdyson.b16 #sec_ctr_prep #sec_do_inout
9112115Sdyson.b16 #sec_cbc_mac_prep #sec_do_in
9212115Sdyson.b16 #sec_cmac_finish_complete_prep #sec_do_in
9312115Sdyson.b16 #sec_cmac_finish_partial_prep #sec_do_in
9412115Sdyson
9512115Sdyson.align 0x100
9612115Sdyson
9712115Sdyson.section #g98_sec_code
9812115Sdyson
9912115Sdyson	// $r0 is always set to 0 in our code - this allows some space savings.
10012115Sdyson	clear b32 $r0
10138909Sbde
10212115Sdyson	// set up the interrupt handler
10312115Sdyson	mov $r1 #ih
10412115Sdyson	mov $iv0 $r1
10512911Sphk
10612115Sdyson	// init stack pointer
10716322Sgpalmer	mov $sp $r0
10816322Sgpalmer
10916322Sgpalmer	// set interrupt dispatch - route timer, fifo, ctxswitch to i0, others to host
11016322Sgpalmer	movw $r1 0xfff0
11116322Sgpalmer	sethi $r1 0
11216322Sgpalmer	mov $r2 0x400
11316322Sgpalmer	iowr I[$r2 + 0x300] $r1
11412115Sdyson
11516322Sgpalmer	// enable the interrupts
11612115Sdyson	or $r1 0xc
11712115Sdyson	iowr I[$r2] $r1
11812115Sdyson
11912115Sdyson	// enable fifo access and context switching
12012115Sdyson	mov $r1 3
12112911Sphk	mov $r2 0x1200
12212115Sdyson	iowr I[$r2] $r1
12312115Sdyson
12412115Sdyson	// enable i0 delivery
12512115Sdyson	bset $flags ie0
12612115Sdyson
12712115Sdyson	// sleep forver, waking only for interrupts.
12812115Sdyson	bset $flags $p0
12912115Sdyson	spin:
13012115Sdyson	sleep $p0
13129208Sbde	bra #spin
13229208Sbde
13329208Sbde// i0 handler
13429208Sbdeih:
13512115Sdyson	// see which interrupts we got
13612115Sdyson	iord $r1 I[$r0 + 0x200]
13712115Sdyson
13812115Sdyson	and $r2 $r1 0x8
13929888Skato	cmpu b32 $r2 0
14029888Skato	bra e #noctx
14129888Skato
14229888Skato		// context switch... prepare the regs for xfer
14312115Sdyson		mov $r2 0x7700
14412115Sdyson		mov $xtargets $r2
14512115Sdyson		mov $xdbase $r0
14612115Sdyson		// 128-byte context.
14712115Sdyson		mov $r2 0
14812115Sdyson		sethi $r2 0x50000
14912115Sdyson
15012115Sdyson		// read current channel
15112115Sdyson		mov $r3 0x1400
15230469Sjulian		iord $r4 I[$r3]
15312115Sdyson		// if bit 30 set, it's active, so we have to unload it first.
15412115Sdyson		shl b32 $r5 $r4 1
15512115Sdyson		cmps b32 $r5 0
15612115Sdyson		bra nc #ctxload
15712115Sdyson
15812115Sdyson			// unload the current channel - save the context
15912115Sdyson			xdst $r0 $r2
16012115Sdyson			xdwait
16112115Sdyson			// and clear bit 30, then write back
16212115Sdyson			bclr $r4 0x1e
16312115Sdyson			iowr I[$r3] $r4
16412115Sdyson			// tell PFIFO we unloaded
16512115Sdyson			mov $r4 1
16612115Sdyson			iowr I[$r3 + 0x200] $r4
16712115Sdyson
16812115Sdyson		bra #noctx
16916322Sgpalmer
17012115Sdyson		ctxload:
17112115Sdyson			// no channel loaded - perhaps we're requested to load one
17212115Sdyson			iord $r4 I[$r3 + 0x100]
17312115Sdyson			shl b32 $r15 $r4 1
17412115Sdyson			cmps b32 $r15 0
17512115Sdyson			// if bit 30 of next channel not set, probably PFIFO is just
17612911Sphk			// killing a context. do a faux load, without the active bit.
17712115Sdyson			bra nc #dummyload
17812115Sdyson
17912115Sdyson				// ok, do a real context load.
18012115Sdyson				xdld $r0 $r2
18112115Sdyson				xdwait
18212115Sdyson				mov $r5 #ctx_dma
18312115Sdyson				mov $r6 #dma_count - 1
18412115Sdyson				ctxload_dma_loop:
18512115Sdyson					ld b32 $r7 D[$r5 + $r6 * 4]
18612115Sdyson					add b32 $r8 $r6 0x180
18712115Sdyson					shl b32 $r8 8
18812115Sdyson					iowr I[$r8] $r7
18912115Sdyson					sub b32 $r6 1
19039028Sbde				bra nc #ctxload_dma_loop
19112115Sdyson
19212115Sdyson			dummyload:
19312115Sdyson			// tell PFIFO we're done
19412115Sdyson			mov $r5 2
19512115Sdyson			iowr I[$r3 + 0x200] $r5
19612115Sdyson
19729888Skato	noctx:
19829888Skato	and $r2 $r1 0x4
19912115Sdyson	cmpu b32 $r2 0
20012115Sdyson	bra e #nocmd
20112115Sdyson
20212115Sdyson		// incoming fifo command.
20312115Sdyson		mov $r3 0x1900
20429888Skato		iord $r2 I[$r3 + 0x100]
20529888Skato		iord $r3 I[$r3]
20629888Skato		// extract the method
20729888Skato		and $r4 $r2 0x7ff
20812115Sdyson		// shift the addr to proper position if we need to interrupt later
20912115Sdyson		shl b32 $r2 0x10
21012115Sdyson
21112115Sdyson		// mthd 0 and 0x100 [NAME, NOP]: ignore
21222521Sdyson		and $r5 $r4 0x7bf
21312115Sdyson		cmpu b32 $r5 0
21412115Sdyson		bra e #cmddone
21522521Sdyson
21612115Sdyson		mov $r5 #engine_cmd_dtable - 0xc0 * 8
21712115Sdyson		mov $r6 #engine_cmd_max
21812115Sdyson		cmpu b32 $r4 0xc0
21912115Sdyson		bra nc #dtable_cmd
22012115Sdyson		mov $r5 #common_cmd_dtable - 0x80 * 8
22139028Sbde		mov $r6 #common_cmd_max
22239028Sbde		cmpu b32 $r4 0x80
22339028Sbde		bra nc #dtable_cmd
22439028Sbde		cmpu b32 $r4 0x60
22539028Sbde		bra nc #dma_cmd
22639028Sbde		cmpu b32 $r4 0x50
22739028Sbde		bra ne #illegal_mthd
22839028Sbde
22939028Sbde			// mthd 0x140: PM_TRIGGER
23039028Sbde			mov $r2 0x2200
23139028Sbde			clear b32 $r3
23239028Sbde			sethi $r3 0x20000
23339028Sbde			iowr I[$r2] $r3
23439028Sbde			bra #cmddone
23539028Sbde
23639028Sbde		dma_cmd:
23712115Sdyson			// mthd 0x180...: DMA_*
23839028Sbde			cmpu b32 $r4 0x60+#dma_count
23912115Sdyson			bra nc #illegal_mthd
24012115Sdyson			shl b32 $r5 $r4 2
24112115Sdyson			add b32 $r5 ((#ctx_dma - 0x60 * 4) & 0xffff)
24212115Sdyson			bset $r3 0x1e
24312115Sdyson			st b32 D[$r5] $r3
24412115Sdyson			add b32 $r4 0x180 - 0x60
24512115Sdyson			shl b32 $r4 8
24612115Sdyson			iowr I[$r4] $r3
24712115Sdyson			bra #cmddone
24812115Sdyson
24912115Sdyson		dtable_cmd:
25012115Sdyson			cmpu b32 $r4 $r6
25112115Sdyson			bra nc #illegal_mthd
25212115Sdyson			shl b32 $r4 3
25312115Sdyson			add b32 $r4 $r5
25412115Sdyson			ld b32 $r5 D[$r4 + 4]
25512115Sdyson			and $r5 $r3
25612115Sdyson			cmpu b32 $r5 0
25712115Sdyson			bra ne #invalid_bitfield
25812115Sdyson			ld b16 $r5 D[$r4]
25912115Sdyson			ld b16 $r6 D[$r4 + 2]
26012115Sdyson			cmpu b32 $r6 2
26112115Sdyson			bra e #cmd_setctx
26212115Sdyson			ld b32 $r7 D[$r0 + #ctx_cond_off]
26312115Sdyson			and $r6 $r7
26412115Sdyson			cmpu b32 $r6 1
26512115Sdyson			bra e #cmddone
26612115Sdyson			call $r5
26712115Sdyson			bra $p1 #dispatch_error
26839028Sbde			bra #cmddone
26939028Sbde
27039028Sbde		cmd_setctx:
27139028Sbde			st b32 D[$r5] $r3
27239028Sbde			bra #cmddone
27339028Sbde
27439028Sbde
27539028Sbde		invalid_bitfield:
27639028Sbde			or $r2 1
27739028Sbde		dispatch_error:
27839028Sbde		illegal_mthd:
27939028Sbde			mov $r4 0x1000
28039028Sbde			iowr I[$r4] $r2
28139028Sbde			iowr I[$r4 + 0x100] $r3
28239028Sbde			mov $r4 0x40
28339028Sbde			iowr I[$r0] $r4
28439028Sbde
28529888Skato			im_loop:
28629888Skato				iord $r4 I[$r0 + 0x200]
28729888Skato				and $r4 0x40
28829888Skato				cmpu b32 $r4 0
28929888Skato			bra ne #im_loop
29012115Sdyson
29129888Skato		cmddone:
29212115Sdyson		// remove the command from FIFO
29312115Sdyson		mov $r3 0x1d00
29412115Sdyson		mov $r4 1
29512115Sdyson		iowr I[$r3] $r4
29612115Sdyson
29712115Sdyson	nocmd:
29812115Sdyson	// ack the processed interrupts
29912115Sdyson	and $r1 $r1 0xc
30012115Sdyson	iowr I[$r0 + 0x100] $r1
30112115Sdysoniret
30212115Sdyson
30312115Sdysoncmd_query_get:
30412115Sdyson	// if bit 0 of param set, trigger interrupt afterwards.
30512115Sdyson	setp $p1 $r3
30612115Sdyson	or $r2 3
30712115Sdyson
30812115Sdyson	// read PTIMER, beware of races...
30912115Sdyson	mov $r4 0xb00
31012115Sdyson	ptimer_retry:
31112115Sdyson		iord $r6 I[$r4 + 0x100]
31212115Sdyson		iord $r5 I[$r4]
31312115Sdyson		iord $r7 I[$r4 + 0x100]
31412115Sdyson		cmpu b32 $r6 $r7
31512115Sdyson	bra ne #ptimer_retry
31612115Sdyson
31712115Sdyson	// prepare the query structure
31812115Sdyson	ld b32 $r4 D[$r0 + #ctx_query_counter]
31912115Sdyson	st b32 D[$r0 + #swap + 0x0] $r4
32012115Sdyson	st b32 D[$r0 + #swap + 0x4] $r0
32112115Sdyson	st b32 D[$r0 + #swap + 0x8] $r5
32212115Sdyson	st b32 D[$r0 + #swap + 0xc] $r6
32312115Sdyson
32412115Sdyson	// will use target 0, DMA_QUERY.
32512115Sdyson	mov $xtargets $r0
32612115Sdyson
32712115Sdyson	ld b32 $r4 D[$r0 + #ctx_query_address_high]
32812115Sdyson	shl b32 $r4 0x18
32912115Sdyson	mov $xdbase $r4
33012115Sdyson
33112115Sdyson	ld b32 $r4 D[$r0 + #ctx_query_address_low]
33212115Sdyson	mov $r5 #swap
33312115Sdyson	sethi $r5 0x20000
33412115Sdyson	xdst $r4 $r5
33512115Sdyson	xdwait
33612115Sdyson
33712115Sdyson	ret
33812115Sdyson
33912115Sdysoncmd_cond_mode:
34012115Sdyson	// if >= 5, INVALID_ENUM
34112115Sdyson	bset $flags $p1
34212115Sdyson	or $r2 2
34312115Sdyson	cmpu b32 $r3 5
34412115Sdyson	bra nc #return
34512115Sdyson
34612115Sdyson	// otherwise, no error.
34712115Sdyson	bclr $flags $p1
34812115Sdyson
34912115Sdyson	// if < 2, no QUERY object is involved
35012115Sdyson	cmpu b32 $r3 2
35112115Sdyson	bra nc #cmd_cond_mode_queryful
35212115Sdyson
35312115Sdyson		xor $r3 1
35412115Sdyson		st b32 D[$r0 + #ctx_cond_off] $r3
35512115Sdyson	return:
35612115Sdyson		ret
35712115Sdyson
35812115Sdyson	cmd_cond_mode_queryful:
35912115Sdyson	// ok, will need to pull a QUERY object, prepare offsets
36012115Sdyson	ld b32 $r4 D[$r0 + #ctx_cond_address_high]
36112115Sdyson	ld b32 $r5 D[$r0 + #ctx_cond_address_low]
36212115Sdyson	and $r6 $r5 0xff
36312115Sdyson	shr b32 $r5 8
36412115Sdyson	shl b32 $r4 0x18
36512115Sdyson	or $r4 $r5
36612115Sdyson	mov $xdbase $r4
36712115Sdyson	mov $xtargets $r0
36812115Sdyson
36912115Sdyson	// pull the first one
37012115Sdyson	mov $r5 #swap
37112115Sdyson	sethi $r5 0x20000
37212115Sdyson	xdld $r6 $r5
37312115Sdyson
37412115Sdyson	// if == 2, only a single QUERY is involved...
37512115Sdyson	cmpu b32 $r3 2
37612115Sdyson	bra ne #cmd_cond_mode_double
37712115Sdyson
37812115Sdyson		xdwait
37912115Sdyson		ld b32 $r4 D[$r0 + #swap + 4]
38012115Sdyson		cmpu b32 $r4 0
38112115Sdyson		xbit $r4 $flags z
38212115Sdyson		st b32 D[$r0 + #ctx_cond_off] $r4
38312115Sdyson		ret
38412115Sdyson
38512115Sdyson	// ok, we'll need to pull second one too
38612115Sdyson	cmd_cond_mode_double:
38712115Sdyson	add b32 $r6 0x10
38812115Sdyson	add b32 $r5 0x10
38912115Sdyson	xdld $r6 $r5
39012115Sdyson	xdwait
39112115Sdyson
39212115Sdyson	// compare COUNTERs
39312115Sdyson	ld b32 $r5 D[$r0 + #swap + 0x00]
39412115Sdyson	ld b32 $r6 D[$r0 + #swap + 0x10]
39512115Sdyson	cmpu b32 $r5 $r6
39612115Sdyson	xbit $r4 $flags z
39712115Sdyson
39812115Sdyson	// compare RESen
39912115Sdyson	ld b32 $r5 D[$r0 + #swap + 0x04]
40012115Sdyson	ld b32 $r6 D[$r0 + #swap + 0x14]
40112115Sdyson	cmpu b32 $r5 $r6
40212115Sdyson	xbit $r5 $flags z
40312115Sdyson	and $r4 $r5
40412115Sdyson
40512115Sdyson	// and negate or not, depending on mode
40612115Sdyson	cmpu b32 $r3 3
40712115Sdyson	xbit $r5 $flags z
40812115Sdyson	xor $r4 $r5
40912115Sdyson	st b32 D[$r0 + #ctx_cond_off] $r4
41012115Sdyson	ret
41112115Sdyson
41212115Sdysoncmd_wrcache_flush:
41312115Sdyson	bclr $flags $p1
41412115Sdyson	mov $r2 0x2200
41512115Sdyson	clear b32 $r3
41612115Sdyson	sethi $r3 0x10000
41712115Sdyson	iowr I[$r2] $r3
41812115Sdyson	ret
41912115Sdyson
42012115Sdysonsec_cmd_mode:
42112115Sdyson	// if >= 0xf, INVALID_ENUM
42212115Sdyson	bset $flags $p1
42312115Sdyson	or $r2 2
42412115Sdyson	cmpu b32 $r3 0xf
42512115Sdyson	bra nc #sec_cmd_mode_return
42612115Sdyson
42712115Sdyson		bclr $flags $p1
42812115Sdyson		st b32 D[$r0 + #ctx_mode] $r3
42912115Sdyson
43012115Sdyson	sec_cmd_mode_return:
43112115Sdyson	ret
43212115Sdyson
43312115Sdysonsec_cmd_length:
43412115Sdyson	// nop if length == 0
43512115Sdyson	cmpu b32 $r3 0
43612115Sdyson	bra e #sec_cmd_mode_return
43712115Sdyson
43812115Sdyson	// init key, IV
43912115Sdyson	cxset 3
44012115Sdyson	mov $r4 #ctx_key
44112115Sdyson	sethi $r4 0x70000
44212115Sdyson	xdst $r0 $r4
44312115Sdyson	mov $r4 #ctx_iv
44427881Sdyson	sethi $r4 0x60000
44527881Sdyson	xdst $r0 $r4
44612115Sdyson	xdwait
44712115Sdyson	ckeyreg $c7
44812115Sdyson
44927881Sdyson	// prepare the targets
45012115Sdyson	mov $r4 0x2100
45112115Sdyson	mov $xtargets $r4
45212115Sdyson
45312115Sdyson	// prepare src address
45412115Sdyson	ld b32 $r4 D[$r0 + #ctx_src_address_high]
45512115Sdyson	ld b32 $r5 D[$r0 + #ctx_src_address_low]
45612115Sdyson	shr b32 $r8 $r5 8
45712115Sdyson	shl b32 $r4 0x18
45812115Sdyson	or $r4 $r8
45912115Sdyson	and $r5 $r5 0xff
46012115Sdyson
46112115Sdyson	// prepare dst address
46212115Sdyson	ld b32 $r6 D[$r0 + #ctx_dst_address_high]
46312115Sdyson	ld b32 $r7 D[$r0 + #ctx_dst_address_low]
46412115Sdyson	shr b32 $r8 $r7 8
46512115Sdyson	shl b32 $r6 0x18
46612115Sdyson	or $r6 $r8
46712115Sdyson	and $r7 $r7 0xff
46812115Sdyson
46912115Sdyson	// find the proper prep & do functions
47012115Sdyson	ld b32 $r8 D[$r0 + #ctx_mode]
47112115Sdyson	shl b32 $r8 2
47212115Sdyson
47312115Sdyson	// run prep
47412115Sdyson	ld b16 $r9 D[$r8 + #sec_dtable]
47512115Sdyson	call $r9
47612115Sdyson
47712115Sdyson	// do it
47812115Sdyson	ld b16 $r9 D[$r8 + #sec_dtable + 2]
47912115Sdyson	call $r9
48012911Sphk	cxset 1
48112115Sdyson	xdwait
48212115Sdyson	cxset 0x61
48312115Sdyson	xdwait
48412115Sdyson	xdwait
48512115Sdyson
48612115Sdyson	// update src address
48712115Sdyson	shr b32 $r8 $r4 0x18
48812115Sdyson	shl b32 $r9 $r4 8
48912115Sdyson	add b32 $r9 $r5
49012115Sdyson	adc b32 $r8 0
49112147Sdyson	st b32 D[$r0 + #ctx_src_address_high] $r8
49212115Sdyson	st b32 D[$r0 + #ctx_src_address_low] $r9
49312115Sdyson
49412115Sdyson	// update dst address
49512115Sdyson	shr b32 $r8 $r6 0x18
49612115Sdyson	shl b32 $r9 $r6 8
49712115Sdyson	add b32 $r9 $r7
49812115Sdyson	adc b32 $r8 0
49912115Sdyson	st b32 D[$r0 + #ctx_dst_address_high] $r8
50012115Sdyson	st b32 D[$r0 + #ctx_dst_address_low] $r9
50112115Sdyson
50212115Sdyson	// pull updated IV
50312115Sdyson	cxset 2
50412115Sdyson	mov $r4 #ctx_iv
50512115Sdyson	sethi $r4 0x60000
50612115Sdyson	xdld $r0 $r4
50712115Sdyson	xdwait
50812115Sdyson
50912115Sdyson	ret
51012115Sdyson
51112115Sdyson
51212115Sdysonsec_copy_prep:
51312115Sdyson	cs0begin 2
51412115Sdyson		cxsin $c0
51512115Sdyson		cxsout $c0
51612115Sdyson	ret
51712115Sdyson
51812115Sdysonsec_store_prep:
51912115Sdyson	cs0begin 1
52012115Sdyson		cxsout $c6
52112115Sdyson	ret
52212115Sdyson
52312115Sdysonsec_ecb_e_prep:
52412115Sdyson	cs0begin 3
52512115Sdyson		cxsin $c0
52612115Sdyson		cenc $c0 $c0
52712115Sdyson		cxsout $c0
52812115Sdyson	ret
52912115Sdyson
53012115Sdysonsec_ecb_d_prep:
53112115Sdyson	ckexp $c7 $c7
53212115Sdyson	cs0begin 3
53312115Sdyson		cxsin $c0
53412115Sdyson		cdec $c0 $c0
53512115Sdyson		cxsout $c0
53612115Sdyson	ret
53712115Sdyson
53812115Sdysonsec_cbc_e_prep:
53912115Sdyson	cs0begin 4
54012115Sdyson		cxsin $c0
54112115Sdyson		cxor $c6 $c0
54212115Sdyson		cenc $c6 $c6
54312115Sdyson		cxsout $c6
54412115Sdyson	ret
54522521Sdyson
54612115Sdysonsec_cbc_d_prep:
54712115Sdyson	ckexp $c7 $c7
54812115Sdyson	cs0begin 5
54912115Sdyson		cmov $c2 $c6
55012115Sdyson		cxsin $c6
55112115Sdyson		cdec $c0 $c6
55212115Sdyson		cxor $c0 $c2
55312115Sdyson		cxsout $c0
55412115Sdyson	ret
55512115Sdyson
55612115Sdysonsec_pcbc_e_prep:
55712115Sdyson	cs0begin 5
55812115Sdyson		cxsin $c0
55912115Sdyson		cxor $c6 $c0
56012115Sdyson		cenc $c6 $c6
56112115Sdyson		cxsout $c6
56212115Sdyson		cxor $c6 $c0
56312115Sdyson	ret
56412115Sdyson
56512115Sdysonsec_pcbc_d_prep:
56612115Sdyson	ckexp $c7 $c7
56712115Sdyson	cs0begin 5
56812115Sdyson		cxsin $c0
56912115Sdyson		cdec $c1 $c0
57012115Sdyson		cxor $c6 $c1
57112115Sdyson		cxsout $c6
57212115Sdyson		cxor $c6 $c0
57312911Sphk	ret
57412115Sdyson
57512115Sdysonsec_cfb_e_prep:
57612115Sdyson	cs0begin 4
57712115Sdyson		cenc $c6 $c6
57812115Sdyson		cxsin $c0
57912115Sdyson		cxor $c6 $c0
58012115Sdyson		cxsout $c6
58112115Sdyson	ret
58212115Sdyson
58312115Sdysonsec_cfb_d_prep:
58412115Sdyson	cs0begin 4
58512115Sdyson		cenc $c0 $c6
58612115Sdyson		cxsin $c6
58712115Sdyson		cxor $c0 $c6
58812115Sdyson		cxsout $c0
58912115Sdyson	ret
59012115Sdyson
59112115Sdysonsec_ofb_prep:
59212115Sdyson	cs0begin 4
59312115Sdyson		cenc $c6 $c6
59412115Sdyson		cxsin $c0
59512115Sdyson		cxor $c0 $c6
59612115Sdyson		cxsout $c0
59712115Sdyson	ret
59812115Sdyson
59912115Sdysonsec_ctr_prep:
60012115Sdyson	cs0begin 5
60112115Sdyson		cenc $c1 $c6
60212115Sdyson		cadd $c6 1
60312115Sdyson		cxsin $c0
60412115Sdyson		cxor $c0 $c1
60512115Sdyson		cxsout $c0
60612115Sdyson	ret
60712115Sdyson
60812115Sdysonsec_cbc_mac_prep:
60912115Sdyson	cs0begin 3
61012115Sdyson		cxsin $c0
61112115Sdyson		cxor $c6 $c0
61212115Sdyson		cenc $c6 $c6
61312115Sdyson	ret
61412115Sdyson
61512115Sdysonsec_cmac_finish_complete_prep:
61612115Sdyson	cs0begin 7
61712115Sdyson		cxsin $c0
61812115Sdyson		cxor $c6 $c0
61912115Sdyson		cxor $c0 $c0
62012115Sdyson		cenc $c0 $c0
62112115Sdyson		cprecmac $c0 $c0
62212115Sdyson		cxor $c6 $c0
62312115Sdyson		cenc $c6 $c6
62412115Sdyson	ret
62512115Sdyson
62612115Sdysonsec_cmac_finish_partial_prep:
62712115Sdyson	cs0begin 8
62812115Sdyson		cxsin $c0
62912115Sdyson		cxor $c6 $c0
63012115Sdyson		cxor $c0 $c0
63112115Sdyson		cenc $c0 $c0
63212115Sdyson		cprecmac $c0 $c0
63312115Sdyson		cprecmac $c0 $c0
63430280Sphk		cxor $c6 $c0
63530474Sphk		cenc $c6 $c6
63630474Sphk	ret
63730492Sphk
63830474Sphk// TODO
63930474Sphksec_do_in:
64012115Sdyson	add b32 $r3 $r5
64112115Sdyson	mov $xdbase $r4
64212115Sdyson	mov $r9 #swap
64312115Sdyson	sethi $r9 0x20000
64412115Sdyson	sec_do_in_loop:
64512115Sdyson		xdld $r5 $r9
64612115Sdyson		xdwait
64712115Sdyson		cxset 0x22
64812115Sdyson		xdst $r0 $r9
64912115Sdyson		cs0exec 1
65012115Sdyson		xdwait
65112115Sdyson		add b32 $r5 0x10
65212115Sdyson		cmpu b32 $r5 $r3
65312115Sdyson	bra ne #sec_do_in_loop
65412115Sdyson	cxset 1
65512115Sdyson	xdwait
65612115Sdyson	ret
65712115Sdyson
65812115Sdysonsec_do_out:
65912115Sdyson	add b32 $r3 $r7
66012115Sdyson	mov $xdbase $r6
66112115Sdyson	mov $r9 #swap
66212115Sdyson	sethi $r9 0x20000
66312115Sdyson	sec_do_out_loop:
66412115Sdyson		cs0exec 1
66512115Sdyson		cxset 0x61
66612115Sdyson		xdld $r7 $r9
66712115Sdyson		xdst $r7 $r9
66812115Sdyson		cxset 1
66912115Sdyson		xdwait
67038909Sbde		add b32 $r7 0x10
67112115Sdyson		cmpu b32 $r7 $r3
67212115Sdyson	bra ne #sec_do_out_loop
67312115Sdyson	ret
67412115Sdyson
67512115Sdysonsec_do_inout:
67612115Sdyson	add b32 $r3 $r5
67712115Sdyson	mov $r9 #swap
67812115Sdyson	sethi $r9 0x20000
67912115Sdyson	sec_do_inout_loop:
68012115Sdyson		mov $xdbase $r4
68112115Sdyson		xdld $r5 $r9
68212115Sdyson		xdwait
68312115Sdyson		cxset 0x21
68434430Seivind		xdst $r0 $r9
68534430Seivind		cs0exec 1
68634430Seivind		cxset 0x61
68712115Sdyson		mov $xdbase $r6
68812115Sdyson		xdld $r7 $r9
68912115Sdyson		xdst $r7 $r9
69012115Sdyson		cxset 1
69112115Sdyson		xdwait
69212115Sdyson		add b32 $r5 0x10
69312115Sdyson		add b32 $r7 0x10
69412115Sdyson		cmpu b32 $r5 $r3
69512115Sdyson	bra ne #sec_do_inout_loop
69612115Sdyson	ret
69712115Sdyson
69812115Sdyson.align 0x100
69912115Sdyson