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

ipmi_kcs_sm.c (12763B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * ipmi_kcs_sm.c
      4 *
      5 * State machine for handling IPMI KCS interfaces.
      6 *
      7 * Author: MontaVista Software, Inc.
      8 *         Corey Minyard <minyard@mvista.com>
      9 *         source@mvista.com
     10 *
     11 * Copyright 2002 MontaVista Software Inc.
     12 */
     13
     14/*
     15 * This state machine is taken from the state machine in the IPMI spec,
     16 * pretty much verbatim.  If you have questions about the states, see
     17 * that document.
     18 */
     19
     20#define DEBUG /* So dev_dbg() is always available. */
     21
     22#include <linux/kernel.h> /* For printk. */
     23#include <linux/module.h>
     24#include <linux/moduleparam.h>
     25#include <linux/string.h>
     26#include <linux/jiffies.h>
     27#include <linux/ipmi_msgdefs.h>		/* for completion codes */
     28#include "ipmi_si_sm.h"
     29
     30/* kcs_debug is a bit-field
     31 *	KCS_DEBUG_ENABLE -	turned on for now
     32 *	KCS_DEBUG_MSG    -	commands and their responses
     33 *	KCS_DEBUG_STATES -	state machine
     34 */
     35#define KCS_DEBUG_STATES	4
     36#define KCS_DEBUG_MSG		2
     37#define	KCS_DEBUG_ENABLE	1
     38
     39static int kcs_debug;
     40module_param(kcs_debug, int, 0644);
     41MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
     42
     43/* The states the KCS driver may be in. */
     44enum kcs_states {
     45	/* The KCS interface is currently doing nothing. */
     46	KCS_IDLE,
     47
     48	/*
     49	 * We are starting an operation.  The data is in the output
     50	 * buffer, but nothing has been done to the interface yet.  This
     51	 * was added to the state machine in the spec to wait for the
     52	 * initial IBF.
     53	 */
     54	KCS_START_OP,
     55
     56	/* We have written a write cmd to the interface. */
     57	KCS_WAIT_WRITE_START,
     58
     59	/* We are writing bytes to the interface. */
     60	KCS_WAIT_WRITE,
     61
     62	/*
     63	 * We have written the write end cmd to the interface, and
     64	 * still need to write the last byte.
     65	 */
     66	KCS_WAIT_WRITE_END,
     67
     68	/* We are waiting to read data from the interface. */
     69	KCS_WAIT_READ,
     70
     71	/*
     72	 * State to transition to the error handler, this was added to
     73	 * the state machine in the spec to be sure IBF was there.
     74	 */
     75	KCS_ERROR0,
     76
     77	/*
     78	 * First stage error handler, wait for the interface to
     79	 * respond.
     80	 */
     81	KCS_ERROR1,
     82
     83	/*
     84	 * The abort cmd has been written, wait for the interface to
     85	 * respond.
     86	 */
     87	KCS_ERROR2,
     88
     89	/*
     90	 * We wrote some data to the interface, wait for it to switch
     91	 * to read mode.
     92	 */
     93	KCS_ERROR3,
     94
     95	/* The hardware failed to follow the state machine. */
     96	KCS_HOSED
     97};
     98
     99#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH
    100#define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH
    101
    102/* Timeouts in microseconds. */
    103#define IBF_RETRY_TIMEOUT (5*USEC_PER_SEC)
    104#define OBF_RETRY_TIMEOUT (5*USEC_PER_SEC)
    105#define MAX_ERROR_RETRIES 10
    106#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
    107
    108struct si_sm_data {
    109	enum kcs_states  state;
    110	struct si_sm_io *io;
    111	unsigned char    write_data[MAX_KCS_WRITE_SIZE];
    112	int              write_pos;
    113	int              write_count;
    114	int              orig_write_count;
    115	unsigned char    read_data[MAX_KCS_READ_SIZE];
    116	int              read_pos;
    117	int	         truncated;
    118
    119	unsigned int  error_retries;
    120	long          ibf_timeout;
    121	long          obf_timeout;
    122	unsigned long  error0_timeout;
    123};
    124
    125static unsigned int init_kcs_data(struct si_sm_data *kcs,
    126				  struct si_sm_io *io)
    127{
    128	kcs->state = KCS_IDLE;
    129	kcs->io = io;
    130	kcs->write_pos = 0;
    131	kcs->write_count = 0;
    132	kcs->orig_write_count = 0;
    133	kcs->read_pos = 0;
    134	kcs->error_retries = 0;
    135	kcs->truncated = 0;
    136	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
    137	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
    138
    139	/* Reserve 2 I/O bytes. */
    140	return 2;
    141}
    142
    143static inline unsigned char read_status(struct si_sm_data *kcs)
    144{
    145	return kcs->io->inputb(kcs->io, 1);
    146}
    147
    148static inline unsigned char read_data(struct si_sm_data *kcs)
    149{
    150	return kcs->io->inputb(kcs->io, 0);
    151}
    152
    153static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)
    154{
    155	kcs->io->outputb(kcs->io, 1, data);
    156}
    157
    158static inline void write_data(struct si_sm_data *kcs, unsigned char data)
    159{
    160	kcs->io->outputb(kcs->io, 0, data);
    161}
    162
    163/* Control codes. */
    164#define KCS_GET_STATUS_ABORT	0x60
    165#define KCS_WRITE_START		0x61
    166#define KCS_WRITE_END		0x62
    167#define KCS_READ_BYTE		0x68
    168
    169/* Status bits. */
    170#define GET_STATUS_STATE(status) (((status) >> 6) & 0x03)
    171#define KCS_IDLE_STATE	0
    172#define KCS_READ_STATE	1
    173#define KCS_WRITE_STATE	2
    174#define KCS_ERROR_STATE	3
    175#define GET_STATUS_ATN(status) ((status) & 0x04)
    176#define GET_STATUS_IBF(status) ((status) & 0x02)
    177#define GET_STATUS_OBF(status) ((status) & 0x01)
    178
    179
    180static inline void write_next_byte(struct si_sm_data *kcs)
    181{
    182	write_data(kcs, kcs->write_data[kcs->write_pos]);
    183	(kcs->write_pos)++;
    184	(kcs->write_count)--;
    185}
    186
    187static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
    188{
    189	(kcs->error_retries)++;
    190	if (kcs->error_retries > MAX_ERROR_RETRIES) {
    191		if (kcs_debug & KCS_DEBUG_ENABLE)
    192			dev_dbg(kcs->io->dev, "ipmi_kcs_sm: kcs hosed: %s\n",
    193				reason);
    194		kcs->state = KCS_HOSED;
    195	} else {
    196		kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
    197		kcs->state = KCS_ERROR0;
    198	}
    199}
    200
    201static inline void read_next_byte(struct si_sm_data *kcs)
    202{
    203	if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
    204		/* Throw the data away and mark it truncated. */
    205		read_data(kcs);
    206		kcs->truncated = 1;
    207	} else {
    208		kcs->read_data[kcs->read_pos] = read_data(kcs);
    209		(kcs->read_pos)++;
    210	}
    211	write_data(kcs, KCS_READ_BYTE);
    212}
    213
    214static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
    215			    long time)
    216{
    217	if (GET_STATUS_IBF(status)) {
    218		kcs->ibf_timeout -= time;
    219		if (kcs->ibf_timeout < 0) {
    220			start_error_recovery(kcs, "IBF not ready in time");
    221			kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
    222			return 1;
    223		}
    224		return 0;
    225	}
    226	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
    227	return 1;
    228}
    229
    230static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
    231			    long time)
    232{
    233	if (!GET_STATUS_OBF(status)) {
    234		kcs->obf_timeout -= time;
    235		if (kcs->obf_timeout < 0) {
    236			kcs->obf_timeout = OBF_RETRY_TIMEOUT;
    237			start_error_recovery(kcs, "OBF not ready in time");
    238			return 1;
    239		}
    240		return 0;
    241	}
    242	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
    243	return 1;
    244}
    245
    246static void clear_obf(struct si_sm_data *kcs, unsigned char status)
    247{
    248	if (GET_STATUS_OBF(status))
    249		read_data(kcs);
    250}
    251
    252static void restart_kcs_transaction(struct si_sm_data *kcs)
    253{
    254	kcs->write_count = kcs->orig_write_count;
    255	kcs->write_pos = 0;
    256	kcs->read_pos = 0;
    257	kcs->state = KCS_WAIT_WRITE_START;
    258	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
    259	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
    260	write_cmd(kcs, KCS_WRITE_START);
    261}
    262
    263static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
    264				 unsigned int size)
    265{
    266	unsigned int i;
    267
    268	if (size < 2)
    269		return IPMI_REQ_LEN_INVALID_ERR;
    270	if (size > MAX_KCS_WRITE_SIZE)
    271		return IPMI_REQ_LEN_EXCEEDED_ERR;
    272
    273	if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
    274		dev_warn(kcs->io->dev, "KCS in invalid state %d\n", kcs->state);
    275		return IPMI_NOT_IN_MY_STATE_ERR;
    276	}
    277
    278	if (kcs_debug & KCS_DEBUG_MSG) {
    279		dev_dbg(kcs->io->dev, "%s -", __func__);
    280		for (i = 0; i < size; i++)
    281			pr_cont(" %02x", data[i]);
    282		pr_cont("\n");
    283	}
    284	kcs->error_retries = 0;
    285	memcpy(kcs->write_data, data, size);
    286	kcs->write_count = size;
    287	kcs->orig_write_count = size;
    288	kcs->write_pos = 0;
    289	kcs->read_pos = 0;
    290	kcs->state = KCS_START_OP;
    291	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
    292	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
    293	return 0;
    294}
    295
    296static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
    297			  unsigned int length)
    298{
    299	if (length < kcs->read_pos) {
    300		kcs->read_pos = length;
    301		kcs->truncated = 1;
    302	}
    303
    304	memcpy(data, kcs->read_data, kcs->read_pos);
    305
    306	if ((length >= 3) && (kcs->read_pos < 3)) {
    307		/* Guarantee that we return at least 3 bytes, with an
    308		   error in the third byte if it is too short. */
    309		data[2] = IPMI_ERR_UNSPECIFIED;
    310		kcs->read_pos = 3;
    311	}
    312	if (kcs->truncated) {
    313		/*
    314		 * Report a truncated error.  We might overwrite
    315		 * another error, but that's too bad, the user needs
    316		 * to know it was truncated.
    317		 */
    318		data[2] = IPMI_ERR_MSG_TRUNCATED;
    319		kcs->truncated = 0;
    320	}
    321
    322	return kcs->read_pos;
    323}
    324
    325/*
    326 * This implements the state machine defined in the IPMI manual, see
    327 * that for details on how this works.  Divide that flowchart into
    328 * sections delimited by "Wait for IBF" and this will become clear.
    329 */
    330static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
    331{
    332	unsigned char status;
    333	unsigned char state;
    334
    335	status = read_status(kcs);
    336
    337	if (kcs_debug & KCS_DEBUG_STATES)
    338		dev_dbg(kcs->io->dev,
    339			"KCS: State = %d, %x\n", kcs->state, status);
    340
    341	/* All states wait for ibf, so just do it here. */
    342	if (!check_ibf(kcs, status, time))
    343		return SI_SM_CALL_WITH_DELAY;
    344
    345	/* Just about everything looks at the KCS state, so grab that, too. */
    346	state = GET_STATUS_STATE(status);
    347
    348	switch (kcs->state) {
    349	case KCS_IDLE:
    350		/* If there's and interrupt source, turn it off. */
    351		clear_obf(kcs, status);
    352
    353		if (GET_STATUS_ATN(status))
    354			return SI_SM_ATTN;
    355		else
    356			return SI_SM_IDLE;
    357
    358	case KCS_START_OP:
    359		if (state != KCS_IDLE_STATE) {
    360			start_error_recovery(kcs,
    361					     "State machine not idle at start");
    362			break;
    363		}
    364
    365		clear_obf(kcs, status);
    366		write_cmd(kcs, KCS_WRITE_START);
    367		kcs->state = KCS_WAIT_WRITE_START;
    368		break;
    369
    370	case KCS_WAIT_WRITE_START:
    371		if (state != KCS_WRITE_STATE) {
    372			start_error_recovery(
    373				kcs,
    374				"Not in write state at write start");
    375			break;
    376		}
    377		read_data(kcs);
    378		if (kcs->write_count == 1) {
    379			write_cmd(kcs, KCS_WRITE_END);
    380			kcs->state = KCS_WAIT_WRITE_END;
    381		} else {
    382			write_next_byte(kcs);
    383			kcs->state = KCS_WAIT_WRITE;
    384		}
    385		break;
    386
    387	case KCS_WAIT_WRITE:
    388		if (state != KCS_WRITE_STATE) {
    389			start_error_recovery(kcs,
    390					     "Not in write state for write");
    391			break;
    392		}
    393		clear_obf(kcs, status);
    394		if (kcs->write_count == 1) {
    395			write_cmd(kcs, KCS_WRITE_END);
    396			kcs->state = KCS_WAIT_WRITE_END;
    397		} else {
    398			write_next_byte(kcs);
    399		}
    400		break;
    401
    402	case KCS_WAIT_WRITE_END:
    403		if (state != KCS_WRITE_STATE) {
    404			start_error_recovery(kcs,
    405					     "Not in write state"
    406					     " for write end");
    407			break;
    408		}
    409		clear_obf(kcs, status);
    410		write_next_byte(kcs);
    411		kcs->state = KCS_WAIT_READ;
    412		break;
    413
    414	case KCS_WAIT_READ:
    415		if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) {
    416			start_error_recovery(
    417				kcs,
    418				"Not in read or idle in read state");
    419			break;
    420		}
    421
    422		if (state == KCS_READ_STATE) {
    423			if (!check_obf(kcs, status, time))
    424				return SI_SM_CALL_WITH_DELAY;
    425			read_next_byte(kcs);
    426		} else {
    427			/*
    428			 * We don't implement this exactly like the state
    429			 * machine in the spec.  Some broken hardware
    430			 * does not write the final dummy byte to the
    431			 * read register.  Thus obf will never go high
    432			 * here.  We just go straight to idle, and we
    433			 * handle clearing out obf in idle state if it
    434			 * happens to come in.
    435			 */
    436			clear_obf(kcs, status);
    437			kcs->orig_write_count = 0;
    438			kcs->state = KCS_IDLE;
    439			return SI_SM_TRANSACTION_COMPLETE;
    440		}
    441		break;
    442
    443	case KCS_ERROR0:
    444		clear_obf(kcs, status);
    445		status = read_status(kcs);
    446		if (GET_STATUS_OBF(status))
    447			/* controller isn't responding */
    448			if (time_before(jiffies, kcs->error0_timeout))
    449				return SI_SM_CALL_WITH_TICK_DELAY;
    450		write_cmd(kcs, KCS_GET_STATUS_ABORT);
    451		kcs->state = KCS_ERROR1;
    452		break;
    453
    454	case KCS_ERROR1:
    455		clear_obf(kcs, status);
    456		write_data(kcs, 0);
    457		kcs->state = KCS_ERROR2;
    458		break;
    459
    460	case KCS_ERROR2:
    461		if (state != KCS_READ_STATE) {
    462			start_error_recovery(kcs,
    463					     "Not in read state for error2");
    464			break;
    465		}
    466		if (!check_obf(kcs, status, time))
    467			return SI_SM_CALL_WITH_DELAY;
    468
    469		clear_obf(kcs, status);
    470		write_data(kcs, KCS_READ_BYTE);
    471		kcs->state = KCS_ERROR3;
    472		break;
    473
    474	case KCS_ERROR3:
    475		if (state != KCS_IDLE_STATE) {
    476			start_error_recovery(kcs,
    477					     "Not in idle state for error3");
    478			break;
    479		}
    480
    481		if (!check_obf(kcs, status, time))
    482			return SI_SM_CALL_WITH_DELAY;
    483
    484		clear_obf(kcs, status);
    485		if (kcs->orig_write_count) {
    486			restart_kcs_transaction(kcs);
    487		} else {
    488			kcs->state = KCS_IDLE;
    489			return SI_SM_TRANSACTION_COMPLETE;
    490		}
    491		break;
    492
    493	case KCS_HOSED:
    494		break;
    495	}
    496
    497	if (kcs->state == KCS_HOSED) {
    498		init_kcs_data(kcs, kcs->io);
    499		return SI_SM_HOSED;
    500	}
    501
    502	return SI_SM_CALL_WITHOUT_DELAY;
    503}
    504
    505static int kcs_size(void)
    506{
    507	return sizeof(struct si_sm_data);
    508}
    509
    510static int kcs_detect(struct si_sm_data *kcs)
    511{
    512	/*
    513	 * It's impossible for the KCS status register to be all 1's,
    514	 * (assuming a properly functioning, self-initialized BMC)
    515	 * but that's what you get from reading a bogus address, so we
    516	 * test that first.
    517	 */
    518	if (read_status(kcs) == 0xff)
    519		return 1;
    520
    521	return 0;
    522}
    523
    524static void kcs_cleanup(struct si_sm_data *kcs)
    525{
    526}
    527
    528const struct si_sm_handlers kcs_smi_handlers = {
    529	.init_data         = init_kcs_data,
    530	.start_transaction = start_kcs_transaction,
    531	.get_result        = get_kcs_result,
    532	.event             = kcs_event,
    533	.detect            = kcs_detect,
    534	.cleanup           = kcs_cleanup,
    535	.size              = kcs_size,
    536};