subr_intr.c (fae8755f16ff5b9bdc32df046e0f16c0cbb48a29) subr_intr.c (103d39efe0c68cb2a808c306b14c3f473a02535d)
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 * Copyright (c) 2015-2016 The FreeBSD Foundation
6 * Copyright (c) 2021 Jessica Clarke <jrtc27@FreeBSD.org>
7 *
8 * Portions of this software were developed by Andrew Turner under

--- 125 unchanged lines hidden (view full) ---

134
135struct intr_ipi {
136 intr_ipi_handler_t *ii_handler;
137 void *ii_handler_arg;
138 struct intr_irqsrc *ii_isrc;
139 char ii_name[INTR_IPI_NAMELEN];
140 u_long *ii_count;
141};
1/*-
2 * Copyright (c) 2015-2016 Svatopluk Kraus
3 * Copyright (c) 2015-2016 Michal Meloun
4 * All rights reserved.
5 * Copyright (c) 2015-2016 The FreeBSD Foundation
6 * Copyright (c) 2021 Jessica Clarke <jrtc27@FreeBSD.org>
7 *
8 * Portions of this software were developed by Andrew Turner under

--- 125 unchanged lines hidden (view full) ---

134
135struct intr_ipi {
136 intr_ipi_handler_t *ii_handler;
137 void *ii_handler_arg;
138 struct intr_irqsrc *ii_isrc;
139 char ii_name[INTR_IPI_NAMELEN];
140 u_long *ii_count;
141};
142
143static device_t intr_ipi_dev;
144static u_int intr_ipi_dev_priority;
145static bool intr_ipi_dev_frozen;
142#endif
143
144static struct mtx pic_list_lock;
145static SLIST_HEAD(, intr_pic) pic_list;
146
147static struct intr_pic *pic_lookup(device_t dev, intptr_t xref, int flags);
148
149/* Interrupt source definition. */

--- 225 unchanged lines hidden (view full) ---

375 * source is learned.
376 */
377int
378intr_isrc_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf)
379{
380
381 KASSERT(isrc != NULL, ("%s: no source", __func__));
382
146#endif
147
148static struct mtx pic_list_lock;
149static SLIST_HEAD(, intr_pic) pic_list;
150
151static struct intr_pic *pic_lookup(device_t dev, intptr_t xref, int flags);
152
153/* Interrupt source definition. */

--- 225 unchanged lines hidden (view full) ---

379 * source is learned.
380 */
381int
382intr_isrc_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf)
383{
384
385 KASSERT(isrc != NULL, ("%s: no source", __func__));
386
383 isrc_increment_count(isrc);
387 if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0)
388 isrc_increment_count(isrc);
384
385#ifdef INTR_SOLO
386 if (isrc->isrc_filter != NULL) {
387 int error;
388 error = isrc->isrc_filter(isrc->isrc_arg, tf);
389 PIC_POST_FILTER(isrc->isrc_dev, isrc);
390 if (error == FILTER_HANDLED)
391 return (0);
392 } else
393#endif
394 if (isrc->isrc_event != NULL) {
395 if (intr_event_handle(isrc->isrc_event, tf) == 0)
396 return (0);
397 }
398
389
390#ifdef INTR_SOLO
391 if (isrc->isrc_filter != NULL) {
392 int error;
393 error = isrc->isrc_filter(isrc->isrc_arg, tf);
394 PIC_POST_FILTER(isrc->isrc_dev, isrc);
395 if (error == FILTER_HANDLED)
396 return (0);
397 } else
398#endif
399 if (isrc->isrc_event != NULL) {
400 if (intr_event_handle(isrc->isrc_event, tf) == 0)
401 return (0);
402 }
403
399 isrc_increment_straycount(isrc);
404 if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0)
405 isrc_increment_straycount(isrc);
400 return (EINVAL);
401}
402
403/*
404 * Alloc unique interrupt number (resource handle) for interrupt source.
405 *
406 * There could be various strategies how to allocate free interrupt number
407 * (resource handle) for new interrupt source.

--- 1402 unchanged lines hidden (view full) ---

1810{
1811
1812 if (ipi >= INTR_IPI_COUNT)
1813 panic("%s: no such IPI %u", __func__, ipi);
1814
1815 return (&ipi_sources[ipi]);
1816}
1817
406 return (EINVAL);
407}
408
409/*
410 * Alloc unique interrupt number (resource handle) for interrupt source.
411 *
412 * There could be various strategies how to allocate free interrupt number
413 * (resource handle) for new interrupt source.

--- 1402 unchanged lines hidden (view full) ---

1816{
1817
1818 if (ipi >= INTR_IPI_COUNT)
1819 panic("%s: no such IPI %u", __func__, ipi);
1820
1821 return (&ipi_sources[ipi]);
1822}
1823
1824int
1825intr_ipi_pic_register(device_t dev, u_int priority)
1826{
1827 if (intr_ipi_dev_frozen) {
1828 device_printf(dev, "IPI device already frozen");
1829 return (EBUSY);
1830 }
1831
1832 if (intr_ipi_dev == NULL || priority > intr_ipi_dev_priority)
1833 intr_ipi_dev = dev;
1834
1835 return (0);
1836}
1837
1818/*
1819 * Setup IPI handler on interrupt controller.
1820 *
1821 * Not SMP coherent.
1822 */
1823void
1824intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
1825 void *arg)
1826{
1827 struct intr_irqsrc *isrc;
1828 struct intr_ipi *ii;
1829 int error;
1830
1838/*
1839 * Setup IPI handler on interrupt controller.
1840 *
1841 * Not SMP coherent.
1842 */
1843void
1844intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
1845 void *arg)
1846{
1847 struct intr_irqsrc *isrc;
1848 struct intr_ipi *ii;
1849 int error;
1850
1831 KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
1851 if (!intr_ipi_dev_frozen) {
1852 if (intr_ipi_dev == NULL)
1853 panic("%s: no IPI PIC attached", __func__);
1854
1855 intr_ipi_dev_frozen = true;
1856 device_printf(intr_ipi_dev, "using for IPIs\n");
1857 }
1858
1832 KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi));
1833
1859 KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi));
1860
1834 error = PIC_IPI_SETUP(intr_irq_root_dev, ipi, &isrc);
1861 error = PIC_IPI_SETUP(intr_ipi_dev, ipi, &isrc);
1835 if (error != 0)
1836 return;
1837
1838 isrc->isrc_handlers++;
1839
1840 ii = intr_ipi_lookup(ipi);
1841 KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi));
1842
1843 ii->ii_handler = hand;
1844 ii->ii_handler_arg = arg;
1845 ii->ii_isrc = isrc;
1846 strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN);
1847 ii->ii_count = intr_ipi_setup_counters(name);
1848
1862 if (error != 0)
1863 return;
1864
1865 isrc->isrc_handlers++;
1866
1867 ii = intr_ipi_lookup(ipi);
1868 KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi));
1869
1870 ii->ii_handler = hand;
1871 ii->ii_handler_arg = arg;
1872 ii->ii_isrc = isrc;
1873 strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN);
1874 ii->ii_count = intr_ipi_setup_counters(name);
1875
1849 PIC_ENABLE_INTR(intr_irq_root_dev, isrc);
1876 PIC_ENABLE_INTR(intr_ipi_dev, isrc);
1850}
1851
1852void
1853intr_ipi_send(cpuset_t cpus, u_int ipi)
1854{
1855 struct intr_ipi *ii;
1856
1877}
1878
1879void
1880intr_ipi_send(cpuset_t cpus, u_int ipi)
1881{
1882 struct intr_ipi *ii;
1883
1857 KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
1884 KASSERT(intr_ipi_dev_frozen,
1885 ("%s: IPI device not yet frozen", __func__));
1858
1859 ii = intr_ipi_lookup(ipi);
1860 if (ii->ii_count == NULL)
1861 panic("%s: not setup IPI %u", __func__, ipi);
1862
1863 /*
1864 * XXX: Surely needed on other architectures too? Either way should be
1865 * some kind of MI hook defined in an MD header, or the responsibility
1866 * of the MD caller if not widespread.
1867 */
1868#ifdef __aarch64__
1869 /*
1870 * Ensure that this CPU's stores will be visible to IPI
1871 * recipients before starting to send the interrupts.
1872 */
1873 dsb(ishst);
1874#endif
1875
1886
1887 ii = intr_ipi_lookup(ipi);
1888 if (ii->ii_count == NULL)
1889 panic("%s: not setup IPI %u", __func__, ipi);
1890
1891 /*
1892 * XXX: Surely needed on other architectures too? Either way should be
1893 * some kind of MI hook defined in an MD header, or the responsibility
1894 * of the MD caller if not widespread.
1895 */
1896#ifdef __aarch64__
1897 /*
1898 * Ensure that this CPU's stores will be visible to IPI
1899 * recipients before starting to send the interrupts.
1900 */
1901 dsb(ishst);
1902#endif
1903
1876 PIC_IPI_SEND(intr_irq_root_dev, ii->ii_isrc, cpus, ipi);
1904 PIC_IPI_SEND(intr_ipi_dev, ii->ii_isrc, cpus, ipi);
1877}
1878
1879/*
1880 * interrupt controller dispatch function for IPIs. It should
1881 * be called straight from the interrupt controller, when associated
1882 * interrupt source is learned. Or from anybody who has an interrupt
1883 * source mapped.
1884 */

--- 14 unchanged lines hidden ---
1905}
1906
1907/*
1908 * interrupt controller dispatch function for IPIs. It should
1909 * be called straight from the interrupt controller, when associated
1910 * interrupt source is learned. Or from anybody who has an interrupt
1911 * source mapped.
1912 */

--- 14 unchanged lines hidden ---