예제 #1
0
static void qdev_pci_bridge_dev_reset(DeviceState *qdev)
{
    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);

    pci_bridge_reset(qdev);
    shpc_reset(dev);
}
예제 #2
0
static void qdev_pci_bridge_dev_reset(DeviceState *qdev)
{
    PCIDevice *dev = PCI_DEVICE(qdev);

    pci_bridge_reset(qdev);
    shpc_reset(dev);
}
예제 #3
0
파일: shpc.c 프로젝트: CTU-IIG/qemu
/* Initialize the SHPC structure in bridge's BAR. */
int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
              unsigned offset, Error **errp)
{
    int i, ret;
    int nslots = SHPC_MAX_SLOTS; /* TODO: qdev property? */
    SHPCDevice *shpc = d->shpc = g_malloc0(sizeof(*d->shpc));
    shpc->sec_bus = sec_bus;
    ret = shpc_cap_add_config(d, errp);
    if (ret) {
        g_free(d->shpc);
        return ret;
    }
    if (nslots < SHPC_MIN_SLOTS) {
        return 0;
    }
    if (nslots > SHPC_MAX_SLOTS ||
        SHPC_IDX_TO_PCI(nslots) > PCI_SLOT_MAX) {
        /* TODO: report an error mesage that makes sense. */
        return -EINVAL;
    }
    shpc->nslots = nslots;
    shpc->config = g_malloc0(SHPC_SIZEOF(d));
    shpc->cmask = g_malloc0(SHPC_SIZEOF(d));
    shpc->wmask = g_malloc0(SHPC_SIZEOF(d));
    shpc->w1cmask = g_malloc0(SHPC_SIZEOF(d));

    shpc_reset(d);

    pci_set_long(shpc->config + SHPC_BASE_OFFSET, offset);

    pci_set_byte(shpc->wmask + SHPC_CMD_CODE, 0xff);
    pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
    pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
    pci_set_long(shpc->wmask + SHPC_SERR_INT,
                 SHPC_INT_DIS |
                 SHPC_SERR_DIS |
                 SHPC_CMD_INT_DIS |
                 SHPC_ARB_SERR_DIS);
    pci_set_long(shpc->w1cmask + SHPC_SERR_INT,
                 SHPC_CMD_DETECTED |
                 SHPC_ARB_DETECTED);
    for (i = 0; i < nslots; ++i) {
        pci_set_byte(shpc->wmask +
                     SHPC_SLOT_EVENT_SERR_INT_DIS(d, i),
                     SHPC_SLOT_EVENT_PRESENCE |
                     SHPC_SLOT_EVENT_ISOLATED_FAULT |
                     SHPC_SLOT_EVENT_BUTTON |
                     SHPC_SLOT_EVENT_MRL |
                     SHPC_SLOT_EVENT_CONNECTED_FAULT |
                     SHPC_SLOT_EVENT_MRL_SERR_DIS |
                     SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS);
        pci_set_byte(shpc->w1cmask +
                     SHPC_SLOT_EVENT_LATCH(i),
                     SHPC_SLOT_EVENT_PRESENCE |
                     SHPC_SLOT_EVENT_ISOLATED_FAULT |
                     SHPC_SLOT_EVENT_BUTTON |
                     SHPC_SLOT_EVENT_MRL |
                     SHPC_SLOT_EVENT_CONNECTED_FAULT);
    }

    /* TODO: init cmask */
    memory_region_init_io(&shpc->mmio, OBJECT(d), &shpc_mmio_ops,
                          d, "shpc-mmio", SHPC_SIZEOF(d));
    shpc_cap_update_dword(d);
    memory_region_add_subregion(bar, offset, &shpc->mmio);

    qbus_set_hotplug_handler(BUS(sec_bus), DEVICE(d), NULL);

    d->cap_present |= QEMU_PCI_CAP_SHPC;
    return 0;
}