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-bus.c (8176B)


      1/*
      2 * isa bus support for qdev.
      3 *
      4 * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 */
     19
     20#include "qemu/osdep.h"
     21#include "qemu/error-report.h"
     22#include "qemu/module.h"
     23#include "qapi/error.h"
     24#include "monitor/monitor.h"
     25#include "hw/sysbus.h"
     26#include "sysemu/sysemu.h"
     27#include "hw/isa/isa.h"
     28
     29static ISABus *isabus;
     30
     31static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
     32static char *isabus_get_fw_dev_path(DeviceState *dev);
     33
     34static void isa_bus_class_init(ObjectClass *klass, void *data)
     35{
     36    BusClass *k = BUS_CLASS(klass);
     37
     38    k->print_dev = isabus_dev_print;
     39    k->get_fw_dev_path = isabus_get_fw_dev_path;
     40}
     41
     42static const TypeInfo isa_dma_info = {
     43    .name = TYPE_ISADMA,
     44    .parent = TYPE_INTERFACE,
     45    .class_size = sizeof(IsaDmaClass),
     46};
     47
     48static const TypeInfo isa_bus_info = {
     49    .name = TYPE_ISA_BUS,
     50    .parent = TYPE_BUS,
     51    .instance_size = sizeof(ISABus),
     52    .class_init = isa_bus_class_init,
     53};
     54
     55ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
     56                    MemoryRegion *address_space_io, Error **errp)
     57{
     58    if (isabus) {
     59        error_setg(errp, "Can't create a second ISA bus");
     60        return NULL;
     61    }
     62    if (!dev) {
     63        dev = qdev_new("isabus-bridge");
     64        sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     65    }
     66
     67    isabus = ISA_BUS(qbus_new(TYPE_ISA_BUS, dev, NULL));
     68    isabus->address_space = address_space;
     69    isabus->address_space_io = address_space_io;
     70    return isabus;
     71}
     72
     73void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
     74{
     75    bus->irqs = irqs;
     76}
     77
     78/*
     79 * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
     80 *
     81 * This function is only for special cases such as the 'ferr', and
     82 * temporary use for normal devices until they are converted to qdev.
     83 */
     84qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
     85{
     86    assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
     87    assert(isairq < ISA_NUM_IRQS);
     88    return isabus->irqs[isairq];
     89}
     90
     91void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq)
     92{
     93    assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
     94    assert(isairq < ISA_NUM_IRQS);
     95    dev->isairq[dev->nirqs] = isairq;
     96    *p = isa_get_irq(dev, isairq);
     97    dev->nirqs++;
     98}
     99
    100void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq)
    101{
    102    qemu_irq irq;
    103    isa_init_irq(isadev, &irq, isairq);
    104    qdev_connect_gpio_out(DEVICE(isadev), gpioirq, irq);
    105}
    106
    107void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16)
    108{
    109    assert(bus && dma8 && dma16);
    110    assert(!bus->dma[0] && !bus->dma[1]);
    111    bus->dma[0] = dma8;
    112    bus->dma[1] = dma16;
    113}
    114
    115IsaDma *isa_get_dma(ISABus *bus, int nchan)
    116{
    117    assert(bus);
    118    return bus->dma[nchan > 3 ? 1 : 0];
    119}
    120
    121static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
    122{
    123    if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
    124        dev->ioport_id = ioport;
    125    }
    126}
    127
    128void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
    129{
    130    memory_region_add_subregion(isabus->address_space_io, start, io);
    131    isa_init_ioport(dev, start);
    132}
    133
    134int isa_register_portio_list(ISADevice *dev,
    135                             PortioList *piolist, uint16_t start,
    136                             const MemoryRegionPortio *pio_start,
    137                             void *opaque, const char *name)
    138{
    139    assert(piolist && !piolist->owner);
    140
    141    if (!isabus) {
    142        return -ENODEV;
    143    }
    144
    145    /* START is how we should treat DEV, regardless of the actual
    146       contents of the portio array.  This is how the old code
    147       actually handled e.g. the FDC device.  */
    148    isa_init_ioport(dev, start);
    149
    150    portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
    151    portio_list_add(piolist, isabus->address_space_io, start);
    152
    153    return 0;
    154}
    155
    156static void isa_device_init(Object *obj)
    157{
    158    ISADevice *dev = ISA_DEVICE(obj);
    159
    160    dev->isairq[0] = -1;
    161    dev->isairq[1] = -1;
    162}
    163
    164ISADevice *isa_new(const char *name)
    165{
    166    return ISA_DEVICE(qdev_new(name));
    167}
    168
    169ISADevice *isa_try_new(const char *name)
    170{
    171    return ISA_DEVICE(qdev_try_new(name));
    172}
    173
    174ISADevice *isa_create_simple(ISABus *bus, const char *name)
    175{
    176    ISADevice *dev;
    177
    178    dev = isa_new(name);
    179    isa_realize_and_unref(dev, bus, &error_fatal);
    180    return dev;
    181}
    182
    183bool isa_realize_and_unref(ISADevice *dev, ISABus *bus, Error **errp)
    184{
    185    return qdev_realize_and_unref(&dev->parent_obj, &bus->parent_obj, errp);
    186}
    187
    188ISADevice *isa_vga_init(ISABus *bus)
    189{
    190    switch (vga_interface_type) {
    191    case VGA_CIRRUS:
    192        return isa_create_simple(bus, "isa-cirrus-vga");
    193    case VGA_QXL:
    194        error_report("%s: qxl: no PCI bus", __func__);
    195        return NULL;
    196    case VGA_STD:
    197        return isa_create_simple(bus, "isa-vga");
    198    case VGA_VMWARE:
    199        error_report("%s: vmware_vga: no PCI bus", __func__);
    200        return NULL;
    201    case VGA_VIRTIO:
    202        error_report("%s: virtio-vga: no PCI bus", __func__);
    203        return NULL;
    204    case VGA_NONE:
    205    default:
    206        return NULL;
    207    }
    208}
    209
    210void isa_build_aml(ISABus *bus, Aml *scope)
    211{
    212    BusChild *kid;
    213    ISADevice *dev;
    214    ISADeviceClass *dc;
    215
    216    QTAILQ_FOREACH(kid, &bus->parent_obj.children, sibling) {
    217        dev = ISA_DEVICE(kid->child);
    218        dc = ISA_DEVICE_GET_CLASS(dev);
    219        if (dc->build_aml) {
    220            dc->build_aml(dev, scope);
    221        }
    222    }
    223}
    224
    225static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
    226{
    227    ISADevice *d = ISA_DEVICE(dev);
    228
    229    if (d->isairq[1] != -1) {
    230        monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
    231                       d->isairq[0], d->isairq[1]);
    232    } else if (d->isairq[0] != -1) {
    233        monitor_printf(mon, "%*sisa irq %d\n", indent, "",
    234                       d->isairq[0]);
    235    }
    236}
    237
    238static void isabus_bridge_class_init(ObjectClass *klass, void *data)
    239{
    240    DeviceClass *dc = DEVICE_CLASS(klass);
    241
    242    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    243    dc->fw_name = "isa";
    244}
    245
    246static const TypeInfo isabus_bridge_info = {
    247    .name          = "isabus-bridge",
    248    .parent        = TYPE_SYS_BUS_DEVICE,
    249    .instance_size = sizeof(SysBusDevice),
    250    .class_init    = isabus_bridge_class_init,
    251};
    252
    253static void isa_device_class_init(ObjectClass *klass, void *data)
    254{
    255    DeviceClass *k = DEVICE_CLASS(klass);
    256    k->bus_type = TYPE_ISA_BUS;
    257}
    258
    259static const TypeInfo isa_device_type_info = {
    260    .name = TYPE_ISA_DEVICE,
    261    .parent = TYPE_DEVICE,
    262    .instance_size = sizeof(ISADevice),
    263    .instance_init = isa_device_init,
    264    .abstract = true,
    265    .class_size = sizeof(ISADeviceClass),
    266    .class_init = isa_device_class_init,
    267};
    268
    269static void isabus_register_types(void)
    270{
    271    type_register_static(&isa_dma_info);
    272    type_register_static(&isa_bus_info);
    273    type_register_static(&isabus_bridge_info);
    274    type_register_static(&isa_device_type_info);
    275}
    276
    277static char *isabus_get_fw_dev_path(DeviceState *dev)
    278{
    279    ISADevice *d = ISA_DEVICE(dev);
    280    char path[40];
    281    int off;
    282
    283    off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
    284    if (d->ioport_id) {
    285        snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
    286    }
    287
    288    return g_strdup(path);
    289}
    290
    291MemoryRegion *isa_address_space(ISADevice *dev)
    292{
    293    if (dev) {
    294        return isa_bus_from_device(dev)->address_space;
    295    }
    296
    297    return isabus->address_space;
    298}
    299
    300MemoryRegion *isa_address_space_io(ISADevice *dev)
    301{
    302    if (dev) {
    303        return isa_bus_from_device(dev)->address_space_io;
    304    }
    305
    306    return isabus->address_space_io;
    307}
    308
    309type_init(isabus_register_types)