5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Nexenta Systems, Inc.
24 * Copyright (c) 2017 by Delphix. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 */
27 /*
28 * Copyright (c) 2010, Intel Corporation.
29 * All rights reserved.
30 */
31
32 /*
33 * PSMI 1.1 extensions are supported only in 2.6 and later versions.
34 * PSMI 1.2 extensions are supported only in 2.7 and later versions.
35 * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
36 * PSMI 1.5 extensions are supported in Solaris Nevada.
37 * PSMI 1.6 extensions are supported in Solaris Nevada.
38 * PSMI 1.7 extensions are supported in Solaris Nevada.
39 */
40 #define PSMI_1_7
41
42 #include <sys/processor.h>
43 #include <sys/time.h>
44 #include <sys/psm.h>
45 #include <sys/smp_impldefs.h>
1587 while (irqptr) {
1588 if ((irqptr->airq_mps_intr_index >= 0) &&
1589 (irqptr->airq_intin_no == intin) &&
1590 (irqptr->airq_ioapicindex == ioapic)) {
1591 APIC_VERBOSE_IOAPIC((CE_NOTE, "!Found irq "
1592 "entry for ioapic:intin %x:%x "
1593 "shared interrupts ?", ioapic, intin));
1594 return (i);
1595 }
1596 irqptr = irqptr->airq_next;
1597 }
1598 }
1599 return (-1);
1600 }
1601
1602 int
1603 apic_allocate_irq(int irq)
1604 {
1605 int freeirq, i;
1606
1607 if ((freeirq = apic_find_free_irq(irq, (APIC_RESV_IRQ - 1))) == -1)
1608 if ((freeirq = apic_find_free_irq(APIC_FIRST_FREE_IRQ,
1609 (irq - 1))) == -1) {
1610 /*
1611 * if BIOS really defines every single irq in the mps
1612 * table, then don't worry about conflicting with
1613 * them, just use any free slot in apic_irq_table
1614 */
1615 for (i = APIC_FIRST_FREE_IRQ; i < APIC_RESV_IRQ; i++) {
1616 if ((apic_irq_table[i] == NULL) ||
1617 apic_irq_table[i]->airq_mps_intr_index ==
1618 FREE_INDEX) {
1619 freeirq = i;
1620 break;
1621 }
1622 }
1623 if (freeirq == -1) {
1624 /* This shouldn't happen, but just in case */
1625 cmn_err(CE_WARN, "%s: NO available IRQ", psm_name);
1626 return (-1);
1627 }
1628 }
1629 if (apic_irq_table[freeirq] == NULL) {
1630 apic_irq_table[freeirq] =
1631 kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
1632 if (apic_irq_table[freeirq] == NULL) {
1633 cmn_err(CE_WARN, "%s: NO memory to allocate IRQ",
1634 psm_name);
1635 return (-1);
1636 }
1637 apic_irq_table[freeirq]->airq_temp_cpu = IRQ_UNINIT;
1638 apic_irq_table[freeirq]->airq_mps_intr_index = FREE_INDEX;
1639 }
1640 return (freeirq);
1641 }
1642
1643 static int
1644 apic_find_free_irq(int start, int end)
1645 {
1646 int i;
1647
1648 for (i = start; i <= end; i++)
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Nexenta Systems, Inc.
24 * Copyright (c) 2017 by Delphix. All rights reserved.
25 * Copyright (c) 2019, Joyent, Inc.
26 */
27 /*
28 * Copyright (c) 2010, Intel Corporation.
29 * All rights reserved.
30 */
31
32 /*
33 * PSMI 1.1 extensions are supported only in 2.6 and later versions.
34 * PSMI 1.2 extensions are supported only in 2.7 and later versions.
35 * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
36 * PSMI 1.5 extensions are supported in Solaris Nevada.
37 * PSMI 1.6 extensions are supported in Solaris Nevada.
38 * PSMI 1.7 extensions are supported in Solaris Nevada.
39 */
40 #define PSMI_1_7
41
42 #include <sys/processor.h>
43 #include <sys/time.h>
44 #include <sys/psm.h>
45 #include <sys/smp_impldefs.h>
1587 while (irqptr) {
1588 if ((irqptr->airq_mps_intr_index >= 0) &&
1589 (irqptr->airq_intin_no == intin) &&
1590 (irqptr->airq_ioapicindex == ioapic)) {
1591 APIC_VERBOSE_IOAPIC((CE_NOTE, "!Found irq "
1592 "entry for ioapic:intin %x:%x "
1593 "shared interrupts ?", ioapic, intin));
1594 return (i);
1595 }
1596 irqptr = irqptr->airq_next;
1597 }
1598 }
1599 return (-1);
1600 }
1601
1602 int
1603 apic_allocate_irq(int irq)
1604 {
1605 int freeirq, i;
1606
1607 if ((freeirq = apic_find_free_irq(irq, (APIC_RESV_IRQ - 1))) == -1) {
1608 if ((freeirq = apic_find_free_irq(APIC_FIRST_FREE_IRQ,
1609 (irq - 1))) == -1) {
1610 /*
1611 * if BIOS really defines every single irq in the mps
1612 * table, then don't worry about conflicting with
1613 * them, just use any free slot in apic_irq_table
1614 */
1615 for (i = APIC_FIRST_FREE_IRQ; i < APIC_RESV_IRQ; i++) {
1616 if ((apic_irq_table[i] == NULL) ||
1617 apic_irq_table[i]->airq_mps_intr_index ==
1618 FREE_INDEX) {
1619 freeirq = i;
1620 break;
1621 }
1622 }
1623
1624 if (freeirq == -1) {
1625 /* This shouldn't happen, but just in case */
1626 cmn_err(CE_WARN, "%s: NO available IRQ", psm_name);
1627 return (-1);
1628 }
1629 }
1630 }
1631
1632 if (apic_irq_table[freeirq] == NULL) {
1633 apic_irq_table[freeirq] =
1634 kmem_zalloc(sizeof (apic_irq_t), KM_NOSLEEP);
1635 if (apic_irq_table[freeirq] == NULL) {
1636 cmn_err(CE_WARN, "%s: NO memory to allocate IRQ",
1637 psm_name);
1638 return (-1);
1639 }
1640 apic_irq_table[freeirq]->airq_temp_cpu = IRQ_UNINIT;
1641 apic_irq_table[freeirq]->airq_mps_intr_index = FREE_INDEX;
1642 }
1643 return (freeirq);
1644 }
1645
1646 static int
1647 apic_find_free_irq(int start, int end)
1648 {
1649 int i;
1650
1651 for (i = start; i <= end; i++)
|