ia64/linux-2.6.18-xen.hg

view drivers/pci/msi.h @ 882:8dec4aa9b8b9

PCI pass through: PCIe IO space multiplexing

This is required for more than 16 HVM domain to boot from
PCIe pass through device.

Linux as dom0 exclusively assigns IO space to downstream PCI bridges
and the assignment unit of PCI bridge IO space is 4K. So the only up
to 16 PCIe device can be accessed via IO space within 64K IO ports.
PCI expansion ROM BIOS often uses IO port access to boot from the
device, so on virtualized environment, it means only up to 16 guest
domain can boot from pass-through device.

This patch allows PCIe IO space sharing of pass-through device.
- reassign IO space of PCIe devices specified by
"guestiomuldev=[<segment>:]<bus>:<dev>[,[<segment:><bus>:dev]][,...]"
to be shared.
This is implemented as Linux PCI quirk fixup.

The sharing unit is PCIe switch. Ie IO space of the end point
devices under the same switch will be shared. If there are more than
one switches, two areas of IO space will be used.

- And the driver which arbitrates the accesses to the multiplexed PCIe
IO space. Later qemu-dm will use this.

Limitation:
IO port of IO shared devices can't be accessed from dom0 Linux device
driver. But this wouldn't be a big issue because PCIe specification
discourages the use of IO space and recommends that IO space should be
used only for bootable device with ROM code. OS device driver should
work without IO space access.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 09:57:49 2009 +0100 (2009-05-28)
parents 268d6984c8e2
children
line source
1 /*
2 * Copyright (C) 2003-2004 Intel
3 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
4 */
6 #ifndef MSI_H
7 #define MSI_H
9 /*
10 * MSI operation vector. Used by the msi core code (drivers/pci/msi.c)
11 * to abstract platform-specific tasks relating to MSI address generation
12 * and resource management.
13 */
14 struct msi_ops {
15 /**
16 * setup - generate an MSI bus address and data for a given vector
17 * @pdev: PCI device context (in)
18 * @vector: vector allocated by the msi core (in)
19 * @addr_hi: upper 32 bits of PCI bus MSI address (out)
20 * @addr_lo: lower 32 bits of PCI bus MSI address (out)
21 * @data: MSI data payload (out)
22 *
23 * Description: The setup op is used to generate a PCI bus addres and
24 * data which the msi core will program into the card MSI capability
25 * registers. The setup routine is responsible for picking an initial
26 * cpu to target the MSI at. The setup routine is responsible for
27 * examining pdev to determine the MSI capabilities of the card and
28 * generating a suitable address/data. The setup routine is
29 * responsible for allocating and tracking any system resources it
30 * needs to route the MSI to the cpu it picks, and for associating
31 * those resources with the passed in vector.
32 *
33 * Returns 0 if the MSI address/data was successfully setup.
34 **/
36 int (*setup) (struct pci_dev *pdev, unsigned int vector,
37 u32 *addr_hi, u32 *addr_lo, u32 *data);
39 /**
40 * teardown - release resources allocated by setup
41 * @vector: vector context for resources (in)
42 *
43 * Description: The teardown op is used to release any resources
44 * that were allocated in the setup routine associated with the passed
45 * in vector.
46 **/
48 void (*teardown) (unsigned int vector);
50 /**
51 * target - retarget an MSI at a different cpu
52 * @vector: vector context for resources (in)
53 * @cpu: new cpu to direct vector at (in)
54 * @addr_hi: new value of PCI bus upper 32 bits (in/out)
55 * @addr_lo: new value of PCI bus lower 32 bits (in/out)
56 *
57 * Description: The target op is used to redirect an MSI vector
58 * at a different cpu. addr_hi/addr_lo coming in are the existing
59 * values that the MSI core has programmed into the card. The
60 * target code is responsible for freeing any resources (if any)
61 * associated with the old address, and generating a new PCI bus
62 * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
63 **/
65 void (*target) (unsigned int vector, unsigned int cpu,
66 u32 *addr_hi, u32 *addr_lo);
67 };
69 extern int msi_register(struct msi_ops *ops);
71 #include <asm/msi.h>
73 /*
74 * Assume the maximum number of hot plug slots supported by the system is about
75 * ten. The worstcase is that each of these slots is hot-added with a device,
76 * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
77 * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
78 * as below to ensure at least one message is assigned to each detected MSI/
79 * MSI-X device function.
80 */
81 #define NR_HP_RESERVED_VECTORS 20
83 extern int vector_irq[NR_VECTORS];
84 extern void (*interrupt[NR_IRQS])(void);
85 extern int pci_vector_resources(int last, int nr_released);
87 /*
88 * MSI-X Address Register
89 */
90 #define PCI_MSIX_FLAGS_QSIZE 0x7FF
91 #define PCI_MSIX_FLAGS_ENABLE (1 << 15)
92 #define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
93 #define PCI_MSIX_FLAGS_BITMASK (1 << 0)
95 #define PCI_MSIX_ENTRY_SIZE 16
96 #define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
97 #define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
98 #define PCI_MSIX_ENTRY_DATA_OFFSET 8
99 #define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
101 #define msi_control_reg(base) (base + PCI_MSI_FLAGS)
102 #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
103 #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI)
104 #define msi_data_reg(base, is64bit) \
105 ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
106 #define msi_mask_bits_reg(base, is64bit) \
107 ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
108 #define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE
109 #define multi_msi_capable(control) \
110 (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
111 #define multi_msi_enable(control, num) \
112 control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
113 #define is_64bit_address(control) (control & PCI_MSI_FLAGS_64BIT)
114 #define is_mask_bit_support(control) (control & PCI_MSI_FLAGS_MASKBIT)
115 #define msi_enable(control, num) multi_msi_enable(control, num); \
116 control |= PCI_MSI_FLAGS_ENABLE
118 #define msix_table_offset_reg(base) (base + 0x04)
119 #define msix_pba_offset_reg(base) (base + 0x08)
120 #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
121 #define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE
122 #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1)
123 #define multi_msix_capable msix_table_size
124 #define msix_unmask(address) (address & ~PCI_MSIX_FLAGS_BITMASK)
125 #define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
126 #define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
128 struct msi_desc {
129 struct {
130 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
131 __u8 maskbit : 1; /* mask-pending bit supported ? */
132 __u8 state : 1; /* {0: free, 1: busy} */
133 __u8 reserved: 1; /* reserved */
134 __u8 entry_nr; /* specific enabled entry */
135 __u8 default_vector; /* default pre-assigned vector */
136 __u8 unused; /* formerly unused destination cpu*/
137 }msi_attrib;
139 struct {
140 __u16 head;
141 __u16 tail;
142 }link;
144 void __iomem *mask_base;
145 struct pci_dev *dev;
147 #ifdef CONFIG_PM
148 /* PM save area for MSIX address/data */
150 u32 address_hi_save;
151 u32 address_lo_save;
152 u32 data_save;
153 #endif
154 };
156 #endif /* MSI_H */