void shpc_reset(PCIDevice *d) { SHPCDevice *shpc = d->shpc; int nslots = shpc->nslots; int i; memset(shpc->config, 0, SHPC_SIZEOF(d)); pci_set_byte(shpc->config + SHPC_NSLOTS, nslots); pci_set_long(shpc->config + SHPC_SLOTS_33, nslots); pci_set_long(shpc->config + SHPC_SLOTS_66, 0); pci_set_byte(shpc->config + SHPC_FIRST_DEV, SHPC_IDX_TO_PCI(0)); pci_set_word(shpc->config + SHPC_PHYS_SLOT, SHPC_IDX_TO_PHYSICAL(0) | SHPC_PHYS_NUM_UP | SHPC_PHYS_MRL | SHPC_PHYS_BUTTON); pci_set_long(shpc->config + SHPC_SERR_INT, SHPC_INT_DIS | SHPC_SERR_DIS | SHPC_CMD_INT_DIS | SHPC_ARB_SERR_DIS); pci_set_byte(shpc->config + SHPC_PROG_IFC, SHPC_PROG_IFC_1_0); pci_set_word(shpc->config + SHPC_SEC_BUS, SHPC_SEC_BUS_33); for (i = 0; i < shpc->nslots; ++i) { pci_set_byte(shpc->config + 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); if (shpc->sec_bus->devices[PCI_DEVFN(SHPC_IDX_TO_PCI(i), 0)]) { shpc_set_status(shpc, i, SHPC_STATE_ENABLED, SHPC_SLOT_STATE_MASK); shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_MRL_OPEN); shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_7_5W, SHPC_SLOT_STATUS_PRSNT_MASK); shpc_set_status(shpc, i, SHPC_LED_ON, SHPC_SLOT_PWR_LED_MASK); } else { shpc_set_status(shpc, i, SHPC_STATE_DISABLED, SHPC_SLOT_STATE_MASK); shpc_set_status(shpc, i, 1, SHPC_SLOT_STATUS_MRL_OPEN); shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_EMPTY, SHPC_SLOT_STATUS_PRSNT_MASK); shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_PWR_LED_MASK); } shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_66); } shpc_set_sec_bus_speed(shpc, SHPC_SEC_BUS_33); shpc->msi_requested = 0; shpc_interrupt_update(d); }
static int versatile_pci_host_init(PCIDevice *d) { pci_set_word(d->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); return 0; }
static int xen_pv_init(PCIDevice *pci_dev) { XenPVDevice *d = XEN_PV_DEVICE(pci_dev); uint8_t *pci_conf; /* device-id property must always be supplied */ if (d->device_id == 0xffff) return -1; pci_conf = pci_dev->config; pci_set_word(pci_conf + PCI_VENDOR_ID, d->vendor_id); pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, d->vendor_id); pci_set_word(pci_conf + PCI_DEVICE_ID, d->device_id); pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, d->device_id); pci_set_byte(pci_conf + PCI_REVISION_ID, d->revision); pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_MEMORY); pci_config_set_prog_interface(pci_conf, 0); pci_conf[PCI_INTERRUPT_PIN] = 1; memory_region_init_io(&d->mmio, NULL, &xen_pv_mmio_ops, d, "mmio", d->size); pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio); return 0; }
static int dec_21154_pci_host_init(PCIDevice *d) { /* PCI2PCI bridge same values as PearPC - check this */ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC); pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154); pci_set_byte(d->config + PCI_REVISION_ID, 0x02); pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI); return 0; }
static int versatile_pci_host_init(PCIDevice *d) { pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX); /* Both boards have the same device ID. Oh well. */ pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO); pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); return 0; }
/* Add SHPC capability to the config space for the device. */ static int shpc_cap_add_config(PCIDevice *d, Error **errp) { uint8_t *config; int config_offset; config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC, 0, SHPC_CAP_LENGTH, errp); if (config_offset < 0) { return config_offset; } config = d->config + config_offset; pci_set_byte(config + SHPC_CAP_DWORD_SELECT, 0); pci_set_byte(config + SHPC_CAP_CxP, 0); pci_set_long(config + SHPC_CAP_DWORD_DATA, 0); d->shpc->cap = config_offset; /* Make dword select and data writeable. */ pci_set_byte(d->wmask + config_offset + SHPC_CAP_DWORD_SELECT, 0xff); pci_set_long(d->wmask + config_offset + SHPC_CAP_DWORD_DATA, 0xffffffff); return 0; }
static int usb_ehci_pci_initfn(PCIDevice *dev) { EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev); EHCIState *s = &i->ehci; uint8_t *pci_conf = dev->config; pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20); /* capabilities pointer */ pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00); /* pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50); */ pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */ pci_set_byte(&pci_conf[PCI_MIN_GNT], 0); pci_set_byte(&pci_conf[PCI_MAX_LAT], 0); /* pci_conf[0x50] = 0x01; *//* power management caps */ pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); /* release # (2.1.4) */ pci_set_byte(&pci_conf[0x61], 0x20); /* frame length adjustment (2.1.5) */ pci_set_word(&pci_conf[0x62], 0x00); /* port wake up capability (2.1.6) */ pci_conf[0x64] = 0x00; pci_conf[0x65] = 0x00; pci_conf[0x66] = 0x00; pci_conf[0x67] = 0x00; pci_conf[0x68] = 0x01; pci_conf[0x69] = 0x00; pci_conf[0x6a] = 0x00; pci_conf[0x6b] = 0x00; /* USBLEGSUP */ pci_conf[0x6c] = 0x00; pci_conf[0x6d] = 0x00; pci_conf[0x6e] = 0x00; pci_conf[0x6f] = 0xc0; /* USBLEFCTLSTS */ s->caps[0x09] = 0x68; /* EECP */ s->irq = dev->irq[3]; s->dma = pci_dma_context(dev); s->capsbase = 0x00; s->opregbase = 0x20; usb_ehci_initfn(s, DEVICE(dev)); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); return 0; }
/* 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; }