]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/gic_v3_var.h
Merge ^/head r295351 through r295543.
[FreeBSD/FreeBSD.git] / sys / arm64 / arm64 / gic_v3_var.h
1 /*-
2  * Copyright (c) 2015 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Semihalf under
6  * the sponsorship of the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #ifndef _GIC_V3_VAR_H_
33 #define _GIC_V3_VAR_H_
34
35 #define GIC_V3_DEVSTR   "ARM Generic Interrupt Controller v3.0"
36
37 DECLARE_CLASS(gic_v3_driver);
38
39 #define LPI_FLAGS_CONF_FLUSH    (1UL << 0)
40 #define LPI_CONFTAB_SIZE        PAGE_SIZE_64K
41 /* 1 bit per LPI + 1 KB more for the obligatory PPI, SGI, SPI stuff */
42 #define LPI_PENDTAB_SIZE        ((LPI_CONFTAB_SIZE / 8) + 0x400)
43
44 struct redist_lpis {
45         vm_offset_t             conf_base;
46         vm_offset_t             pend_base[MAXCPU];
47         uint64_t                flags;
48 };
49
50 struct gic_redists {
51         /*
52          * Re-Distributor region description.
53          * We will have few of those depending
54          * on the #redistributor-regions property in FDT.
55          */
56         struct resource **      regions;
57         /* Number of Re-Distributor regions */
58         u_int                   nregions;
59         /* Per-CPU Re-Distributor handler */
60         struct resource *       pcpu[MAXCPU];
61         /* LPIs data */
62         struct redist_lpis      lpis;
63 };
64
65 struct gic_v3_softc {
66         device_t                dev;
67         struct resource **      gic_res;
68         struct mtx              gic_mtx;
69         /* Distributor */
70         struct resource *       gic_dist;
71         /* Re-Distributors */
72         struct gic_redists      gic_redists;
73
74         u_int                   gic_nirqs;
75         u_int                   gic_idbits;
76
77         boolean_t               gic_registered;
78 };
79
80 MALLOC_DECLARE(M_GIC_V3);
81
82 /* Device methods */
83 int gic_v3_attach(device_t dev);
84 int gic_v3_detach(device_t dev);
85
86 /*
87  * ITS
88  */
89 #define GIC_V3_ITS_DEVSTR       "ARM GIC Interrupt Translation Service"
90 #define GIC_V3_ITS_COMPSTR      "arm,gic-v3-its"
91
92 DECLARE_CLASS(gic_v3_its_driver);
93
94 /* LPI chunk owned by ITS device */
95 struct lpi_chunk {
96         u_int   lpi_base;
97         u_int   lpi_num;
98         u_int   lpi_free;       /* First free LPI in set */
99         u_int   *lpi_col_ids;
100 };
101
102 /* ITS device */
103 struct its_dev {
104         TAILQ_ENTRY(its_dev)    entry;
105         /* PCI device */
106         device_t                pci_dev;
107         /* Device ID (i.e. PCI device ID) */
108         uint32_t                devid;
109         /* List of assigned LPIs */
110         struct lpi_chunk        lpis;
111         /* Virtual address of ITT */
112         vm_offset_t             itt;
113 };
114 TAILQ_HEAD(its_dev_list, its_dev);
115
116 /* ITS private table description */
117 struct its_ptab {
118         vm_offset_t     ptab_vaddr;     /* Virtual Address of table */
119         size_t          ptab_pgsz;      /* Page size */
120         size_t          ptab_npages;    /* Number of pages */
121 };
122
123 /* ITS collection description. */
124 struct its_col {
125         uint64_t        col_target;     /* Target Re-Distributor */
126         uint64_t        col_id;         /* Collection ID */
127 };
128
129 /* ITS command. Each command is 32 bytes long */
130 struct its_cmd {
131         uint64_t        cmd_dword[4];   /* ITS command double word */
132 };
133
134 /* ITS commands encoding */
135 #define ITS_CMD_MOVI            (0x01)
136 #define ITS_CMD_SYNC            (0x05)
137 #define ITS_CMD_MAPD            (0x08)
138 #define ITS_CMD_MAPC            (0x09)
139 #define ITS_CMD_MAPVI           (0x0a)
140 #define ITS_CMD_MAPI            (0x0b)
141 #define ITS_CMD_INV             (0x0c)
142 #define ITS_CMD_INVALL          (0x0d)
143 /* Command */
144 #define CMD_COMMAND_MASK        (0xFFUL)
145 /* PCI device ID */
146 #define CMD_DEVID_SHIFT         (32)
147 #define CMD_DEVID_MASK          (0xFFFFFFFFUL << CMD_DEVID_SHIFT)
148 /* Size of IRQ ID bitfield */
149 #define CMD_SIZE_MASK           (0xFFUL)
150 /* Virtual LPI ID */
151 #define CMD_ID_MASK             (0xFFFFFFFFUL)
152 /* Physical LPI ID */
153 #define CMD_PID_SHIFT           (32)
154 #define CMD_PID_MASK            (0xFFFFFFFFUL << CMD_PID_SHIFT)
155 /* Collection */
156 #define CMD_COL_MASK            (0xFFFFUL)
157 /* Target (CPU or Re-Distributor) */
158 #define CMD_TARGET_SHIFT        (16)
159 #define CMD_TARGET_MASK         (0xFFFFFFFFUL << CMD_TARGET_SHIFT)
160 /* Interrupt Translation Table address */
161 #define CMD_ITT_MASK            (0xFFFFFFFFFF00UL)
162 /* Valid command bit */
163 #define CMD_VALID_SHIFT         (63)
164 #define CMD_VALID_MASK          (1UL << CMD_VALID_SHIFT)
165
166 /*
167  * ITS command descriptor.
168  * Idea for command description passing taken from Linux.
169  */
170 struct its_cmd_desc {
171         uint8_t cmd_type;
172
173         union {
174                 struct {
175                         struct its_dev *its_dev;
176                         struct its_col *col;
177                         uint32_t id;
178                 } cmd_desc_movi;
179
180                 struct {
181                         struct its_col *col;
182                 } cmd_desc_sync;
183
184                 struct {
185                         struct its_col *col;
186                         uint8_t valid;
187                 } cmd_desc_mapc;
188
189                 struct {
190                         struct its_dev *its_dev;
191                         struct its_col *col;
192                         uint32_t pid;
193                         uint32_t id;
194                 } cmd_desc_mapvi;
195
196                 struct {
197                         struct its_dev *its_dev;
198                         struct its_col *col;
199                         uint32_t pid;
200                 } cmd_desc_mapi;
201
202                 struct {
203                         struct its_dev *its_dev;
204                         uint8_t valid;
205                 } cmd_desc_mapd;
206
207                 struct {
208                         struct its_dev *its_dev;
209                         struct its_col *col;
210                         uint32_t pid;
211                 } cmd_desc_inv;
212
213                 struct {
214                         struct its_col *col;
215                 } cmd_desc_invall;
216         };
217 };
218
219 #define ITS_CMDQ_SIZE           PAGE_SIZE_64K
220 #define ITS_CMDQ_NENTRIES       (ITS_CMDQ_SIZE / sizeof(struct its_cmd))
221
222 #define ITS_FLAGS_CMDQ_FLUSH    (1UL << 0)
223
224 #define ITS_TARGET_NONE         0xFBADBEEF
225
226 struct gic_v3_its_softc {
227         device_t                dev;
228         struct resource *       its_res;
229
230         struct its_cmd *        its_cmdq_base;  /* ITS command queue base */
231         struct its_cmd *        its_cmdq_write; /* ITS command queue write ptr */
232         struct its_ptab         its_ptabs[GITS_BASER_NUM];/* ITS private tables */
233         struct its_col *        its_cols[MAXCPU];/* Per-CPU collections */
234
235         uint64_t                its_flags;
236
237         struct its_dev_list     its_dev_list;
238
239         unsigned long *         its_lpi_bitmap;
240         uint32_t                its_lpi_maxid;
241
242         struct mtx              its_dev_lock;
243         struct mtx              its_cmd_lock;
244
245         uint32_t                its_socket;     /* Socket number ITS is attached to */
246 };
247
248 /* Stuff that is specific to the vendor's implementation */
249 typedef uint32_t (*its_devbits_func_t)(device_t);
250 typedef uint32_t (*its_devid_func_t)(device_t);
251
252 struct its_quirks {
253         uint64_t                cpuid;
254         uint64_t                cpuid_mask;
255         its_devid_func_t        devid_func;
256         its_devbits_func_t      devbits_func;
257 };
258
259 extern devclass_t gic_v3_its_devclass;
260
261 int gic_v3_its_detach(device_t);
262
263 int gic_v3_its_alloc_msix(device_t, device_t, int *);
264 int gic_v3_its_alloc_msi(device_t, device_t, int, int *);
265 int gic_v3_its_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
266
267 int its_init_cpu(struct gic_v3_its_softc *);
268
269 int lpi_migrate(device_t, uint32_t, u_int);
270 void lpi_unmask_irq(device_t, uint32_t);
271 void lpi_mask_irq(device_t, uint32_t);
272 /*
273  * GIC Distributor accessors.
274  * Notice that only GIC sofc can be passed.
275  */
276 #define gic_d_read(sc, len, reg)                \
277 ({                                              \
278         bus_read_##len(sc->gic_dist, reg);      \
279 })
280
281 #define gic_d_write(sc, len, reg, val)          \
282 ({                                              \
283         bus_write_##len(sc->gic_dist, reg, val);\
284 })
285
286 /* GIC Re-Distributor accessors (per-CPU) */
287 #define gic_r_read(sc, len, reg)                \
288 ({                                              \
289         u_int cpu = PCPU_GET(cpuid);            \
290                                                 \
291         bus_read_##len(                         \
292             sc->gic_redists.pcpu[cpu],          \
293             reg);                               \
294 })
295
296 #define gic_r_write(sc, len, reg, val)          \
297 ({                                              \
298         u_int cpu = PCPU_GET(cpuid);            \
299                                                 \
300         bus_write_##len(                        \
301             sc->gic_redists.pcpu[cpu],          \
302             reg, val);                          \
303 })
304
305 #define PCI_DEVID_GENERIC(pci_dev)                              \
306 ({                                                              \
307         ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) |    \
308         (pci_get_bus(pci_dev) << PCI_RID_BUS_SHIFT) |           \
309         (pci_get_slot(pci_dev) << PCI_RID_SLOT_SHIFT) |         \
310         (pci_get_function(pci_dev) << PCI_RID_FUNC_SHIFT));     \
311 })
312
313 /*
314  * Request number of maximum MSI-X vectors for this device.
315  * Device can ask for less vectors than maximum supported but not more.
316  */
317 #define PCI_MSIX_NUM(pci_dev)                   \
318 ({                                              \
319         struct pci_devinfo *dinfo;              \
320         pcicfgregs *cfg;                        \
321                                                 \
322         dinfo = device_get_ivars(pci_dev);      \
323         cfg = &dinfo->cfg;                      \
324                                                 \
325         cfg->msix.msix_msgnum;                  \
326 })
327
328 #endif /* _GIC_V3_VAR_H_ */