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

i2c_.fuc (8147B)


      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#define T_TIMEOUT  2200000
     26#define T_RISEFALL 1000
     27#define T_HOLD     5000
     28
     29#ifdef INCLUDE_PROC
     30process(PROC_I2C_, #i2c_init, #i2c_recv)
     31#endif
     32
     33/******************************************************************************
     34 * I2C_ data segment
     35 *****************************************************************************/
     36#ifdef INCLUDE_DATA
     37i2c_scl_map:
     38.b32 NV_PPWR_OUTPUT_I2C_0_SCL
     39.b32 NV_PPWR_OUTPUT_I2C_1_SCL
     40.b32 NV_PPWR_OUTPUT_I2C_2_SCL
     41.b32 NV_PPWR_OUTPUT_I2C_3_SCL
     42.b32 NV_PPWR_OUTPUT_I2C_4_SCL
     43.b32 NV_PPWR_OUTPUT_I2C_5_SCL
     44.b32 NV_PPWR_OUTPUT_I2C_6_SCL
     45.b32 NV_PPWR_OUTPUT_I2C_7_SCL
     46.b32 NV_PPWR_OUTPUT_I2C_8_SCL
     47.b32 NV_PPWR_OUTPUT_I2C_9_SCL
     48i2c_sda_map:
     49.b32 NV_PPWR_OUTPUT_I2C_0_SDA
     50.b32 NV_PPWR_OUTPUT_I2C_1_SDA
     51.b32 NV_PPWR_OUTPUT_I2C_2_SDA
     52.b32 NV_PPWR_OUTPUT_I2C_3_SDA
     53.b32 NV_PPWR_OUTPUT_I2C_4_SDA
     54.b32 NV_PPWR_OUTPUT_I2C_5_SDA
     55.b32 NV_PPWR_OUTPUT_I2C_6_SDA
     56.b32 NV_PPWR_OUTPUT_I2C_7_SDA
     57.b32 NV_PPWR_OUTPUT_I2C_8_SDA
     58.b32 NV_PPWR_OUTPUT_I2C_9_SDA
     59#if NVKM_PPWR_CHIPSET < GF119
     60i2c_ctrl:
     61.b32 0x00e138
     62.b32 0x00e150
     63.b32 0x00e168
     64.b32 0x00e180
     65.b32 0x00e254
     66.b32 0x00e274
     67.b32 0x00e764
     68.b32 0x00e780
     69.b32 0x00e79c
     70.b32 0x00e7b8
     71#endif
     72#endif
     73
     74/******************************************************************************
     75 * I2C_ code segment
     76 *****************************************************************************/
     77#ifdef INCLUDE_CODE
     78
     79// $r3  - value
     80// $r2  - sda line
     81// $r1  - scl line
     82// $r0  - zero
     83i2c_drive_scl:
     84	cmp b32 $r3 0
     85	bra e #i2c_drive_scl_lo
     86	nv_iowr(NV_PPWR_OUTPUT_SET, $r1)
     87	ret
     88	i2c_drive_scl_lo:
     89	nv_iowr(NV_PPWR_OUTPUT_CLR, $r1)
     90	ret
     91
     92i2c_drive_sda:
     93	cmp b32 $r3 0
     94	bra e #i2c_drive_sda_lo
     95	nv_iowr(NV_PPWR_OUTPUT_SET, $r2)
     96	ret
     97	i2c_drive_sda_lo:
     98	nv_iowr(NV_PPWR_OUTPUT_CLR, $r2)
     99	ret
    100
    101i2c_sense_scl:
    102	bclr $flags $p1
    103	nv_iord($r3, NV_PPWR_INPUT)
    104	and $r3 $r1
    105	bra z #i2c_sense_scl_done
    106		bset $flags $p1
    107	i2c_sense_scl_done:
    108	ret
    109
    110i2c_sense_sda:
    111	bclr $flags $p1
    112	nv_iord($r3, NV_PPWR_INPUT)
    113	and $r3 $r2
    114	bra z #i2c_sense_sda_done
    115		bset $flags $p1
    116	i2c_sense_sda_done:
    117	ret
    118
    119#define i2c_drive_scl(v) /*
    120*/	mov $r3 (v) /*
    121*/	call(i2c_drive_scl)
    122#define i2c_drive_sda(v) /*
    123*/	mov $r3 (v) /*
    124*/	call(i2c_drive_sda)
    125#define i2c_sense_scl() /*
    126*/	call(i2c_sense_scl)
    127#define i2c_sense_sda() /*
    128*/	call(i2c_sense_sda)
    129#define i2c_delay(v) /*
    130*/	mov $r14 (v) /*
    131*/	call(nsec)
    132
    133#define i2c_trace_init() /*
    134*/	imm32($r6, 0x10000000) /*
    135*/	sub b32 $r7 $r6 1 /*
    136*/
    137#define i2c_trace_down() /*
    138*/	shr b32 $r6 4 /*
    139*/	push $r5 /*
    140*/	shl b32 $r5 $r6 4 /*
    141*/	sub b32 $r5 $r6 /*
    142*/	not b32 $r5 /*
    143*/	and $r7 $r5 /*
    144*/	pop $r5 /*
    145*/
    146#define i2c_trace_exit() /*
    147*/	shl b32 $r6 4 /*
    148*/
    149#define i2c_trace_next() /*
    150*/	add b32 $r7 $r6 /*
    151*/
    152#define i2c_trace_call(func) /*
    153*/	i2c_trace_next() /*
    154*/	i2c_trace_down() /*
    155*/	call(func) /*
    156*/	i2c_trace_exit() /*
    157*/
    158
    159i2c_raise_scl:
    160	push $r4
    161	mov $r4 (T_TIMEOUT / T_RISEFALL)
    162	i2c_drive_scl(1)
    163	i2c_raise_scl_wait:
    164		i2c_delay(T_RISEFALL)
    165		i2c_sense_scl()
    166		bra $p1 #i2c_raise_scl_done
    167		sub b32 $r4 1
    168		bra nz #i2c_raise_scl_wait
    169	i2c_raise_scl_done:
    170	pop $r4
    171	ret
    172
    173i2c_start:
    174	i2c_sense_scl()
    175	bra not $p1 #i2c_start_rep
    176	i2c_sense_sda()
    177	bra not $p1 #i2c_start_rep
    178	bra #i2c_start_send
    179	i2c_start_rep:
    180		i2c_drive_scl(0)
    181		i2c_drive_sda(1)
    182		i2c_trace_call(i2c_raise_scl)
    183		bra not $p1 #i2c_start_out
    184	i2c_start_send:
    185	i2c_drive_sda(0)
    186	i2c_delay(T_HOLD)
    187	i2c_drive_scl(0)
    188	i2c_delay(T_HOLD)
    189	i2c_start_out:
    190	ret
    191
    192i2c_stop:
    193	i2c_drive_scl(0)
    194	i2c_drive_sda(0)
    195	i2c_delay(T_RISEFALL)
    196	i2c_drive_scl(1)
    197	i2c_delay(T_HOLD)
    198	i2c_drive_sda(1)
    199	i2c_delay(T_HOLD)
    200	ret
    201
    202// $r3  - value
    203// $r2  - sda line
    204// $r1  - scl line
    205// $r0  - zero
    206i2c_bitw:
    207	call(i2c_drive_sda)
    208	i2c_delay(T_RISEFALL)
    209	i2c_trace_call(i2c_raise_scl)
    210	bra not $p1 #i2c_bitw_out
    211	i2c_delay(T_HOLD)
    212	i2c_drive_scl(0)
    213	i2c_delay(T_HOLD)
    214	i2c_bitw_out:
    215	ret
    216
    217// $r3  - value (out)
    218// $r2  - sda line
    219// $r1  - scl line
    220// $r0  - zero
    221i2c_bitr:
    222	i2c_drive_sda(1)
    223	i2c_delay(T_RISEFALL)
    224	i2c_trace_call(i2c_raise_scl)
    225	bra not $p1 #i2c_bitr_done
    226	i2c_sense_sda()
    227	i2c_drive_scl(0)
    228	i2c_delay(T_HOLD)
    229	xbit $r3 $flags $p1
    230	bset $flags $p1
    231	i2c_bitr_done:
    232	ret
    233
    234i2c_get_byte:
    235	mov $r5 0
    236	mov $r4 8
    237	i2c_get_byte_next:
    238		shl b32 $r5 1
    239		i2c_trace_call(i2c_bitr)
    240		bra not $p1 #i2c_get_byte_done
    241		or $r5 $r3
    242		sub b32 $r4 1
    243		bra nz #i2c_get_byte_next
    244	mov $r3 1
    245	i2c_trace_call(i2c_bitw)
    246	i2c_get_byte_done:
    247	ret
    248
    249i2c_put_byte:
    250	mov $r4 8
    251	i2c_put_byte_next:
    252		sub b32 $r4 1
    253		xbit $r3 $r5 $r4
    254		i2c_trace_call(i2c_bitw)
    255		bra not $p1 #i2c_put_byte_done
    256		cmp b32 $r4 0
    257		bra ne #i2c_put_byte_next
    258	i2c_trace_call(i2c_bitr)
    259	bra not $p1 #i2c_put_byte_done
    260	i2c_trace_next()
    261	cmp b32 $r3 1
    262	bra ne #i2c_put_byte_done
    263	bclr $flags $p1	// nack
    264	i2c_put_byte_done:
    265	ret
    266
    267i2c_addr:
    268	i2c_trace_call(i2c_start)
    269	bra not $p1 #i2c_addr_done
    270	extr $r3 $r12 I2C__MSG_DATA0_ADDR
    271	shl b32 $r3 1
    272	or $r5 $r3
    273	i2c_trace_call(i2c_put_byte)
    274	i2c_addr_done:
    275	ret
    276
    277i2c_acquire_addr:
    278	extr $r14 $r12 I2C__MSG_DATA0_PORT
    279#if NVKM_PPWR_CHIPSET < GF119
    280	shl b32 $r14 2
    281	add b32 $r14 #i2c_ctrl
    282	ld b32 $r14 D[$r14]
    283#else
    284	shl b32 $r14 5
    285	add b32 $r14 0x00d014
    286#endif
    287	ret
    288
    289i2c_acquire:
    290	call(i2c_acquire_addr)
    291	call(rd32)
    292	bset $r13 3
    293	call(wr32)
    294	ret
    295
    296i2c_release:
    297	call(i2c_acquire_addr)
    298	call(rd32)
    299	bclr $r13 3
    300	call(wr32)
    301	ret
    302
    303// description
    304//
    305// $r15 - current (i2c)
    306// $r14 - sender process name
    307// $r13 - message
    308// $r12 - data0
    309// $r11 - data1
    310// $r0  - zero
    311i2c_recv:
    312	bclr $flags $p1
    313	extr $r1 $r12 I2C__MSG_DATA0_PORT
    314	shl b32 $r1 2
    315	cmp b32 $r1 (#i2c_sda_map - #i2c_scl_map)
    316	bra ge #i2c_recv_done
    317	add b32 $r3 $r1 #i2c_sda_map
    318	ld b32 $r2 D[$r3]
    319	add b32 $r3 $r1 #i2c_scl_map
    320	ld b32 $r1 D[$r3]
    321
    322	bset $flags $p2
    323	push $r13
    324	push $r14
    325
    326	push $r13
    327	i2c_trace_init()
    328	i2c_trace_call(i2c_acquire)
    329	pop $r13
    330
    331	cmp b32 $r13 I2C__MSG_RD08
    332	bra ne #i2c_recv_not_rd08
    333		mov $r5 0
    334		i2c_trace_call(i2c_addr)
    335		bra not $p1 #i2c_recv_done
    336		extr $r5 $r12 I2C__MSG_DATA0_RD08_REG
    337		i2c_trace_call(i2c_put_byte)
    338		bra not $p1 #i2c_recv_done
    339		mov $r5 1
    340		i2c_trace_call(i2c_addr)
    341		bra not $p1 #i2c_recv_done
    342		i2c_trace_call(i2c_get_byte)
    343		bra not $p1 #i2c_recv_done
    344		ins $r11 $r5 I2C__MSG_DATA1_RD08_VAL
    345		i2c_trace_call(i2c_stop)
    346		mov b32 $r11 $r5
    347		clear b32 $r7
    348		bra #i2c_recv_done
    349
    350	i2c_recv_not_rd08:
    351	cmp b32 $r13 I2C__MSG_WR08
    352	bra ne #i2c_recv_not_wr08
    353		mov $r5 0
    354		call(i2c_addr)
    355		bra not $p1 #i2c_recv_done
    356		extr $r5 $r12 I2C__MSG_DATA0_WR08_REG
    357		call(i2c_put_byte)
    358		bra not $p1 #i2c_recv_done
    359		mov $r5 0
    360		call(i2c_addr)
    361		bra not $p1 #i2c_recv_done
    362		extr $r5 $r11 I2C__MSG_DATA1_WR08_VAL
    363		call(i2c_put_byte)
    364		bra not $p1 #i2c_recv_done
    365		call(i2c_stop)
    366		clear b32 $r7
    367		extr $r5 $r12 I2C__MSG_DATA0_WR08_SYNC
    368		bra nz #i2c_recv_done
    369		bclr $flags $p2
    370		bra #i2c_recv_done
    371
    372	i2c_recv_not_wr08:
    373
    374	i2c_recv_done:
    375	extr $r14 $r12 I2C__MSG_DATA0_PORT
    376	call(i2c_release)
    377
    378	pop $r14
    379	pop $r13
    380	bra not $p2 #i2c_recv_exit
    381	mov b32 $r12 $r7
    382	call(send)
    383
    384	i2c_recv_exit:
    385	ret
    386
    387// description
    388//
    389// $r15 - current (i2c)
    390// $r0  - zero
    391i2c_init:
    392	ret
    393#endif