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);
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)
45 struct gic_v3_irqsrc {
46 struct intr_irqsrc gi_isrc;
48 enum intr_polarity gi_pol;
49 enum intr_trigger gi_trig;
54 vm_offset_t conf_base;
55 vm_offset_t pend_base[MAXCPU];
61 * Re-Distributor region description.
62 * We will have few of those depending
63 * on the #redistributor-regions property in FDT.
65 struct resource ** regions;
66 /* Number of Re-Distributor regions */
68 /* Per-CPU Re-Distributor handler */
69 struct resource * pcpu[MAXCPU];
71 struct redist_lpis lpis;
76 struct resource ** gic_res;
79 struct resource * gic_dist;
81 struct gic_redists gic_redists;
86 boolean_t gic_registered;
89 struct gic_v3_irqsrc *gic_irqs;
94 #define GIC_INTR_ISRC(sc, irq) (&sc->gic_irqs[irq].gi_isrc)
97 MALLOC_DECLARE(M_GIC_V3);
100 int gic_v3_attach(device_t dev);
101 int gic_v3_detach(device_t dev);
102 int arm_gic_v3_intr(void *);
107 #define GIC_V3_ITS_DEVSTR "ARM GIC Interrupt Translation Service"
108 #define GIC_V3_ITS_COMPSTR "arm,gic-v3-its"
110 DECLARE_CLASS(gic_v3_its_driver);
112 /* LPI chunk owned by ITS device */
115 u_int lpi_free; /* First free LPI in set */
118 u_int lpi_num; /* Total number of LPIs in chunk */
119 u_int lpi_busy; /* Number of busy LPIs in chink */
124 TAILQ_ENTRY(its_dev) entry;
127 /* Device ID (i.e. PCI device ID) */
129 /* List of assigned LPIs */
130 struct lpi_chunk lpis;
131 /* Virtual address of ITT */
135 TAILQ_HEAD(its_dev_list, its_dev);
137 /* ITS private table description */
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 */
144 /* ITS collection description. */
146 uint64_t col_target; /* Target Re-Distributor */
147 uint64_t col_id; /* Collection ID */
150 /* ITS command. Each command is 32 bytes long */
152 uint64_t cmd_dword[4]; /* ITS command double word */
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)
165 #define CMD_COMMAND_MASK (0xFFUL)
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)
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)
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)
188 * ITS command descriptor.
189 * Idea for command description passing taken from Linux.
191 struct its_cmd_desc {
196 struct its_dev *its_dev;
211 struct its_dev *its_dev;
218 struct its_dev *its_dev;
224 struct its_dev *its_dev;
229 struct its_dev *its_dev;
240 #define ITS_CMDQ_SIZE PAGE_SIZE_64K
241 #define ITS_CMDQ_NENTRIES (ITS_CMDQ_SIZE / sizeof(struct its_cmd))
243 #define ITS_FLAGS_CMDQ_FLUSH (1UL << 0)
245 #define ITS_TARGET_NONE 0xFBADBEEF
247 struct gic_v3_its_softc {
249 struct resource * its_res;
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 */
258 struct its_dev_list its_dev_list;
260 bitstr_t * its_lpi_bitmap;
261 uint32_t its_lpi_maxid;
263 struct mtx its_dev_lock;
264 struct mtx its_cmd_lock;
266 uint32_t its_socket; /* Socket number ITS is attached to */
269 /* Stuff that is specific to the vendor's implementation */
270 typedef uint32_t (*its_devbits_func_t)(device_t);
275 its_devbits_func_t devbits_func;
278 extern devclass_t gic_v3_its_devclass;
280 int gic_v3_its_detach(device_t);
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 *);
288 int its_init_cpu(struct gic_v3_its_softc *);
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);
294 * GIC Distributor accessors.
295 * Notice that only GIC sofc can be passed.
297 #define gic_d_read(sc, len, reg) \
299 bus_read_##len(sc->gic_dist, reg); \
302 #define gic_d_write(sc, len, reg, val) \
304 bus_write_##len(sc->gic_dist, reg, val);\
307 /* GIC Re-Distributor accessors (per-CPU) */
308 #define gic_r_read(sc, len, reg) \
310 u_int cpu = PCPU_GET(cpuid); \
313 sc->gic_redists.pcpu[cpu], \
317 #define gic_r_write(sc, len, reg, val) \
319 u_int cpu = PCPU_GET(cpuid); \
322 sc->gic_redists.pcpu[cpu], \
326 #define PCI_DEVID_GENERIC(pci_dev) \
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)); \
335 * Request number of maximum MSI-X vectors for this device.
336 * Device can ask for less vectors than maximum supported but not more.
338 #define PCI_MSIX_NUM(pci_dev) \
340 struct pci_devinfo *dinfo; \
343 dinfo = device_get_ivars(pci_dev); \
346 cfg->msix.msix_msgnum; \
349 #endif /* _GIC_V3_VAR_H_ */