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 vm_offset_t conf_base;
46 vm_offset_t pend_base[MAXCPU];
52 * Re-Distributor region description.
53 * We will have few of those depending
54 * on the #redistributor-regions property in FDT.
56 struct resource ** regions;
57 /* Number of Re-Distributor regions */
59 /* Per-CPU Re-Distributor handler */
60 struct resource * pcpu[MAXCPU];
62 struct redist_lpis lpis;
67 struct resource ** gic_res;
70 struct resource * gic_dist;
72 struct gic_redists gic_redists;
77 boolean_t gic_registered;
80 MALLOC_DECLARE(M_GIC_V3);
83 int gic_v3_attach(device_t dev);
84 int gic_v3_detach(device_t dev);
89 #define GIC_V3_ITS_DEVSTR "ARM GIC Interrupt Translation Service"
90 #define GIC_V3_ITS_COMPSTR "arm,gic-v3-its"
92 DECLARE_CLASS(gic_v3_its_driver);
94 /* LPI chunk owned by ITS device */
98 u_int lpi_free; /* First free LPI in set */
104 TAILQ_ENTRY(its_dev) entry;
107 /* Device ID (i.e. PCI device ID) */
109 /* List of assigned LPIs */
110 struct lpi_chunk lpis;
111 /* Virtual address of ITT */
114 TAILQ_HEAD(its_dev_list, its_dev);
116 /* ITS private table description */
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 */
123 /* ITS collection description. */
125 uint64_t col_target; /* Target Re-Distributor */
126 uint64_t col_id; /* Collection ID */
129 /* ITS command. Each command is 32 bytes long */
131 uint64_t cmd_dword[4]; /* ITS command double word */
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)
144 #define CMD_COMMAND_MASK (0xFFUL)
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)
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)
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)
167 * ITS command descriptor.
168 * Idea for command description passing taken from Linux.
170 struct its_cmd_desc {
175 struct its_dev *its_dev;
190 struct its_dev *its_dev;
197 struct its_dev *its_dev;
203 struct its_dev *its_dev;
208 struct its_dev *its_dev;
219 #define ITS_CMDQ_SIZE PAGE_SIZE_64K
220 #define ITS_CMDQ_NENTRIES (ITS_CMDQ_SIZE / sizeof(struct its_cmd))
222 #define ITS_FLAGS_CMDQ_FLUSH (1UL << 0)
224 #define ITS_TARGET_NONE 0xFBADBEEF
226 struct gic_v3_its_softc {
228 struct resource * its_res;
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 */
237 struct its_dev_list its_dev_list;
239 unsigned long * its_lpi_bitmap;
240 uint32_t its_lpi_maxid;
242 struct mtx its_dev_lock;
243 struct mtx its_cmd_lock;
245 uint32_t its_socket; /* Socket number ITS is attached to */
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);
255 its_devid_func_t devid_func;
256 its_devbits_func_t devbits_func;
259 extern devclass_t gic_v3_its_devclass;
261 int gic_v3_its_detach(device_t);
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 *);
267 int its_init_cpu(struct gic_v3_its_softc *);
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);
273 * GIC Distributor accessors.
274 * Notice that only GIC sofc can be passed.
276 #define gic_d_read(sc, len, reg) \
278 bus_read_##len(sc->gic_dist, reg); \
281 #define gic_d_write(sc, len, reg, val) \
283 bus_write_##len(sc->gic_dist, reg, val);\
286 /* GIC Re-Distributor accessors (per-CPU) */
287 #define gic_r_read(sc, len, reg) \
289 u_int cpu = PCPU_GET(cpuid); \
292 sc->gic_redists.pcpu[cpu], \
296 #define gic_r_write(sc, len, reg, val) \
298 u_int cpu = PCPU_GET(cpuid); \
301 sc->gic_redists.pcpu[cpu], \
305 #define PCI_DEVID_GENERIC(pci_dev) \
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)); \
314 * Request number of maximum MSI-X vectors for this device.
315 * Device can ask for less vectors than maximum supported but not more.
317 #define PCI_MSIX_NUM(pci_dev) \
319 struct pci_devinfo *dinfo; \
322 dinfo = device_get_ivars(pci_dev); \
325 cfg->msix.msix_msgnum; \
328 #endif /* _GIC_V3_VAR_H_ */