]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/include/jailhouse/pci.h
f511d508a38548993a0def8b4e6093f7e338f8d0
[jailhouse.git] / hypervisor / include / jailhouse / pci.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2014
5  *
6  * Authors:
7  *  Ivan Kolchin <ivan.kolchin@siemens.com>
8  *  Jan Kiszka <jan.kiszka@siemens.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2.  See
11  * the COPYING file in the top-level directory.
12  */
13
14 #ifndef _JAILHOUSE_PCI_H
15 #define _JAILHOUSE_PCI_H
16
17 #include <asm/cell.h>
18
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
31
32 #define PCI_CONFIG_HEADER_SIZE  0x40
33
34 #define PCI_NUM_BARS            6
35
36 #define PCI_DEV_CLASS_MEM       0x05
37
38 #define PCI_CAP_MSI             0x05
39 #define PCI_CAP_MSIX            0x11
40
41 #define PCI_IVSHMEM_NUM_MMIO_REGIONS    2
42
43 struct cell;
44
45 /**
46  * @defgroup PCI PCI Subsystem
47  *
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
51  * mappings.
52  *
53  * @{
54  */
55
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
62
63 /** MSI-X vectors supported per device without extra allocation. */
64 #define PCI_EMBEDDED_MSIX_VECTS 16
65
66 /**
67  * Access moderation return codes.
68  * See pci_cfg_read_moderate() and pci_cfg_write_moderate().
69  */
70 enum pci_access { PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM, PCI_ACCESS_DONE };
71
72 /** MSI config space registers. See PCI specification. */
73 union pci_msi_registers {
74         /** @privatesection */
75         struct {
76                 u16 padding;
77                 u16 enable:1,
78                     ignore1:3,
79                     mme:3,
80                     ignore2:9;
81                 u32 address;
82                 u16 data;
83         } __attribute__((packed)) msg32;
84         struct {
85                 u32 padding; /* use msg32 */
86                 u64 address;
87                 u16 data;
88         } __attribute__((packed)) msg64;
89         u32 raw[4];
90         /** @publicsection */
91 } __attribute__((packed));
92
93 /** MSI-X config space registers. See PCI specification. */
94 union pci_msix_registers {
95         /** @privatesection */
96         struct {
97                 u16 padding;
98                 u16 ignore:14,
99                     fmask:1,
100                     enable:1;
101         } __attribute__((packed));
102         u32 raw;
103         /** @publicsection */
104 } __attribute__((packed));
105
106 /** MSI-X table entry. See PCI specification. */
107 union pci_msix_vector {
108         /** @privatesection */
109         struct {
110                 u64 address;
111                 u32 data;
112                 u32 masked:1;
113                 u32 reserved:31;
114         } __attribute__((packed));
115         u32 raw[4];
116         /** @publicsection */
117 } __attribute__((packed));
118
119 struct pci_ivshmem_endpoint;
120
121 /**
122  * PCI device state.
123  */
124 struct pci_device {
125         /** Reference to static device configuration. */
126         const struct jailhouse_pci_device *info;
127         /** Owning cell. */
128         struct cell *cell;
129         /** Shadow BAR */
130         u32 bar[PCI_NUM_BARS];
131
132         /** Shadow state of MSI config space registers. */
133         union pci_msi_registers msi_registers;
134
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];
149 };
150
151 unsigned int pci_mmio_count_regions(struct cell *cell);
152
153 int pci_init(void);
154
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);
157
158 struct pci_device *pci_get_assigned_device(const struct cell *cell, u16 bdf);
159
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);
164
165 int pci_mmio_access_handler(const struct cell *cell, bool is_write, u64 addr,
166                             u32 *value);
167
168 int pci_cell_init(struct cell *cell);
169 void pci_cell_exit(struct cell *cell);
170
171 void pci_config_commit(struct cell *cell_added_removed);
172
173 unsigned int pci_enabled_msi_vectors(struct pci_device *device);
174
175 void pci_prepare_handover(void);
176 void pci_shutdown(void);
177
178 /**
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).
183  *
184  * @return Read value.
185  *
186  * @see pci_read_config
187  * @see arch_pci_write_config
188  */
189 u32 arch_pci_read_config(u16 bdf, u16 address, unsigned int size);
190
191 /**
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).
197  *
198  * @see pci_write_config
199  * @see arch_pci_read_config
200  */
201 void arch_pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size);
202
203 /**
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.
207  *
208  * @return 0 on success, negative error code otherwise.
209  *
210  * @see arch_pci_remove_physical_device
211  */
212 int arch_pci_add_physical_device(struct cell *cell, struct pci_device *device);
213
214 /**
215  * Perform architecture-specific steps on physical PCI device removal.
216  * @param device        Device to be removed.
217  *
218  * @see arch_pci_add_physical_device
219  */
220 void arch_pci_remove_physical_device(struct pci_device *device);
221
222 /**
223  * Avoid MSI vector delivery of a given device.
224  * @param device        Device to be silenced.
225  * @param cap           MSI capability of the device.
226  */
227 void arch_pci_suppress_msi(struct pci_device *device,
228                            const struct jailhouse_pci_capability *cap);
229
230 /**
231  * Update MSI vector mapping for a given device.
232  * @param device        Device to be updated.
233  * @param cap           MSI capability of the device.
234  *
235  * @return 0 on success, negative error code otherwise.
236  *
237  * @see arch_pci_update_msix_vector
238  */
239 int arch_pci_update_msi(struct pci_device *device,
240                         const struct jailhouse_pci_capability *cap);
241
242 /**
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.
246  *
247  * @return 0 on success, negative error code otherwise.
248  *
249  * @see arch_pci_update_msi
250  */
251 int arch_pci_update_msix_vector(struct pci_device *device, unsigned int index);
252
253 /**
254  * @defgroup PCI-IVSHMEM ivshmem
255  * @{
256  */
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,
263                                      u32 *value);
264 /** @} PCI-IVSHMEM */
265 /** @} PCI */
266 #endif /* !_JAILHOUSE_PCI_H */