static void qdev_pci_bridge_dev_reset(DeviceState *qdev) { PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev); pci_bridge_reset(qdev); shpc_reset(dev); }
static void qdev_pci_bridge_dev_reset(DeviceState *qdev) { PCIDevice *dev = PCI_DEVICE(qdev); pci_bridge_reset(qdev); shpc_reset(dev); }
/* 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; }