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 --- |