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

ec_kb3310b.c (2821B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
      4 *
      5 *  Copyright (C) 2008 Lemote Inc.
      6 *  Author: liujl <liujl@lemote.com>, 2008-04-20
      7 */
      8
      9#include <linux/io.h>
     10#include <linux/export.h>
     11#include <linux/spinlock.h>
     12#include <linux/delay.h>
     13
     14#include "ec_kb3310b.h"
     15
     16static DEFINE_SPINLOCK(index_access_lock);
     17static DEFINE_SPINLOCK(port_access_lock);
     18
     19unsigned char ec_read(unsigned short addr)
     20{
     21	unsigned char value;
     22	unsigned long flags;
     23
     24	spin_lock_irqsave(&index_access_lock, flags);
     25	outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
     26	outb((addr & 0x00ff), EC_IO_PORT_LOW);
     27	value = inb(EC_IO_PORT_DATA);
     28	spin_unlock_irqrestore(&index_access_lock, flags);
     29
     30	return value;
     31}
     32EXPORT_SYMBOL_GPL(ec_read);
     33
     34void ec_write(unsigned short addr, unsigned char val)
     35{
     36	unsigned long flags;
     37
     38	spin_lock_irqsave(&index_access_lock, flags);
     39	outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
     40	outb((addr & 0x00ff), EC_IO_PORT_LOW);
     41	outb(val, EC_IO_PORT_DATA);
     42	/*  flush the write action */
     43	inb(EC_IO_PORT_DATA);
     44	spin_unlock_irqrestore(&index_access_lock, flags);
     45}
     46EXPORT_SYMBOL_GPL(ec_write);
     47
     48/*
     49 * This function is used for EC command writes and corresponding status queries.
     50 */
     51int ec_query_seq(unsigned char cmd)
     52{
     53	int timeout;
     54	unsigned char status;
     55	unsigned long flags;
     56	int ret = 0;
     57
     58	spin_lock_irqsave(&port_access_lock, flags);
     59
     60	/* make chip goto reset mode */
     61	udelay(EC_REG_DELAY);
     62	outb(cmd, EC_CMD_PORT);
     63	udelay(EC_REG_DELAY);
     64
     65	/* check if the command is received by ec */
     66	timeout = EC_CMD_TIMEOUT;
     67	status = inb(EC_STS_PORT);
     68	while (timeout-- && (status & (1 << 1))) {
     69		status = inb(EC_STS_PORT);
     70		udelay(EC_REG_DELAY);
     71	}
     72
     73	spin_unlock_irqrestore(&port_access_lock, flags);
     74
     75	if (timeout <= 0) {
     76		printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
     77		ret = -EINVAL;
     78	} else
     79		printk(KERN_INFO
     80			   "(%x/%d)ec issued command %d status : 0x%x\n",
     81			   timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
     82
     83	return ret;
     84}
     85EXPORT_SYMBOL_GPL(ec_query_seq);
     86
     87/*
     88 * Send query command to EC to get the proper event number
     89 */
     90int ec_query_event_num(void)
     91{
     92	return ec_query_seq(CMD_GET_EVENT_NUM);
     93}
     94EXPORT_SYMBOL(ec_query_event_num);
     95
     96/*
     97 * Get event number from EC
     98 *
     99 * NOTE: This routine must follow the query_event_num function in the
    100 * interrupt.
    101 */
    102int ec_get_event_num(void)
    103{
    104	int timeout = 100;
    105	unsigned char value;
    106	unsigned char status;
    107
    108	udelay(EC_REG_DELAY);
    109	status = inb(EC_STS_PORT);
    110	udelay(EC_REG_DELAY);
    111	while (timeout-- && !(status & (1 << 0))) {
    112		status = inb(EC_STS_PORT);
    113		udelay(EC_REG_DELAY);
    114	}
    115	if (timeout <= 0) {
    116		pr_info("%s: get event number timeout.\n", __func__);
    117
    118		return -EINVAL;
    119	}
    120	value = inb(EC_DAT_PORT);
    121	udelay(EC_REG_DELAY);
    122
    123	return value;
    124}
    125EXPORT_SYMBOL(ec_get_event_num);