9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 */
29
30 #include <sys/processor.h>
31 #include <sys/time.h>
32 #include <sys/psm.h>
33 #include <sys/smp_impldefs.h>
34 #include <sys/cram.h>
35 #include <sys/acpi/acpi.h>
36 #include <sys/acpica.h>
37 #include <sys/psm_common.h>
38 #include <sys/pit.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/ddi_impldefs.h>
42 #include <sys/pci.h>
43 #include <sys/promif.h>
44 #include <sys/x86_archext.h>
45 #include <sys/cpc_impl.h>
46 #include <sys/uadmin.h>
47 #include <sys/panic.h>
48 #include <sys/debug.h>
1812
1813 return (apix_set_cpu(vecp, bindcpu, &ret));
1814 }
1815
1816 /*
1817 * For interrupts which call add_avintr() before apic is initialized.
1818 * ioapix_setup_intr() will
1819 * - allocate vector
1820 * - copy over ISR
1821 */
1822 static void
1823 ioapix_setup_intr(int irqno, iflag_t *flagp)
1824 {
1825 extern struct av_head autovect[];
1826 apix_vector_t *vecp;
1827 apic_irq_t *irqp;
1828 uchar_t ioapicindex, ipin;
1829 ulong_t iflag;
1830 struct autovec *avp;
1831
1832 irqp = apic_irq_table[irqno];
1833 ioapicindex = acpi_find_ioapic(irqno);
1834 ASSERT(ioapicindex != 0xFF);
1835 ipin = irqno - apic_io_vectbase[ioapicindex];
1836
1837 if ((irqp != NULL) && (irqp->airq_mps_intr_index == ACPI_INDEX)) {
1838 ASSERT(irqp->airq_intin_no == ipin &&
1839 irqp->airq_ioapicindex == ioapicindex);
1840 vecp = xv_vector(irqp->airq_cpu, irqp->airq_vector);
1841 ASSERT(!IS_VECT_FREE(vecp));
1842 } else {
1843 vecp = apix_alloc_intx(NULL, 0, irqno);
1844
1845 irqp = apic_irq_table[irqno];
1846 irqp->airq_mps_intr_index = ACPI_INDEX;
1847 irqp->airq_ioapicindex = ioapicindex;
1848 irqp->airq_intin_no = ipin;
1849 irqp->airq_iflag = *flagp;
1850 irqp->airq_share++;
1851 apic_record_rdt_entry(irqp, irqno);
1852 }
1853
1854 /* copy over autovect */
1855 for (avp = autovect[irqno].avh_link; avp; avp = avp->av_link)
1856 apix_insert_av(vecp, avp->av_intr_id, avp->av_vector,
1857 avp->av_intarg1, avp->av_intarg2, avp->av_ticksp,
1858 avp->av_prilevel, avp->av_dip);
1859
1860 /* Program I/O APIC */
1861 iflag = intr_clear();
1862 lock_set(&apix_lock);
1863
1864 (void) apix_setup_io_intr(vecp);
1865
1866 lock_clear(&apix_lock);
1867 intr_restore(iflag);
1868
1869 APIC_VERBOSE_IOAPIC((CE_CONT, "apix: setup ioapic, irqno %x "
1870 "(ioapic %x, ipin %x) is bound to cpu %x, vector %x\n",
1871 irqno, ioapicindex, ipin, irqp->airq_cpu, irqp->airq_vector));
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright (c) 2010, Intel Corporation.
27 * All rights reserved.
28 */
29 /*
30 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
31 */
32
33 #include <sys/processor.h>
34 #include <sys/time.h>
35 #include <sys/psm.h>
36 #include <sys/smp_impldefs.h>
37 #include <sys/cram.h>
38 #include <sys/acpi/acpi.h>
39 #include <sys/acpica.h>
40 #include <sys/psm_common.h>
41 #include <sys/pit.h>
42 #include <sys/ddi.h>
43 #include <sys/sunddi.h>
44 #include <sys/ddi_impldefs.h>
45 #include <sys/pci.h>
46 #include <sys/promif.h>
47 #include <sys/x86_archext.h>
48 #include <sys/cpc_impl.h>
49 #include <sys/uadmin.h>
50 #include <sys/panic.h>
51 #include <sys/debug.h>
1815
1816 return (apix_set_cpu(vecp, bindcpu, &ret));
1817 }
1818
1819 /*
1820 * For interrupts which call add_avintr() before apic is initialized.
1821 * ioapix_setup_intr() will
1822 * - allocate vector
1823 * - copy over ISR
1824 */
1825 static void
1826 ioapix_setup_intr(int irqno, iflag_t *flagp)
1827 {
1828 extern struct av_head autovect[];
1829 apix_vector_t *vecp;
1830 apic_irq_t *irqp;
1831 uchar_t ioapicindex, ipin;
1832 ulong_t iflag;
1833 struct autovec *avp;
1834
1835 ioapicindex = acpi_find_ioapic(irqno);
1836 ASSERT(ioapicindex != 0xFF);
1837 ipin = irqno - apic_io_vectbase[ioapicindex];
1838
1839 mutex_enter(&airq_mutex);
1840 irqp = apic_irq_table[irqno];
1841
1842 /*
1843 * The irq table entry should not exist unless the interrupts are shared.
1844 * In that case, make sure it matches what we would initialize it to.
1845 */
1846 if (irqp != NULL) {
1847 ASSERT(irqp->airq_mps_intr_index == ACPI_INDEX);
1848 ASSERT(irqp->airq_intin_no == ipin &&
1849 irqp->airq_ioapicindex == ioapicindex);
1850 vecp = xv_vector(irqp->airq_cpu, irqp->airq_vector);
1851 ASSERT(!IS_VECT_FREE(vecp));
1852 mutex_exit(&airq_mutex);
1853 } else {
1854 irqp = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
1855
1856 irqp->airq_cpu = IRQ_UNINIT;
1857 irqp->airq_origirq = (uchar_t)irqno;
1858 irqp->airq_mps_intr_index = ACPI_INDEX;
1859 irqp->airq_ioapicindex = ioapicindex;
1860 irqp->airq_intin_no = ipin;
1861 irqp->airq_iflag = *flagp;
1862 irqp->airq_share++;
1863
1864 apic_irq_table[irqno] = irqp;
1865 mutex_exit(&airq_mutex);
1866
1867 vecp = apix_alloc_intx(NULL, 0, irqno);
1868 }
1869
1870 /* copy over autovect */
1871 for (avp = autovect[irqno].avh_link; avp; avp = avp->av_link)
1872 apix_insert_av(vecp, avp->av_intr_id, avp->av_vector,
1873 avp->av_intarg1, avp->av_intarg2, avp->av_ticksp,
1874 avp->av_prilevel, avp->av_dip);
1875
1876 /* Program I/O APIC */
1877 iflag = intr_clear();
1878 lock_set(&apix_lock);
1879
1880 (void) apix_setup_io_intr(vecp);
1881
1882 lock_clear(&apix_lock);
1883 intr_restore(iflag);
1884
1885 APIC_VERBOSE_IOAPIC((CE_CONT, "apix: setup ioapic, irqno %x "
1886 "(ioapic %x, ipin %x) is bound to cpu %x, vector %x\n",
1887 irqno, ioapicindex, ipin, irqp->airq_cpu, irqp->airq_vector));
|