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

properties.c (3081B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2019 Google LLC
      4 */
      5
      6#include <linux/errno.h>
      7#include <linux/export.h>
      8#include <linux/platform_data/wilco-ec.h>
      9#include <linux/string.h>
     10#include <linux/types.h>
     11#include <asm/unaligned.h>
     12
     13/* Operation code; what the EC should do with the property */
     14enum ec_property_op {
     15	EC_OP_GET = 0,
     16	EC_OP_SET = 1,
     17};
     18
     19struct ec_property_request {
     20	u8 op; /* One of enum ec_property_op */
     21	u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
     22	u8 length;
     23	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
     24} __packed;
     25
     26struct ec_property_response {
     27	u8 reserved[2];
     28	u8 op; /* One of enum ec_property_op */
     29	u8 property_id[4]; /* The 32 bit PID is stored Little Endian */
     30	u8 length;
     31	u8 data[WILCO_EC_PROPERTY_MAX_SIZE];
     32} __packed;
     33
     34static int send_property_msg(struct wilco_ec_device *ec,
     35			     struct ec_property_request *rq,
     36			     struct ec_property_response *rs)
     37{
     38	struct wilco_ec_message ec_msg;
     39	int ret;
     40
     41	memset(&ec_msg, 0, sizeof(ec_msg));
     42	ec_msg.type = WILCO_EC_MSG_PROPERTY;
     43	ec_msg.request_data = rq;
     44	ec_msg.request_size = sizeof(*rq);
     45	ec_msg.response_data = rs;
     46	ec_msg.response_size = sizeof(*rs);
     47
     48	ret = wilco_ec_mailbox(ec, &ec_msg);
     49	if (ret < 0)
     50		return ret;
     51	if (rs->op != rq->op)
     52		return -EBADMSG;
     53	if (memcmp(rq->property_id, rs->property_id, sizeof(rs->property_id)))
     54		return -EBADMSG;
     55
     56	return 0;
     57}
     58
     59int wilco_ec_get_property(struct wilco_ec_device *ec,
     60			  struct wilco_ec_property_msg *prop_msg)
     61{
     62	struct ec_property_request rq;
     63	struct ec_property_response rs;
     64	int ret;
     65
     66	memset(&rq, 0, sizeof(rq));
     67	rq.op = EC_OP_GET;
     68	put_unaligned_le32(prop_msg->property_id, rq.property_id);
     69
     70	ret = send_property_msg(ec, &rq, &rs);
     71	if (ret < 0)
     72		return ret;
     73
     74	prop_msg->length = rs.length;
     75	memcpy(prop_msg->data, rs.data, rs.length);
     76
     77	return 0;
     78}
     79EXPORT_SYMBOL_GPL(wilco_ec_get_property);
     80
     81int wilco_ec_set_property(struct wilco_ec_device *ec,
     82			  struct wilco_ec_property_msg *prop_msg)
     83{
     84	struct ec_property_request rq;
     85	struct ec_property_response rs;
     86	int ret;
     87
     88	memset(&rq, 0, sizeof(rq));
     89	rq.op = EC_OP_SET;
     90	put_unaligned_le32(prop_msg->property_id, rq.property_id);
     91	rq.length = prop_msg->length;
     92	memcpy(rq.data, prop_msg->data, prop_msg->length);
     93
     94	ret = send_property_msg(ec, &rq, &rs);
     95	if (ret < 0)
     96		return ret;
     97	if (rs.length != prop_msg->length)
     98		return -EBADMSG;
     99
    100	return 0;
    101}
    102EXPORT_SYMBOL_GPL(wilco_ec_set_property);
    103
    104int wilco_ec_get_byte_property(struct wilco_ec_device *ec, u32 property_id,
    105			       u8 *val)
    106{
    107	struct wilco_ec_property_msg msg;
    108	int ret;
    109
    110	msg.property_id = property_id;
    111
    112	ret = wilco_ec_get_property(ec, &msg);
    113	if (ret < 0)
    114		return ret;
    115	if (msg.length != 1)
    116		return -EBADMSG;
    117
    118	*val = msg.data[0];
    119
    120	return 0;
    121}
    122EXPORT_SYMBOL_GPL(wilco_ec_get_byte_property);
    123
    124int wilco_ec_set_byte_property(struct wilco_ec_device *ec, u32 property_id,
    125			       u8 val)
    126{
    127	struct wilco_ec_property_msg msg;
    128
    129	msg.property_id = property_id;
    130	msg.data[0] = val;
    131	msg.length = 1;
    132
    133	return wilco_ec_set_property(ec, &msg);
    134}
    135EXPORT_SYMBOL_GPL(wilco_ec_set_byte_property);