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

w1_io.c (11841B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
      4 */
      5
      6#include <asm/io.h>
      7
      8#include <linux/delay.h>
      9#include <linux/moduleparam.h>
     10#include <linux/module.h>
     11
     12#include "w1_internal.h"
     13
     14static int w1_delay_parm = 1;
     15module_param_named(delay_coef, w1_delay_parm, int, 0);
     16
     17static int w1_disable_irqs = 0;
     18module_param_named(disable_irqs, w1_disable_irqs, int, 0);
     19
     20static u8 w1_crc8_table[] = {
     21	0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
     22	157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
     23	35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
     24	190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
     25	70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
     26	219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
     27	101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
     28	248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
     29	140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
     30	17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
     31	175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
     32	50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
     33	202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
     34	87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
     35	233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
     36	116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
     37};
     38
     39static void w1_delay(unsigned long tm)
     40{
     41	udelay(tm * w1_delay_parm);
     42}
     43
     44static void w1_write_bit(struct w1_master *dev, int bit);
     45static u8 w1_read_bit(struct w1_master *dev);
     46
     47/**
     48 * w1_touch_bit() - Generates a write-0 or write-1 cycle and samples the level.
     49 * @dev:	the master device
     50 * @bit:	0 - write a 0, 1 - write a 0 read the level
     51 */
     52u8 w1_touch_bit(struct w1_master *dev, int bit)
     53{
     54	if (dev->bus_master->touch_bit)
     55		return dev->bus_master->touch_bit(dev->bus_master->data, bit);
     56	else if (bit)
     57		return w1_read_bit(dev);
     58	else {
     59		w1_write_bit(dev, 0);
     60		return 0;
     61	}
     62}
     63EXPORT_SYMBOL_GPL(w1_touch_bit);
     64
     65/**
     66 * w1_write_bit() - Generates a write-0 or write-1 cycle.
     67 * @dev:	the master device
     68 * @bit:	bit to write
     69 *
     70 * Only call if dev->bus_master->touch_bit is NULL
     71 */
     72static void w1_write_bit(struct w1_master *dev, int bit)
     73{
     74	unsigned long flags = 0;
     75
     76	if(w1_disable_irqs) local_irq_save(flags);
     77
     78	if (bit) {
     79		dev->bus_master->write_bit(dev->bus_master->data, 0);
     80		w1_delay(6);
     81		dev->bus_master->write_bit(dev->bus_master->data, 1);
     82		w1_delay(64);
     83	} else {
     84		dev->bus_master->write_bit(dev->bus_master->data, 0);
     85		w1_delay(60);
     86		dev->bus_master->write_bit(dev->bus_master->data, 1);
     87		w1_delay(10);
     88	}
     89
     90	if(w1_disable_irqs) local_irq_restore(flags);
     91}
     92
     93/**
     94 * w1_pre_write() - pre-write operations
     95 * @dev:	the master device
     96 *
     97 * Pre-write operation, currently only supporting strong pullups.
     98 * Program the hardware for a strong pullup, if one has been requested and
     99 * the hardware supports it.
    100 */
    101static void w1_pre_write(struct w1_master *dev)
    102{
    103	if (dev->pullup_duration &&
    104		dev->enable_pullup && dev->bus_master->set_pullup) {
    105		dev->bus_master->set_pullup(dev->bus_master->data,
    106			dev->pullup_duration);
    107	}
    108}
    109
    110/**
    111 * w1_post_write() - post-write options
    112 * @dev:	the master device
    113 *
    114 * Post-write operation, currently only supporting strong pullups.
    115 * If a strong pullup was requested, clear it if the hardware supports
    116 * them, or execute the delay otherwise, in either case clear the request.
    117 */
    118static void w1_post_write(struct w1_master *dev)
    119{
    120	if (dev->pullup_duration) {
    121		if (dev->enable_pullup && dev->bus_master->set_pullup)
    122			dev->bus_master->set_pullup(dev->bus_master->data, 0);
    123		else
    124			msleep(dev->pullup_duration);
    125		dev->pullup_duration = 0;
    126	}
    127}
    128
    129/**
    130 * w1_write_8() - Writes 8 bits.
    131 * @dev:	the master device
    132 * @byte:	the byte to write
    133 */
    134void w1_write_8(struct w1_master *dev, u8 byte)
    135{
    136	int i;
    137
    138	if (dev->bus_master->write_byte) {
    139		w1_pre_write(dev);
    140		dev->bus_master->write_byte(dev->bus_master->data, byte);
    141	}
    142	else
    143		for (i = 0; i < 8; ++i) {
    144			if (i == 7)
    145				w1_pre_write(dev);
    146			w1_touch_bit(dev, (byte >> i) & 0x1);
    147		}
    148	w1_post_write(dev);
    149}
    150EXPORT_SYMBOL_GPL(w1_write_8);
    151
    152
    153/**
    154 * w1_read_bit() - Generates a write-1 cycle and samples the level.
    155 * @dev:	the master device
    156 *
    157 * Only call if dev->bus_master->touch_bit is NULL
    158 */
    159static u8 w1_read_bit(struct w1_master *dev)
    160{
    161	int result;
    162	unsigned long flags = 0;
    163
    164	/* sample timing is critical here */
    165	local_irq_save(flags);
    166	dev->bus_master->write_bit(dev->bus_master->data, 0);
    167	w1_delay(6);
    168	dev->bus_master->write_bit(dev->bus_master->data, 1);
    169	w1_delay(9);
    170
    171	result = dev->bus_master->read_bit(dev->bus_master->data);
    172	local_irq_restore(flags);
    173
    174	w1_delay(55);
    175
    176	return result & 0x1;
    177}
    178
    179/**
    180 * w1_triplet() - * Does a triplet - used for searching ROM addresses.
    181 * @dev:	the master device
    182 * @bdir:	the bit to write if both id_bit and comp_bit are 0
    183 *
    184 * Return bits:
    185 *  bit 0 = id_bit
    186 *  bit 1 = comp_bit
    187 *  bit 2 = dir_taken
    188 *
    189 * If both bits 0 & 1 are set, the search should be restarted.
    190 *
    191 * Return:        bit fields - see above
    192 */
    193u8 w1_triplet(struct w1_master *dev, int bdir)
    194{
    195	if (dev->bus_master->triplet)
    196		return dev->bus_master->triplet(dev->bus_master->data, bdir);
    197	else {
    198		u8 id_bit   = w1_touch_bit(dev, 1);
    199		u8 comp_bit = w1_touch_bit(dev, 1);
    200		u8 retval;
    201
    202		if (id_bit && comp_bit)
    203			return 0x03;  /* error */
    204
    205		if (!id_bit && !comp_bit) {
    206			/* Both bits are valid, take the direction given */
    207			retval = bdir ? 0x04 : 0;
    208		} else {
    209			/* Only one bit is valid, take that direction */
    210			bdir = id_bit;
    211			retval = id_bit ? 0x05 : 0x02;
    212		}
    213
    214		if (dev->bus_master->touch_bit)
    215			w1_touch_bit(dev, bdir);
    216		else
    217			w1_write_bit(dev, bdir);
    218		return retval;
    219	}
    220}
    221EXPORT_SYMBOL_GPL(w1_triplet);
    222
    223/**
    224 * w1_read_8() - Reads 8 bits.
    225 * @dev:	the master device
    226 *
    227 * Return:        the byte read
    228 */
    229u8 w1_read_8(struct w1_master *dev)
    230{
    231	int i;
    232	u8 res = 0;
    233
    234	if (dev->bus_master->read_byte)
    235		res = dev->bus_master->read_byte(dev->bus_master->data);
    236	else
    237		for (i = 0; i < 8; ++i)
    238			res |= (w1_touch_bit(dev,1) << i);
    239
    240	return res;
    241}
    242EXPORT_SYMBOL_GPL(w1_read_8);
    243
    244/**
    245 * w1_write_block() - Writes a series of bytes.
    246 * @dev:	the master device
    247 * @buf:	pointer to the data to write
    248 * @len:	the number of bytes to write
    249 */
    250void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
    251{
    252	int i;
    253
    254	if (dev->bus_master->write_block) {
    255		w1_pre_write(dev);
    256		dev->bus_master->write_block(dev->bus_master->data, buf, len);
    257	}
    258	else
    259		for (i = 0; i < len; ++i)
    260			w1_write_8(dev, buf[i]); /* calls w1_pre_write */
    261	w1_post_write(dev);
    262}
    263EXPORT_SYMBOL_GPL(w1_write_block);
    264
    265/**
    266 * w1_touch_block() - Touches a series of bytes.
    267 * @dev:	the master device
    268 * @buf:	pointer to the data to write
    269 * @len:	the number of bytes to write
    270 */
    271void w1_touch_block(struct w1_master *dev, u8 *buf, int len)
    272{
    273	int i, j;
    274	u8 tmp;
    275
    276	for (i = 0; i < len; ++i) {
    277		tmp = 0;
    278		for (j = 0; j < 8; ++j) {
    279			if (j == 7)
    280				w1_pre_write(dev);
    281			tmp |= w1_touch_bit(dev, (buf[i] >> j) & 0x1) << j;
    282		}
    283
    284		buf[i] = tmp;
    285	}
    286}
    287EXPORT_SYMBOL_GPL(w1_touch_block);
    288
    289/**
    290 * w1_read_block() - Reads a series of bytes.
    291 * @dev:	the master device
    292 * @buf:	pointer to the buffer to fill
    293 * @len:	the number of bytes to read
    294 * Return:	the number of bytes read
    295 */
    296u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)
    297{
    298	int i;
    299	u8 ret;
    300
    301	if (dev->bus_master->read_block)
    302		ret = dev->bus_master->read_block(dev->bus_master->data, buf, len);
    303	else {
    304		for (i = 0; i < len; ++i)
    305			buf[i] = w1_read_8(dev);
    306		ret = len;
    307	}
    308
    309	return ret;
    310}
    311EXPORT_SYMBOL_GPL(w1_read_block);
    312
    313/**
    314 * w1_reset_bus() - Issues a reset bus sequence.
    315 * @dev:	the master device
    316 * Return:	0=Device present, 1=No device present or error
    317 */
    318int w1_reset_bus(struct w1_master *dev)
    319{
    320	int result;
    321	unsigned long flags = 0;
    322
    323	if(w1_disable_irqs) local_irq_save(flags);
    324
    325	if (dev->bus_master->reset_bus)
    326		result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
    327	else {
    328		dev->bus_master->write_bit(dev->bus_master->data, 0);
    329		/* minimum 480, max ? us
    330		 * be nice and sleep, except 18b20 spec lists 960us maximum,
    331		 * so until we can sleep with microsecond accuracy, spin.
    332		 * Feel free to come up with some other way to give up the
    333		 * cpu for such a short amount of time AND get it back in
    334		 * the maximum amount of time.
    335		 */
    336		w1_delay(500);
    337		dev->bus_master->write_bit(dev->bus_master->data, 1);
    338		w1_delay(70);
    339
    340		result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1;
    341		/* minimum 70 (above) + 430 = 500 us
    342		 * There aren't any timing requirements between a reset and
    343		 * the following transactions.  Sleeping is safe here.
    344		 */
    345		/* w1_delay(430); min required time */
    346		msleep(1);
    347	}
    348
    349	if(w1_disable_irqs) local_irq_restore(flags);
    350
    351	return result;
    352}
    353EXPORT_SYMBOL_GPL(w1_reset_bus);
    354
    355u8 w1_calc_crc8(u8 * data, int len)
    356{
    357	u8 crc = 0;
    358
    359	while (len--)
    360		crc = w1_crc8_table[crc ^ *data++];
    361
    362	return crc;
    363}
    364EXPORT_SYMBOL_GPL(w1_calc_crc8);
    365
    366void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb)
    367{
    368	dev->attempts++;
    369	if (dev->bus_master->search)
    370		dev->bus_master->search(dev->bus_master->data, dev,
    371			search_type, cb);
    372	else
    373		w1_search(dev, search_type, cb);
    374}
    375
    376/**
    377 * w1_reset_select_slave() - reset and select a slave
    378 * @sl:		the slave to select
    379 *
    380 * Resets the bus and then selects the slave by sending either a skip rom
    381 * or a rom match.  A skip rom is issued if there is only one device
    382 * registered on the bus.
    383 * The w1 master lock must be held.
    384 *
    385 * Return:	0=success, anything else=error
    386 */
    387int w1_reset_select_slave(struct w1_slave *sl)
    388{
    389	if (w1_reset_bus(sl->master))
    390		return -1;
    391
    392	if (sl->master->slave_count == 1)
    393		w1_write_8(sl->master, W1_SKIP_ROM);
    394	else {
    395		u8 match[9] = {W1_MATCH_ROM, };
    396		u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
    397
    398		memcpy(&match[1], &rn, 8);
    399		w1_write_block(sl->master, match, 9);
    400	}
    401	return 0;
    402}
    403EXPORT_SYMBOL_GPL(w1_reset_select_slave);
    404
    405/**
    406 * w1_reset_resume_command() - resume instead of another match ROM
    407 * @dev:	the master device
    408 *
    409 * When the workflow with a slave amongst many requires several
    410 * successive commands a reset between each, this function is similar
    411 * to doing a reset then a match ROM for the last matched ROM. The
    412 * advantage being that the matched ROM step is skipped in favor of the
    413 * resume command. The slave must support the command of course.
    414 *
    415 * If the bus has only one slave, traditionnaly the match ROM is skipped
    416 * and a "SKIP ROM" is done for efficiency. On multi-slave busses, this
    417 * doesn't work of course, but the resume command is the next best thing.
    418 *
    419 * The w1 master lock must be held.
    420 */
    421int w1_reset_resume_command(struct w1_master *dev)
    422{
    423	if (w1_reset_bus(dev))
    424		return -1;
    425
    426	w1_write_8(dev, dev->slave_count > 1 ? W1_RESUME_CMD : W1_SKIP_ROM);
    427	return 0;
    428}
    429EXPORT_SYMBOL_GPL(w1_reset_resume_command);
    430
    431/**
    432 * w1_next_pullup() - register for a strong pullup
    433 * @dev:	the master device
    434 * @delay:	time in milliseconds
    435 *
    436 * Put out a strong pull-up of the specified duration after the next write
    437 * operation.  Not all hardware supports strong pullups.  Hardware that
    438 * doesn't support strong pullups will sleep for the given time after the
    439 * write operation without a strong pullup.  This is a one shot request for
    440 * the next write, specifying zero will clear a previous request.
    441 * The w1 master lock must be held.
    442 *
    443 * Return:	0=success, anything else=error
    444 */
    445void w1_next_pullup(struct w1_master *dev, int delay)
    446{
    447	dev->pullup_duration = delay;
    448}
    449EXPORT_SYMBOL_GPL(w1_next_pullup);