2 * Copyright (c) 2015 The FreeBSD Foundation
5 * This software was developed by Semihalf under
6 * the sponsorship of the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
32 #ifndef _GIC_V3_VAR_H_
33 #define _GIC_V3_VAR_H_
35 #define GIC_V3_DEVSTR "ARM Generic Interrupt Controller v3.0"
37 DECLARE_CLASS(gic_v3_driver);
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)
47 struct gic_v3_irqsrc {
48 struct intr_irqsrc gi_isrc;
50 enum intr_polarity gi_pol;
51 enum intr_trigger gi_trig;
56 vm_offset_t conf_base;
57 vm_offset_t pend_base[MAXCPU];
63 * Re-Distributor region description.
64 * We will have few of those depending
65 * on the #redistributor-regions property in FDT.
67 struct resource ** regions;
68 /* Number of Re-Distributor regions */
70 /* Per-CPU Re-Distributor handler */
71 struct resource * pcpu[MAXCPU];
73 struct redist_lpis lpis;
78 struct resource ** gic_res;
81 struct resource * gic_dist;
83 struct gic_redists gic_redists;
88 boolean_t gic_registered;
92 device_t *gic_children;
93 struct intr_pic *gic_pic;
94 struct gic_v3_irqsrc *gic_irqs;
99 #define GIC_INTR_ISRC(sc, irq) (&sc->gic_irqs[irq].gi_isrc)
102 MALLOC_DECLARE(M_GIC_V3);
107 GICV3_IVAR_REDIST_VADDR,
110 __BUS_ACCESSOR(gicv3, nirqs, GICV3, NIRQS, u_int);
111 __BUS_ACCESSOR(gicv3, redist_vaddr, GICV3, REDIST_VADDR, void *);
114 int gic_v3_attach(device_t dev);
115 int gic_v3_detach(device_t dev);
116 int arm_gic_v3_intr(void *);
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);
129 /* LPI chunk owned by ITS device */
132 u_int lpi_free; /* First free LPI in set */
136 u_int lpi_num; /* Total number of LPIs in chunk */
137 u_int lpi_busy; /* Number of busy LPIs in chink */
142 TAILQ_ENTRY(its_dev) entry;
145 /* Device ID (i.e. PCI device ID) */
147 /* List of assigned LPIs */
148 struct lpi_chunk lpis;
149 /* Virtual address of ITT */
154 TAILQ_HEAD(its_dev_list, its_dev);
156 /* ITS private table description */
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 */
163 /* ITS collection description. */
165 uint64_t col_target; /* Target Re-Distributor */
166 uint64_t col_id; /* Collection ID */
169 /* ITS command. Each command is 32 bytes long */
171 uint64_t cmd_dword[4]; /* ITS command double word */
174 #define GIC_V3_ITS_DEVSTR "ARM GIC Interrupt Translation Service"
175 #define GIC_V3_ITS_COMPSTR "arm,gic-v3-its"
177 DECLARE_CLASS(gic_v3_its_driver);
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)
189 #define CMD_COMMAND_MASK (0xFFUL)
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)
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)
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)
213 * ITS command descriptor.
214 * Idea for command description passing taken from Linux.
216 struct its_cmd_desc {
221 struct its_dev *its_dev;
236 struct its_dev *its_dev;
243 struct its_dev *its_dev;
249 struct its_dev *its_dev;
254 struct its_dev *its_dev;
265 #define ITS_TARGET_NONE 0xFBADBEEF
268 #define ITS_CMDQ_SIZE PAGE_SIZE_64K
269 #define ITS_CMDQ_NENTRIES (ITS_CMDQ_SIZE / sizeof(struct its_cmd))
271 #define ITS_FLAGS_CMDQ_FLUSH (1UL << 0)
273 struct gic_v3_its_softc {
275 struct resource * its_res;
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 */
285 struct its_dev_list its_dev_list;
288 bitstr_t * its_lpi_bitmap;
289 uint32_t its_lpi_maxid;
291 struct mtx its_dev_lock;
292 struct mtx its_cmd_lock;
294 uint32_t its_socket; /* Socket number ITS is attached to */
297 /* Stuff that is specific to the vendor's implementation */
298 typedef uint32_t (*its_devbits_func_t)(device_t);
303 its_devbits_func_t devbits_func;
306 extern devclass_t gic_v3_its_devclass;
308 int gic_v3_its_detach(device_t);
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 *);
316 int its_init_cpu(struct gic_v3_its_softc *);
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);
323 * GIC Distributor accessors.
324 * Notice that only GIC sofc can be passed.
326 #define gic_d_read(sc, len, reg) \
328 bus_read_##len(sc->gic_dist, reg); \
331 #define gic_d_write(sc, len, reg, val) \
333 bus_write_##len(sc->gic_dist, reg, val);\
336 /* GIC Re-Distributor accessors (per-CPU) */
337 #define gic_r_read(sc, len, reg) \
339 u_int cpu = PCPU_GET(cpuid); \
342 sc->gic_redists.pcpu[cpu], \
346 #define gic_r_write(sc, len, reg, val) \
348 u_int cpu = PCPU_GET(cpuid); \
351 sc->gic_redists.pcpu[cpu], \
355 #define PCI_DEVID_GENERIC(pci_dev) \
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)); \
364 * Request number of maximum MSI-X vectors for this device.
365 * Device can ask for less vectors than maximum supported but not more.
367 #define PCI_MSIX_NUM(pci_dev) \
369 struct pci_devinfo *dinfo; \
372 dinfo = device_get_ivars(pci_dev); \
375 cfg->msix.msix_msgnum; \
378 #endif /* _GIC_V3_VAR_H_ */