brintos

brintos / linux-shallow public Read only

0
0
Text · 12.7 KiB · 66b147b Raw
699 lines · plain
1/*2 *  fuc microcode for g98 sec engine3 *  Copyright (C) 2010  Marcin Kościelnicki4 *5 *  This program is free software; you can redistribute it and/or modify6 *  it under the terms of the GNU General Public License as published by7 *  the Free Software Foundation; either version 2 of the License, or8 *  (at your option) any later version.9 *10 *  This program is distributed in the hope that it will be useful,11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the13 *  GNU General Public License for more details.14 *15 *  You should have received a copy of the GNU General Public License16 *  along with this program; if not, write to the Free Software17 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA18 */19 20.section #g98_sec_data21 22ctx_dma:23ctx_dma_query:		.b32 024ctx_dma_src:		.b32 025ctx_dma_dst:		.b32 026.equ #dma_count 327ctx_query_address_high:	.b32 028ctx_query_address_low:	.b32 029ctx_query_counter:	.b32 030ctx_cond_address_high:	.b32 031ctx_cond_address_low:	.b32 032ctx_cond_off:		.b32 033ctx_src_address_high:	.b32 034ctx_src_address_low:	.b32 035ctx_dst_address_high:	.b32 036ctx_dst_address_low:	.b32 037ctx_mode:		.b32 038.align 1639ctx_key:		.skip 1640ctx_iv:			.skip 1641 42.align 0x8043swap:44.skip 3245 46.align 847common_cmd_dtable:48.b32 #ctx_query_address_high + 0x20000 ~0xff49.b32 #ctx_query_address_low + 0x20000 ~0xfffffff050.b32 #ctx_query_counter + 0x20000 ~0xffffffff51.b32 #cmd_query_get + 0x00000 ~152.b32 #ctx_cond_address_high + 0x20000 ~0xff53.b32 #ctx_cond_address_low + 0x20000 ~0xfffffff054.b32 #cmd_cond_mode + 0x00000 ~755.b32 #cmd_wrcache_flush + 0x00000 ~056.equ #common_cmd_max 0x8857 58 59.align 860engine_cmd_dtable:61.b32 #ctx_key + 0x0 + 0x20000 ~0xffffffff62.b32 #ctx_key + 0x4 + 0x20000 ~0xffffffff63.b32 #ctx_key + 0x8 + 0x20000 ~0xffffffff64.b32 #ctx_key + 0xc + 0x20000 ~0xffffffff65.b32 #ctx_iv + 0x0 + 0x20000 ~0xffffffff66.b32 #ctx_iv + 0x4 + 0x20000 ~0xffffffff67.b32 #ctx_iv + 0x8 + 0x20000 ~0xffffffff68.b32 #ctx_iv + 0xc + 0x20000 ~0xffffffff69.b32 #ctx_src_address_high + 0x20000 ~0xff70.b32 #ctx_src_address_low + 0x20000 ~0xfffffff071.b32 #ctx_dst_address_high + 0x20000 ~0xff72.b32 #ctx_dst_address_low + 0x20000 ~0xfffffff073.b32 #sec_cmd_mode + 0x00000 ~0xf74.b32 #sec_cmd_length + 0x10000 ~0x0ffffff075.equ #engine_cmd_max 0xce76 77.align 478sec_dtable:79.b16 #sec_copy_prep #sec_do_inout80.b16 #sec_store_prep #sec_do_out81.b16 #sec_ecb_e_prep #sec_do_inout82.b16 #sec_ecb_d_prep #sec_do_inout83.b16 #sec_cbc_e_prep #sec_do_inout84.b16 #sec_cbc_d_prep #sec_do_inout85.b16 #sec_pcbc_e_prep #sec_do_inout86.b16 #sec_pcbc_d_prep #sec_do_inout87.b16 #sec_cfb_e_prep #sec_do_inout88.b16 #sec_cfb_d_prep #sec_do_inout89.b16 #sec_ofb_prep #sec_do_inout90.b16 #sec_ctr_prep #sec_do_inout91.b16 #sec_cbc_mac_prep #sec_do_in92.b16 #sec_cmac_finish_complete_prep #sec_do_in93.b16 #sec_cmac_finish_partial_prep #sec_do_in94 95.align 0x10096 97.section #g98_sec_code98 99	// $r0 is always set to 0 in our code - this allows some space savings.100	clear b32 $r0101 102	// set up the interrupt handler103	mov $r1 #ih104	mov $iv0 $r1105 106	// init stack pointer107	mov $sp $r0108 109	// set interrupt dispatch - route timer, fifo, ctxswitch to i0, others to host110	movw $r1 0xfff0111	sethi $r1 0112	mov $r2 0x400113	iowr I[$r2 + 0x300] $r1114 115	// enable the interrupts116	or $r1 0xc117	iowr I[$r2] $r1118 119	// enable fifo access and context switching120	mov $r1 3121	mov $r2 0x1200122	iowr I[$r2] $r1123 124	// enable i0 delivery125	bset $flags ie0126 127	// sleep forver, waking only for interrupts.128	bset $flags $p0129	spin:130	sleep $p0131	bra #spin132 133// i0 handler134ih:135	// see which interrupts we got136	iord $r1 I[$r0 + 0x200]137 138	and $r2 $r1 0x8139	cmpu b32 $r2 0140	bra e #noctx141 142		// context switch... prepare the regs for xfer143		mov $r2 0x7700144		mov $xtargets $r2145		mov $xdbase $r0146		// 128-byte context.147		mov $r2 0148		sethi $r2 0x50000149 150		// read current channel151		mov $r3 0x1400152		iord $r4 I[$r3]153		// if bit 30 set, it's active, so we have to unload it first.154		shl b32 $r5 $r4 1155		cmps b32 $r5 0156		bra nc #ctxload157 158			// unload the current channel - save the context159			xdst $r0 $r2160			xdwait161			// and clear bit 30, then write back162			bclr $r4 0x1e163			iowr I[$r3] $r4164			// tell PFIFO we unloaded165			mov $r4 1166			iowr I[$r3 + 0x200] $r4167 168		bra #noctx169 170		ctxload:171			// no channel loaded - perhaps we're requested to load one172			iord $r4 I[$r3 + 0x100]173			shl b32 $r15 $r4 1174			cmps b32 $r15 0175			// if bit 30 of next channel not set, probably PFIFO is just176			// killing a context. do a faux load, without the active bit.177			bra nc #dummyload178 179				// ok, do a real context load.180				xdld $r0 $r2181				xdwait182				mov $r5 #ctx_dma183				mov $r6 #dma_count - 1184				ctxload_dma_loop:185					ld b32 $r7 D[$r5 + $r6 * 4]186					add b32 $r8 $r6 0x180187					shl b32 $r8 8188					iowr I[$r8] $r7189					sub b32 $r6 1190				bra nc #ctxload_dma_loop191 192			dummyload:193			// tell PFIFO we're done194			mov $r5 2195			iowr I[$r3 + 0x200] $r5196 197	noctx:198	and $r2 $r1 0x4199	cmpu b32 $r2 0200	bra e #nocmd201 202		// incoming fifo command.203		mov $r3 0x1900204		iord $r2 I[$r3 + 0x100]205		iord $r3 I[$r3]206		// extract the method207		and $r4 $r2 0x7ff208		// shift the addr to proper position if we need to interrupt later209		shl b32 $r2 0x10210 211		// mthd 0 and 0x100 [NAME, NOP]: ignore212		and $r5 $r4 0x7bf213		cmpu b32 $r5 0214		bra e #cmddone215 216		mov $r5 #engine_cmd_dtable - 0xc0 * 8217		mov $r6 #engine_cmd_max218		cmpu b32 $r4 0xc0219		bra nc #dtable_cmd220		mov $r5 #common_cmd_dtable - 0x80 * 8221		mov $r6 #common_cmd_max222		cmpu b32 $r4 0x80223		bra nc #dtable_cmd224		cmpu b32 $r4 0x60225		bra nc #dma_cmd226		cmpu b32 $r4 0x50227		bra ne #illegal_mthd228 229			// mthd 0x140: PM_TRIGGER230			mov $r2 0x2200231			clear b32 $r3232			sethi $r3 0x20000233			iowr I[$r2] $r3234			bra #cmddone235 236		dma_cmd:237			// mthd 0x180...: DMA_*238			cmpu b32 $r4 0x60+#dma_count239			bra nc #illegal_mthd240			shl b32 $r5 $r4 2241			add b32 $r5 ((#ctx_dma - 0x60 * 4) & 0xffff)242			bset $r3 0x1e243			st b32 D[$r5] $r3244			add b32 $r4 0x180 - 0x60245			shl b32 $r4 8246			iowr I[$r4] $r3247			bra #cmddone248 249		dtable_cmd:250			cmpu b32 $r4 $r6251			bra nc #illegal_mthd252			shl b32 $r4 3253			add b32 $r4 $r5254			ld b32 $r5 D[$r4 + 4]255			and $r5 $r3256			cmpu b32 $r5 0257			bra ne #invalid_bitfield258			ld b16 $r5 D[$r4]259			ld b16 $r6 D[$r4 + 2]260			cmpu b32 $r6 2261			bra e #cmd_setctx262			ld b32 $r7 D[$r0 + #ctx_cond_off]263			and $r6 $r7264			cmpu b32 $r6 1265			bra e #cmddone266			call $r5267			bra $p1 #dispatch_error268			bra #cmddone269 270		cmd_setctx:271			st b32 D[$r5] $r3272			bra #cmddone273 274 275		invalid_bitfield:276			or $r2 1277		dispatch_error:278		illegal_mthd:279			mov $r4 0x1000280			iowr I[$r4] $r2281			iowr I[$r4 + 0x100] $r3282			mov $r4 0x40283			iowr I[$r0] $r4284 285			im_loop:286				iord $r4 I[$r0 + 0x200]287				and $r4 0x40288				cmpu b32 $r4 0289			bra ne #im_loop290 291		cmddone:292		// remove the command from FIFO293		mov $r3 0x1d00294		mov $r4 1295		iowr I[$r3] $r4296 297	nocmd:298	// ack the processed interrupts299	and $r1 $r1 0xc300	iowr I[$r0 + 0x100] $r1301iret302 303cmd_query_get:304	// if bit 0 of param set, trigger interrupt afterwards.305	setp $p1 $r3306	or $r2 3307 308	// read PTIMER, beware of races...309	mov $r4 0xb00310	ptimer_retry:311		iord $r6 I[$r4 + 0x100]312		iord $r5 I[$r4]313		iord $r7 I[$r4 + 0x100]314		cmpu b32 $r6 $r7315	bra ne #ptimer_retry316 317	// prepare the query structure318	ld b32 $r4 D[$r0 + #ctx_query_counter]319	st b32 D[$r0 + #swap + 0x0] $r4320	st b32 D[$r0 + #swap + 0x4] $r0321	st b32 D[$r0 + #swap + 0x8] $r5322	st b32 D[$r0 + #swap + 0xc] $r6323 324	// will use target 0, DMA_QUERY.325	mov $xtargets $r0326 327	ld b32 $r4 D[$r0 + #ctx_query_address_high]328	shl b32 $r4 0x18329	mov $xdbase $r4330 331	ld b32 $r4 D[$r0 + #ctx_query_address_low]332	mov $r5 #swap333	sethi $r5 0x20000334	xdst $r4 $r5335	xdwait336 337	ret338 339cmd_cond_mode:340	// if >= 5, INVALID_ENUM341	bset $flags $p1342	or $r2 2343	cmpu b32 $r3 5344	bra nc #return345 346	// otherwise, no error.347	bclr $flags $p1348 349	// if < 2, no QUERY object is involved350	cmpu b32 $r3 2351	bra nc #cmd_cond_mode_queryful352 353		xor $r3 1354		st b32 D[$r0 + #ctx_cond_off] $r3355	return:356		ret357 358	cmd_cond_mode_queryful:359	// ok, will need to pull a QUERY object, prepare offsets360	ld b32 $r4 D[$r0 + #ctx_cond_address_high]361	ld b32 $r5 D[$r0 + #ctx_cond_address_low]362	and $r6 $r5 0xff363	shr b32 $r5 8364	shl b32 $r4 0x18365	or $r4 $r5366	mov $xdbase $r4367	mov $xtargets $r0368 369	// pull the first one370	mov $r5 #swap371	sethi $r5 0x20000372	xdld $r6 $r5373 374	// if == 2, only a single QUERY is involved...375	cmpu b32 $r3 2376	bra ne #cmd_cond_mode_double377 378		xdwait379		ld b32 $r4 D[$r0 + #swap + 4]380		cmpu b32 $r4 0381		xbit $r4 $flags z382		st b32 D[$r0 + #ctx_cond_off] $r4383		ret384 385	// ok, we'll need to pull second one too386	cmd_cond_mode_double:387	add b32 $r6 0x10388	add b32 $r5 0x10389	xdld $r6 $r5390	xdwait391 392	// compare COUNTERs393	ld b32 $r5 D[$r0 + #swap + 0x00]394	ld b32 $r6 D[$r0 + #swap + 0x10]395	cmpu b32 $r5 $r6396	xbit $r4 $flags z397 398	// compare RESen399	ld b32 $r5 D[$r0 + #swap + 0x04]400	ld b32 $r6 D[$r0 + #swap + 0x14]401	cmpu b32 $r5 $r6402	xbit $r5 $flags z403	and $r4 $r5404 405	// and negate or not, depending on mode406	cmpu b32 $r3 3407	xbit $r5 $flags z408	xor $r4 $r5409	st b32 D[$r0 + #ctx_cond_off] $r4410	ret411 412cmd_wrcache_flush:413	bclr $flags $p1414	mov $r2 0x2200415	clear b32 $r3416	sethi $r3 0x10000417	iowr I[$r2] $r3418	ret419 420sec_cmd_mode:421	// if >= 0xf, INVALID_ENUM422	bset $flags $p1423	or $r2 2424	cmpu b32 $r3 0xf425	bra nc #sec_cmd_mode_return426 427		bclr $flags $p1428		st b32 D[$r0 + #ctx_mode] $r3429 430	sec_cmd_mode_return:431	ret432 433sec_cmd_length:434	// nop if length == 0435	cmpu b32 $r3 0436	bra e #sec_cmd_mode_return437 438	// init key, IV439	cxset 3440	mov $r4 #ctx_key441	sethi $r4 0x70000442	xdst $r0 $r4443	mov $r4 #ctx_iv444	sethi $r4 0x60000445	xdst $r0 $r4446	xdwait447	ckeyreg $c7448 449	// prepare the targets450	mov $r4 0x2100451	mov $xtargets $r4452 453	// prepare src address454	ld b32 $r4 D[$r0 + #ctx_src_address_high]455	ld b32 $r5 D[$r0 + #ctx_src_address_low]456	shr b32 $r8 $r5 8457	shl b32 $r4 0x18458	or $r4 $r8459	and $r5 $r5 0xff460 461	// prepare dst address462	ld b32 $r6 D[$r0 + #ctx_dst_address_high]463	ld b32 $r7 D[$r0 + #ctx_dst_address_low]464	shr b32 $r8 $r7 8465	shl b32 $r6 0x18466	or $r6 $r8467	and $r7 $r7 0xff468 469	// find the proper prep & do functions470	ld b32 $r8 D[$r0 + #ctx_mode]471	shl b32 $r8 2472 473	// run prep474	ld b16 $r9 D[$r8 + #sec_dtable]475	call $r9476 477	// do it478	ld b16 $r9 D[$r8 + #sec_dtable + 2]479	call $r9480	cxset 1481	xdwait482	cxset 0x61483	xdwait484	xdwait485 486	// update src address487	shr b32 $r8 $r4 0x18488	shl b32 $r9 $r4 8489	add b32 $r9 $r5490	adc b32 $r8 0491	st b32 D[$r0 + #ctx_src_address_high] $r8492	st b32 D[$r0 + #ctx_src_address_low] $r9493 494	// update dst address495	shr b32 $r8 $r6 0x18496	shl b32 $r9 $r6 8497	add b32 $r9 $r7498	adc b32 $r8 0499	st b32 D[$r0 + #ctx_dst_address_high] $r8500	st b32 D[$r0 + #ctx_dst_address_low] $r9501 502	// pull updated IV503	cxset 2504	mov $r4 #ctx_iv505	sethi $r4 0x60000506	xdld $r0 $r4507	xdwait508 509	ret510 511 512sec_copy_prep:513	cs0begin 2514		cxsin $c0515		cxsout $c0516	ret517 518sec_store_prep:519	cs0begin 1520		cxsout $c6521	ret522 523sec_ecb_e_prep:524	cs0begin 3525		cxsin $c0526		cenc $c0 $c0527		cxsout $c0528	ret529 530sec_ecb_d_prep:531	ckexp $c7 $c7532	cs0begin 3533		cxsin $c0534		cdec $c0 $c0535		cxsout $c0536	ret537 538sec_cbc_e_prep:539	cs0begin 4540		cxsin $c0541		cxor $c6 $c0542		cenc $c6 $c6543		cxsout $c6544	ret545 546sec_cbc_d_prep:547	ckexp $c7 $c7548	cs0begin 5549		cmov $c2 $c6550		cxsin $c6551		cdec $c0 $c6552		cxor $c0 $c2553		cxsout $c0554	ret555 556sec_pcbc_e_prep:557	cs0begin 5558		cxsin $c0559		cxor $c6 $c0560		cenc $c6 $c6561		cxsout $c6562		cxor $c6 $c0563	ret564 565sec_pcbc_d_prep:566	ckexp $c7 $c7567	cs0begin 5568		cxsin $c0569		cdec $c1 $c0570		cxor $c6 $c1571		cxsout $c6572		cxor $c6 $c0573	ret574 575sec_cfb_e_prep:576	cs0begin 4577		cenc $c6 $c6578		cxsin $c0579		cxor $c6 $c0580		cxsout $c6581	ret582 583sec_cfb_d_prep:584	cs0begin 4585		cenc $c0 $c6586		cxsin $c6587		cxor $c0 $c6588		cxsout $c0589	ret590 591sec_ofb_prep:592	cs0begin 4593		cenc $c6 $c6594		cxsin $c0595		cxor $c0 $c6596		cxsout $c0597	ret598 599sec_ctr_prep:600	cs0begin 5601		cenc $c1 $c6602		cadd $c6 1603		cxsin $c0604		cxor $c0 $c1605		cxsout $c0606	ret607 608sec_cbc_mac_prep:609	cs0begin 3610		cxsin $c0611		cxor $c6 $c0612		cenc $c6 $c6613	ret614 615sec_cmac_finish_complete_prep:616	cs0begin 7617		cxsin $c0618		cxor $c6 $c0619		cxor $c0 $c0620		cenc $c0 $c0621		cprecmac $c0 $c0622		cxor $c6 $c0623		cenc $c6 $c6624	ret625 626sec_cmac_finish_partial_prep:627	cs0begin 8628		cxsin $c0629		cxor $c6 $c0630		cxor $c0 $c0631		cenc $c0 $c0632		cprecmac $c0 $c0633		cprecmac $c0 $c0634		cxor $c6 $c0635		cenc $c6 $c6636	ret637 638// TODO639sec_do_in:640	add b32 $r3 $r5641	mov $xdbase $r4642	mov $r9 #swap643	sethi $r9 0x20000644	sec_do_in_loop:645		xdld $r5 $r9646		xdwait647		cxset 0x22648		xdst $r0 $r9649		cs0exec 1650		xdwait651		add b32 $r5 0x10652		cmpu b32 $r5 $r3653	bra ne #sec_do_in_loop654	cxset 1655	xdwait656	ret657 658sec_do_out:659	add b32 $r3 $r7660	mov $xdbase $r6661	mov $r9 #swap662	sethi $r9 0x20000663	sec_do_out_loop:664		cs0exec 1665		cxset 0x61666		xdld $r7 $r9667		xdst $r7 $r9668		cxset 1669		xdwait670		add b32 $r7 0x10671		cmpu b32 $r7 $r3672	bra ne #sec_do_out_loop673	ret674 675sec_do_inout:676	add b32 $r3 $r5677	mov $r9 #swap678	sethi $r9 0x20000679	sec_do_inout_loop:680		mov $xdbase $r4681		xdld $r5 $r9682		xdwait683		cxset 0x21684		xdst $r0 $r9685		cs0exec 1686		cxset 0x61687		mov $xdbase $r6688		xdld $r7 $r9689		xdst $r7 $r9690		cxset 1691		xdwait692		add b32 $r5 0x10693		add b32 $r7 0x10694		cmpu b32 $r5 $r3695	bra ne #sec_do_inout_loop696	ret697 698.align 0x100699