qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pci_ipmi_bt.c (4373B)


      1 /*
      2  * QEMU PCI IPMI BT emulation
      3  *
      4  * Copyright (c) 2017 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 #include "qemu/osdep.h"
     25 #include "migration/vmstate.h"
     26 #include "qapi/error.h"
     27 #include "hw/ipmi/ipmi_bt.h"
     28 #include "hw/pci/pci.h"
     29 #include "qom/object.h"
     30 
     31 #define TYPE_PCI_IPMI_BT "pci-ipmi-bt"
     32 OBJECT_DECLARE_SIMPLE_TYPE(PCIIPMIBTDevice, PCI_IPMI_BT)
     33 
     34 struct PCIIPMIBTDevice {
     35     PCIDevice dev;
     36     IPMIBT bt;
     37     bool irq_enabled;
     38     uint32_t uuid;
     39 };
     40 
     41 static void pci_ipmi_raise_irq(IPMIBT *ik)
     42 {
     43     PCIIPMIBTDevice *pik = ik->opaque;
     44 
     45     pci_set_irq(&pik->dev, true);
     46 }
     47 
     48 static void pci_ipmi_lower_irq(IPMIBT *ik)
     49 {
     50     PCIIPMIBTDevice *pik = ik->opaque;
     51 
     52     pci_set_irq(&pik->dev, false);
     53 }
     54 
     55 static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp)
     56 {
     57     Error *err = NULL;
     58     PCIIPMIBTDevice *pik = PCI_IPMI_BT(pd);
     59     IPMIInterface *ii = IPMI_INTERFACE(pd);
     60     IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
     61 
     62     if (!pik->bt.bmc) {
     63         error_setg(errp, "IPMI device requires a bmc attribute to be set");
     64         return;
     65     }
     66 
     67     pik->uuid = ipmi_next_uuid();
     68 
     69     pik->bt.bmc->intf = ii;
     70     pik->bt.opaque = pik;
     71 
     72     pci_config_set_prog_interface(pd->config, 0x02); /* BT */
     73     pci_config_set_interrupt_pin(pd->config, 0x01);
     74     pik->bt.use_irq = 1;
     75     pik->bt.raise_irq = pci_ipmi_raise_irq;
     76     pik->bt.lower_irq = pci_ipmi_lower_irq;
     77 
     78     iic->init(ii, 8, &err);
     79     if (err) {
     80         error_propagate(errp, err);
     81         return;
     82     }
     83     pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pik->bt.io);
     84 }
     85 
     86 const VMStateDescription vmstate_PCIIPMIBTDevice = {
     87     .name = TYPE_IPMI_INTERFACE_PREFIX "pci-bt",
     88     .version_id = 1,
     89     .minimum_version_id = 1,
     90     .fields      = (VMStateField[]) {
     91         VMSTATE_PCI_DEVICE(dev, PCIIPMIBTDevice),
     92         VMSTATE_STRUCT(bt, PCIIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT),
     93         VMSTATE_END_OF_LIST()
     94     }
     95 };
     96 
     97 static void pci_ipmi_bt_instance_init(Object *obj)
     98 {
     99     PCIIPMIBTDevice *pik = PCI_IPMI_BT(obj);
    100 
    101     ipmi_bmc_find_and_link(obj, (Object **) &pik->bt.bmc);
    102 }
    103 
    104 static void *pci_ipmi_bt_get_backend_data(IPMIInterface *ii)
    105 {
    106     PCIIPMIBTDevice *pik = PCI_IPMI_BT(ii);
    107 
    108     return &pik->bt;
    109 }
    110 
    111 static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data)
    112 {
    113     DeviceClass *dc = DEVICE_CLASS(oc);
    114     PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
    115     IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc);
    116 
    117     pdc->vendor_id = PCI_VENDOR_ID_QEMU;
    118     pdc->device_id = PCI_DEVICE_ID_QEMU_IPMI;
    119     pdc->revision = 1;
    120     pdc->class_id = PCI_CLASS_SERIAL_IPMI;
    121 
    122     dc->vmsd = &vmstate_PCIIPMIBTDevice;
    123     dc->desc = "PCI IPMI BT";
    124     pdc->realize = pci_ipmi_bt_realize;
    125 
    126     iic->get_backend_data = pci_ipmi_bt_get_backend_data;
    127     ipmi_bt_class_init(iic);
    128 }
    129 
    130 static const TypeInfo pci_ipmi_bt_info = {
    131     .name          = TYPE_PCI_IPMI_BT,
    132     .parent        = TYPE_PCI_DEVICE,
    133     .instance_size = sizeof(PCIIPMIBTDevice),
    134     .instance_init = pci_ipmi_bt_instance_init,
    135     .class_init    = pci_ipmi_bt_class_init,
    136     .interfaces = (InterfaceInfo[]) {
    137         { TYPE_IPMI_INTERFACE },
    138         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
    139         { }
    140     }
    141 };
    142 
    143 static void pci_ipmi_bt_register_types(void)
    144 {
    145     type_register_static(&pci_ipmi_bt_info);
    146 }
    147 
    148 type_init(pci_ipmi_bt_register_types)