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

isa_ipmi_bt.c (5054B)


      1/*
      2 * QEMU ISA IPMI BT emulation
      3 *
      4 * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "qemu/module.h"
     27#include "qapi/error.h"
     28#include "hw/irq.h"
     29#include "hw/ipmi/ipmi_bt.h"
     30#include "hw/isa/isa.h"
     31#include "hw/qdev-properties.h"
     32#include "migration/vmstate.h"
     33#include "qom/object.h"
     34
     35#define TYPE_ISA_IPMI_BT "isa-ipmi-bt"
     36OBJECT_DECLARE_SIMPLE_TYPE(ISAIPMIBTDevice, ISA_IPMI_BT)
     37
     38struct ISAIPMIBTDevice {
     39    ISADevice dev;
     40    int32_t isairq;
     41    qemu_irq irq;
     42    IPMIBT bt;
     43    uint32_t uuid;
     44};
     45
     46static void isa_ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
     47{
     48    ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
     49
     50    ipmi_bt_get_fwinfo(&iib->bt, info);
     51    info->interrupt_number = iib->isairq;
     52    info->i2c_slave_address = iib->bt.bmc->slave_addr;
     53    info->uuid = iib->uuid;
     54}
     55
     56static void isa_ipmi_bt_raise_irq(IPMIBT *ib)
     57{
     58    ISAIPMIBTDevice *iib = ib->opaque;
     59
     60    qemu_irq_raise(iib->irq);
     61}
     62
     63static void isa_ipmi_bt_lower_irq(IPMIBT *ib)
     64{
     65    ISAIPMIBTDevice *iib = ib->opaque;
     66
     67    qemu_irq_lower(iib->irq);
     68}
     69
     70static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
     71{
     72    Error *err = NULL;
     73    ISADevice *isadev = ISA_DEVICE(dev);
     74    ISAIPMIBTDevice *iib = ISA_IPMI_BT(dev);
     75    IPMIInterface *ii = IPMI_INTERFACE(dev);
     76    IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
     77
     78    if (!iib->bt.bmc) {
     79        error_setg(errp, "IPMI device requires a bmc attribute to be set");
     80        return;
     81    }
     82
     83    iib->uuid = ipmi_next_uuid();
     84
     85    iib->bt.bmc->intf = ii;
     86    iib->bt.opaque = iib;
     87
     88    iic->init(ii, 0, &err);
     89    if (err) {
     90        error_propagate(errp, err);
     91        return;
     92    }
     93
     94    if (iib->isairq > 0) {
     95        isa_init_irq(isadev, &iib->irq, iib->isairq);
     96        iib->bt.use_irq = 1;
     97        iib->bt.raise_irq = isa_ipmi_bt_raise_irq;
     98        iib->bt.lower_irq = isa_ipmi_bt_lower_irq;
     99    }
    100
    101    qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);
    102
    103    isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
    104}
    105
    106static const VMStateDescription vmstate_ISAIPMIBTDevice = {
    107    .name = TYPE_IPMI_INTERFACE_PREFIX "isa-bt",
    108    .version_id = 2,
    109    .minimum_version_id = 2,
    110    /*
    111     * Version 1 had messed up the array transfer, it's not even usable
    112     * because it used VMSTATE_VBUFFER_UINT32, but it did not transfer
    113     * the buffer length, so random things would happen.
    114     */
    115    .fields      = (VMStateField[]) {
    116        VMSTATE_STRUCT(bt, ISAIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT),
    117        VMSTATE_END_OF_LIST()
    118    }
    119};
    120
    121static void isa_ipmi_bt_init(Object *obj)
    122{
    123    ISAIPMIBTDevice *iib = ISA_IPMI_BT(obj);
    124
    125    ipmi_bmc_find_and_link(obj, (Object **) &iib->bt.bmc);
    126
    127    vmstate_register(NULL, 0, &vmstate_ISAIPMIBTDevice, iib);
    128}
    129
    130static void *isa_ipmi_bt_get_backend_data(IPMIInterface *ii)
    131{
    132    ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
    133
    134    return &iib->bt;
    135}
    136
    137static Property ipmi_isa_properties[] = {
    138    DEFINE_PROP_UINT32("ioport", ISAIPMIBTDevice, bt.io_base,  0xe4),
    139    DEFINE_PROP_INT32("irq",   ISAIPMIBTDevice, isairq,  5),
    140    DEFINE_PROP_END_OF_LIST(),
    141};
    142
    143static void isa_ipmi_bt_class_init(ObjectClass *oc, void *data)
    144{
    145    DeviceClass *dc = DEVICE_CLASS(oc);
    146    IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc);
    147
    148    dc->realize = isa_ipmi_bt_realize;
    149    device_class_set_props(dc, ipmi_isa_properties);
    150
    151    iic->get_backend_data = isa_ipmi_bt_get_backend_data;
    152    ipmi_bt_class_init(iic);
    153    iic->get_fwinfo = isa_ipmi_bt_get_fwinfo;
    154}
    155
    156static const TypeInfo isa_ipmi_bt_info = {
    157    .name          = TYPE_ISA_IPMI_BT,
    158    .parent        = TYPE_ISA_DEVICE,
    159    .instance_size = sizeof(ISAIPMIBTDevice),
    160    .instance_init = isa_ipmi_bt_init,
    161    .class_init    = isa_ipmi_bt_class_init,
    162    .interfaces = (InterfaceInfo[]) {
    163        { TYPE_IPMI_INTERFACE },
    164        { }
    165    }
    166};
    167
    168static void ipmi_register_types(void)
    169{
    170    type_register_static(&isa_ipmi_bt_info);
    171}
    172
    173type_init(ipmi_register_types)