2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2014
7 * Ivan Kolchin <ivan.kolchin@siemens.com>
8 * Jan Kiszka <jan.kiszka@siemens.com>
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
14 #ifndef _JAILHOUSE_PCI_H
15 #define _JAILHOUSE_PCI_H
19 #define PCI_CFG_COMMAND 0x04
20 # define PCI_CMD_MEM (1 << 1)
21 # define PCI_CMD_MASTER (1 << 2)
22 # define PCI_CMD_INTX_OFF (1 << 10)
23 #define PCI_CFG_STATUS 0x06
24 # define PCI_STS_CAPS (1 << 4)
25 #define PCI_CFG_BAR 0x10
26 # define PCI_BAR_64BIT 0x4
27 #define PCI_CFG_BAR_END 0x27
28 #define PCI_CFG_ROMBAR 0x30
29 #define PCI_CFG_CAPS 0x34
30 #define PCI_CFG_INT 0x3c
32 #define PCI_CONFIG_HEADER_SIZE 0x40
34 #define PCI_NUM_BARS 6
36 #define PCI_DEV_CLASS_MEM 0x05
38 #define PCI_CAP_MSI 0x05
39 #define PCI_CAP_MSIX 0x11
41 #define PCI_IVSHMEM_NUM_MMIO_REGIONS 2
46 * @defgroup PCI PCI Subsystem
48 * The PCI subsystem provides access to PCI resources for the hypervisor and
49 * manages the cell's access to device configuration spaces and MSI-X tables.
50 * The subsystem depends on IOMMU services to configure DMA and interrupt
56 /** Extract PCI bus from BDF form. */
57 #define PCI_BUS(bdf) ((bdf) >> 8)
58 /** Extract PCI device/function from BDF form. */
59 #define PCI_DEVFN(bdf) ((bdf) & 0xff)
60 /** Extract PCI bus, device and function as parameter list from BDF form. */
61 #define PCI_BDF_PARAMS(bdf) (bdf) >> 8, ((bdf) >> 3) & 0x1f, (bdf) & 7
63 /** MSI-X vectors supported per device without extra allocation. */
64 #define PCI_EMBEDDED_MSIX_VECTS 16
67 * Access moderation return codes.
68 * See pci_cfg_read_moderate() and pci_cfg_write_moderate().
70 enum pci_access { PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM, PCI_ACCESS_DONE };
72 /** MSI config space registers. See PCI specification. */
73 union pci_msi_registers {
74 /** @privatesection */
83 } __attribute__((packed)) msg32;
85 u32 padding; /* use msg32 */
88 } __attribute__((packed)) msg64;
91 } __attribute__((packed));
93 /** MSI-X config space registers. See PCI specification. */
94 union pci_msix_registers {
95 /** @privatesection */
101 } __attribute__((packed));
103 /** @publicsection */
104 } __attribute__((packed));
106 /** MSI-X table entry. See PCI specification. */
107 union pci_msix_vector {
108 /** @privatesection */
114 } __attribute__((packed));
116 /** @publicsection */
117 } __attribute__((packed));
119 struct pci_ivshmem_endpoint;
125 /** Reference to static device configuration. */
126 const struct jailhouse_pci_device *info;
130 u32 bar[PCI_NUM_BARS];
132 /** Shadow state of MSI config space registers. */
133 union pci_msi_registers msi_registers;
135 /** Shadow state of MSI-X config space registers. */
136 union pci_msix_registers msix_registers;
137 /** Next PCI device in this cell with MSI-X support. */
138 struct pci_device *next_msix_device;
139 /** Next virtual PCI device in this cell. */
140 struct pci_device *next_virtual_device;
141 /** ivshmem specific data. */
142 struct pci_ivshmem_endpoint *ivshmem_endpoint;
143 /** Real MSI-X table. */
144 union pci_msix_vector *msix_table;
145 /** Shadow state of MSI-X table. */
146 union pci_msix_vector *msix_vectors;
147 /** Buffer for shadow table of up to PCI_EMBEDDED_MSIX_VECTS vectors. */
148 union pci_msix_vector msix_vector_array[PCI_EMBEDDED_MSIX_VECTS];
151 unsigned int pci_mmio_count_regions(struct cell *cell);
155 u32 pci_read_config(u16 bdf, u16 address, unsigned int size);
156 void pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size);
158 struct pci_device *pci_get_assigned_device(const struct cell *cell, u16 bdf);
160 enum pci_access pci_cfg_read_moderate(struct pci_device *device, u16 address,
161 unsigned int size, u32 *value);
162 enum pci_access pci_cfg_write_moderate(struct pci_device *device, u16 address,
163 unsigned int size, u32 value);
165 int pci_mmio_access_handler(const struct cell *cell, bool is_write, u64 addr,
168 int pci_cell_init(struct cell *cell);
169 void pci_cell_exit(struct cell *cell);
171 void pci_config_commit(struct cell *cell_added_removed);
173 unsigned int pci_enabled_msi_vectors(struct pci_device *device);
175 void pci_prepare_handover(void);
176 void pci_shutdown(void);
179 * Read from PCI config space via architecture-specific method.
180 * @param bdf 16-bit bus/device/function ID of target.
181 * @param address Config space access address.
182 * @param size Access size (1, 2 or 4 bytes).
184 * @return Read value.
186 * @see pci_read_config
187 * @see arch_pci_write_config
189 u32 arch_pci_read_config(u16 bdf, u16 address, unsigned int size);
192 * Write to PCI config space via architecture-specific method.
193 * @param bdf 16-bit bus/device/function ID of target.
194 * @param address Config space access address.
195 * @param value Value to be written.
196 * @param size Access size (1, 2 or 4 bytes).
198 * @see pci_write_config
199 * @see arch_pci_read_config
201 void arch_pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size);
204 * Perform architecture-specific steps on physical PCI device addition.
205 * @param cell Cell to which the device is added.
206 * @param device Device to be added.
208 * @return 0 on success, negative error code otherwise.
210 * @see arch_pci_remove_physical_device
212 int arch_pci_add_physical_device(struct cell *cell, struct pci_device *device);
215 * Perform architecture-specific steps on physical PCI device removal.
216 * @param device Device to be removed.
218 * @see arch_pci_add_physical_device
220 void arch_pci_remove_physical_device(struct pci_device *device);
223 * Avoid MSI vector delivery of a given device.
224 * @param device Device to be silenced.
225 * @param cap MSI capability of the device.
227 void arch_pci_suppress_msi(struct pci_device *device,
228 const struct jailhouse_pci_capability *cap);
231 * Update MSI vector mapping for a given device.
232 * @param device Device to be updated.
233 * @param cap MSI capability of the device.
235 * @return 0 on success, negative error code otherwise.
237 * @see arch_pci_update_msix_vector
239 int arch_pci_update_msi(struct pci_device *device,
240 const struct jailhouse_pci_capability *cap);
243 * Update MSI-X vector mapping for a given device and vector.
244 * @param device Device to be updated.
245 * @param index MSI-X vector number.
247 * @return 0 on success, negative error code otherwise.
249 * @see arch_pci_update_msi
251 int arch_pci_update_msix_vector(struct pci_device *device, unsigned int index);
254 * @defgroup PCI-IVSHMEM ivshmem
257 int pci_ivshmem_init(struct cell *cell, struct pci_device *device);
258 void pci_ivshmem_exit(struct pci_device *device);
259 int pci_ivshmem_update_msix(struct pci_device *device);
260 enum pci_access pci_ivshmem_cfg_write(struct pci_device *device,
261 unsigned int row, u32 mask, u32 value);
262 enum pci_access pci_ivshmem_cfg_read(struct pci_device *device, u16 address,
264 /** @} PCI-IVSHMEM */
266 #endif /* !_JAILHOUSE_PCI_H */