ia64/xen-unstable

view xen/arch/x86/msi.c @ 19800:78962f85c562

IOMMU: Add two generic functions to vendor neutral interface

Add 2 generic functions into the vendor neutral iommu interface, The
reason is that from changeset 19732, there is only one global flag
"iommu_enabled" that controls iommu enablement for both vtd and amd
systems, so we need different code paths for vtd and amd iommu systems
if this flag has been turned on. Also, the early checking of
"iommu_enabled" in iommu_setup() is removed to prevent iommu
functionalities from been disabled on amd systems.

Signed-off-by: Wei Wang <wei.wang2@amd.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 19 08:41:50 2009 +0100 (2009-06-19)
parents 931dbe86e5f3
children
line source
1 /*
2 * File: msi.c
3 * Purpose: PCI Message Signaled Interrupt (MSI)
4 *
5 * Copyright (C) 2003-2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
9 #include <xen/config.h>
10 #include <xen/lib.h>
11 #include <xen/init.h>
12 #include <xen/irq.h>
13 #include <xen/delay.h>
14 #include <xen/sched.h>
15 #include <xen/acpi.h>
16 #include <xen/errno.h>
17 #include <xen/pci.h>
18 #include <xen/pci_regs.h>
19 #include <xen/keyhandler.h>
20 #include <asm/io.h>
21 #include <asm/smp.h>
22 #include <asm/desc.h>
23 #include <asm/msi.h>
24 #include <asm/fixmap.h>
25 #include <mach_apic.h>
26 #include <io_ports.h>
27 #include <public/physdev.h>
28 #include <xen/iommu.h>
30 /* bitmap indicate which fixed map is free */
31 DEFINE_SPINLOCK(msix_fixmap_lock);
32 DECLARE_BITMAP(msix_fixmap_pages, FIX_MSIX_MAX_PAGES);
34 static int msix_fixmap_alloc(void)
35 {
36 int i, rc = -ENOMEM;
38 spin_lock(&msix_fixmap_lock);
39 for ( i = 0; i < FIX_MSIX_MAX_PAGES; i++ )
40 if ( !test_bit(i, &msix_fixmap_pages) )
41 break;
42 if ( i == FIX_MSIX_MAX_PAGES )
43 goto out;
44 rc = FIX_MSIX_IO_RESERV_BASE + i;
45 set_bit(i, &msix_fixmap_pages);
47 out:
48 spin_unlock(&msix_fixmap_lock);
49 return rc;
50 }
52 static void msix_fixmap_free(int idx)
53 {
54 spin_lock(&msix_fixmap_lock);
55 if ( idx >= FIX_MSIX_IO_RESERV_BASE )
56 clear_bit(idx - FIX_MSIX_IO_RESERV_BASE, &msix_fixmap_pages);
57 spin_unlock(&msix_fixmap_lock);
58 }
60 static int msix_get_fixmap(struct pci_dev *dev, unsigned long table_paddr,
61 unsigned long entry_paddr)
62 {
63 int nr_page, idx;
65 nr_page = (entry_paddr >> PAGE_SHIFT) - (table_paddr >> PAGE_SHIFT);
67 if ( nr_page < 0 || nr_page >= MAX_MSIX_TABLE_PAGES )
68 return -EINVAL;
70 spin_lock(&dev->msix_table_lock);
71 if ( dev->msix_table_refcnt[nr_page]++ == 0 )
72 {
73 idx = msix_fixmap_alloc();
74 if ( idx < 0 )
75 {
76 dev->msix_table_refcnt[nr_page]--;
77 goto out;
78 }
79 set_fixmap_nocache(idx, entry_paddr);
80 dev->msix_table_idx[nr_page] = idx;
81 }
82 else
83 idx = dev->msix_table_idx[nr_page];
85 out:
86 spin_unlock(&dev->msix_table_lock);
87 return idx;
88 }
90 static void msix_put_fixmap(struct pci_dev *dev, int idx)
91 {
92 int i;
93 unsigned long start;
95 spin_lock(&dev->msix_table_lock);
96 for ( i = 0; i < MAX_MSIX_TABLE_PAGES; i++ )
97 {
98 if ( dev->msix_table_idx[i] == idx )
99 break;
100 }
101 if ( i == MAX_MSIX_TABLE_PAGES )
102 goto out;
104 if ( --dev->msix_table_refcnt[i] == 0 )
105 {
106 start = fix_to_virt(idx);
107 destroy_xen_mappings(start, start + PAGE_SIZE);
108 msix_fixmap_free(idx);
109 dev->msix_table_idx[i] = 0;
110 }
112 out:
113 spin_unlock(&dev->msix_table_lock);
114 }
116 /*
117 * MSI message composition
118 */
119 void msi_compose_msg(struct pci_dev *pdev, int vector,
120 struct msi_msg *msg)
121 {
122 unsigned dest;
123 cpumask_t tmp;
125 tmp = TARGET_CPUS;
126 if ( vector )
127 {
128 dest = cpu_mask_to_apicid(tmp);
130 msg->address_hi = MSI_ADDR_BASE_HI;
131 msg->address_lo =
132 MSI_ADDR_BASE_LO |
133 ((INT_DEST_MODE == 0) ?
134 MSI_ADDR_DESTMODE_PHYS:
135 MSI_ADDR_DESTMODE_LOGIC) |
136 ((INT_DELIVERY_MODE != dest_LowestPrio) ?
137 MSI_ADDR_REDIRECTION_CPU:
138 MSI_ADDR_REDIRECTION_LOWPRI) |
139 MSI_ADDR_DEST_ID(dest);
141 msg->data =
142 MSI_DATA_TRIGGER_EDGE |
143 MSI_DATA_LEVEL_ASSERT |
144 ((INT_DELIVERY_MODE != dest_LowestPrio) ?
145 MSI_DATA_DELIVERY_FIXED:
146 MSI_DATA_DELIVERY_LOWPRI) |
147 MSI_DATA_VECTOR(vector);
148 }
149 }
151 static void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
152 {
153 switch ( entry->msi_attrib.type )
154 {
155 case PCI_CAP_ID_MSI:
156 {
157 struct pci_dev *dev = entry->dev;
158 int pos = entry->msi_attrib.pos;
159 u16 data;
160 u8 bus = dev->bus;
161 u8 slot = PCI_SLOT(dev->devfn);
162 u8 func = PCI_FUNC(dev->devfn);
164 msg->address_lo = pci_conf_read32(bus, slot, func,
165 msi_lower_address_reg(pos));
166 if ( entry->msi_attrib.is_64 )
167 {
168 msg->address_hi = pci_conf_read32(bus, slot, func,
169 msi_upper_address_reg(pos));
170 data = pci_conf_read16(bus, slot, func, msi_data_reg(pos, 1));
171 }
172 else
173 {
174 msg->address_hi = 0;
175 data = pci_conf_read16(bus, slot, func, msi_data_reg(pos, 0));
176 }
177 msg->data = data;
178 break;
179 }
180 case PCI_CAP_ID_MSIX:
181 {
182 void __iomem *base;
183 base = entry->mask_base;
185 msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
186 msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
187 msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
188 break;
189 }
190 default:
191 BUG();
192 }
194 if ( iommu_enabled )
195 iommu_read_msi_from_ire(entry, msg);
196 }
198 static int set_vector_msi(struct msi_desc *entry)
199 {
200 if ( entry->vector >= NR_VECTORS )
201 {
202 dprintk(XENLOG_ERR, "Trying to install msi data for Vector %d\n",
203 entry->vector);
204 return -EINVAL;
205 }
207 irq_desc[entry->vector].msi_desc = entry;
208 return 0;
209 }
211 static int unset_vector_msi(int vector)
212 {
213 ASSERT(spin_is_locked(&irq_desc[vector].lock));
215 if ( vector >= NR_VECTORS )
216 {
217 dprintk(XENLOG_ERR, "Trying to uninstall msi data for Vector %d\n",
218 vector);
219 return -EINVAL;
220 }
222 irq_desc[vector].msi_desc = NULL;
224 return 0;
225 }
227 static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
228 {
229 if ( iommu_enabled )
230 iommu_update_ire_from_msi(entry, msg);
232 switch ( entry->msi_attrib.type )
233 {
234 case PCI_CAP_ID_MSI:
235 {
236 struct pci_dev *dev = entry->dev;
237 int pos = entry->msi_attrib.pos;
238 u8 bus = dev->bus;
239 u8 slot = PCI_SLOT(dev->devfn);
240 u8 func = PCI_FUNC(dev->devfn);
242 pci_conf_write32(bus, slot, func, msi_lower_address_reg(pos),
243 msg->address_lo);
244 if ( entry->msi_attrib.is_64 )
245 {
246 pci_conf_write32(bus, slot, func, msi_upper_address_reg(pos),
247 msg->address_hi);
248 pci_conf_write16(bus, slot, func, msi_data_reg(pos, 1),
249 msg->data);
250 }
251 else
252 pci_conf_write16(bus, slot, func, msi_data_reg(pos, 0),
253 msg->data);
254 break;
255 }
256 case PCI_CAP_ID_MSIX:
257 {
258 void __iomem *base;
259 base = entry->mask_base;
261 writel(msg->address_lo,
262 base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
263 writel(msg->address_hi,
264 base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
265 writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
266 break;
267 }
268 default:
269 BUG();
270 }
271 entry->msg = *msg;
272 }
274 void set_msi_affinity(unsigned int vector, cpumask_t mask)
275 {
276 struct msi_desc *desc = irq_desc[vector].msi_desc;
277 struct msi_msg msg;
278 unsigned int dest;
280 memset(&msg, 0, sizeof(msg));
281 cpus_and(mask, mask, cpu_online_map);
282 if ( cpus_empty(mask) )
283 mask = TARGET_CPUS;
284 dest = cpu_mask_to_apicid(mask);
286 if ( !desc )
287 return;
289 ASSERT(spin_is_locked(&irq_desc[vector].lock));
290 read_msi_msg(desc, &msg);
292 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
293 msg.address_lo |= MSI_ADDR_DEST_ID(dest);
295 write_msi_msg(desc, &msg);
296 }
298 static void msi_set_enable(struct pci_dev *dev, int enable)
299 {
300 int pos;
301 u16 control;
302 u8 bus = dev->bus;
303 u8 slot = PCI_SLOT(dev->devfn);
304 u8 func = PCI_FUNC(dev->devfn);
306 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSI);
307 if ( pos )
308 {
309 control = pci_conf_read16(bus, slot, func, pos + PCI_MSI_FLAGS);
310 control &= ~PCI_MSI_FLAGS_ENABLE;
311 if ( enable )
312 control |= PCI_MSI_FLAGS_ENABLE;
313 pci_conf_write16(bus, slot, func, pos + PCI_MSI_FLAGS, control);
314 }
315 }
317 static void msix_set_enable(struct pci_dev *dev, int enable)
318 {
319 int pos;
320 u16 control;
321 u8 bus = dev->bus;
322 u8 slot = PCI_SLOT(dev->devfn);
323 u8 func = PCI_FUNC(dev->devfn);
325 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX);
326 if ( pos )
327 {
328 control = pci_conf_read16(bus, slot, func, pos + PCI_MSIX_FLAGS);
329 control &= ~PCI_MSIX_FLAGS_ENABLE;
330 if ( enable )
331 control |= PCI_MSIX_FLAGS_ENABLE;
332 pci_conf_write16(bus, slot, func, pos + PCI_MSIX_FLAGS, control);
333 }
334 }
336 static void msix_flush_writes(unsigned int vector)
337 {
338 struct msi_desc *entry = irq_desc[vector].msi_desc;
340 BUG_ON(!entry || !entry->dev);
341 switch (entry->msi_attrib.type) {
342 case PCI_CAP_ID_MSI:
343 /* nothing to do */
344 break;
345 case PCI_CAP_ID_MSIX:
346 {
347 int offset = PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
348 readl(entry->mask_base + offset);
349 break;
350 }
351 default:
352 BUG();
353 break;
354 }
355 }
357 int msi_maskable_irq(const struct msi_desc *entry)
358 {
359 BUG_ON(!entry);
360 return entry->msi_attrib.type != PCI_CAP_ID_MSI
361 || entry->msi_attrib.maskbit;
362 }
364 static void msi_set_mask_bit(unsigned int vector, int flag)
365 {
366 struct msi_desc *entry = irq_desc[vector].msi_desc;
368 ASSERT(spin_is_locked(&irq_desc[vector].lock));
369 BUG_ON(!entry || !entry->dev);
370 switch (entry->msi_attrib.type) {
371 case PCI_CAP_ID_MSI:
372 if (entry->msi_attrib.maskbit) {
373 int pos;
374 u32 mask_bits;
375 u8 bus = entry->dev->bus;
376 u8 slot = PCI_SLOT(entry->dev->devfn);
377 u8 func = PCI_FUNC(entry->dev->devfn);
379 pos = (long)entry->mask_base;
380 mask_bits = pci_conf_read32(bus, slot, func, pos);
381 mask_bits &= ~(1);
382 mask_bits |= flag;
383 pci_conf_write32(bus, slot, func, pos, mask_bits);
384 }
385 break;
386 case PCI_CAP_ID_MSIX:
387 {
388 int offset = PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
389 writel(flag, entry->mask_base + offset);
390 readl(entry->mask_base + offset);
391 break;
392 }
393 default:
394 BUG();
395 break;
396 }
397 entry->msi_attrib.masked = !!flag;
398 }
400 void mask_msi_vector(unsigned int vector)
401 {
402 msi_set_mask_bit(vector, 1);
403 msix_flush_writes(vector);
404 }
406 void unmask_msi_vector(unsigned int vector)
407 {
408 msi_set_mask_bit(vector, 0);
409 msix_flush_writes(vector);
410 }
412 static struct msi_desc* alloc_msi_entry(void)
413 {
414 struct msi_desc *entry;
416 entry = xmalloc(struct msi_desc);
417 if ( !entry )
418 return NULL;
420 INIT_LIST_HEAD(&entry->list);
421 entry->dev = NULL;
422 entry->remap_index = -1;
424 return entry;
425 }
427 int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
428 {
429 struct msi_msg msg;
431 msi_compose_msg(dev, desc->vector, &msg);
432 set_vector_msi(desc);
433 write_msi_msg(irq_desc[desc->vector].msi_desc, &msg);
435 return 0;
436 }
438 void teardown_msi_vector(int vector)
439 {
440 unset_vector_msi(vector);
441 }
443 int msi_free_vector(struct msi_desc *entry)
444 {
445 if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
446 {
447 unsigned long start;
449 writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
451 start = (unsigned long)entry->mask_base & ~(PAGE_SIZE - 1);
452 msix_put_fixmap(entry->dev, virt_to_fix(start));
453 }
454 list_del(&entry->list);
455 xfree(entry);
456 return 0;
457 }
459 static struct msi_desc *find_msi_entry(struct pci_dev *dev,
460 int vector, int cap_id)
461 {
462 struct msi_desc *entry;
464 list_for_each_entry( entry, &dev->msi_list, list )
465 {
466 if ( entry->msi_attrib.type == cap_id &&
467 (vector == -1 || entry->vector == vector) )
468 return entry;
469 }
471 return NULL;
472 }
474 /**
475 * msi_capability_init - configure device's MSI capability structure
476 * @dev: pointer to the pci_dev data structure of MSI device function
477 *
478 * Setup the MSI capability structure of device function with a single
479 * MSI irq, regardless of device function is capable of handling
480 * multiple messages. A return of zero indicates the successful setup
481 * of an entry zero with the new MSI irq or non-zero for otherwise.
482 **/
483 static int msi_capability_init(struct pci_dev *dev,
484 int vector,
485 struct msi_desc **desc)
486 {
487 struct msi_desc *entry;
488 int pos;
489 u16 control;
490 u8 bus = dev->bus;
491 u8 slot = PCI_SLOT(dev->devfn);
492 u8 func = PCI_FUNC(dev->devfn);
494 ASSERT(spin_is_locked(&pcidevs_lock));
495 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSI);
496 control = pci_conf_read16(bus, slot, func, msi_control_reg(pos));
497 /* MSI Entry Initialization */
498 msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
500 entry = alloc_msi_entry();
501 if ( !entry )
502 return -ENOMEM;
504 entry->msi_attrib.type = PCI_CAP_ID_MSI;
505 entry->msi_attrib.is_64 = is_64bit_address(control);
506 entry->msi_attrib.entry_nr = 0;
507 entry->msi_attrib.maskbit = is_mask_bit_support(control);
508 entry->msi_attrib.masked = 1;
509 entry->msi_attrib.pos = pos;
510 entry->vector = vector;
511 if ( is_mask_bit_support(control) )
512 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
513 is_64bit_address(control));
514 entry->dev = dev;
515 if ( entry->msi_attrib.maskbit )
516 {
517 unsigned int maskbits, temp;
518 /* All MSIs are unmasked by default, Mask them all */
519 maskbits = pci_conf_read32(bus, slot, func,
520 msi_mask_bits_reg(pos, is_64bit_address(control)));
521 temp = (1 << multi_msi_capable(control));
522 temp = ((temp - 1) & ~temp);
523 maskbits |= temp;
524 pci_conf_write32(bus, slot, func,
525 msi_mask_bits_reg(pos, is_64bit_address(control)),
526 maskbits);
527 }
528 list_add_tail(&entry->list, &dev->msi_list);
530 *desc = entry;
531 /* Restore the original MSI enabled bits */
532 pci_conf_write16(bus, slot, func, msi_control_reg(pos), control);
534 return 0;
535 }
537 /**
538 * msix_capability_init - configure device's MSI-X capability
539 * @dev: pointer to the pci_dev data structure of MSI-X device function
540 * @entries: pointer to an array of struct msix_entry entries
541 * @nvec: number of @entries
542 *
543 * Setup the MSI-X capability structure of device function with a
544 * single MSI-X irq. A return of zero indicates the successful setup of
545 * requested MSI-X entries with allocated irqs or non-zero for otherwise.
546 **/
547 static int msix_capability_init(struct pci_dev *dev,
548 struct msi_info *msi,
549 struct msi_desc **desc)
550 {
551 struct msi_desc *entry;
552 int pos;
553 u16 control;
554 unsigned long table_paddr, entry_paddr;
555 u32 table_offset, entry_offset;
556 u8 bir;
557 void __iomem *base;
558 int idx;
559 u8 bus = dev->bus;
560 u8 slot = PCI_SLOT(dev->devfn);
561 u8 func = PCI_FUNC(dev->devfn);
563 ASSERT(spin_is_locked(&pcidevs_lock));
564 ASSERT(desc);
566 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX);
567 control = pci_conf_read16(bus, slot, func, msix_control_reg(pos));
568 msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
570 /* MSI-X Table Initialization */
571 entry = alloc_msi_entry();
572 if ( !entry )
573 return -ENOMEM;
575 /* Request & Map MSI-X table region */
576 table_offset = pci_conf_read32(bus, slot, func, msix_table_offset_reg(pos));
577 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
578 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
579 entry_offset = msi->entry_nr * PCI_MSIX_ENTRY_SIZE;
581 table_paddr = msi->table_base + table_offset;
582 entry_paddr = table_paddr + entry_offset;
583 idx = msix_get_fixmap(dev, table_paddr, entry_paddr);
584 if ( idx < 0 )
585 {
586 xfree(entry);
587 return idx;
588 }
589 base = (void *)(fix_to_virt(idx) + (entry_paddr & ((1UL << PAGE_SHIFT) - 1)));
591 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
592 entry->msi_attrib.is_64 = 1;
593 entry->msi_attrib.entry_nr = msi->entry_nr;
594 entry->msi_attrib.maskbit = 1;
595 entry->msi_attrib.masked = 1;
596 entry->msi_attrib.pos = pos;
597 entry->vector = msi->vector;
598 entry->dev = dev;
599 entry->mask_base = base;
601 list_add_tail(&entry->list, &dev->msi_list);
603 /* Mask interrupt here */
604 writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
606 *desc = entry;
607 /* Restore MSI-X enabled bits */
608 pci_conf_write16(bus, slot, func, msix_control_reg(pos), control);
610 return 0;
611 }
613 /**
614 * pci_enable_msi - configure device's MSI capability structure
615 * @dev: pointer to the pci_dev data structure of MSI device function
616 *
617 * Setup the MSI capability structure of device function with
618 * a single MSI irq upon its software driver call to request for
619 * MSI mode enabled on its hardware device function. A return of zero
620 * indicates the successful setup of an entry zero with the new MSI
621 * irq or non-zero for otherwise.
622 **/
623 static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
624 {
625 int status;
626 struct pci_dev *pdev;
628 ASSERT(spin_is_locked(&pcidevs_lock));
629 pdev = pci_get_pdev(msi->bus, msi->devfn);
630 if ( !pdev )
631 return -ENODEV;
633 if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSI) )
634 {
635 dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on "
636 "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
637 PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
638 return 0;
639 }
641 status = msi_capability_init(pdev, msi->vector, desc);
642 return status;
643 }
645 static void __pci_disable_msi(struct msi_desc *entry)
646 {
647 struct pci_dev *dev;
648 int pos;
649 u16 control;
650 u8 bus, slot, func;
652 dev = entry->dev;
653 bus = dev->bus;
654 slot = PCI_SLOT(dev->devfn);
655 func = PCI_FUNC(dev->devfn);
657 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSI);
658 control = pci_conf_read16(bus, slot, func, msi_control_reg(pos));
659 msi_set_enable(dev, 0);
661 BUG_ON(list_empty(&dev->msi_list));
663 }
665 /**
666 * pci_enable_msix - configure device's MSI-X capability structure
667 * @dev: pointer to the pci_dev data structure of MSI-X device function
668 * @entries: pointer to an array of MSI-X entries
669 * @nvec: number of MSI-X irqs requested for allocation by device driver
670 *
671 * Setup the MSI-X capability structure of device function with the number
672 * of requested irqs upon its software driver call to request for
673 * MSI-X mode enabled on its hardware device function. A return of zero
674 * indicates the successful configuration of MSI-X capability structure
675 * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
676 * Or a return of > 0 indicates that driver request is exceeding the number
677 * of irqs available. Driver should use the returned value to re-send
678 * its request.
679 **/
680 static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
681 {
682 int status, pos, nr_entries;
683 struct pci_dev *pdev;
684 u16 control;
685 u8 slot = PCI_SLOT(msi->devfn);
686 u8 func = PCI_FUNC(msi->devfn);
688 ASSERT(spin_is_locked(&pcidevs_lock));
689 pdev = pci_get_pdev(msi->bus, msi->devfn);
690 if ( !pdev )
691 return -ENODEV;
693 pos = pci_find_cap_offset(msi->bus, slot, func, PCI_CAP_ID_MSIX);
694 control = pci_conf_read16(msi->bus, slot, func, msi_control_reg(pos));
695 nr_entries = multi_msix_capable(control);
696 if (msi->entry_nr >= nr_entries)
697 return -EINVAL;
699 if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSIX) )
700 {
701 dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on "
702 "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
703 PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
704 return 0;
705 }
707 status = msix_capability_init(pdev, msi, desc);
708 return status;
709 }
711 static void __pci_disable_msix(struct msi_desc *entry)
712 {
713 struct pci_dev *dev;
714 int pos;
715 u16 control;
716 u8 bus, slot, func;
718 dev = entry->dev;
719 bus = dev->bus;
720 slot = PCI_SLOT(dev->devfn);
721 func = PCI_FUNC(dev->devfn);
723 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX);
724 control = pci_conf_read16(bus, slot, func, msix_control_reg(pos));
725 msix_set_enable(dev, 0);
727 BUG_ON(list_empty(&dev->msi_list));
729 writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
731 pci_conf_write16(bus, slot, func, msix_control_reg(pos), control);
732 }
734 /*
735 * Notice: only construct the msi_desc
736 * no change to irq_desc here, and the interrupt is masked
737 */
738 int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
739 {
740 ASSERT(spin_is_locked(&pcidevs_lock));
742 return msi->table_base ? __pci_enable_msix(msi, desc) :
743 __pci_enable_msi(msi, desc);
744 }
746 /*
747 * Device only, no irq_desc
748 */
749 void pci_disable_msi(struct msi_desc *msi_desc)
750 {
751 if ( msi_desc->msi_attrib.type == PCI_CAP_ID_MSI )
752 __pci_disable_msi(msi_desc);
753 else if ( msi_desc->msi_attrib.type == PCI_CAP_ID_MSIX )
754 __pci_disable_msix(msi_desc);
755 }
757 static void msi_free_vectors(struct pci_dev* dev)
758 {
759 struct msi_desc *entry, *tmp;
760 irq_desc_t *desc;
761 unsigned long flags, vector;
763 list_for_each_entry_safe( entry, tmp, &dev->msi_list, list )
764 {
765 vector = entry->vector;
766 desc = &irq_desc[vector];
767 pci_disable_msi(entry);
769 spin_lock_irqsave(&desc->lock, flags);
771 teardown_msi_vector(vector);
773 if ( desc->handler == &pci_msi_type )
774 {
775 /* MSI is not shared, so should be released already */
776 BUG_ON(desc->status & IRQ_GUEST);
777 desc->handler = &no_irq_type;
778 }
780 spin_unlock_irqrestore(&desc->lock, flags);
781 msi_free_vector(entry);
782 }
783 }
785 void pci_cleanup_msi(struct pci_dev *pdev)
786 {
787 /* Disable MSI and/or MSI-X */
788 msi_set_enable(pdev, 0);
789 msix_set_enable(pdev, 0);
790 msi_free_vectors(pdev);
791 }
793 int pci_restore_msi_state(struct pci_dev *pdev)
794 {
795 unsigned long flags;
796 int vector;
797 struct msi_desc *entry, *tmp;
798 irq_desc_t *desc;
800 ASSERT(spin_is_locked(&pcidevs_lock));
802 if (!pdev)
803 return -EINVAL;
805 list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list )
806 {
807 vector = entry->vector;
808 desc = &irq_desc[vector];
810 spin_lock_irqsave(&desc->lock, flags);
812 ASSERT(desc->msi_desc == entry);
814 if (desc->msi_desc != entry)
815 {
816 dprintk(XENLOG_ERR, "Restore MSI for dev %x:%x not set before?\n",
817 pdev->bus, pdev->devfn);
818 spin_unlock_irqrestore(&desc->lock, flags);
819 return -EINVAL;
820 }
822 if ( entry->msi_attrib.type == PCI_CAP_ID_MSI )
823 msi_set_enable(pdev, 0);
824 else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
825 msix_set_enable(pdev, 0);
827 write_msi_msg(entry, &entry->msg);
829 msi_set_mask_bit(vector, entry->msi_attrib.masked);
831 if ( entry->msi_attrib.type == PCI_CAP_ID_MSI )
832 msi_set_enable(pdev, 1);
833 else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
834 msix_set_enable(pdev, 1);
836 spin_unlock_irqrestore(&desc->lock, flags);
837 }
839 return 0;
840 }
842 unsigned int pci_msix_get_table_len(struct pci_dev *pdev)
843 {
844 int pos;
845 u16 control;
846 u8 bus, slot, func;
847 unsigned int len;
849 bus = pdev->bus;
850 slot = PCI_SLOT(pdev->devfn);
851 func = PCI_FUNC(pdev->devfn);
853 pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX);
854 if ( !pos )
855 return 0;
857 control = pci_conf_read16(bus, slot, func, msix_control_reg(pos));
858 len = msix_table_size(control) * PCI_MSIX_ENTRY_SIZE;
860 return len;
861 }