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

sabre.c (16597B)


      1/*
      2 * QEMU Ultrasparc Sabre PCI host (PBM)
      3 *
      4 * Copyright (c) 2006 Fabrice Bellard
      5 * Copyright (c) 2012,2013 Artyom Tarasenko
      6 * Copyright (c) 2018 Mark Cave-Ayland
      7 *
      8 * Permission is hereby granted, free of charge, to any person obtaining a copy
      9 * of this software and associated documentation files (the "Software"), to deal
     10 * in the Software without restriction, including without limitation the rights
     11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     12 * copies of the Software, and to permit persons to whom the Software is
     13 * furnished to do so, subject to the following conditions:
     14 *
     15 * The above copyright notice and this permission notice shall be included in
     16 * all copies or substantial portions of the Software.
     17 *
     18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     24 * THE SOFTWARE.
     25 */
     26
     27#include "qemu/osdep.h"
     28#include "hw/sysbus.h"
     29#include "hw/pci/pci.h"
     30#include "hw/pci/pci_host.h"
     31#include "hw/qdev-properties.h"
     32#include "hw/pci/pci_bridge.h"
     33#include "hw/pci/pci_bus.h"
     34#include "hw/irq.h"
     35#include "hw/pci-bridge/simba.h"
     36#include "hw/pci-host/sabre.h"
     37#include "qapi/error.h"
     38#include "qemu/log.h"
     39#include "qemu/module.h"
     40#include "sysemu/runstate.h"
     41#include "trace.h"
     42
     43/*
     44 * Chipset docs:
     45 * PBM: "UltraSPARC IIi User's Manual",
     46 * https://web.archive.org/web/20030403110020/http://www.sun.com/processors/manuals/805-0087.pdf
     47 */
     48
     49#define PBM_PCI_IMR_MASK    0x7fffffff
     50#define PBM_PCI_IMR_ENABLED 0x80000000
     51
     52#define POR          (1U << 31)
     53#define SOFT_POR     (1U << 30)
     54#define SOFT_XIR     (1U << 29)
     55#define BTN_POR      (1U << 28)
     56#define BTN_XIR      (1U << 27)
     57#define RESET_MASK   0xf8000000
     58#define RESET_WCMASK 0x98000000
     59#define RESET_WMASK  0x60000000
     60
     61#define NO_IRQ_REQUEST (MAX_IVEC + 1)
     62
     63static inline void sabre_set_request(SabreState *s, unsigned int irq_num)
     64{
     65    trace_sabre_set_request(irq_num);
     66    s->irq_request = irq_num;
     67    qemu_set_irq(s->ivec_irqs[irq_num], 1);
     68}
     69
     70static inline void sabre_check_irqs(SabreState *s)
     71{
     72    unsigned int i;
     73
     74    /* Previous request is not acknowledged, resubmit */
     75    if (s->irq_request != NO_IRQ_REQUEST) {
     76        sabre_set_request(s, s->irq_request);
     77        return;
     78    }
     79    /* no request pending */
     80    if (s->pci_irq_in == 0ULL) {
     81        return;
     82    }
     83    for (i = 0; i < 32; i++) {
     84        if (s->pci_irq_in & (1ULL << i)) {
     85            if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
     86                sabre_set_request(s, i);
     87                return;
     88            }
     89        }
     90    }
     91    for (i = 32; i < 64; i++) {
     92        if (s->pci_irq_in & (1ULL << i)) {
     93            if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
     94                sabre_set_request(s, i);
     95                break;
     96            }
     97        }
     98    }
     99}
    100
    101static inline void sabre_clear_request(SabreState *s, unsigned int irq_num)
    102{
    103    trace_sabre_clear_request(irq_num);
    104    qemu_set_irq(s->ivec_irqs[irq_num], 0);
    105    s->irq_request = NO_IRQ_REQUEST;
    106}
    107
    108static AddressSpace *sabre_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
    109{
    110    IOMMUState *is = opaque;
    111
    112    return &is->iommu_as;
    113}
    114
    115static void sabre_config_write(void *opaque, hwaddr addr,
    116                               uint64_t val, unsigned size)
    117{
    118    SabreState *s = opaque;
    119
    120    trace_sabre_config_write(addr, val);
    121
    122    switch (addr) {
    123    case 0x30 ... 0x4f: /* DMA error registers */
    124        /* XXX: not implemented yet */
    125        break;
    126    case 0xc00 ... 0xc3f: /* PCI interrupt control */
    127        if (addr & 4) {
    128            unsigned int ino = (addr & 0x3f) >> 3;
    129            s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
    130            s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
    131            if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
    132                sabre_clear_request(s, ino);
    133            }
    134            sabre_check_irqs(s);
    135        }
    136        break;
    137    case 0x1000 ... 0x107f: /* OBIO interrupt control */
    138        if (addr & 4) {
    139            unsigned int ino = ((addr & 0xff) >> 3);
    140            s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
    141            s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
    142            if ((s->irq_request == (ino | 0x20))
    143                 && !(val & ~PBM_PCI_IMR_MASK)) {
    144                sabre_clear_request(s, ino | 0x20);
    145            }
    146            sabre_check_irqs(s);
    147        }
    148        break;
    149    case 0x1400 ... 0x14ff: /* PCI interrupt clear */
    150        if (addr & 4) {
    151            unsigned int ino = (addr & 0xff) >> 5;
    152            if ((s->irq_request / 4)  == ino) {
    153                sabre_clear_request(s, s->irq_request);
    154                sabre_check_irqs(s);
    155            }
    156        }
    157        break;
    158    case 0x1800 ... 0x1860: /* OBIO interrupt clear */
    159        if (addr & 4) {
    160            unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
    161            if (s->irq_request == ino) {
    162                sabre_clear_request(s, ino);
    163                sabre_check_irqs(s);
    164            }
    165        }
    166        break;
    167    case 0x2000 ... 0x202f: /* PCI control */
    168        s->pci_control[(addr & 0x3f) >> 2] = val;
    169        break;
    170    case 0xf020 ... 0xf027: /* Reset control */
    171        if (addr & 4) {
    172            val &= RESET_MASK;
    173            s->reset_control &= ~(val & RESET_WCMASK);
    174            s->reset_control |= val & RESET_WMASK;
    175            if (val & SOFT_POR) {
    176                s->nr_resets = 0;
    177                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    178            } else if (val & SOFT_XIR) {
    179                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    180            }
    181        }
    182        break;
    183    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
    184    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
    185    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
    186    case 0xf000 ... 0xf01f: /* FFB config, memory control */
    187        /* we don't care */
    188    default:
    189        break;
    190    }
    191}
    192
    193static uint64_t sabre_config_read(void *opaque,
    194                                  hwaddr addr, unsigned size)
    195{
    196    SabreState *s = opaque;
    197    uint32_t val = 0;
    198
    199    switch (addr) {
    200    case 0x30 ... 0x4f: /* DMA error registers */
    201        /* XXX: not implemented yet */
    202        break;
    203    case 0xc00 ... 0xc3f: /* PCI interrupt control */
    204        if (addr & 4) {
    205            val = s->pci_irq_map[(addr & 0x3f) >> 3];
    206        }
    207        break;
    208    case 0x1000 ... 0x107f: /* OBIO interrupt control */
    209        if (addr & 4) {
    210            val = s->obio_irq_map[(addr & 0xff) >> 3];
    211        }
    212        break;
    213    case 0x1080 ... 0x108f: /* PCI bus error */
    214        if (addr & 4) {
    215            val = s->pci_err_irq_map[(addr & 0xf) >> 3];
    216        }
    217        break;
    218    case 0x2000 ... 0x202f: /* PCI control */
    219        val = s->pci_control[(addr & 0x3f) >> 2];
    220        break;
    221    case 0xf020 ... 0xf027: /* Reset control */
    222        if (addr & 4) {
    223            val = s->reset_control;
    224        }
    225        break;
    226    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
    227    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
    228    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
    229    case 0xf000 ... 0xf01f: /* FFB config, memory control */
    230        /* we don't care */
    231    default:
    232        break;
    233    }
    234    trace_sabre_config_read(addr, val);
    235
    236    return val;
    237}
    238
    239static const MemoryRegionOps sabre_config_ops = {
    240    .read = sabre_config_read,
    241    .write = sabre_config_write,
    242    .endianness = DEVICE_BIG_ENDIAN,
    243};
    244
    245static void sabre_pci_config_write(void *opaque, hwaddr addr,
    246                                   uint64_t val, unsigned size)
    247{
    248    SabreState *s = opaque;
    249    PCIHostState *phb = PCI_HOST_BRIDGE(s);
    250
    251    trace_sabre_pci_config_write(addr, val);
    252    pci_data_write(phb->bus, addr, val, size);
    253}
    254
    255static uint64_t sabre_pci_config_read(void *opaque, hwaddr addr,
    256                                      unsigned size)
    257{
    258    uint32_t ret;
    259    SabreState *s = opaque;
    260    PCIHostState *phb = PCI_HOST_BRIDGE(s);
    261
    262    ret = pci_data_read(phb->bus, addr, size);
    263    trace_sabre_pci_config_read(addr, ret);
    264    return ret;
    265}
    266
    267/* The sabre host has an IRQ line for each IRQ line of each slot.  */
    268static int pci_sabre_map_irq(PCIDevice *pci_dev, int irq_num)
    269{
    270    /* Return the irq as swizzled by the PBM */
    271    return irq_num;
    272}
    273
    274static int pci_simbaA_map_irq(PCIDevice *pci_dev, int irq_num)
    275{
    276    /* The on-board devices have fixed (legacy) OBIO intnos */
    277    switch (PCI_SLOT(pci_dev->devfn)) {
    278    case 1:
    279        /* Onboard NIC */
    280        return OBIO_NIC_IRQ;
    281    case 3:
    282        /* Onboard IDE */
    283        return OBIO_HDD_IRQ;
    284    default:
    285        /* Normal intno, fall through */
    286        break;
    287    }
    288
    289    return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
    290}
    291
    292static int pci_simbaB_map_irq(PCIDevice *pci_dev, int irq_num)
    293{
    294    return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
    295}
    296
    297static void pci_sabre_set_irq(void *opaque, int irq_num, int level)
    298{
    299    SabreState *s = opaque;
    300
    301    trace_sabre_pci_set_irq(irq_num, level);
    302
    303    /* PCI IRQ map onto the first 32 INO.  */
    304    if (irq_num < 32) {
    305        if (level) {
    306            s->pci_irq_in |= 1ULL << irq_num;
    307            if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
    308                sabre_set_request(s, irq_num);
    309            }
    310        } else {
    311            s->pci_irq_in &= ~(1ULL << irq_num);
    312        }
    313    } else {
    314        /* OBIO IRQ map onto the next 32 INO.  */
    315        if (level) {
    316            trace_sabre_pci_set_obio_irq(irq_num, level);
    317            s->pci_irq_in |= 1ULL << irq_num;
    318            if ((s->irq_request == NO_IRQ_REQUEST)
    319                && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
    320                sabre_set_request(s, irq_num);
    321            }
    322        } else {
    323            s->pci_irq_in &= ~(1ULL << irq_num);
    324        }
    325    }
    326}
    327
    328static void sabre_reset(DeviceState *d)
    329{
    330    SabreState *s = SABRE(d);
    331    PCIDevice *pci_dev;
    332    unsigned int i;
    333    uint16_t cmd;
    334
    335    for (i = 0; i < 8; i++) {
    336        s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
    337    }
    338    for (i = 0; i < 32; i++) {
    339        s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
    340    }
    341
    342    s->irq_request = NO_IRQ_REQUEST;
    343    s->pci_irq_in = 0ULL;
    344
    345    if (s->nr_resets++ == 0) {
    346        /* Power on reset */
    347        s->reset_control = POR;
    348    }
    349
    350    /* As this is the busA PCI bridge which contains the on-board devices
    351     * attached to the ebus, ensure that we initially allow IO transactions
    352     * so that we get the early serial console until OpenBIOS can properly
    353     * configure the PCI bridge itself */
    354    pci_dev = PCI_DEVICE(s->bridgeA);
    355    cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
    356    pci_set_word(pci_dev->config + PCI_COMMAND, cmd | PCI_COMMAND_IO);
    357    pci_bridge_update_mappings(PCI_BRIDGE(pci_dev));
    358}
    359
    360static const MemoryRegionOps pci_config_ops = {
    361    .read = sabre_pci_config_read,
    362    .write = sabre_pci_config_write,
    363    .endianness = DEVICE_LITTLE_ENDIAN,
    364};
    365
    366static void sabre_realize(DeviceState *dev, Error **errp)
    367{
    368    SabreState *s = SABRE(dev);
    369    PCIHostState *phb = PCI_HOST_BRIDGE(dev);
    370    PCIDevice *pci_dev;
    371
    372    memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
    373    memory_region_add_subregion(get_system_memory(), s->mem_base,
    374                                &s->pci_mmio);
    375
    376    phb->bus = pci_register_root_bus(dev, "pci",
    377                                     pci_sabre_set_irq, pci_sabre_map_irq, s,
    378                                     &s->pci_mmio,
    379                                     &s->pci_ioport,
    380                                     0, 0x40, TYPE_PCI_BUS);
    381
    382    pci_create_simple(phb->bus, 0, TYPE_SABRE_PCI_DEVICE);
    383
    384    /* IOMMU */
    385    memory_region_add_subregion_overlap(&s->sabre_config, 0x200,
    386                    sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
    387    pci_setup_iommu(phb->bus, sabre_pci_dma_iommu, s->iommu);
    388
    389    /* APB secondary busses */
    390    pci_dev = pci_new_multifunction(PCI_DEVFN(1, 0), true,
    391                                    TYPE_SIMBA_PCI_BRIDGE);
    392    s->bridgeB = PCI_BRIDGE(pci_dev);
    393    pci_bridge_map_irq(s->bridgeB, "pciB", pci_simbaB_map_irq);
    394    pci_realize_and_unref(pci_dev, phb->bus, &error_fatal);
    395
    396    pci_dev = pci_new_multifunction(PCI_DEVFN(1, 1), true,
    397                                    TYPE_SIMBA_PCI_BRIDGE);
    398    s->bridgeA = PCI_BRIDGE(pci_dev);
    399    pci_bridge_map_irq(s->bridgeA, "pciA", pci_simbaA_map_irq);
    400    pci_realize_and_unref(pci_dev, phb->bus, &error_fatal);
    401}
    402
    403static void sabre_init(Object *obj)
    404{
    405    SabreState *s = SABRE(obj);
    406    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    407    unsigned int i;
    408
    409    for (i = 0; i < 8; i++) {
    410        s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
    411    }
    412    for (i = 0; i < 2; i++) {
    413        s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
    414    }
    415    for (i = 0; i < 32; i++) {
    416        s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
    417    }
    418    qdev_init_gpio_in_named(DEVICE(s), pci_sabre_set_irq, "pbm-irq", MAX_IVEC);
    419    qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
    420    s->irq_request = NO_IRQ_REQUEST;
    421    s->pci_irq_in = 0ULL;
    422
    423    /* IOMMU */
    424    object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
    425                             (Object **) &s->iommu,
    426                             qdev_prop_allow_set_link_before_realize,
    427                             0);
    428
    429    /* sabre_config */
    430    memory_region_init_io(&s->sabre_config, OBJECT(s), &sabre_config_ops, s,
    431                          "sabre-config", 0x10000);
    432    /* at region 0 */
    433    sysbus_init_mmio(sbd, &s->sabre_config);
    434
    435    memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
    436                          "sabre-pci-config", 0x1000000);
    437    /* at region 1 */
    438    sysbus_init_mmio(sbd, &s->pci_config);
    439
    440    /* pci_ioport */
    441    memory_region_init(&s->pci_ioport, OBJECT(s), "sabre-pci-ioport",
    442                       0x1000000);
    443
    444    /* at region 2 */
    445    sysbus_init_mmio(sbd, &s->pci_ioport);
    446}
    447
    448static void sabre_pci_realize(PCIDevice *d, Error **errp)
    449{
    450    pci_set_word(d->config + PCI_COMMAND,
    451                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
    452    pci_set_word(d->config + PCI_STATUS,
    453                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
    454                 PCI_STATUS_DEVSEL_MEDIUM);
    455}
    456
    457static void sabre_pci_class_init(ObjectClass *klass, void *data)
    458{
    459    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    460    DeviceClass *dc = DEVICE_CLASS(klass);
    461
    462    k->realize = sabre_pci_realize;
    463    k->vendor_id = PCI_VENDOR_ID_SUN;
    464    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
    465    k->class_id = PCI_CLASS_BRIDGE_HOST;
    466    /*
    467     * PCI-facing part of the host bridge, not usable without the
    468     * host-facing part, which can't be device_add'ed, yet.
    469     */
    470    dc->user_creatable = false;
    471}
    472
    473static const TypeInfo sabre_pci_info = {
    474    .name          = TYPE_SABRE_PCI_DEVICE,
    475    .parent        = TYPE_PCI_DEVICE,
    476    .instance_size = sizeof(SabrePCIState),
    477    .class_init    = sabre_pci_class_init,
    478    .interfaces = (InterfaceInfo[]) {
    479        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
    480        { },
    481    },
    482};
    483
    484static char *sabre_ofw_unit_address(const SysBusDevice *dev)
    485{
    486    SabreState *s = SABRE(dev);
    487
    488    return g_strdup_printf("%x,%x",
    489               (uint32_t)((s->special_base >> 32) & 0xffffffff),
    490               (uint32_t)(s->special_base & 0xffffffff));
    491}
    492
    493static Property sabre_properties[] = {
    494    DEFINE_PROP_UINT64("special-base", SabreState, special_base, 0),
    495    DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0),
    496    DEFINE_PROP_END_OF_LIST(),
    497};
    498
    499static void sabre_class_init(ObjectClass *klass, void *data)
    500{
    501    DeviceClass *dc = DEVICE_CLASS(klass);
    502    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
    503
    504    dc->realize = sabre_realize;
    505    dc->reset = sabre_reset;
    506    device_class_set_props(dc, sabre_properties);
    507    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    508    dc->fw_name = "pci";
    509    sbc->explicit_ofw_unit_address = sabre_ofw_unit_address;
    510}
    511
    512static const TypeInfo sabre_info = {
    513    .name          = TYPE_SABRE,
    514    .parent        = TYPE_PCI_HOST_BRIDGE,
    515    .instance_size = sizeof(SabreState),
    516    .instance_init = sabre_init,
    517    .class_init    = sabre_class_init,
    518};
    519
    520static void sabre_register_types(void)
    521{
    522    type_register_static(&sabre_info);
    523    type_register_static(&sabre_pci_info);
    524}
    525
    526type_init(sabre_register_types)