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

xio3130_downstream.c (5812B)


      1/*
      2 * x3130_downstream.c
      3 * TI X3130 pci express downstream port switch
      4 *
      5 * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
      6 *                    VA Linux Systems Japan K.K.
      7 *
      8 * This program is free software; you can redistribute it and/or modify
      9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation; either version 2 of the License, or
     11 * (at your option) any later version.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License along
     19 * with this program; if not, see <http://www.gnu.org/licenses/>.
     20 */
     21
     22#include "qemu/osdep.h"
     23#include "hw/pci/pci_ids.h"
     24#include "hw/pci/msi.h"
     25#include "hw/pci/pcie.h"
     26#include "hw/pci/pcie_port.h"
     27#include "hw/qdev-properties.h"
     28#include "migration/vmstate.h"
     29#include "qapi/error.h"
     30#include "qemu/module.h"
     31
     32#define PCI_DEVICE_ID_TI_XIO3130D       0x8233  /* downstream port */
     33#define XIO3130_REVISION                0x1
     34#define XIO3130_MSI_OFFSET              0x70
     35#define XIO3130_MSI_SUPPORTED_FLAGS     PCI_MSI_FLAGS_64BIT
     36#define XIO3130_MSI_NR_VECTOR           1
     37#define XIO3130_SSVID_OFFSET            0x80
     38#define XIO3130_SSVID_SVID              0
     39#define XIO3130_SSVID_SSID              0
     40#define XIO3130_EXP_OFFSET              0x90
     41#define XIO3130_AER_OFFSET              0x100
     42
     43static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
     44                                         uint32_t val, int len)
     45{
     46    uint16_t slt_ctl, slt_sta;
     47
     48    pcie_cap_slot_get(d, &slt_ctl, &slt_sta);
     49    pci_bridge_write_config(d, address, val, len);
     50    pcie_cap_flr_write_config(d, address, val, len);
     51    pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
     52    pcie_aer_write_config(d, address, val, len);
     53}
     54
     55static void xio3130_downstream_reset(DeviceState *qdev)
     56{
     57    PCIDevice *d = PCI_DEVICE(qdev);
     58
     59    pcie_cap_deverr_reset(d);
     60    pcie_cap_slot_reset(d);
     61    pcie_cap_arifwd_reset(d);
     62    pci_bridge_reset(qdev);
     63}
     64
     65static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
     66{
     67    PCIEPort *p = PCIE_PORT(d);
     68    PCIESlot *s = PCIE_SLOT(d);
     69    int rc;
     70
     71    pci_bridge_initfn(d, TYPE_PCIE_BUS);
     72    pcie_port_init_reg(d);
     73
     74    rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
     75                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
     76                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
     77                  errp);
     78    if (rc < 0) {
     79        assert(rc == -ENOTSUP);
     80        goto err_bridge;
     81    }
     82
     83    rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
     84                               XIO3130_SSVID_SVID, XIO3130_SSVID_SSID,
     85                               errp);
     86    if (rc < 0) {
     87        goto err_bridge;
     88    }
     89
     90    rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,
     91                       p->port, errp);
     92    if (rc < 0) {
     93        goto err_msi;
     94    }
     95    pcie_cap_flr_init(d);
     96    pcie_cap_deverr_init(d);
     97    pcie_cap_slot_init(d, s);
     98    pcie_cap_arifwd_init(d);
     99
    100    pcie_chassis_create(s->chassis);
    101    rc = pcie_chassis_add_slot(s);
    102    if (rc < 0) {
    103        error_setg(errp, "Can't add chassis slot, error %d", rc);
    104        goto err_pcie_cap;
    105    }
    106
    107    rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET,
    108                       PCI_ERR_SIZEOF, errp);
    109    if (rc < 0) {
    110        goto err;
    111    }
    112
    113    return;
    114
    115err:
    116    pcie_chassis_del_slot(s);
    117err_pcie_cap:
    118    pcie_cap_exit(d);
    119err_msi:
    120    msi_uninit(d);
    121err_bridge:
    122    pci_bridge_exitfn(d);
    123}
    124
    125static void xio3130_downstream_exitfn(PCIDevice *d)
    126{
    127    PCIESlot *s = PCIE_SLOT(d);
    128
    129    pcie_aer_exit(d);
    130    pcie_chassis_del_slot(s);
    131    pcie_cap_exit(d);
    132    msi_uninit(d);
    133    pci_bridge_exitfn(d);
    134}
    135
    136static Property xio3130_downstream_props[] = {
    137    DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
    138                    QEMU_PCIE_SLTCAP_PCP_BITNR, true),
    139    DEFINE_PROP_END_OF_LIST()
    140};
    141
    142static const VMStateDescription vmstate_xio3130_downstream = {
    143    .name = "xio3130-express-downstream-port",
    144    .priority = MIG_PRI_PCI_BUS,
    145    .version_id = 1,
    146    .minimum_version_id = 1,
    147    .post_load = pcie_cap_slot_post_load,
    148    .fields = (VMStateField[]) {
    149        VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot),
    150        VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log,
    151                       PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog),
    152        VMSTATE_END_OF_LIST()
    153    }
    154};
    155
    156static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
    157{
    158    DeviceClass *dc = DEVICE_CLASS(klass);
    159    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    160
    161    k->is_bridge = true;
    162    k->config_write = xio3130_downstream_write_config;
    163    k->realize = xio3130_downstream_realize;
    164    k->exit = xio3130_downstream_exitfn;
    165    k->vendor_id = PCI_VENDOR_ID_TI;
    166    k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
    167    k->revision = XIO3130_REVISION;
    168    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    169    dc->desc = "TI X3130 Downstream Port of PCI Express Switch";
    170    dc->reset = xio3130_downstream_reset;
    171    dc->vmsd = &vmstate_xio3130_downstream;
    172    device_class_set_props(dc, xio3130_downstream_props);
    173}
    174
    175static const TypeInfo xio3130_downstream_info = {
    176    .name          = "xio3130-downstream",
    177    .parent        = TYPE_PCIE_SLOT,
    178    .class_init    = xio3130_downstream_class_init,
    179    .interfaces = (InterfaceInfo[]) {
    180        { INTERFACE_PCIE_DEVICE },
    181        { }
    182    },
    183};
    184
    185static void xio3130_downstream_register_types(void)
    186{
    187    type_register_static(&xio3130_downstream_info);
    188}
    189
    190type_init(xio3130_downstream_register_types)