Lines Matching +full:0 +full:- +full:dev
4 * Copyright IBM, Corp. 2012-2013
10 * See the COPYING file in the top-level directory.
19 #include "qemu/host-utils.h"
23 void (*func)(QPCIDevice *dev, int devfn, void *data), in qpci_device_foreach() argument
28 for (slot = 0; slot < 32; slot++) { in qpci_device_foreach()
31 for (fn = 0; fn < 8; fn++) { in qpci_device_foreach()
32 QPCIDevice *dev; in qpci_device_foreach() local
34 dev = qpci_device_find(bus, QPCI_DEVFN(slot, fn)); in qpci_device_foreach()
35 if (!dev) { in qpci_device_foreach()
39 if (vendor_id != -1 && in qpci_device_foreach()
40 qpci_config_readw(dev, PCI_VENDOR_ID) != vendor_id) { in qpci_device_foreach()
41 g_free(dev); in qpci_device_foreach()
45 if (device_id != -1 && in qpci_device_foreach()
46 qpci_config_readw(dev, PCI_DEVICE_ID) != device_id) { in qpci_device_foreach()
47 g_free(dev); in qpci_device_foreach()
51 func(dev, QPCI_DEVFN(slot, fn), data); in qpci_device_foreach()
56 bool qpci_has_buggy_msi(QPCIDevice *dev) in qpci_has_buggy_msi() argument
58 return dev->bus->has_buggy_msi; in qpci_has_buggy_msi()
61 bool qpci_check_buggy_msi(QPCIDevice *dev) in qpci_check_buggy_msi() argument
63 if (qpci_has_buggy_msi(dev)) { in qpci_check_buggy_msi()
70 static void qpci_device_set(QPCIDevice *dev, QPCIBus *bus, int devfn) in qpci_device_set() argument
72 g_assert(dev); in qpci_device_set()
74 dev->bus = bus; in qpci_device_set()
75 dev->devfn = devfn; in qpci_device_set()
80 QPCIDevice *dev; in qpci_device_find() local
82 dev = g_malloc0(sizeof(*dev)); in qpci_device_find()
83 qpci_device_set(dev, bus, devfn); in qpci_device_find()
85 if (qpci_config_readw(dev, PCI_VENDOR_ID) == 0xFFFF) { in qpci_device_find()
86 g_free(dev); in qpci_device_find()
90 return dev; in qpci_device_find()
93 void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr) in qpci_device_init() argument
97 qpci_device_set(dev, bus, addr->devfn); in qpci_device_init()
98 vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID); in qpci_device_init()
99 device_id = qpci_config_readw(dev, PCI_DEVICE_ID); in qpci_device_init()
100 g_assert(!addr->vendor_id || vendor_id == addr->vendor_id); in qpci_device_init()
101 g_assert(!addr->device_id || device_id == addr->device_id); in qpci_device_init()
104 static uint8_t qpci_find_resource_reserve_capability(QPCIDevice *dev) in qpci_find_resource_reserve_capability() argument
107 uint8_t cap = 0; in qpci_find_resource_reserve_capability()
109 if (qpci_config_readw(dev, PCI_VENDOR_ID) != PCI_VENDOR_ID_REDHAT) { in qpci_find_resource_reserve_capability()
110 return 0; in qpci_find_resource_reserve_capability()
113 device_id = qpci_config_readw(dev, PCI_DEVICE_ID); in qpci_find_resource_reserve_capability()
117 return 0; in qpci_find_resource_reserve_capability()
121 cap = qpci_find_capability(dev, PCI_CAP_ID_VNDR, cap); in qpci_find_resource_reserve_capability()
123 qpci_config_readb(dev, cap + REDHAT_PCI_CAP_TYPE_OFFSET) != in qpci_find_resource_reserve_capability()
126 uint8_t cap_len = qpci_config_readb(dev, cap + PCI_CAP_FLAGS); in qpci_find_resource_reserve_capability()
128 return 0; in qpci_find_resource_reserve_capability()
136 QPCIDevice *dev; in qpci_secondary_buses_rec() local
141 for (index = 0; index < 32; index++) { in qpci_secondary_buses_rec()
142 dev = qpci_device_find(qbus, QPCI_DEVFN(bus + index, 0)); in qpci_secondary_buses_rec()
143 if (dev == NULL) { in qpci_secondary_buses_rec()
146 class = qpci_config_readw(dev, PCI_CLASS_DEVICE); in qpci_secondary_buses_rec()
148 qpci_config_writeb(dev, PCI_SECONDARY_BUS, 255); in qpci_secondary_buses_rec()
149 qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 0); in qpci_secondary_buses_rec()
151 g_free(dev); in qpci_secondary_buses_rec()
154 for (index = 0; index < 32; index++) { in qpci_secondary_buses_rec()
155 dev = qpci_device_find(qbus, QPCI_DEVFN(bus + index, 0)); in qpci_secondary_buses_rec()
156 if (dev == NULL) { in qpci_secondary_buses_rec()
159 class = qpci_config_readw(dev, PCI_CLASS_DEVICE); in qpci_secondary_buses_rec()
161 g_free(dev); in qpci_secondary_buses_rec()
165 pribus = qpci_config_readb(dev, PCI_PRIMARY_BUS); in qpci_secondary_buses_rec()
167 qpci_config_writeb(dev, PCI_PRIMARY_BUS, bus); in qpci_secondary_buses_rec()
170 secbus = qpci_config_readb(dev, PCI_SECONDARY_BUS); in qpci_secondary_buses_rec()
174 qpci_config_writeb(dev, PCI_SECONDARY_BUS, secbus); in qpci_secondary_buses_rec()
177 subbus = qpci_config_readb(dev, PCI_SUBORDINATE_BUS); in qpci_secondary_buses_rec()
178 qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 255); in qpci_secondary_buses_rec()
184 uint8_t cap = qpci_find_resource_reserve_capability(dev); in qpci_secondary_buses_rec()
189 tmp_res_bus = qpci_config_readl(dev, cap + in qpci_secondary_buses_rec()
191 if (tmp_res_bus != (uint32_t)-1) { in qpci_secondary_buses_rec()
192 res_bus = tmp_res_bus & 0xFF; in qpci_secondary_buses_rec()
195 res_bus = 0; in qpci_secondary_buses_rec()
206 qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, subbus); in qpci_secondary_buses_rec()
207 g_free(dev); in qpci_secondary_buses_rec()
213 int last_bus = 0; in qpci_secondary_buses_init()
215 qpci_secondary_buses_rec(bus, 0, &last_bus); in qpci_secondary_buses_init()
221 void qpci_device_enable(QPCIDevice *dev) in qpci_device_enable() argument
225 /* FIXME -- does this need to be a bus callout? */ in qpci_device_enable()
226 cmd = qpci_config_readw(dev, PCI_COMMAND); in qpci_device_enable()
228 qpci_config_writew(dev, PCI_COMMAND, cmd); in qpci_device_enable()
231 cmd = qpci_config_readw(dev, PCI_COMMAND); in qpci_device_enable()
239 * @dev: the PCI device
241 * @start_addr: 0 to begin iteration or the last return value to continue
247 * 0 if no further matching capability is found
249 uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr) in qpci_find_capability() argument
255 addr = qpci_config_readb(dev, start_addr + PCI_CAP_LIST_NEXT); in qpci_find_capability()
257 addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST); in qpci_find_capability()
261 cap = qpci_config_readb(dev, addr); in qpci_find_capability()
263 addr = qpci_config_readb(dev, addr + PCI_CAP_LIST_NEXT); in qpci_find_capability()
265 } while (cap != id && addr != 0); in qpci_find_capability()
270 void qpci_msix_enable(QPCIDevice *dev) in qpci_msix_enable() argument
278 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); in qpci_msix_enable()
279 g_assert_cmphex(addr, !=, 0); in qpci_msix_enable()
281 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); in qpci_msix_enable()
282 qpci_config_writew(dev, addr + PCI_MSIX_FLAGS, val | PCI_MSIX_FLAGS_ENABLE); in qpci_msix_enable()
284 table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE); in qpci_msix_enable()
286 dev->msix_table_bar = qpci_iomap(dev, bir_table, NULL); in qpci_msix_enable()
287 dev->msix_table_off = table & ~PCI_MSIX_FLAGS_BIRMASK; in qpci_msix_enable()
289 table = qpci_config_readl(dev, addr + PCI_MSIX_PBA); in qpci_msix_enable()
292 dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL); in qpci_msix_enable()
294 dev->msix_pba_bar = dev->msix_table_bar; in qpci_msix_enable()
296 dev->msix_pba_off = table & ~PCI_MSIX_FLAGS_BIRMASK; in qpci_msix_enable()
298 dev->msix_enabled = true; in qpci_msix_enable()
301 void qpci_msix_disable(QPCIDevice *dev) in qpci_msix_disable() argument
306 g_assert(dev->msix_enabled); in qpci_msix_disable()
307 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); in qpci_msix_disable()
308 g_assert_cmphex(addr, !=, 0); in qpci_msix_disable()
309 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); in qpci_msix_disable()
310 qpci_config_writew(dev, addr + PCI_MSIX_FLAGS, in qpci_msix_disable()
313 if (dev->msix_pba_bar.addr != dev->msix_table_bar.addr) { in qpci_msix_disable()
314 qpci_iounmap(dev, dev->msix_pba_bar); in qpci_msix_disable()
316 qpci_iounmap(dev, dev->msix_table_bar); in qpci_msix_disable()
318 dev->msix_enabled = 0; in qpci_msix_disable()
319 dev->msix_table_off = 0; in qpci_msix_disable()
320 dev->msix_pba_off = 0; in qpci_msix_disable()
323 bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry) in qpci_msix_pending() argument
329 g_assert(dev->msix_enabled); in qpci_msix_pending()
330 pba_entry = qpci_io_readl(dev, dev->msix_pba_bar, dev->msix_pba_off + off); in qpci_msix_pending()
331 return (pba_entry & (1 << bit_n)) != 0; in qpci_msix_pending()
334 bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry) in qpci_msix_masked() argument
338 uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE; in qpci_msix_masked()
340 g_assert(dev->msix_enabled); in qpci_msix_masked()
341 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); in qpci_msix_masked()
342 g_assert_cmphex(addr, !=, 0); in qpci_msix_masked()
343 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); in qpci_msix_masked()
348 return (qpci_io_readl(dev, dev->msix_table_bar, in qpci_msix_masked()
350 & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0; in qpci_msix_masked()
354 uint16_t qpci_msix_table_size(QPCIDevice *dev) in qpci_msix_table_size() argument
359 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0); in qpci_msix_table_size()
360 g_assert_cmphex(addr, !=, 0); in qpci_msix_table_size()
362 control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS); in qpci_msix_table_size()
366 uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset) in qpci_config_readb() argument
368 return dev->bus->config_readb(dev->bus, dev->devfn, offset); in qpci_config_readb()
371 uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset) in qpci_config_readw() argument
373 return dev->bus->config_readw(dev->bus, dev->devfn, offset); in qpci_config_readw()
376 uint32_t qpci_config_readl(QPCIDevice *dev, uint8_t offset) in qpci_config_readl() argument
378 return dev->bus->config_readl(dev->bus, dev->devfn, offset); in qpci_config_readl()
382 void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value) in qpci_config_writeb() argument
384 dev->bus->config_writeb(dev->bus, dev->devfn, offset, value); in qpci_config_writeb()
387 void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value) in qpci_config_writew() argument
389 dev->bus->config_writew(dev->bus, dev->devfn, offset, value); in qpci_config_writew()
392 void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value) in qpci_config_writel() argument
394 dev->bus->config_writel(dev->bus, dev->devfn, offset, value); in qpci_config_writel()
397 uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off) in qpci_io_readb() argument
399 QPCIBus *bus = dev->bus; in qpci_io_readb()
402 return bus->pio_readb(bus, token.addr + off); in qpci_io_readb()
406 bus->memread(dev->bus, token.addr + off, &val, sizeof(val)); in qpci_io_readb()
411 uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off) in qpci_io_readw() argument
413 QPCIBus *bus = dev->bus; in qpci_io_readw()
416 return bus->pio_readw(bus, token.addr + off); in qpci_io_readw()
420 bus->memread(bus, token.addr + off, &val, sizeof(val)); in qpci_io_readw()
425 uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off) in qpci_io_readl() argument
427 QPCIBus *bus = dev->bus; in qpci_io_readl()
430 return bus->pio_readl(bus, token.addr + off); in qpci_io_readl()
434 bus->memread(dev->bus, token.addr + off, &val, sizeof(val)); in qpci_io_readl()
439 uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off) in qpci_io_readq() argument
441 QPCIBus *bus = dev->bus; in qpci_io_readq()
444 return bus->pio_readq(bus, token.addr + off); in qpci_io_readq()
448 bus->memread(bus, token.addr + off, &val, sizeof(val)); in qpci_io_readq()
453 void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_io_writeb() argument
456 QPCIBus *bus = dev->bus; in qpci_io_writeb()
459 bus->pio_writeb(bus, token.addr + off, value); in qpci_io_writeb()
461 bus->memwrite(bus, token.addr + off, &value, sizeof(value)); in qpci_io_writeb()
465 void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_io_writew() argument
468 QPCIBus *bus = dev->bus; in qpci_io_writew()
471 bus->pio_writew(bus, token.addr + off, value); in qpci_io_writew()
474 bus->memwrite(bus, token.addr + off, &value, sizeof(value)); in qpci_io_writew()
478 void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_io_writel() argument
481 QPCIBus *bus = dev->bus; in qpci_io_writel()
484 bus->pio_writel(bus, token.addr + off, value); in qpci_io_writel()
487 bus->memwrite(bus, token.addr + off, &value, sizeof(value)); in qpci_io_writel()
491 void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_io_writeq() argument
494 QPCIBus *bus = dev->bus; in qpci_io_writeq()
497 bus->pio_writeq(bus, token.addr + off, value); in qpci_io_writeq()
500 bus->memwrite(bus, token.addr + off, &value, sizeof(value)); in qpci_io_writeq()
504 void qpci_memread(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_memread() argument
508 dev->bus->memread(dev->bus, token.addr + off, buf, len); in qpci_memread()
511 void qpci_memwrite(QPCIDevice *dev, QPCIBar token, uint64_t off, in qpci_memwrite() argument
515 dev->bus->memwrite(dev->bus, token.addr + off, buf, len); in qpci_memwrite()
518 QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr) in qpci_iomap() argument
520 QPCIBus *bus = dev->bus; in qpci_iomap()
531 g_assert(barno >= 0 && barno <= 5); in qpci_iomap()
534 qpci_config_writel(dev, bar_reg, 0xFFFFFFFF); in qpci_iomap()
535 addr = qpci_config_readl(dev, bar_reg); in qpci_iomap()
552 loc = QEMU_ALIGN_UP(bus->pio_alloc_ptr, size); in qpci_iomap()
554 g_assert(loc >= bus->pio_alloc_ptr); in qpci_iomap()
555 g_assert(loc + size <= bus->pio_limit); in qpci_iomap()
557 bus->pio_alloc_ptr = loc + size; in qpci_iomap()
560 qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO); in qpci_iomap()
562 loc = QEMU_ALIGN_UP(bus->mmio_alloc_ptr, size); in qpci_iomap()
565 g_assert(loc >= bus->mmio_alloc_ptr); in qpci_iomap()
566 g_assert(loc + size <= bus->mmio_limit); in qpci_iomap()
568 bus->mmio_alloc_ptr = loc + size; in qpci_iomap()
571 qpci_config_writel(dev, bar_reg, loc); in qpci_iomap()
578 void qpci_iounmap(QPCIDevice *dev, QPCIBar bar) in qpci_iounmap() argument
583 QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr) in qpci_legacy_iomap() argument
594 opts->arg = addr; in add_qpci_address()
595 opts->size_arg = sizeof(QPCIAddress); in add_qpci_address()