cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

emc141x.c (8632B)


      1/*
      2 * SMSC EMC141X temperature sensor.
      3 *
      4 * Copyright (c) 2020 Bytedance Corporation
      5 * Written by John Wang <wangzhiqiang.bj@bytedance.com>
      6 *
      7 * This program is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU General Public License as
      9 * published by the Free Software Foundation; either version 2 or
     10 * (at your option) version 3 of the License.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License along
     18 * with this program; if not, see <http://www.gnu.org/licenses/>.
     19 */
     20
     21#include "qemu/osdep.h"
     22#include "hw/i2c/i2c.h"
     23#include "migration/vmstate.h"
     24#include "qapi/error.h"
     25#include "qapi/visitor.h"
     26#include "qemu/module.h"
     27#include "qom/object.h"
     28#include "hw/sensor/emc141x_regs.h"
     29
     30#define SENSORS_COUNT_MAX    4
     31
     32struct EMC141XState {
     33    I2CSlave parent_obj;
     34    struct {
     35        uint8_t raw_temp_min;
     36        uint8_t raw_temp_current;
     37        uint8_t raw_temp_max;
     38    } sensor[SENSORS_COUNT_MAX];
     39    uint8_t len;
     40    uint8_t data;
     41    uint8_t pointer;
     42};
     43
     44struct EMC141XClass {
     45    I2CSlaveClass parent_class;
     46    uint8_t model;
     47    unsigned sensors_count;
     48};
     49
     50#define TYPE_EMC141X "emc141x"
     51OBJECT_DECLARE_TYPE(EMC141XState, EMC141XClass, EMC141X)
     52
     53static void emc141x_get_temperature(Object *obj, Visitor *v, const char *name,
     54                                    void *opaque, Error **errp)
     55{
     56    EMC141XState *s = EMC141X(obj);
     57    EMC141XClass *sc = EMC141X_GET_CLASS(s);
     58    int64_t value;
     59    unsigned tempid;
     60
     61    if (sscanf(name, "temperature%u", &tempid) != 1) {
     62        error_setg(errp, "error reading %s: %s", name, g_strerror(errno));
     63        return;
     64    }
     65
     66    if (tempid >= sc->sensors_count) {
     67        error_setg(errp, "error reading %s", name);
     68        return;
     69    }
     70
     71    value = s->sensor[tempid].raw_temp_current * 1000;
     72
     73    visit_type_int(v, name, &value, errp);
     74}
     75
     76static void emc141x_set_temperature(Object *obj, Visitor *v, const char *name,
     77                                    void *opaque, Error **errp)
     78{
     79    EMC141XState *s = EMC141X(obj);
     80    EMC141XClass *sc = EMC141X_GET_CLASS(s);
     81    int64_t temp;
     82    unsigned tempid;
     83
     84    if (!visit_type_int(v, name, &temp, errp)) {
     85        return;
     86    }
     87
     88    if (sscanf(name, "temperature%u", &tempid) != 1) {
     89        error_setg(errp, "error reading %s: %s", name, g_strerror(errno));
     90        return;
     91    }
     92
     93    if (tempid >= sc->sensors_count) {
     94        error_setg(errp, "error reading %s", name);
     95        return;
     96    }
     97
     98    s->sensor[tempid].raw_temp_current = temp / 1000;
     99}
    100
    101static void emc141x_read(EMC141XState *s)
    102{
    103    EMC141XClass *sc = EMC141X_GET_CLASS(s);
    104    switch (s->pointer) {
    105    case EMC141X_DEVICE_ID:
    106        s->data = sc->model;
    107        break;
    108    case EMC141X_MANUFACTURER_ID:
    109        s->data = MANUFACTURER_ID;
    110        break;
    111    case EMC141X_REVISION:
    112        s->data = REVISION;
    113        break;
    114    case EMC141X_TEMP_HIGH0:
    115        s->data = s->sensor[0].raw_temp_current;
    116        break;
    117    case EMC141X_TEMP_HIGH1:
    118        s->data = s->sensor[1].raw_temp_current;
    119        break;
    120    case EMC141X_TEMP_HIGH2:
    121        s->data = s->sensor[2].raw_temp_current;
    122        break;
    123    case EMC141X_TEMP_HIGH3:
    124        s->data = s->sensor[3].raw_temp_current;
    125        break;
    126    case EMC141X_TEMP_MAX_HIGH0:
    127        s->data = s->sensor[0].raw_temp_max;
    128        break;
    129    case EMC141X_TEMP_MAX_HIGH1:
    130        s->data = s->sensor[1].raw_temp_max;
    131        break;
    132    case EMC141X_TEMP_MAX_HIGH2:
    133        s->data = s->sensor[2].raw_temp_max;
    134        break;
    135    case EMC141X_TEMP_MAX_HIGH3:
    136        s->data = s->sensor[3].raw_temp_max;
    137        break;
    138    case EMC141X_TEMP_MIN_HIGH0:
    139        s->data = s->sensor[0].raw_temp_min;
    140        break;
    141    case EMC141X_TEMP_MIN_HIGH1:
    142        s->data = s->sensor[1].raw_temp_min;
    143        break;
    144    case EMC141X_TEMP_MIN_HIGH2:
    145        s->data = s->sensor[2].raw_temp_min;
    146        break;
    147    case EMC141X_TEMP_MIN_HIGH3:
    148        s->data = s->sensor[3].raw_temp_min;
    149        break;
    150    default:
    151        s->data = 0;
    152    }
    153}
    154
    155static void emc141x_write(EMC141XState *s)
    156{
    157    switch (s->pointer) {
    158    case EMC141X_TEMP_MAX_HIGH0:
    159        s->sensor[0].raw_temp_max = s->data;
    160        break;
    161    case EMC141X_TEMP_MAX_HIGH1:
    162        s->sensor[1].raw_temp_max = s->data;
    163        break;
    164    case EMC141X_TEMP_MAX_HIGH2:
    165        s->sensor[2].raw_temp_max = s->data;
    166        break;
    167    case EMC141X_TEMP_MAX_HIGH3:
    168        s->sensor[3].raw_temp_max = s->data;
    169        break;
    170    case EMC141X_TEMP_MIN_HIGH0:
    171        s->sensor[0].raw_temp_min = s->data;
    172        break;
    173    case EMC141X_TEMP_MIN_HIGH1:
    174        s->sensor[1].raw_temp_min = s->data;
    175        break;
    176    case EMC141X_TEMP_MIN_HIGH2:
    177        s->sensor[2].raw_temp_min = s->data;
    178        break;
    179    case EMC141X_TEMP_MIN_HIGH3:
    180        s->sensor[3].raw_temp_min = s->data;
    181        break;
    182    default:
    183        s->data = 0;
    184    }
    185}
    186
    187static uint8_t emc141x_rx(I2CSlave *i2c)
    188{
    189    EMC141XState *s = EMC141X(i2c);
    190
    191    if (s->len == 0) {
    192        s->len++;
    193        return s->data;
    194    } else {
    195        return 0xff;
    196    }
    197}
    198
    199static int emc141x_tx(I2CSlave *i2c, uint8_t data)
    200{
    201    EMC141XState *s = EMC141X(i2c);
    202
    203    if (s->len == 0) {
    204        /* first byte is the reg pointer */
    205        s->pointer = data;
    206        s->len++;
    207    } else if (s->len == 1) {
    208        s->data = data;
    209        emc141x_write(s);
    210    }
    211
    212    return 0;
    213}
    214
    215static int emc141x_event(I2CSlave *i2c, enum i2c_event event)
    216{
    217    EMC141XState *s = EMC141X(i2c);
    218
    219    if (event == I2C_START_RECV) {
    220        emc141x_read(s);
    221    }
    222
    223    s->len = 0;
    224    return 0;
    225}
    226
    227static const VMStateDescription vmstate_emc141x = {
    228    .name = "EMC141X",
    229    .version_id = 0,
    230    .minimum_version_id = 0,
    231    .fields = (VMStateField[]) {
    232        VMSTATE_UINT8(len, EMC141XState),
    233        VMSTATE_UINT8(data, EMC141XState),
    234        VMSTATE_UINT8(pointer, EMC141XState),
    235        VMSTATE_I2C_SLAVE(parent_obj, EMC141XState),
    236        VMSTATE_END_OF_LIST()
    237    }
    238};
    239
    240static void emc141x_reset(DeviceState *dev)
    241{
    242    EMC141XState *s = EMC141X(dev);
    243    int i;
    244
    245    for (i = 0; i < SENSORS_COUNT_MAX; i++) {
    246        s->sensor[i].raw_temp_max = 0x55;
    247    }
    248    s->pointer = 0;
    249    s->len = 0;
    250}
    251
    252static void emc141x_initfn(Object *obj)
    253{
    254    object_property_add(obj, "temperature0", "int",
    255                        emc141x_get_temperature,
    256                        emc141x_set_temperature, NULL, NULL);
    257    object_property_add(obj, "temperature1", "int",
    258                        emc141x_get_temperature,
    259                        emc141x_set_temperature, NULL, NULL);
    260    object_property_add(obj, "temperature2", "int",
    261                        emc141x_get_temperature,
    262                        emc141x_set_temperature, NULL, NULL);
    263    object_property_add(obj, "temperature3", "int",
    264                        emc141x_get_temperature,
    265                        emc141x_set_temperature, NULL, NULL);
    266}
    267
    268static void emc141x_class_init(ObjectClass *klass, void *data)
    269{
    270    DeviceClass *dc = DEVICE_CLASS(klass);
    271    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
    272
    273    dc->reset = emc141x_reset;
    274    k->event = emc141x_event;
    275    k->recv = emc141x_rx;
    276    k->send = emc141x_tx;
    277    dc->vmsd = &vmstate_emc141x;
    278}
    279
    280static void emc1413_class_init(ObjectClass *klass, void *data)
    281{
    282    EMC141XClass *ec = EMC141X_CLASS(klass);
    283
    284    emc141x_class_init(klass, data);
    285    ec->model = EMC1413_DEVICE_ID;
    286    ec->sensors_count = 3;
    287}
    288
    289static void emc1414_class_init(ObjectClass *klass, void *data)
    290{
    291    EMC141XClass *ec = EMC141X_CLASS(klass);
    292
    293    emc141x_class_init(klass, data);
    294    ec->model = EMC1414_DEVICE_ID;
    295    ec->sensors_count = 4;
    296}
    297
    298static const TypeInfo emc141x_info = {
    299    .name          = TYPE_EMC141X,
    300    .parent        = TYPE_I2C_SLAVE,
    301    .instance_size = sizeof(EMC141XState),
    302    .class_size    = sizeof(EMC141XClass),
    303    .instance_init = emc141x_initfn,
    304    .abstract      = true,
    305};
    306
    307static const TypeInfo emc1413_info = {
    308    .name          = "emc1413",
    309    .parent        = TYPE_EMC141X,
    310    .class_init    = emc1413_class_init,
    311};
    312
    313static const TypeInfo emc1414_info = {
    314    .name          = "emc1414",
    315    .parent        = TYPE_EMC141X,
    316    .class_init    = emc1414_class_init,
    317};
    318
    319static void emc141x_register_types(void)
    320{
    321    type_register_static(&emc141x_info);
    322    type_register_static(&emc1413_info);
    323    type_register_static(&emc1414_info);
    324}
    325
    326type_init(emc141x_register_types)