Lines Matching +full:flags +full:- +full:mask
42 * Flag for interrupt controllers to declare broken MSI/MSI-X support.
43 * values: false - broken; true - non-broken.
45 * Setting this flag to false will remove MSI/MSI-X capability from all devices.
47 * It is preferable for controllers to set this to true (non-broken) even if
48 * they do not actually support MSI/MSI-X: guests normally probe the controller
49 * type and do not attempt to enable MSI/MSI-X with interrupt controllers not
58 static inline uint8_t msi_cap_sizeof(uint16_t flags) in msi_cap_sizeof() argument
60 switch (flags & (PCI_MSI_FLAGS_MASKBIT | PCI_MSI_FLAGS_64BIT)) { in msi_cap_sizeof()
85 MSI_DPRINTF("%s:%x " fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
87 static inline unsigned int msi_nr_vectors(uint16_t flags) in msi_nr_vectors() argument
90 ((flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE)); in msi_nr_vectors()
95 return dev->msi_cap + PCI_MSI_FLAGS; in msi_flags_off()
100 return dev->msi_cap + PCI_MSI_ADDRESS_LO; in msi_address_lo_off()
105 return dev->msi_cap + PCI_MSI_ADDRESS_HI; in msi_address_hi_off()
110 return dev->msi_cap + (msi64bit ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32); in msi_data_off()
115 return dev->msi_cap + (msi64bit ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32); in msi_mask_off()
120 return dev->msi_cap + (msi64bit ? PCI_MSI_PENDING_64 : PCI_MSI_PENDING_32); in msi_pending_off()
129 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_set_message() local
130 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_set_message()
133 pci_set_quad(dev->config + msi_address_lo_off(dev), msg.address); in msi_set_message()
135 pci_set_long(dev->config + msi_address_lo_off(dev), msg.address); in msi_set_message()
137 pci_set_word(dev->config + msi_data_off(dev, msi64bit), msg.data); in msi_set_message()
142 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_prepare_message() local
143 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_prepare_message()
144 unsigned int nr_vectors = msi_nr_vectors(flags); in msi_prepare_message()
150 msg.address = pci_get_quad(dev->config + msi_address_lo_off(dev)); in msi_prepare_message()
152 msg.address = pci_get_long(dev->config + msi_address_lo_off(dev)); in msi_prepare_message()
156 msg.data = pci_get_word(dev->config + msi_data_off(dev, msi64bit)); in msi_prepare_message()
158 msg.data &= ~(nr_vectors - 1); in msi_prepare_message()
167 return dev->msi_prepare_message(dev, vector); in msi_get_message()
173 (pci_get_word(dev->config + msi_flags_off(dev)) & in msi_enabled()
178 * Make PCI device @dev MSI-capable.
179 * Non-zero @offset puts capability MSI at that offset in PCI config
182 * If @msi64bit, make the device capable of sending a 64-bit message
184 * If @msi_per_vector_mask, make the device support per-vector masking.
186 * Return 0 on success; set @errp and return -errno on error.
188 * -ENOTSUP means lacking msi support for a msi-capable platform.
189 * -EINVAL means capability overlap, happens when @offset is non-zero,
198 uint16_t flags; in msi_init() local
204 return -ENOTSUP; in msi_init()
209 " 64bit %d mask %d\n", in msi_init()
212 assert(!(nr_vectors & (nr_vectors - 1))); /* power of 2 */ in msi_init()
218 flags = vectors_order << ctz32(PCI_MSI_FLAGS_QMASK); in msi_init()
220 flags |= PCI_MSI_FLAGS_64BIT; in msi_init()
223 flags |= PCI_MSI_FLAGS_MASKBIT; in msi_init()
226 cap_size = msi_cap_sizeof(flags); in msi_init()
233 dev->msi_cap = config_offset; in msi_init()
234 dev->cap_present |= QEMU_PCI_CAP_MSI; in msi_init()
236 pci_set_word(dev->config + msi_flags_off(dev), flags); in msi_init()
237 pci_set_word(dev->wmask + msi_flags_off(dev), in msi_init()
239 pci_set_long(dev->wmask + msi_address_lo_off(dev), in msi_init()
242 pci_set_long(dev->wmask + msi_address_hi_off(dev), 0xffffffff); in msi_init()
244 pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff); in msi_init()
247 /* Make mask bits 0 to nr_vectors - 1 writable. */ in msi_init()
248 pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit), in msi_init()
249 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors)); in msi_init()
252 dev->msi_prepare_message = msi_prepare_message; in msi_init()
259 uint16_t flags; in msi_uninit() local
265 flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_uninit()
266 cap_size = msi_cap_sizeof(flags); in msi_uninit()
268 dev->cap_present &= ~QEMU_PCI_CAP_MSI; in msi_uninit()
269 dev->msi_prepare_message = NULL; in msi_uninit()
276 uint16_t flags; in msi_reset() local
283 flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_reset()
284 flags &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); in msi_reset()
285 msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_reset()
287 pci_set_word(dev->config + msi_flags_off(dev), flags); in msi_reset()
288 pci_set_long(dev->config + msi_address_lo_off(dev), 0); in msi_reset()
290 pci_set_long(dev->config + msi_address_hi_off(dev), 0); in msi_reset()
292 pci_set_word(dev->config + msi_data_off(dev, msi64bit), 0); in msi_reset()
293 if (flags & PCI_MSI_FLAGS_MASKBIT) { in msi_reset()
294 pci_set_long(dev->config + msi_mask_off(dev, msi64bit), 0); in msi_reset()
295 pci_set_long(dev->config + msi_pending_off(dev, msi64bit), 0); in msi_reset()
302 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_is_masked() local
303 uint32_t mask, data; in msi_is_masked() local
304 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_is_masked()
307 if (!(flags & PCI_MSI_FLAGS_MASKBIT)) { in msi_is_masked()
311 data = pci_get_word(dev->config + msi_data_off(dev, msi64bit)); in msi_is_masked()
316 mask = pci_get_long(dev->config + in msi_is_masked()
317 msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT)); in msi_is_masked()
318 return mask & (1U << vector); in msi_is_masked()
321 void msi_set_mask(PCIDevice *dev, int vector, bool mask, Error **errp) in msi_set_mask() argument
323 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_set_mask() local
324 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_set_mask()
329 vector, (PCI_MSI_VECTORS_MAX - 1)); in msi_set_mask()
335 irq_state = pci_get_long(dev->config + msi_mask_off(dev, msi64bit)); in msi_set_mask()
337 if (mask) { in msi_set_mask()
343 pci_set_long(dev->config + msi_mask_off(dev, msi64bit), irq_state); in msi_set_mask()
345 pending = pci_get_long(dev->config + msi_pending_off(dev, msi64bit)); in msi_set_mask()
346 if (!mask && (pending & vector_mask)) { in msi_set_mask()
348 pci_set_long(dev->config + msi_pending_off(dev, msi64bit), pending); in msi_set_mask()
355 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_notify() local
356 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_notify()
357 unsigned int nr_vectors = msi_nr_vectors(flags); in msi_notify()
362 assert(flags & PCI_MSI_FLAGS_MASKBIT); in msi_notify()
364 dev->config + msi_pending_off(dev, msi64bit), 1U << vector); in msi_notify()
380 dev->msi_trigger(dev, msg); in msi_send_message()
386 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_write_config() local
387 bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; in msi_write_config()
388 bool msi_per_vector_mask = flags & PCI_MSI_FLAGS_MASKBIT; in msi_write_config()
396 !ranges_overlap(addr, len, dev->msi_cap, msi_cap_sizeof(flags))) { in msi_write_config()
404 flags, in msi_write_config()
405 pci_get_long(dev->config + msi_address_lo_off(dev))); in msi_write_config()
407 fprintf(stderr, " address-hi: 0x%"PRIx32, in msi_write_config()
408 pci_get_long(dev->config + msi_address_hi_off(dev))); in msi_write_config()
411 pci_get_word(dev->config + msi_data_off(dev, msi64bit))); in msi_write_config()
412 if (flags & PCI_MSI_FLAGS_MASKBIT) { in msi_write_config()
413 fprintf(stderr, " mask 0x%"PRIx32" pending 0x%"PRIx32, in msi_write_config()
414 pci_get_long(dev->config + msi_mask_off(dev, msi64bit)), in msi_write_config()
415 pci_get_long(dev->config + msi_pending_off(dev, msi64bit))); in msi_write_config()
421 for (vector = 0; vector < msi_nr_vectors(flags); vector++) { in msi_write_config()
429 if (!(flags & PCI_MSI_FLAGS_ENABLE)) { in msi_write_config()
435 * the driver is prohibited from writing enable bit to mask in msi_write_config()
440 * While enabled for MSI or MSI-X operation, a function is prohibited in msi_write_config()
442 * service (MSI, MSI-X, and INTx# are mutually exclusive). in msi_write_config()
452 (flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE); in msi_write_config()
454 (flags & PCI_MSI_FLAGS_QMASK) >> ctz32(PCI_MSI_FLAGS_QMASK); in msi_write_config()
456 flags &= ~PCI_MSI_FLAGS_QSIZE; in msi_write_config()
457 flags |= log_max_vecs << ctz32(PCI_MSI_FLAGS_QSIZE); in msi_write_config()
458 pci_set_word(dev->config + msi_flags_off(dev), flags); in msi_write_config()
467 nr_vectors = msi_nr_vectors(flags); in msi_write_config()
470 pending = pci_get_long(dev->config + msi_pending_off(dev, msi64bit)); in msi_write_config()
471 pending &= 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors); in msi_write_config()
472 pci_set_long(dev->config + msi_pending_off(dev, msi64bit), pending); in msi_write_config()
481 dev->config + msi_pending_off(dev, msi64bit), 1U << vector); in msi_write_config()
488 uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); in msi_nr_vectors_allocated() local
489 return msi_nr_vectors(flags); in msi_nr_vectors_allocated()