Home | History | Annotate | Line # | Download | only in broadcom
bcm2835_intr.c revision 1.38
      1 /*	$NetBSD: bcm2835_intr.c,v 1.38 2021/03/08 14:22:42 mlelstv Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2012, 2015, 2019 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Nick Hudson
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.38 2021/03/08 14:22:42 mlelstv Exp $");
     34 
     35 #define _INTR_PRIVATE
     36 
     37 #include "opt_bcm283x.h"
     38 
     39 #include <sys/param.h>
     40 #include <sys/bus.h>
     41 #include <sys/cpu.h>
     42 #include <sys/device.h>
     43 #include <sys/kernel.h>
     44 #include <sys/kmem.h>
     45 #include <sys/proc.h>
     46 
     47 #include <dev/fdt/fdtvar.h>
     48 
     49 #include <machine/intr.h>
     50 
     51 #include <arm/locore.h>
     52 
     53 #include <arm/pic/picvar.h>
     54 #include <arm/cortex/gtmr_var.h>
     55 
     56 #include <arm/broadcom/bcm2835_intr.h>
     57 #include <arm/broadcom/bcm2835reg.h>
     58 #include <arm/broadcom/bcm2835var.h>
     59 
     60 #include <arm/fdt/arm_fdtvar.h>
     61 
     62 static void bcm2835_irq_handler(void *);
     63 static void bcm2836mp_intr_init(void *, struct cpu_info *);
     64 
     65 static void bcm2835_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     66 static void bcm2835_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     67 static int bcm2835_pic_find_pending_irqs(struct pic_softc *);
     68 static void bcm2835_pic_establish_irq(struct pic_softc *, struct intrsource *);
     69 static void bcm2835_pic_source_name(struct pic_softc *, int, char *,
     70     size_t);
     71 
     72 static void bcm2836mp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     73 static void bcm2836mp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     74 static int bcm2836mp_pic_find_pending_irqs(struct pic_softc *);
     75 static void bcm2836mp_pic_establish_irq(struct pic_softc *, struct intrsource *);
     76 static void bcm2836mp_pic_source_name(struct pic_softc *, int, char *,
     77     size_t);
     78 #ifdef MULTIPROCESSOR
     79 int bcm2836mp_ipi_handler(void *);
     80 static void bcm2836mp_cpu_init(struct pic_softc *, struct cpu_info *);
     81 static void bcm2836mp_send_ipi(struct pic_softc *, const kcpuset_t *, u_long);
     82 #endif
     83 
     84 static int bcm2835_icu_fdt_decode_irq(u_int *);
     85 static void *bcm2835_icu_fdt_establish(device_t, u_int *, int, int,
     86     int (*)(void *), void *, const char *);
     87 static void bcm2835_icu_fdt_disestablish(device_t, void *);
     88 static bool bcm2835_icu_fdt_intrstr(device_t, u_int *, char *, size_t);
     89 
     90 static int bcm2835_icu_intr(void *);
     91 
     92 static int bcm2836mp_icu_fdt_decode_irq(u_int *);
     93 static void *bcm2836mp_icu_fdt_establish(device_t, u_int *, int, int,
     94     int (*)(void *), void *, const char *);
     95 static void bcm2836mp_icu_fdt_disestablish(device_t, void *);
     96 static bool bcm2836mp_icu_fdt_intrstr(device_t, u_int *, char *, size_t);
     97 
     98 static int  bcm2835_icu_match(device_t, cfdata_t, void *);
     99 static void bcm2835_icu_attach(device_t, device_t, void *);
    100 
    101 static int bcm2835_int_base;
    102 static int bcm2836mp_int_base[BCM2836_NCPUS];
    103 
    104 #define	BCM2835_INT_BASE		bcm2835_int_base
    105 #define	BCM2836_INT_BASECPUN(n)		bcm2836mp_int_base[(n)]
    106 
    107 #define BCM2836_INT_CNTPSIRQ_CPUN(n)	(BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTPSIRQ)
    108 #define BCM2836_INT_CNTPNSIRQ_CPUN(n)	(BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTPNSIRQ)
    109 #define BCM2836_INT_CNTVIRQ_CPUN(n)	(BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTVIRQ)
    110 #define BCM2836_INT_CNTHPIRQ_CPUN(n)	(BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTHPIRQ)
    111 #define BCM2836_INT_MAILBOX0_CPUN(n)	(BCM2836_INT_BASECPUN(n) + BCM2836_INT_MAILBOX0)
    112 
    113 /* Periperal Interrupt sources */
    114 #define	BCM2835_NIRQ			96
    115 
    116 #define BCM2835_INT_GPU0BASE		(BCM2835_INT_BASE + 0)
    117 #define BCM2835_INT_TIMER0		(BCM2835_INT_GPU0BASE + 0)
    118 #define BCM2835_INT_TIMER1		(BCM2835_INT_GPU0BASE + 1)
    119 #define BCM2835_INT_TIMER2		(BCM2835_INT_GPU0BASE + 2)
    120 #define BCM2835_INT_TIMER3		(BCM2835_INT_GPU0BASE + 3)
    121 #define BCM2835_INT_USB			(BCM2835_INT_GPU0BASE + 9)
    122 #define BCM2835_INT_DMA0		(BCM2835_INT_GPU0BASE + 16)
    123 #define BCM2835_INT_DMA2		(BCM2835_INT_GPU0BASE + 18)
    124 #define BCM2835_INT_DMA3		(BCM2835_INT_GPU0BASE + 19)
    125 #define BCM2835_INT_AUX			(BCM2835_INT_GPU0BASE + 29)
    126 #define BCM2835_INT_ARM			(BCM2835_INT_GPU0BASE + 30)
    127 
    128 #define BCM2835_INT_GPU1BASE		(BCM2835_INT_BASE + 32)
    129 #define BCM2835_INT_GPIO0		(BCM2835_INT_GPU1BASE + 17)
    130 #define BCM2835_INT_GPIO1		(BCM2835_INT_GPU1BASE + 18)
    131 #define BCM2835_INT_GPIO2		(BCM2835_INT_GPU1BASE + 19)
    132 #define BCM2835_INT_GPIO3		(BCM2835_INT_GPU1BASE + 20)
    133 #define BCM2835_INT_BSC			(BCM2835_INT_GPU1BASE + 21)
    134 #define BCM2835_INT_SPI0		(BCM2835_INT_GPU1BASE + 22)
    135 #define BCM2835_INT_PCM			(BCM2835_INT_GPU1BASE + 23)
    136 #define BCM2835_INT_SDHOST		(BCM2835_INT_GPU1BASE + 24)
    137 #define BCM2835_INT_UART0		(BCM2835_INT_GPU1BASE + 25)
    138 #define BCM2835_INT_EMMC		(BCM2835_INT_GPU1BASE + 30)
    139 
    140 #define BCM2835_INT_BASICBASE		(BCM2835_INT_BASE + 64)
    141 #define BCM2835_INT_ARMTIMER		(BCM2835_INT_BASICBASE + 0)
    142 #define BCM2835_INT_ARMMAILBOX		(BCM2835_INT_BASICBASE + 1)
    143 #define BCM2835_INT_ARMDOORBELL0	(BCM2835_INT_BASICBASE + 2)
    144 #define BCM2835_INT_ARMDOORBELL1	(BCM2835_INT_BASICBASE + 3)
    145 #define BCM2835_INT_GPU0HALTED		(BCM2835_INT_BASICBASE + 4)
    146 #define BCM2835_INT_GPU1HALTED		(BCM2835_INT_BASICBASE + 5)
    147 #define BCM2835_INT_ILLEGALTYPE0	(BCM2835_INT_BASICBASE + 6)
    148 #define BCM2835_INT_ILLEGALTYPE1	(BCM2835_INT_BASICBASE + 7)
    149 
    150 static void
    151 bcm2835_set_priority(struct pic_softc *pic, int ipl)
    152 {
    153 }
    154 
    155 static struct pic_ops bcm2835_picops = {
    156 	.pic_unblock_irqs = bcm2835_pic_unblock_irqs,
    157 	.pic_block_irqs = bcm2835_pic_block_irqs,
    158 	.pic_find_pending_irqs = bcm2835_pic_find_pending_irqs,
    159 	.pic_establish_irq = bcm2835_pic_establish_irq,
    160 	.pic_source_name = bcm2835_pic_source_name,
    161 	.pic_set_priority = bcm2835_set_priority,
    162 };
    163 
    164 static struct pic_softc bcm2835_pic = {
    165 	.pic_ops = &bcm2835_picops,
    166 	.pic_maxsources = BCM2835_NIRQ,
    167 	.pic_name = "bcm2835 pic",
    168 };
    169 
    170 static struct pic_ops bcm2836mp_picops = {
    171 	.pic_unblock_irqs = bcm2836mp_pic_unblock_irqs,
    172 	.pic_block_irqs = bcm2836mp_pic_block_irqs,
    173 	.pic_find_pending_irqs = bcm2836mp_pic_find_pending_irqs,
    174 	.pic_establish_irq = bcm2836mp_pic_establish_irq,
    175 	.pic_source_name = bcm2836mp_pic_source_name,
    176 #if defined(MULTIPROCESSOR)
    177 	.pic_cpu_init = bcm2836mp_cpu_init,
    178 	.pic_ipi_send = bcm2836mp_send_ipi,
    179 #endif
    180 };
    181 
    182 static struct pic_softc bcm2836mp_pic[BCM2836_NCPUS] = {
    183 	[0 ... BCM2836_NCPUS - 1] = {
    184 		.pic_ops = &bcm2836mp_picops,
    185 		.pic_maxsources = BCM2836_NIRQPERCPU,
    186 		.pic_name = "bcm2836 pic",
    187 	}
    188 };
    189 
    190 static struct fdtbus_interrupt_controller_func bcm2835icu_fdt_funcs = {
    191 	.establish = bcm2835_icu_fdt_establish,
    192 	.disestablish = bcm2835_icu_fdt_disestablish,
    193 	.intrstr = bcm2835_icu_fdt_intrstr
    194 };
    195 
    196 static struct fdtbus_interrupt_controller_func bcm2836mpicu_fdt_funcs = {
    197 	.establish = bcm2836mp_icu_fdt_establish,
    198 	.disestablish = bcm2836mp_icu_fdt_disestablish,
    199 	.intrstr = bcm2836mp_icu_fdt_intrstr
    200 };
    201 
    202 struct bcm2836mp_interrupt {
    203 	bool bi_done;
    204 	TAILQ_ENTRY(bcm2836mp_interrupt) bi_next;
    205 	int bi_irq;
    206 	int bi_ipl;
    207 	int bi_flags;
    208 	int (*bi_func)(void *);
    209 	void *bi_arg;
    210 	void *bi_ihs[BCM2836_NCPUS];
    211 };
    212 
    213 static TAILQ_HEAD(, bcm2836mp_interrupt) bcm2836mp_interrupts =
    214     TAILQ_HEAD_INITIALIZER(bcm2836mp_interrupts);
    215 
    216 struct bcm2835icu_irqhandler;
    217 struct bcm2835icu_irq;
    218 struct bcm2835icu_softc;
    219 
    220 struct bcm2835icu_irqhandler {
    221 	struct bcm2835icu_irq	*ih_irq;
    222 	int			(*ih_fn)(void *);
    223 	void			*ih_arg;
    224 	TAILQ_ENTRY(bcm2835icu_irqhandler) ih_next;
    225 };
    226 
    227 struct bcm2835icu_irq {
    228 	struct bcm2835icu_softc	*intr_sc;
    229 	void			*intr_ih;
    230 	void			*intr_arg;
    231 	int			intr_refcnt;
    232 	int			intr_ipl;
    233 	int			intr_irq;
    234 	int			intr_mpsafe;
    235 	TAILQ_HEAD(, bcm2835icu_irqhandler) intr_handlers;
    236 };
    237 
    238 struct bcm2835icu_softc {
    239 	device_t		sc_dev;
    240 	bus_space_tag_t		sc_iot;
    241 	bus_space_handle_t	sc_ioh;
    242 
    243 	struct bcm2835icu_irq	*sc_irq[BCM2835_NIRQ];
    244 
    245 	int sc_phandle;
    246 };
    247 
    248 static struct bcm2835icu_softc *bcml1icu_sc;
    249 static struct bcm2835icu_softc *bcmicu_sc;
    250 
    251 #define read_bcm2835reg(o)	\
    252 	bus_space_read_4(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, (o))
    253 
    254 #define write_bcm2835reg(o, v)	\
    255 	bus_space_write_4(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, (o), (v))
    256 
    257 
    258 #define bcm2835_barrier() \
    259 	bus_space_barrier(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, 0, \
    260 	    BCM2835_ARMICU_SIZE, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
    261 
    262 static const char * const bcm2835_sources[BCM2835_NIRQ] = {
    263 	"(unused  0)",	"(unused  1)",	"(unused  2)",	"timer3",
    264 	"(unused  4)",	"(unused  5)",	"(unused  6)",	"jpeg",
    265 	"(unused  8)",	"usb",		"(unused 10)",	"(unused 11)",
    266 	"(unused 12)",	"(unused 13)",	"(unused 14)",	"(unused 15)",
    267 	"dma0",		"dma1",		"dma2",		"dma3",
    268 	"dma4",		"dma5",		"dma6",		"dma7",
    269 	"dma8",		"dma9",		"dma10",	"dma11",
    270 	"dma12",	"aux",		"(unused 30)",	"(unused 31)",
    271 	"(unused 32)",	"(unused 33)",	"(unused 34)",	"(unused 35)",
    272 	"(unused 36)",	"(unused 37)",	"(unused 38)",	"(unused 39)",
    273 	"(unused 40)",	"(unused 41)",	"(unused 42)",	"i2c spl slv",
    274 	"(unused 44)",	"pwa0",		"pwa1",		"(unused 47)",
    275 	"smi",		"gpio[0]",	"gpio[1]",	"gpio[2]",
    276 	"gpio[3]",	"i2c",		"spi",		"pcm",
    277 	"sdhost",	"uart",		"(unused 58)",	"(unused 59)",
    278 	"(unused 60)",	"(unused 61)",	"emmc",		"(unused 63)",
    279 	"Timer",	"Mailbox",	"Doorbell0",	"Doorbell1",
    280 	"GPU0 Halted",	"GPU1 Halted",	"Illegal #1",	"Illegal #0"
    281 };
    282 
    283 static const char * const bcm2836mp_sources[BCM2836_NIRQPERCPU] = {
    284 	"cntpsirq",	"cntpnsirq",	"cnthpirq",	"cntvirq",
    285 	"mailbox0",	"mailbox1",	"mailbox2",	"mailbox3",
    286 	"gpu",		"pmu"
    287 };
    288 
    289 #define	BCM2836_INTBIT_GPUPENDING	__BIT(8)
    290 
    291 #define	BCM2835_INTBIT_PENDING1		__BIT(8)
    292 #define	BCM2835_INTBIT_PENDING2		__BIT(9)
    293 #define	BCM2835_INTBIT_ARM		__BITS(0,7)
    294 #define	BCM2835_INTBIT_GPU0		__BITS(10,14)
    295 #define	BCM2835_INTBIT_GPU1		__BITS(15,20)
    296 
    297 CFATTACH_DECL_NEW(bcmicu, sizeof(struct bcm2835icu_softc),
    298     bcm2835_icu_match, bcm2835_icu_attach, NULL, NULL);
    299 
    300 static const struct device_compatible_entry compat_data[] = {
    301 	{ .compat = "brcm,bcm2708-armctrl-ic",	.value = 0 },
    302 	{ .compat = "brcm,bcm2709-armctrl-ic",	.value = 0 },
    303 	{ .compat = "brcm,bcm2835-armctrl-ic",	.value = 0 },
    304 	{ .compat = "brcm,bcm2836-armctrl-ic",	.value = 0 },
    305 	{ .compat = "brcm,bcm2836-l1-intc",	.value = 1 },
    306 	DEVICE_COMPAT_EOL
    307 };
    308 
    309 static int
    310 bcm2835_icu_match(device_t parent, cfdata_t cf, void *aux)
    311 {
    312 	struct fdt_attach_args * const faa = aux;
    313 
    314 	return of_compatible_match(faa->faa_phandle, compat_data);
    315 }
    316 
    317 static void
    318 bcm2835_icu_attach(device_t parent, device_t self, void *aux)
    319 {
    320 	struct bcm2835icu_softc * const sc = device_private(self);
    321 	struct fdt_attach_args * const faa = aux;
    322 	struct fdtbus_interrupt_controller_func *ifuncs;
    323 	const struct device_compatible_entry *dce;
    324 	const int phandle = faa->faa_phandle;
    325 	bus_addr_t addr;
    326 	bus_size_t size;
    327 	bus_space_handle_t ioh;
    328 	int error;
    329 
    330 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
    331 		aprint_error(": couldn't get registers\n");
    332 		return;
    333 	}
    334 
    335 	sc->sc_dev = self;
    336 	sc->sc_iot = faa->faa_bst;
    337 
    338 	if (bus_space_map(sc->sc_iot, addr, size, 0, &ioh) != 0) {
    339 		aprint_error(": couldn't map device\n");
    340 		return;
    341 	}
    342 
    343 	sc->sc_ioh = ioh;
    344 	sc->sc_phandle = phandle;
    345 
    346 	dce = of_compatible_lookup(faa->faa_phandle, compat_data);
    347 	KASSERT(dce != NULL);
    348 
    349 	if (dce->value != 0) {
    350 #if defined(MULTIPROCESSOR)
    351 		aprint_normal(": Multiprocessor");
    352 #endif
    353 		bcml1icu_sc = sc;
    354 
    355 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
    356 		    BCM2836_LOCAL_CONTROL, 0);
    357 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
    358 		    BCM2836_LOCAL_PRESCALER, 0x80000000);
    359 
    360 		ifuncs = &bcm2836mpicu_fdt_funcs;
    361 
    362 		bcm2836mp_intr_init(self, curcpu());
    363 		arm_fdt_cpu_hatch_register(self, bcm2836mp_intr_init);
    364 	} else {
    365 		if (bcml1icu_sc == NULL)
    366 			arm_fdt_irq_set_handler(bcm2835_irq_handler);
    367 		bcmicu_sc = sc;
    368 		sc->sc_ioh = ioh;
    369 		sc->sc_phandle = phandle;
    370 		bcm2835_int_base = pic_add(&bcm2835_pic, PIC_IRQBASE_ALLOC);
    371 		ifuncs = &bcm2835icu_fdt_funcs;
    372 	}
    373 
    374 	error = fdtbus_register_interrupt_controller(self, phandle, ifuncs);
    375 	if (error != 0) {
    376 		aprint_error(": couldn't register with fdtbus: %d\n", error);
    377 		return;
    378 	}
    379 	aprint_normal("\n");
    380 }
    381 
    382 static void
    383 bcm2835_irq_handler(void *frame)
    384 {
    385 	struct cpu_info * const ci = curcpu();
    386 	const int oldipl = ci->ci_cpl;
    387 	const cpuid_t cpuid = ci->ci_core_id;
    388 	const uint32_t oldipl_mask = __BIT(oldipl);
    389 	int ipl_mask = 0;
    390 
    391 	KASSERT(cpuid < BCM2836_NCPUS);
    392 
    393 	ci->ci_data.cpu_nintr++;
    394 
    395 	bcm2835_barrier();
    396 	if (cpuid == 0) {
    397 		ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic);
    398 	}
    399 #if defined(SOC_BCM2836)
    400 	ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic[cpuid]);
    401 #endif
    402 
    403 	/*
    404 	 * Record the pending_ipls and deliver them if we can.
    405 	 */
    406 	if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
    407 		pic_do_pending_ints(I32_bit, oldipl, frame);
    408 }
    409 
    410 static void
    411 bcm2835_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    412     uint32_t irq_mask)
    413 {
    414 
    415 	write_bcm2835reg(BCM2835_INTC_ENABLEBASE + (irqbase >> 3), irq_mask);
    416 	bcm2835_barrier();
    417 }
    418 
    419 static void
    420 bcm2835_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
    421     uint32_t irq_mask)
    422 {
    423 
    424 	write_bcm2835reg(BCM2835_INTC_DISABLEBASE + (irqbase >> 3), irq_mask);
    425 	bcm2835_barrier();
    426 }
    427 
    428 /*
    429  * Called with interrupts disabled
    430  */
    431 static int
    432 bcm2835_pic_find_pending_irqs(struct pic_softc *pic)
    433 {
    434 	int ipl = 0;
    435 	uint32_t bpending, gpu0irq, gpu1irq, armirq;
    436 
    437 	bcm2835_barrier();
    438 	bpending = read_bcm2835reg(BCM2835_INTC_IRQBPENDING);
    439 	if (bpending == 0)
    440 		return 0;
    441 
    442 	armirq = bpending & BCM2835_INTBIT_ARM;
    443 	gpu0irq = bpending & BCM2835_INTBIT_GPU0;
    444 	gpu1irq = bpending & BCM2835_INTBIT_GPU1;
    445 
    446 	if (armirq) {
    447 		ipl |= pic_mark_pending_sources(pic,
    448 		    BCM2835_INT_BASICBASE - BCM2835_INT_BASE, armirq);
    449 	}
    450 
    451 	if (gpu0irq || (bpending & BCM2835_INTBIT_PENDING1)) {
    452 		uint32_t pending1;
    453 
    454 		pending1 = read_bcm2835reg(BCM2835_INTC_IRQ1PENDING);
    455 		ipl |= pic_mark_pending_sources(pic,
    456 		    BCM2835_INT_GPU0BASE - BCM2835_INT_BASE, pending1);
    457 	}
    458 	if (gpu1irq || (bpending & BCM2835_INTBIT_PENDING2)) {
    459 		uint32_t pending2;
    460 
    461 		pending2 = read_bcm2835reg(BCM2835_INTC_IRQ2PENDING);
    462 		ipl |= pic_mark_pending_sources(pic,
    463 		    BCM2835_INT_GPU1BASE - BCM2835_INT_BASE, pending2);
    464 	}
    465 
    466 	return ipl;
    467 }
    468 
    469 static void
    470 bcm2835_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    471 {
    472 
    473 	/* Nothing really*/
    474 	KASSERT(is->is_irq < BCM2835_NIRQ);
    475 	KASSERT(is->is_type == IST_LEVEL);
    476 }
    477 
    478 static void
    479 bcm2835_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
    480 {
    481 
    482 	strlcpy(buf, bcm2835_sources[irq], len);
    483 }
    484 
    485 static int
    486 bcm2835_icu_fdt_decode_irq(u_int *specifier)
    487 {
    488 	u_int base;
    489 
    490 	if (!specifier)
    491 		return -1;
    492 
    493 	/* 1st cell is the bank number. 0 = ARM, 1 = GPU0, 2 = GPU1 */
    494 	/* 2nd cell is the irq relative to that bank */
    495 
    496 	const u_int bank = be32toh(specifier[0]);
    497 	switch (bank) {
    498 	case 0:
    499 		base = BCM2835_INT_BASICBASE;
    500 		break;
    501 	case 1:
    502 		base = BCM2835_INT_GPU0BASE;
    503 		break;
    504 	case 2:
    505 		base = BCM2835_INT_GPU1BASE;
    506 		break;
    507 	default:
    508 		return -1;
    509 	}
    510 	const u_int off = be32toh(specifier[1]);
    511 
    512 	return base + off;
    513 }
    514 
    515 static void *
    516 bcm2835_icu_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
    517     int (*func)(void *), void *arg, const char *xname)
    518 {
    519 	struct bcm2835icu_softc * const sc = device_private(dev);
    520 	struct bcm2835icu_irq *firq;
    521 	struct bcm2835icu_irqhandler *firqh;
    522 	int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
    523 	int irq, irqidx;
    524 
    525 	irq = bcm2835_icu_fdt_decode_irq(specifier);
    526 	if (irq == -1)
    527 		return NULL;
    528 	irqidx = irq - BCM2835_INT_BASE;
    529 
    530 	KASSERT(irqidx < BCM2835_NIRQ);
    531 
    532 	firq = sc->sc_irq[irqidx];
    533 	if (firq == NULL) {
    534 		firq = kmem_alloc(sizeof(*firq), KM_SLEEP);
    535 		firq->intr_sc = sc;
    536 		firq->intr_refcnt = 0;
    537 		firq->intr_arg = arg;
    538 		firq->intr_ipl = ipl;
    539 		firq->intr_mpsafe = iflags;
    540 		firq->intr_irq = irq;
    541 		TAILQ_INIT(&firq->intr_handlers);
    542 		if (arg == NULL) {
    543 			firq->intr_ih = intr_establish_xname(irq, ipl,
    544 			    IST_LEVEL | iflags, func, NULL, xname);
    545 		} else {
    546 			firq->intr_ih = intr_establish_xname(irq, ipl,
    547 			    IST_LEVEL | iflags, bcm2835_icu_intr, firq, xname);
    548 		}
    549 		if (firq->intr_ih == NULL) {
    550 			kmem_free(firq, sizeof(*firq));
    551 			return NULL;
    552 		}
    553 		sc->sc_irq[irqidx] = firq;
    554 	} else {
    555 		if (firq->intr_arg == NULL || arg == NULL) {
    556 			device_printf(dev,
    557 			    "cannot share irq with NULL-arg handler\n");
    558 			return NULL;
    559 		}
    560 		if (firq->intr_ipl != ipl) {
    561 			device_printf(dev,
    562 			    "cannot share irq with different ipl\n");
    563 			return NULL;
    564 		}
    565 		if (firq->intr_mpsafe != iflags) {
    566 			device_printf(dev,
    567 			    "cannot share irq between mpsafe/non-mpsafe\n");
    568 			return NULL;
    569 		}
    570 	}
    571 
    572 	firqh = kmem_alloc(sizeof(*firqh), KM_SLEEP);
    573 	firqh->ih_irq = firq;
    574 	firqh->ih_fn = func;
    575 	firqh->ih_arg = arg;
    576 
    577 	firq->intr_refcnt++;
    578 	TAILQ_INSERT_TAIL(&firq->intr_handlers, firqh, ih_next);
    579 
    580 	/*
    581 	 * XXX interrupt_distribute(9) assumes that any interrupt
    582 	 * handle can be used as an input to the MD interrupt_distribute
    583 	 * implementationm, so we are forced to return the handle
    584 	 * we got back from intr_establish().  Upshot is that the
    585 	 * input to bcm2835_icu_fdt_disestablish() is ambiguous for
    586 	 * shared IRQs, rendering them un-disestablishable.
    587 	 */
    588 
    589 	return firq->intr_ih;
    590 }
    591 
    592 static void
    593 bcm2835_icu_fdt_disestablish(device_t dev, void *ih)
    594 {
    595 	struct bcm2835icu_softc * const sc = device_private(dev);
    596 	struct bcm2835icu_irqhandler *firqh;
    597 	struct bcm2835icu_irq *firq;
    598 	u_int n;
    599 
    600 	for (n = 0; n < BCM2835_NIRQ; n++) {
    601 		firq = sc->sc_irq[n];
    602 		if (firq == NULL || firq->intr_ih != ih)
    603 			continue;
    604 
    605 		KASSERT(firq->intr_refcnt > 0);
    606 		KASSERT(n == (firq->intr_irq - BCM2835_INT_BASE));
    607 
    608 		/* XXX see above */
    609 		if (firq->intr_refcnt > 1)
    610 			panic("%s: cannot disestablish shared irq", __func__);
    611 
    612 		intr_disestablish(firq->intr_ih);
    613 
    614 		firqh = TAILQ_FIRST(&firq->intr_handlers);
    615 		TAILQ_REMOVE(&firq->intr_handlers, firqh, ih_next);
    616 		kmem_free(firqh, sizeof(*firqh));
    617 
    618 		sc->sc_irq[n] = NULL;
    619 		kmem_free(firq, sizeof(*firq));
    620 
    621 		return;
    622 	}
    623 
    624 	panic("%s: interrupt not established", __func__);
    625 }
    626 
    627 static int
    628 bcm2835_icu_intr(void *priv)
    629 {
    630 	struct bcm2835icu_irq *firq = priv;
    631 	struct bcm2835icu_irqhandler *firqh;
    632 	int handled = 0;
    633 
    634 	TAILQ_FOREACH(firqh, &firq->intr_handlers, ih_next) {
    635 		handled |= firqh->ih_fn(firqh->ih_arg);
    636 	}
    637 
    638 	return handled;
    639 }
    640 
    641 static bool
    642 bcm2835_icu_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
    643 {
    644 	int irq;
    645 
    646 	irq = bcm2835_icu_fdt_decode_irq(specifier);
    647 	if (irq == -1)
    648 		return false;
    649 
    650 	snprintf(buf, buflen, "icu irq %d", irq);
    651 
    652 	return true;
    653 }
    654 
    655 #define	BCM2836MP_TIMER_IRQS	__BITS(3,0)
    656 #define	BCM2836MP_MAILBOX_IRQS	__BITS(4,7)
    657 #define	BCM2836MP_GPU_IRQ	__BIT(8)
    658 #define	BCM2836MP_PMU_IRQ	__BIT(9)
    659 #define	BCM2836MP_ALL_IRQS	(BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS | BCM2836MP_GPU_IRQ | BCM2836MP_PMU_IRQ)
    660 
    661 static void
    662 bcm2836mp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    663     uint32_t irq_mask)
    664 {
    665 	const bus_space_tag_t iot = bcml1icu_sc->sc_iot;
    666 	const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh;
    667 	const cpuid_t cpuid = pic - &bcm2836mp_pic[0];
    668 
    669 	KASSERT(cpuid < BCM2836_NCPUS);
    670 	KASSERT(irqbase == 0);
    671 
    672 	if (irq_mask & BCM2836MP_TIMER_IRQS) {
    673 		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
    674 		uint32_t val = bus_space_read_4(iot, ioh,
    675 		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
    676 		val |= mask;
    677 		bus_space_write_4(iot, ioh,
    678 		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
    679 		    val);
    680 		bus_space_barrier(iot, ioh,
    681 		    BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE,
    682 		    BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE,
    683 		    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
    684 	}
    685 	if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
    686 		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
    687 		uint32_t val = bus_space_read_4(iot, ioh,
    688 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
    689 		val |= mask;
    690 		bus_space_write_4(iot, ioh,
    691 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
    692 		    val);
    693 		bus_space_barrier(iot, ioh,
    694 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE,
    695 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_SIZE,
    696 		    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
    697 	}
    698 	if (irq_mask & BCM2836MP_PMU_IRQ) {
    699 		bus_space_write_4(iot, ioh, BCM2836_LOCAL_PM_ROUTING_SET,
    700 		    __BIT(cpuid));
    701 		bus_space_barrier(iot, ioh, BCM2836_LOCAL_PM_ROUTING_SET, 4,
    702 		    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
    703 	}
    704 
    705 	return;
    706 }
    707 
    708 static void
    709 bcm2836mp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
    710     uint32_t irq_mask)
    711 {
    712 	const bus_space_tag_t iot = bcml1icu_sc->sc_iot;
    713 	const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh;
    714 	const cpuid_t cpuid = pic - &bcm2836mp_pic[0];
    715 
    716 	KASSERT(cpuid < BCM2836_NCPUS);
    717 	KASSERT(irqbase == 0);
    718 
    719 	if (irq_mask & BCM2836MP_TIMER_IRQS) {
    720 		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
    721 		uint32_t val = bus_space_read_4(iot, ioh,
    722 		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
    723 		val &= ~mask;
    724 		bus_space_write_4(iot, ioh,
    725 		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
    726 		    val);
    727 	}
    728 	if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
    729 		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
    730 		uint32_t val = bus_space_read_4(iot, ioh,
    731 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
    732 		val &= ~mask;
    733 		bus_space_write_4(iot, ioh,
    734 		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
    735 		    val);
    736 	}
    737 	if (irq_mask & BCM2836MP_PMU_IRQ) {
    738 		bus_space_write_4(iot, ioh, BCM2836_LOCAL_PM_ROUTING_CLR,
    739 		    __BIT(cpuid));
    740 	}
    741 
    742 	bcm2835_barrier();
    743 	return;
    744 }
    745 
    746 static int
    747 bcm2836mp_pic_find_pending_irqs(struct pic_softc *pic)
    748 {
    749 	struct cpu_info * const ci = curcpu();
    750 	const cpuid_t cpuid = ci->ci_core_id;
    751 	uint32_t lpending;
    752 	int ipl = 0;
    753 
    754 	KASSERT(cpuid < BCM2836_NCPUS);
    755 	KASSERT(pic == &bcm2836mp_pic[cpuid]);
    756 
    757 	bcm2835_barrier();
    758 
    759 	lpending = bus_space_read_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
    760 	    BCM2836_LOCAL_INTC_IRQPENDINGN(cpuid));
    761 
    762 	lpending &= ~BCM2836_INTBIT_GPUPENDING;
    763 	const uint32_t allirqs = lpending & BCM2836MP_ALL_IRQS;
    764 	if (allirqs) {
    765 		ipl |= pic_mark_pending_sources(pic, 0, allirqs);
    766 	}
    767 
    768 	return ipl;
    769 }
    770 
    771 static void
    772 bcm2836mp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    773 {
    774 	/* Nothing really*/
    775 	KASSERT(is->is_irq >= 0);
    776 	KASSERT(is->is_irq < BCM2836_NIRQPERCPU);
    777 }
    778 
    779 static void
    780 bcm2836mp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
    781 {
    782 
    783 	irq %= BCM2836_NIRQPERCPU;
    784 	strlcpy(buf, bcm2836mp_sources[irq], len);
    785 }
    786 
    787 
    788 #if defined(MULTIPROCESSOR)
    789 static void bcm2836mp_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
    790 {
    791 	const cpuid_t cpuid = ci->ci_core_id;
    792 
    793 	KASSERT(cpuid < BCM2836_NCPUS);
    794 
    795 	/* Enable IRQ and not FIQ */
    796 	bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
    797 	    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid), 1);
    798 }
    799 
    800 static void
    801 bcm2836mp_send_ipi(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi)
    802 {
    803 	KASSERT(pic != NULL);
    804 	KASSERT(pic != &bcm2835_pic);
    805 	KASSERT(pic->pic_cpus != NULL);
    806 
    807 	const cpuid_t cpuid = pic - &bcm2836mp_pic[0];
    808 	KASSERT(cpuid < BCM2836_NCPUS);
    809 
    810 	bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
    811 	    BCM2836_LOCAL_MAILBOX0_SETN(cpuid), __BIT(ipi));
    812 }
    813 
    814 int
    815 bcm2836mp_ipi_handler(void *priv)
    816 {
    817 	const struct cpu_info *ci = curcpu();
    818 	const cpuid_t cpuid = ci->ci_core_id;
    819 	uint32_t ipimask, bit;
    820 
    821 	KASSERT(cpuid < BCM2836_NCPUS);
    822 
    823 	ipimask = bus_space_read_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
    824 	    BCM2836_LOCAL_MAILBOX0_CLRN(cpuid));
    825 	bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
    826 	    BCM2836_LOCAL_MAILBOX0_CLRN(cpuid), ipimask);
    827 
    828 	while ((bit = ffs(ipimask)) > 0) {
    829 		const u_int ipi = bit - 1;
    830 		switch (ipi) {
    831 		case IPI_AST:
    832 			pic_ipi_ast(priv);
    833 			break;
    834 		case IPI_NOP:
    835 			pic_ipi_nop(priv);
    836 			break;
    837 #ifdef __HAVE_PREEMPTION
    838 		case IPI_KPREEMPT:
    839 			pic_ipi_kpreempt(priv);
    840 			break;
    841 #endif
    842 		case IPI_XCALL:
    843 			pic_ipi_xcall(priv);
    844 			break;
    845 		case IPI_GENERIC:
    846 			pic_ipi_generic(priv);
    847 			break;
    848 		case IPI_SHOOTDOWN:
    849 			pic_ipi_shootdown(priv);
    850 			break;
    851 #ifdef DDB
    852 		case IPI_DDB:
    853 			pic_ipi_ddb(priv);
    854 			break;
    855 #endif
    856 		}
    857 		ipimask &= ~__BIT(ipi);
    858 	}
    859 
    860 	return 1;
    861 }
    862 #endif
    863 
    864 static void
    865 bcm2836mp_intr_init(void *priv, struct cpu_info *ci)
    866 {
    867 	const cpuid_t cpuid = ci->ci_core_id;
    868 	struct pic_softc * const pic = &bcm2836mp_pic[cpuid];
    869 
    870 	KASSERT(cpuid < BCM2836_NCPUS);
    871 
    872 #if defined(MULTIPROCESSOR)
    873 	pic->pic_cpus = ci->ci_kcpuset;
    874 
    875 	/*
    876 	 * Append "#n" to avoid duplication of .pic_name[]
    877 	 * It should be a unique id for intr_get_source()
    878 	 */
    879 	char suffix[sizeof("#00000")];
    880 	snprintf(suffix, sizeof(suffix), "#%lu", cpuid);
    881 	strlcat(pic->pic_name, suffix, sizeof(pic->pic_name));
    882 #endif
    883 	bcm2836mp_int_base[cpuid] = pic_add(pic, PIC_IRQBASE_ALLOC);
    884 
    885 #if defined(MULTIPROCESSOR)
    886 	intr_establish(BCM2836_INT_MAILBOX0_CPUN(cpuid), IPL_HIGH,
    887 	    IST_LEVEL | IST_MPSAFE, bcm2836mp_ipi_handler, NULL);
    888 
    889 	struct bcm2836mp_interrupt *bip;
    890 	TAILQ_FOREACH(bip, &bcm2836mp_interrupts, bi_next) {
    891 		if (bip->bi_done)
    892 			continue;
    893 
    894 		const int irq = BCM2836_INT_BASECPUN(cpuid) + bip->bi_irq;
    895 		void *ih = intr_establish(irq, bip->bi_ipl,
    896 		    IST_LEVEL | bip->bi_flags, bip->bi_func, bip->bi_arg);
    897 
    898 		bip->bi_ihs[cpuid] = ih;
    899 	}
    900 #endif
    901 }
    902 
    903 static int
    904 bcm2836mp_icu_fdt_decode_irq(u_int *specifier)
    905 {
    906 
    907 	if (!specifier)
    908 		return -1;
    909 	return be32toh(specifier[0]);
    910 }
    911 
    912 static void *
    913 bcm2836mp_icu_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
    914     int (*func)(void *), void *arg, const char *xname)
    915 {
    916 	int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
    917 	struct bcm2836mp_interrupt *bip;
    918 	void *ih;
    919 
    920 	int irq = bcm2836mp_icu_fdt_decode_irq(specifier);
    921 	if (irq == -1)
    922 		return NULL;
    923 
    924 	TAILQ_FOREACH(bip, &bcm2836mp_interrupts, bi_next) {
    925 		if (irq == bip->bi_irq)
    926 			return NULL;
    927 	}
    928 
    929 	bip = kmem_alloc(sizeof(*bip), KM_SLEEP);
    930 	if (bip == NULL)
    931 		return NULL;
    932 
    933 	bip->bi_done = false;
    934 	bip->bi_irq = irq;
    935 	bip->bi_ipl = ipl;
    936 	bip->bi_flags = IST_LEVEL | iflags;
    937 	bip->bi_func = func;
    938 	bip->bi_arg = arg;
    939 
    940 	/*
    941 	 * If we're not cold and the BPs have been started then we can
    942 	 * register the interrupt for all CPUs now, e.g. PMU
    943 	 */
    944 	if (!cold) {
    945 		for (cpuid_t cpuid = 0; cpuid < BCM2836_NCPUS; cpuid++) {
    946 			ih = intr_establish_xname(
    947 			    BCM2836_INT_BASECPUN(cpuid) + irq, ipl,
    948 			    IST_LEVEL | iflags, func, arg, xname);
    949 			if (!ih) {
    950 				kmem_free(bip, sizeof(*bip));
    951 				return NULL;
    952 			}
    953 			bip->bi_ihs[cpuid] = ih;
    954 
    955 		}
    956 		bip->bi_done = true;
    957 		ih = bip->bi_ihs[0];
    958 		goto done;
    959 	}
    960 
    961 	/*
    962 	 * Otherwise we can only establish the interrupt for the BP and
    963 	 * delay until bcm2836mp_intr_init is called for each AP, e.g.
    964 	 * gtmr
    965 	 */
    966 	ih = intr_establish_xname(BCM2836_INT_BASECPUN(0) + irq, ipl,
    967 	    IST_LEVEL | iflags, func, arg, xname);
    968 	if (!ih) {
    969 		kmem_free(bip, sizeof(*bip));
    970 		return NULL;
    971 	}
    972 
    973 	bip->bi_ihs[0] = ih;
    974 	for (cpuid_t cpuid = 1; cpuid < BCM2836_NCPUS; cpuid++)
    975 		bip->bi_ihs[cpuid] = NULL;
    976 
    977 done:
    978 	TAILQ_INSERT_TAIL(&bcm2836mp_interrupts, bip, bi_next);
    979 
    980 	/*
    981 	 * Return the intr_establish handle for cpu 0 for API compatibility.
    982 	 * Any cpu would do here as these sources don't support set_affinity
    983 	 * when the handle is used in interrupt_distribute(9)
    984 	 */
    985 	return ih;
    986 }
    987 
    988 static void
    989 bcm2836mp_icu_fdt_disestablish(device_t dev, void *ih)
    990 {
    991 	struct bcm2836mp_interrupt *bip;
    992 
    993 	TAILQ_FOREACH(bip, &bcm2836mp_interrupts, bi_next) {
    994 		if (bip->bi_ihs[0] == ih)
    995 			break;
    996 	}
    997 
    998 	if (bip == NULL)
    999 		return;
   1000 
   1001 	for (cpuid_t cpuid = 0; cpuid < BCM2836_NCPUS; cpuid++)
   1002 		intr_disestablish(bip->bi_ihs[cpuid]);
   1003 
   1004 	TAILQ_REMOVE(&bcm2836mp_interrupts, bip, bi_next);
   1005 
   1006 	kmem_free(bip, sizeof(*bip));
   1007 }
   1008 
   1009 static bool
   1010 bcm2836mp_icu_fdt_intrstr(device_t dev, u_int *specifier, char *buf,
   1011     size_t buflen)
   1012 {
   1013 	int irq;
   1014 
   1015 	irq = bcm2836mp_icu_fdt_decode_irq(specifier);
   1016 	if (irq == -1)
   1017 		return false;
   1018 
   1019 	snprintf(buf, buflen, "local_intc irq %d", irq);
   1020 
   1021 	return true;
   1022 }
   1023