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