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

memx.fuc (9182B)


      1/*
      2 * Copyright 2013 Red Hat Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: Ben Skeggs
     23 */
     24
     25#ifdef INCLUDE_PROC
     26process(PROC_MEMX, #memx_init, #memx_recv)
     27#endif
     28
     29/******************************************************************************
     30 * MEMX data segment
     31 *****************************************************************************/
     32#ifdef INCLUDE_DATA
     33.equ #memx_opcode 0
     34.equ #memx_header 2
     35.equ #memx_length 4
     36.equ #memx_func   8
     37
     38#define handler(cmd,hdr,len,func) /*
     39*/	.b16 MEMX_##cmd /*
     40*/	.b16 hdr /*
     41*/	.b16 len /*
     42*/      .b16 0 /*
     43*/	.b32 func
     44
     45memx_func_head:
     46handler(ENTER , 0x0000, 0x0000, #memx_func_enter)
     47memx_func_next:
     48handler(LEAVE , 0x0000, 0x0000, #memx_func_leave)
     49handler(WR32  , 0x0000, 0x0002, #memx_func_wr32)
     50handler(WAIT  , 0x0004, 0x0000, #memx_func_wait)
     51handler(DELAY , 0x0001, 0x0000, #memx_func_delay)
     52handler(VBLANK, 0x0001, 0x0000, #memx_func_wait_vblank)
     53handler(TRAIN , 0x0000, 0x0000, #memx_func_train)
     54memx_func_tail:
     55
     56.equ #memx_func_size #memx_func_next - #memx_func_head
     57.equ #memx_func_num (#memx_func_tail - #memx_func_head) / #memx_func_size
     58
     59memx_ts_start:
     60.b32 0
     61memx_ts_end:
     62.b32 0
     63
     64memx_data_head:
     65.skip 0x0800
     66memx_data_tail:
     67
     68memx_train_head:
     69.skip 0x0100
     70memx_train_tail:
     71#endif
     72
     73/******************************************************************************
     74 * MEMX code segment
     75 *****************************************************************************/
     76#ifdef INCLUDE_CODE
     77// description
     78//
     79// $r15 - current (memx)
     80// $r4  - packet length
     81// $r3  - opcode desciption
     82// $r0  - zero
     83memx_func_enter:
     84#if NVKM_PPWR_CHIPSET == GT215
     85	mov $r8 0x1610
     86	nv_rd32($r7, $r8)
     87	imm32($r6, 0xfffffffc)
     88	and $r7 $r6
     89	mov $r6 0x2
     90	or $r7 $r6
     91	nv_wr32($r8, $r7)
     92#else
     93	mov $r6 0x001620
     94	imm32($r7, ~0x00000aa2);
     95	nv_rd32($r8, $r6)
     96	and $r8 $r7
     97	nv_wr32($r6, $r8)
     98
     99	imm32($r7, ~0x00000001)
    100	nv_rd32($r8, $r6)
    101	and $r8 $r7
    102	nv_wr32($r6, $r8)
    103
    104	mov $r6 0x0026f0
    105	nv_rd32($r8, $r6)
    106	and $r8 $r7
    107	nv_wr32($r6, $r8)
    108#endif
    109
    110	mov $r6 NV_PPWR_OUTPUT_SET_FB_PAUSE
    111	nv_iowr(NV_PPWR_OUTPUT_SET, $r6)
    112	memx_func_enter_wait:
    113		nv_iord($r6, NV_PPWR_OUTPUT)
    114		and $r6 NV_PPWR_OUTPUT_FB_PAUSE
    115		bra z #memx_func_enter_wait
    116
    117	nv_iord($r6, NV_PPWR_TIMER_LOW)
    118	st b32 D[$r0 + #memx_ts_start] $r6
    119	ret
    120
    121// description
    122//
    123// $r15 - current (memx)
    124// $r4  - packet length
    125// $r3  - opcode desciption
    126// $r0  - zero
    127memx_func_leave:
    128	nv_iord($r6, NV_PPWR_TIMER_LOW)
    129	st b32 D[$r0 + #memx_ts_end] $r6
    130
    131	mov $r6 NV_PPWR_OUTPUT_CLR_FB_PAUSE
    132	nv_iowr(NV_PPWR_OUTPUT_CLR, $r6)
    133	memx_func_leave_wait:
    134		nv_iord($r6, NV_PPWR_OUTPUT)
    135		and $r6 NV_PPWR_OUTPUT_FB_PAUSE
    136		bra nz #memx_func_leave_wait
    137
    138#if NVKM_PPWR_CHIPSET == GT215
    139	mov $r8 0x1610
    140	nv_rd32($r7, $r8)
    141	imm32($r6, 0xffffffcc)
    142	and $r7 $r6
    143	nv_wr32($r8, $r7)
    144#else
    145	mov $r6 0x0026f0
    146	imm32($r7, 0x00000001)
    147	nv_rd32($r8, $r6)
    148	or $r8 $r7
    149	nv_wr32($r6, $r8)
    150
    151	mov $r6 0x001620
    152	nv_rd32($r8, $r6)
    153	or $r8 $r7
    154	nv_wr32($r6, $r8)
    155
    156	imm32($r7, 0x00000aa2);
    157	nv_rd32($r8, $r6)
    158	or $r8 $r7
    159	nv_wr32($r6, $r8)
    160#endif
    161	ret
    162
    163#if NVKM_PPWR_CHIPSET < GF119
    164// description
    165//
    166// $r15 - current (memx)
    167// $r4  - packet length
    168//	+00: head to wait for vblank on
    169// $r3  - opcode desciption
    170// $r0  - zero
    171memx_func_wait_vblank:
    172	ld b32 $r6 D[$r1 + 0x00]
    173	cmp b32 $r6 0x0
    174	bra z #memx_func_wait_vblank_head0
    175	cmp b32 $r6 0x1
    176	bra z #memx_func_wait_vblank_head1
    177	bra #memx_func_wait_vblank_fini
    178
    179	memx_func_wait_vblank_head1:
    180	mov $r7 0x20
    181	bra #memx_func_wait_vblank_0
    182
    183	memx_func_wait_vblank_head0:
    184	mov $r7 0x8
    185
    186	memx_func_wait_vblank_0:
    187		nv_iord($r6, NV_PPWR_INPUT)
    188		and $r6 $r7
    189		bra nz #memx_func_wait_vblank_0
    190
    191	memx_func_wait_vblank_1:
    192		nv_iord($r6, NV_PPWR_INPUT)
    193		and $r6 $r7
    194		bra z #memx_func_wait_vblank_1
    195
    196	memx_func_wait_vblank_fini:
    197	add b32 $r1 0x4
    198	ret
    199
    200#else
    201
    202// XXX: currently no-op
    203//
    204// $r15 - current (memx)
    205// $r4  - packet length
    206//	+00: head to wait for vblank on
    207// $r3  - opcode desciption
    208// $r0  - zero
    209memx_func_wait_vblank:
    210	add b32 $r1 0x4
    211	ret
    212
    213#endif
    214
    215// description
    216//
    217// $r15 - current (memx)
    218// $r4  - packet length
    219//	+00*n: addr
    220//	+04*n: data
    221// $r3  - opcode desciption
    222// $r0  - zero
    223memx_func_wr32:
    224	ld b32 $r6 D[$r1 + 0x00]
    225	ld b32 $r5 D[$r1 + 0x04]
    226	add b32 $r1 0x08
    227	nv_wr32($r6, $r5)
    228	sub b32 $r4 0x02
    229	bra nz #memx_func_wr32
    230	ret
    231
    232// description
    233//
    234// $r15 - current (memx)
    235// $r4  - packet length
    236//	+00: addr
    237//	+04: mask
    238//	+08: data
    239//	+0c: timeout (ns)
    240// $r3  - opcode desciption
    241// $r0  - zero
    242memx_func_wait:
    243	nv_iord($r8, NV_PPWR_TIMER_LOW)
    244	ld b32 $r14 D[$r1 + 0x00]
    245	ld b32 $r13 D[$r1 + 0x04]
    246	ld b32 $r12 D[$r1 + 0x08]
    247	ld b32 $r11 D[$r1 + 0x0c]
    248	add b32 $r1 0x10
    249	call(wait)
    250	ret
    251
    252// description
    253//
    254// $r15 - current (memx)
    255// $r4  - packet length
    256//	+00: time (ns)
    257// $r3  - opcode desciption
    258// $r0  - zero
    259memx_func_delay:
    260	ld b32 $r14 D[$r1 + 0x00]
    261	add b32 $r1 0x04
    262	call(nsec)
    263	ret
    264
    265// description
    266//
    267// $r15 - current (memx)
    268// $r4  - packet length
    269// $r3  - opcode desciption
    270// $r0  - zero
    271memx_func_train:
    272#if NVKM_PPWR_CHIPSET == GT215
    273// $r5 - outer loop counter
    274// $r6 - inner loop counter
    275// $r7 - entry counter (#memx_train_head + $r7)
    276	mov $r5 0x3
    277	mov $r7 0x0
    278
    279// Read random memory to wake up... things
    280	imm32($r9, 0x700000)
    281	nv_rd32($r8,$r9)
    282	mov $r14 0x2710
    283	call(nsec)
    284
    285	memx_func_train_loop_outer:
    286		mulu $r8 $r5 0x101
    287		sethi $r8 0x02000000
    288		imm32($r9, 0x1111e0)
    289		nv_wr32($r9, $r8)
    290		push $r5
    291
    292		mov $r6 0x0
    293		memx_func_train_loop_inner:
    294			mov $r8 0x1111
    295			mulu $r9 $r6 $r8
    296			shl b32 $r8 $r9 0x10
    297			or $r8 $r9
    298			imm32($r9, 0x100720)
    299			nv_wr32($r9, $r8)
    300
    301			imm32($r9, 0x100080)
    302			nv_rd32($r8, $r9)
    303			or $r8 $r8 0x20
    304			nv_wr32($r9, $r8)
    305
    306			imm32($r9, 0x10053c)
    307			imm32($r8, 0x80003002)
    308			nv_wr32($r9, $r8)
    309
    310			imm32($r14, 0x100560)
    311			imm32($r13, 0x80000000)
    312			add b32 $r12 $r13 0
    313			imm32($r11, 0x001e8480)
    314			call(wait)
    315
    316			// $r5 - inner inner loop counter
    317			// $r9 - result
    318			mov $r5 0
    319			imm32($r9, 0x8300ffff)
    320			memx_func_train_loop_4x:
    321				imm32($r10, 0x100080)
    322				nv_rd32($r8, $r10)
    323				imm32($r11, 0xffffffdf)
    324				and $r8 $r11
    325				nv_wr32($r10, $r8)
    326
    327				imm32($r10, 0x10053c)
    328				imm32($r8, 0x80003002)
    329				nv_wr32($r10, $r8)
    330
    331				imm32($r14, 0x100560)
    332				imm32($r13, 0x80000000)
    333				mov b32 $r12 $r13
    334				imm32($r11, 0x00002710)
    335				call(wait)
    336
    337				nv_rd32($r13, $r14)
    338				and $r9 $r9 $r13
    339
    340				add b32 $r5 1
    341				cmp b16 $r5 0x4
    342				bra l #memx_func_train_loop_4x
    343
    344			add b32 $r10 $r7 #memx_train_head
    345			st b32 D[$r10 + 0] $r9
    346			add b32 $r6 1
    347			add b32 $r7 4
    348
    349			cmp b16 $r6 0x10
    350			bra l #memx_func_train_loop_inner
    351
    352		pop $r5
    353		add b32 $r5 1
    354		cmp b16 $r5 7
    355		bra l #memx_func_train_loop_outer
    356
    357#endif
    358	ret
    359
    360// description
    361//
    362// $r15 - current (memx)
    363// $r14 - sender process name
    364// $r13 - message (exec)
    365// $r12 - head of script
    366// $r11 - tail of script
    367// $r0  - zero
    368memx_exec:
    369	push $r14
    370	push $r13
    371	mov b32 $r1 $r12
    372	mov b32 $r2 $r11
    373
    374	memx_exec_next:
    375		// fetch the packet header
    376		ld b32 $r3 D[$r1]
    377		add b32 $r1 4
    378		extr $r4 $r3 16:31
    379		extr $r3 $r3 0:15
    380
    381		// execute the opcode handler
    382		sub b32 $r3 1
    383		mulu $r3 #memx_func_size
    384		ld b32 $r5 D[$r3 + #memx_func_head + #memx_func]
    385		call $r5
    386
    387		// keep going, if we haven't reached the end
    388		cmp b32 $r1 $r2
    389		bra l #memx_exec_next
    390
    391	// send completion reply
    392	ld b32 $r11 D[$r0 + #memx_ts_start]
    393	ld b32 $r12 D[$r0 + #memx_ts_end]
    394	sub b32 $r12 $r11
    395	nv_iord($r11, NV_PPWR_INPUT)
    396	pop $r13
    397	pop $r14
    398	call(send)
    399	ret
    400
    401// description
    402//
    403// $r15 - current (memx)
    404// $r14 - sender process name
    405// $r13 - message
    406// $r12 - data0
    407// $r11 - data1
    408// $r0  - zero
    409memx_info:
    410	cmp b16 $r12 0x1
    411	bra e #memx_info_train
    412
    413	memx_info_data:
    414	mov $r12 #memx_data_head
    415	mov $r11 #memx_data_tail - #memx_data_head
    416	bra #memx_info_send
    417
    418	memx_info_train:
    419	mov $r12 #memx_train_head
    420	mov $r11 #memx_train_tail - #memx_train_head
    421
    422	memx_info_send:
    423	call(send)
    424	ret
    425
    426// description
    427//
    428// $r15 - current (memx)
    429// $r14 - sender process name
    430// $r13 - message
    431// $r12 - data0
    432// $r11 - data1
    433// $r0  - zero
    434memx_recv:
    435	cmp b32 $r13 MEMX_MSG_EXEC
    436	bra e #memx_exec
    437	cmp b32 $r13 MEMX_MSG_INFO
    438	bra e #memx_info
    439	ret
    440
    441// description
    442//
    443// $r15 - current (memx)
    444// $r0  - zero
    445memx_init:
    446	ret
    447#endif