]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/gic_v3_var.h
MFV r302218: file 5.28.
[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 #ifndef INTRNG
40 #define LPI_FLAGS_CONF_FLUSH    (1UL << 0)
41 #define LPI_CONFTAB_SIZE        PAGE_SIZE_64K
42 /* 1 bit per LPI + 1 KB more for the obligatory PPI, SGI, SPI stuff */
43 #define LPI_PENDTAB_SIZE        ((LPI_CONFTAB_SIZE / 8) + 0x400)
44 #endif
45
46 #ifdef INTRNG
47 struct gic_v3_irqsrc {
48         struct intr_irqsrc      gi_isrc;
49         uint32_t                gi_irq;
50         enum intr_polarity      gi_pol;
51         enum intr_trigger       gi_trig;
52 };
53 #endif
54
55 struct redist_lpis {
56         vm_offset_t             conf_base;
57         vm_offset_t             pend_base[MAXCPU];
58         uint64_t                flags;
59 };
60
61 struct gic_redists {
62         /*
63          * Re-Distributor region description.
64          * We will have few of those depending
65          * on the #redistributor-regions property in FDT.
66          */
67         struct resource **      regions;
68         /* Number of Re-Distributor regions */
69         u_int                   nregions;
70         /* Per-CPU Re-Distributor handler */
71         struct resource *       pcpu[MAXCPU];
72         /* LPIs data */
73         struct redist_lpis      lpis;
74 };
75
76 struct gic_v3_softc {
77         device_t                dev;
78         struct resource **      gic_res;
79         struct mtx              gic_mtx;
80         /* Distributor */
81         struct resource *       gic_dist;
82         /* Re-Distributors */
83         struct gic_redists      gic_redists;
84
85         u_int                   gic_nirqs;
86         u_int                   gic_idbits;
87
88         boolean_t               gic_registered;
89
90 #ifdef INTRNG
91         int                     gic_nchildren;
92         device_t                *gic_children;
93         struct intr_pic         *gic_pic;
94         struct gic_v3_irqsrc    *gic_irqs;
95 #endif
96 };
97
98 #ifdef INTRNG
99 #define GIC_INTR_ISRC(sc, irq)  (&sc->gic_irqs[irq].gi_isrc)
100 #endif
101
102 MALLOC_DECLARE(M_GIC_V3);
103
104 /* ivars */
105 enum {
106         GICV3_IVAR_NIRQS,
107         GICV3_IVAR_REDIST_VADDR,
108 };
109
110 __BUS_ACCESSOR(gicv3, nirqs, GICV3, NIRQS, u_int);
111 __BUS_ACCESSOR(gicv3, redist_vaddr, GICV3, REDIST_VADDR, void *);
112
113 /* Device methods */
114 int gic_v3_attach(device_t dev);
115 int gic_v3_detach(device_t dev);
116 int arm_gic_v3_intr(void *);
117
118 #ifdef INTRNG
119 uint32_t gic_r_read_4(device_t, bus_size_t);
120 uint64_t gic_r_read_8(device_t, bus_size_t);
121 void gic_r_write_4(device_t, bus_size_t, uint32_t var);
122 void gic_r_write_8(device_t, bus_size_t, uint64_t var);
123 #endif
124
125 /*
126  * ITS
127  */
128
129 /* LPI chunk owned by ITS device */
130 struct lpi_chunk {
131         u_int   lpi_base;
132         u_int   lpi_free;       /* First free LPI in set */
133 #ifndef INTRNG
134         u_int   *lpi_col_ids;
135 #endif
136         u_int   lpi_num;        /* Total number of LPIs in chunk */
137         u_int   lpi_busy;       /* Number of busy LPIs in chink */
138 };
139
140 /* ITS device */
141 struct its_dev {
142         TAILQ_ENTRY(its_dev)    entry;
143         /* PCI device */
144         device_t                pci_dev;
145         /* Device ID (i.e. PCI device ID) */
146         uint32_t                devid;
147         /* List of assigned LPIs */
148         struct lpi_chunk        lpis;
149         /* Virtual address of ITT */
150         vm_offset_t             itt;
151         size_t                  itt_size;
152 };
153 #ifndef INTRNG
154 TAILQ_HEAD(its_dev_list, its_dev);
155
156 /* ITS private table description */
157 struct its_ptab {
158         vm_offset_t     ptab_vaddr;     /* Virtual Address of table */
159         size_t          ptab_pgsz;      /* Page size */
160         size_t          ptab_npages;    /* Number of pages */
161 };
162
163 /* ITS collection description. */
164 struct its_col {
165         uint64_t        col_target;     /* Target Re-Distributor */
166         uint64_t        col_id;         /* Collection ID */
167 };
168
169 /* ITS command. Each command is 32 bytes long */
170 struct its_cmd {
171         uint64_t        cmd_dword[4];   /* ITS command double word */
172 };
173
174 #define GIC_V3_ITS_DEVSTR       "ARM GIC Interrupt Translation Service"
175 #define GIC_V3_ITS_COMPSTR      "arm,gic-v3-its"
176
177 DECLARE_CLASS(gic_v3_its_driver);
178
179 /* ITS commands encoding */
180 #define ITS_CMD_MOVI            (0x01)
181 #define ITS_CMD_SYNC            (0x05)
182 #define ITS_CMD_MAPD            (0x08)
183 #define ITS_CMD_MAPC            (0x09)
184 #define ITS_CMD_MAPVI           (0x0a)
185 #define ITS_CMD_MAPI            (0x0b)
186 #define ITS_CMD_INV             (0x0c)
187 #define ITS_CMD_INVALL          (0x0d)
188 /* Command */
189 #define CMD_COMMAND_MASK        (0xFFUL)
190 /* PCI device ID */
191 #define CMD_DEVID_SHIFT         (32)
192 #define CMD_DEVID_MASK          (0xFFFFFFFFUL << CMD_DEVID_SHIFT)
193 /* Size of IRQ ID bitfield */
194 #define CMD_SIZE_MASK           (0xFFUL)
195 /* Virtual LPI ID */
196 #define CMD_ID_MASK             (0xFFFFFFFFUL)
197 /* Physical LPI ID */
198 #define CMD_PID_SHIFT           (32)
199 #define CMD_PID_MASK            (0xFFFFFFFFUL << CMD_PID_SHIFT)
200 /* Collection */
201 #define CMD_COL_MASK            (0xFFFFUL)
202 /* Target (CPU or Re-Distributor) */
203 #define CMD_TARGET_SHIFT        (16)
204 #define CMD_TARGET_MASK         (0xFFFFFFFFUL << CMD_TARGET_SHIFT)
205 /* Interrupt Translation Table address */
206 #define CMD_ITT_MASK            (0xFFFFFFFFFF00UL)
207 /* Valid command bit */
208 #define CMD_VALID_SHIFT         (63)
209 #define CMD_VALID_MASK          (1UL << CMD_VALID_SHIFT)
210 #endif /* INTRNG */
211
212 /*
213  * ITS command descriptor.
214  * Idea for command description passing taken from Linux.
215  */
216 struct its_cmd_desc {
217         uint8_t cmd_type;
218
219         union {
220                 struct {
221                         struct its_dev *its_dev;
222                         struct its_col *col;
223                         uint32_t id;
224                 } cmd_desc_movi;
225
226                 struct {
227                         struct its_col *col;
228                 } cmd_desc_sync;
229
230                 struct {
231                         struct its_col *col;
232                         uint8_t valid;
233                 } cmd_desc_mapc;
234
235                 struct {
236                         struct its_dev *its_dev;
237                         struct its_col *col;
238                         uint32_t pid;
239                         uint32_t id;
240                 } cmd_desc_mapvi;
241
242                 struct {
243                         struct its_dev *its_dev;
244                         struct its_col *col;
245                         uint32_t pid;
246                 } cmd_desc_mapi;
247
248                 struct {
249                         struct its_dev *its_dev;
250                         uint8_t valid;
251                 } cmd_desc_mapd;
252
253                 struct {
254                         struct its_dev *its_dev;
255                         struct its_col *col;
256                         uint32_t pid;
257                 } cmd_desc_inv;
258
259                 struct {
260                         struct its_col *col;
261                 } cmd_desc_invall;
262         };
263 };
264
265 #define ITS_TARGET_NONE         0xFBADBEEF
266
267 #ifndef INTRNG
268 #define ITS_CMDQ_SIZE           PAGE_SIZE_64K
269 #define ITS_CMDQ_NENTRIES       (ITS_CMDQ_SIZE / sizeof(struct its_cmd))
270
271 #define ITS_FLAGS_CMDQ_FLUSH    (1UL << 0)
272
273 struct gic_v3_its_softc {
274         device_t                dev;
275         struct resource *       its_res;
276
277         struct its_cmd *        its_cmdq_base;  /* ITS command queue base */
278         struct its_cmd *        its_cmdq_write; /* ITS command queue write ptr */
279         struct its_ptab         its_ptabs[GITS_BASER_NUM];/* ITS private tables */
280         struct its_col *        its_cols[MAXCPU];/* Per-CPU collections */
281
282         uint64_t                its_flags;
283
284 #ifndef INTRNG
285         struct its_dev_list     its_dev_list;
286 #endif
287
288         bitstr_t *              its_lpi_bitmap;
289         uint32_t                its_lpi_maxid;
290
291         struct mtx              its_dev_lock;
292         struct mtx              its_cmd_lock;
293
294         uint32_t                its_socket;     /* Socket number ITS is attached to */
295 };
296
297 /* Stuff that is specific to the vendor's implementation */
298 typedef uint32_t (*its_devbits_func_t)(device_t);
299
300 struct its_quirks {
301         uint64_t                cpuid;
302         uint64_t                cpuid_mask;
303         its_devbits_func_t      devbits_func;
304 };
305
306 extern devclass_t gic_v3_its_devclass;
307
308 int gic_v3_its_detach(device_t);
309
310 int gic_v3_its_alloc_msix(device_t, device_t, int *);
311 int gic_v3_its_release_msix(device_t, device_t, int);
312 int gic_v3_its_alloc_msi(device_t, device_t, int, int *);
313 int gic_v3_its_release_msi(device_t, device_t, int, int *);
314 int gic_v3_its_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
315
316 int its_init_cpu(struct gic_v3_its_softc *);
317
318 int lpi_migrate(device_t, uint32_t, u_int);
319 void lpi_unmask_irq(device_t, uint32_t);
320 void lpi_mask_irq(device_t, uint32_t);
321 #endif
322 /*
323  * GIC Distributor accessors.
324  * Notice that only GIC sofc can be passed.
325  */
326 #define gic_d_read(sc, len, reg)                \
327 ({                                              \
328         bus_read_##len(sc->gic_dist, reg);      \
329 })
330
331 #define gic_d_write(sc, len, reg, val)          \
332 ({                                              \
333         bus_write_##len(sc->gic_dist, reg, val);\
334 })
335
336 /* GIC Re-Distributor accessors (per-CPU) */
337 #define gic_r_read(sc, len, reg)                \
338 ({                                              \
339         u_int cpu = PCPU_GET(cpuid);            \
340                                                 \
341         bus_read_##len(                         \
342             sc->gic_redists.pcpu[cpu],          \
343             reg);                               \
344 })
345
346 #define gic_r_write(sc, len, reg, val)          \
347 ({                                              \
348         u_int cpu = PCPU_GET(cpuid);            \
349                                                 \
350         bus_write_##len(                        \
351             sc->gic_redists.pcpu[cpu],          \
352             reg, val);                          \
353 })
354
355 #define PCI_DEVID_GENERIC(pci_dev)                              \
356 ({                                                              \
357         ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) |    \
358         (pci_get_bus(pci_dev) << PCI_RID_BUS_SHIFT) |           \
359         (pci_get_slot(pci_dev) << PCI_RID_SLOT_SHIFT) |         \
360         (pci_get_function(pci_dev) << PCI_RID_FUNC_SHIFT));     \
361 })
362
363 /*
364  * Request number of maximum MSI-X vectors for this device.
365  * Device can ask for less vectors than maximum supported but not more.
366  */
367 #define PCI_MSIX_NUM(pci_dev)                   \
368 ({                                              \
369         struct pci_devinfo *dinfo;              \
370         pcicfgregs *cfg;                        \
371                                                 \
372         dinfo = device_get_ivars(pci_dev);      \
373         cfg = &dinfo->cfg;                      \
374                                                 \
375         cfg->msix.msix_msgnum;                  \
376 })
377
378 #endif /* _GIC_V3_VAR_H_ */