cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

com.fuc (8039B)


      1/* fuc microcode util functions for gf100 PGRAPH
      2 *
      3 * Copyright 2011 Red Hat Inc.
      4 *
      5 * Permission is hereby granted, free of charge, to any person obtaining a
      6 * copy of this software and associated documentation files (the "Software"),
      7 * to deal in the Software without restriction, including without limitation
      8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9 * and/or sell copies of the Software, and to permit persons to whom the
     10 * Software is furnished to do so, subject to the following conditions:
     11 *
     12 * The above copyright notice and this permission notice shall be included in
     13 * all copies or substantial portions of the Software.
     14 *
     15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     21 * OTHER DEALINGS IN THE SOFTWARE.
     22 *
     23 * Authors: Ben Skeggs
     24 */
     25
     26#ifdef INCLUDE_CODE
     27// queue_put - add request to queue
     28//
     29// In : $r13 queue pointer
     30//	$r14 command
     31//	$r15 data
     32//
     33queue_put:
     34	// make sure we have space..
     35	ld b32 $r8 D[$r13 + 0x0]	// GET
     36	ld b32 $r9 D[$r13 + 0x4]	// PUT
     37	xor $r8 8
     38	cmpu b32 $r8 $r9
     39	bra ne #queue_put_next
     40		mov $r15 E_CMD_OVERFLOW
     41		call(error)
     42		ret
     43
     44	// store cmd/data on queue
     45	queue_put_next:
     46	and $r8 $r9 7
     47	shl b32 $r8 3
     48	add b32 $r8 $r13
     49	add b32 $r8 8
     50	st b32 D[$r8 + 0x0] $r14
     51	st b32 D[$r8 + 0x4] $r15
     52
     53	// update PUT
     54	add b32 $r9 1
     55	and $r9 0xf
     56	st b32 D[$r13 + 0x4] $r9
     57	ret
     58
     59// queue_get - fetch request from queue
     60//
     61// In : $r13 queue pointer
     62//
     63// Out:	$p1  clear on success (data available)
     64//	$r14 command
     65// 	$r15 data
     66//
     67queue_get:
     68	bset $flags $p1
     69	ld b32 $r8 D[$r13 + 0x0]	// GET
     70	ld b32 $r9 D[$r13 + 0x4]	// PUT
     71	cmpu b32 $r8 $r9
     72	bra e #queue_get_done
     73		// fetch first cmd/data pair
     74		and $r9 $r8 7
     75		shl b32 $r9 3
     76		add b32 $r9 $r13
     77		add b32 $r9 8
     78		ld b32 $r14 D[$r9 + 0x0]
     79		ld b32 $r15 D[$r9 + 0x4]
     80
     81		// update GET
     82		add b32 $r8 1
     83		and $r8 0xf
     84		st b32 D[$r13 + 0x0] $r8
     85		bclr $flags $p1
     86queue_get_done:
     87	ret
     88
     89// nv_rd32 - read 32-bit value from nv register
     90//
     91// In : $r14 register
     92// Out: $r15 value
     93//
     94nv_rd32:
     95	mov b32 $r12 $r14
     96	bset $r12 31			// MMIO_CTRL_PENDING
     97	nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
     98	nv_rd32_wait:
     99		nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
    100		xbit $r12 $r12 31
    101		bra ne #nv_rd32_wait
    102	mov $r10 6			// DONE_MMIO_RD
    103	call(wait_doneo)
    104	nv_iord($r15, NV_PGRAPH_FECS_MMIO_RDVAL, 0)
    105	ret
    106
    107// nv_wr32 - write 32-bit value to nv register
    108//
    109// In : $r14 register
    110//      $r15 value
    111//
    112nv_wr32:
    113	nv_iowr(NV_PGRAPH_FECS_MMIO_WRVAL, 0, $r15)
    114	mov b32 $r12 $r14
    115	bset $r12 31			// MMIO_CTRL_PENDING
    116	bset $r12 30			// MMIO_CTRL_WRITE
    117	nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
    118	nv_wr32_wait:
    119		nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
    120		xbit $r12 $r12 31
    121		bra ne #nv_wr32_wait
    122	ret
    123
    124// wait_donez - wait on FUC_DONE bit to become clear
    125//
    126// In : $r10 bit to wait on
    127//
    128wait_donez:
    129	trace_set(T_WAIT);
    130	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
    131	wait_donez_ne:
    132		nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
    133		xbit $r8 $r8 $r10
    134		bra ne #wait_donez_ne
    135	trace_clr(T_WAIT)
    136	ret
    137
    138// wait_doneo - wait on FUC_DONE bit to become set
    139//
    140// In : $r10 bit to wait on
    141//
    142wait_doneo:
    143	trace_set(T_WAIT);
    144	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
    145	wait_doneo_e:
    146		nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
    147		xbit $r8 $r8 $r10
    148		bra e #wait_doneo_e
    149	trace_clr(T_WAIT)
    150	ret
    151
    152// mmctx_size - determine size of a mmio list transfer
    153//
    154// In : $r14 mmio list head
    155//      $r15 mmio list tail
    156// Out: $r15 transfer size (in bytes)
    157//
    158mmctx_size:
    159	clear b32 $r9
    160	nv_mmctx_size_loop:
    161		ld b32 $r8 D[$r14]
    162		shr b32 $r8 26
    163		add b32 $r8 1
    164		shl b32 $r8 2
    165		add b32 $r9 $r8
    166		add b32 $r14 4
    167		cmpu b32 $r14 $r15
    168		bra ne #nv_mmctx_size_loop
    169	mov b32 $r15 $r9
    170	ret
    171
    172// mmctx_xfer - execute a list of mmio transfers
    173//
    174// In : $r10 flags
    175//		bit 0: direction (0 = save, 1 = load)
    176//		bit 1: set if first transfer
    177//		bit 2: set if last transfer
    178//	$r11 base
    179//	$r12 mmio list head
    180//	$r13 mmio list tail
    181//	$r14 multi_stride
    182//	$r15 multi_mask
    183//
    184mmctx_xfer:
    185	trace_set(T_MMCTX)
    186	clear b32 $r9
    187	or $r11 $r11
    188	bra e #mmctx_base_disabled
    189		nv_iowr(NV_PGRAPH_FECS_MMCTX_BASE, 0, $r11)
    190		bset $r9 0			// BASE_EN
    191	mmctx_base_disabled:
    192	or $r14 $r14
    193	bra e #mmctx_multi_disabled
    194		nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_STRIDE, 0, $r14)
    195		nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_MASK, 0, $r15)
    196		bset $r9 1			// MULTI_EN
    197	mmctx_multi_disabled:
    198
    199	xbit $r11 $r10 0
    200	shl b32 $r11 16			// DIR
    201	bset $r11 12			// QLIMIT = 0x10
    202	xbit $r14 $r10 1
    203	shl b32 $r14 17
    204	or $r11 $r14			// START_TRIGGER
    205	nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
    206
    207	// loop over the mmio list, and send requests to the hw
    208	mmctx_exec_loop:
    209		// wait for space in mmctx queue
    210		mmctx_wait_free:
    211			nv_iord($r14, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
    212			and $r14 0x1f
    213			bra e #mmctx_wait_free
    214
    215		// queue up an entry
    216		ld b32 $r14 D[$r12]
    217		or $r14 $r9
    218		nv_iowr(NV_PGRAPH_FECS_MMCTX_QUEUE, 0, $r14)
    219		add b32 $r12 4
    220		cmpu b32 $r12 $r13
    221		bra ne #mmctx_exec_loop
    222
    223	xbit $r11 $r10 2
    224	bra ne #mmctx_stop
    225		// wait for queue to empty
    226		mmctx_fini_wait:
    227			nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
    228			and $r11 0x1f
    229			cmpu b32 $r11 0x10
    230			bra ne #mmctx_fini_wait
    231		mov $r10 5			// DONE_MMCTX
    232		call(wait_donez)
    233		bra #mmctx_done
    234	mmctx_stop:
    235		xbit $r11 $r10 0
    236		shl b32 $r11 16			// DIR
    237		bset $r11 12			// QLIMIT = 0x10
    238		bset $r11 18			// STOP_TRIGGER
    239		nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
    240		mmctx_stop_wait:
    241			// wait for STOP_TRIGGER to clear
    242			nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
    243			xbit $r11 $r11 18
    244			bra ne #mmctx_stop_wait
    245	mmctx_done:
    246	trace_clr(T_MMCTX)
    247	ret
    248
    249// Wait for DONE_STRAND
    250//
    251strand_wait:
    252	push $r10
    253	mov $r10 2
    254	call(wait_donez)
    255	pop $r10
    256	ret
    257
    258// unknown - call before issuing strand commands
    259//
    260strand_pre:
    261	mov $r9 NV_PGRAPH_FECS_STRAND_CMD_ENABLE
    262	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
    263	call(strand_wait)
    264	ret
    265
    266// unknown - call after issuing strand commands
    267//
    268strand_post:
    269	mov $r9 NV_PGRAPH_FECS_STRAND_CMD_DISABLE
    270	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
    271	call(strand_wait)
    272	ret
    273
    274// Selects strand set?!
    275//
    276// In: $r14 id
    277//
    278strand_set:
    279	mov $r12 0xf
    280	nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r12)
    281	mov $r12 NV_PGRAPH_FECS_STRAND_CMD_DEACTIVATE_FILTER
    282	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
    283	nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r14)
    284	mov $r12 NV_PGRAPH_FECS_STRAND_CMD_ACTIVATE_FILTER
    285	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
    286	call(strand_wait)
    287	ret
    288
    289// Initialise strand context data
    290//
    291// In : $r15 context base
    292// Out: $r15 context size (in bytes)
    293//
    294// Strandset(?) 3 hardcoded currently
    295//
    296strand_ctx_init:
    297	trace_set(T_STRINIT)
    298	call(strand_pre)
    299	mov $r14 3
    300	call(strand_set)
    301
    302	clear b32 $r12
    303	nv_iowr(NV_PGRAPH_FECS_STRAND_SELECT, 0x3f, $r12)
    304	mov $r12 NV_PGRAPH_FECS_STRAND_CMD_SEEK
    305	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
    306	call(strand_wait)
    307	sub b32 $r12 $r0 1
    308	nv_iowr(NV_PGRAPH_FECS_STRAND_DATA, 0x3f, $r12)
    309	mov $r12 NV_PGRAPH_FECS_STRAND_CMD_GET_INFO
    310	nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
    311	call(strand_wait)
    312	call(strand_post)
    313
    314	// read the size of each strand, poke the context offset of
    315	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
    316	// about it later then.
    317	nv_mkio($r8, NV_PGRAPH_FECS_STRAND_SAVE_SWBASE, 0x00)
    318	nv_iord($r9, NV_PGRAPH_FECS_STRANDS_CNT, 0x00)
    319	shr b32 $r14 $r15 8
    320	ctx_init_strand_loop:
    321		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
    322		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
    323		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
    324		shr b32 $r10 6
    325		add b32 $r10 1
    326		add b32 $r14 $r10
    327		add b32 $r8 4
    328		sub b32 $r9 1
    329		bra ne #ctx_init_strand_loop
    330
    331	shl b32 $r14 8
    332	sub b32 $r15 $r14 $r15
    333	trace_clr(T_STRINIT)
    334	ret
    335#endif