MachIntr: Add two methods to find IRQ
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 28 Aug 2012 04:23:26 +0000 (12:23 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 28 Aug 2012 04:26:28 +0000 (12:26 +0800)
- Find IRQ conforming to the specified trigger and polarity, if it was
  configured.
- Find IRQ by GSI, the located IRQ must conform to the specified trigger
  and polarity if it was configured.

sys/platform/pc32/apic/ioapic_abi.c
sys/platform/pc32/apic/ioapic_abi.h
sys/platform/pc32/i386/mptable.c
sys/platform/pc32/icu/icu_abi.c
sys/platform/pc32/isa/clock.c
sys/platform/pc64/apic/ioapic_abi.c
sys/platform/pc64/apic/ioapic_abi.h
sys/platform/pc64/icu/icu_abi.c
sys/platform/pc64/isa/clock.c
sys/platform/pc64/x86_64/mptable.c
sys/sys/machintr.h

index 0bdf382..ced1388 100644 (file)
@@ -496,6 +496,10 @@ static void        ioapic_abi_intr_teardown(int);
 static void    ioapic_abi_legacy_intr_config(int,
                    enum intr_trigger, enum intr_polarity);
 static int     ioapic_abi_legacy_intr_cpuid(int);
 static void    ioapic_abi_legacy_intr_config(int,
                    enum intr_trigger, enum intr_polarity);
 static int     ioapic_abi_legacy_intr_cpuid(int);
+static int     ioapic_abi_legacy_intr_find(int,
+                   enum intr_trigger, enum intr_polarity);
+static int     ioapic_abi_legacy_intr_find_bygsi(int,
+                   enum intr_trigger, enum intr_polarity);
 
 static int     ioapic_abi_msi_alloc(int [], int, int);
 static void    ioapic_abi_msi_release(const int [], int, int);
 
 static int     ioapic_abi_msi_alloc(int [], int, int);
 static void    ioapic_abi_msi_release(const int [], int, int);
@@ -527,6 +531,8 @@ struct machintr_abi MachIntrABI_IOAPIC = {
 
        .legacy_intr_config = ioapic_abi_legacy_intr_config,
        .legacy_intr_cpuid = ioapic_abi_legacy_intr_cpuid,
 
        .legacy_intr_config = ioapic_abi_legacy_intr_config,
        .legacy_intr_cpuid = ioapic_abi_legacy_intr_cpuid,
+       .legacy_intr_find = ioapic_abi_legacy_intr_find,
+       .legacy_intr_find_bygsi = ioapic_abi_legacy_intr_find_bygsi,
 
        .msi_alloc      = ioapic_abi_msi_alloc,
        .msi_release    = ioapic_abi_msi_release,
 
        .msi_alloc      = ioapic_abi_msi_alloc,
        .msi_release    = ioapic_abi_msi_release,
@@ -842,14 +848,22 @@ ioapic_fixup_legacy_irqmaps(void)
        }
 }
 
        }
 }
 
-int
-ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
+static int
+ioapic_abi_legacy_intr_find_bygsi(int gsi, enum intr_trigger trig,
     enum intr_polarity pola)
 {
        int cpu;
 
     enum intr_polarity pola)
 {
        int cpu;
 
-       KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL);
-       KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW);
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
 
        for (cpu = 0; cpu < ncpus; ++cpu) {
                int irq;
 
        for (cpu = 0; cpu < ncpus; ++cpu) {
                int irq;
@@ -861,7 +875,9 @@ ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
                        if (map->im_gsi == gsi) {
                                KKASSERT(map->im_type == IOAPIC_IMT_LEGACY);
 
                        if (map->im_gsi == gsi) {
                                KKASSERT(map->im_type == IOAPIC_IMT_LEGACY);
 
-                               if (map->im_flags & IOAPIC_IMF_CONF) {
+                               if ((map->im_flags & IOAPIC_IMF_CONF) &&
+                                   trig != INTR_TRIGGER_CONFORM &&
+                                   pola != INTR_POLARITY_CONFORM) {
                                        if (map->im_trig != trig ||
                                            map->im_pola != pola)
                                                return -1;
                                        if (map->im_trig != trig ||
                                            map->im_pola != pola)
                                                return -1;
@@ -873,14 +889,22 @@ ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
        return -1;
 }
 
        return -1;
 }
 
-int
-ioapic_find_legacy_by_irq(int irq, enum intr_trigger trig,
+static int
+ioapic_abi_legacy_intr_find(int irq, enum intr_trigger trig,
     enum intr_polarity pola)
 {
        int cpu;
 
     enum intr_polarity pola)
 {
        int cpu;
 
-       KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL);
-       KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW);
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
 
        if (irq < 0 || irq >= ioapic_abi_legacy_irq_max)
                return -1;
 
        if (irq < 0 || irq >= ioapic_abi_legacy_irq_max)
                return -1;
@@ -889,7 +913,9 @@ ioapic_find_legacy_by_irq(int irq, enum intr_trigger trig,
                const struct ioapic_irqmap *map = &ioapic_irqmaps[cpu][irq];
 
                if (map->im_type == IOAPIC_IMT_LEGACY) {
                const struct ioapic_irqmap *map = &ioapic_irqmaps[cpu][irq];
 
                if (map->im_type == IOAPIC_IMT_LEGACY) {
-                       if (map->im_flags & IOAPIC_IMF_CONF) {
+                       if ((map->im_flags & IOAPIC_IMF_CONF) &&
+                           trig != INTR_TRIGGER_CONFORM &&
+                           pola != INTR_POLARITY_CONFORM) {
                                if (map->im_trig != trig ||
                                    map->im_pola != pola)
                                        return -1;
                                if (map->im_trig != trig ||
                                    map->im_pola != pola)
                                        return -1;
index 3fd3d4e..7c548ec 100644 (file)
@@ -70,7 +70,4 @@ void  ioapic_set_legacy_irqmap(int, int, enum intr_trigger,
            enum intr_polarity);
 void   ioapic_fixup_legacy_irqmaps(void);
 
            enum intr_polarity);
 void   ioapic_fixup_legacy_irqmaps(void);
 
-int    ioapic_find_legacy_by_gsi(int, enum intr_trigger, enum intr_polarity);
-int    ioapic_find_legacy_by_irq(int, enum intr_trigger, enum intr_polarity);
-
 #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */
 #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */
index 745adee..444ed5c 100644 (file)
@@ -1441,7 +1441,7 @@ mptable_pci_int_route(int bus, int dev, int pin, int intline)
                gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
                        pci_int->mpci_ioapic_pin);
                if (gsi >= 0) {
                gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
                        pci_int->mpci_ioapic_pin);
                if (gsi >= 0) {
-                       irq = ioapic_find_legacy_by_gsi(gsi,
+                       irq = machintr_legacy_intr_find_bygsi(gsi,
                                INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
                }
        }
                                INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
                }
        }
@@ -1452,7 +1452,7 @@ mptable_pci_int_route(int bus, int dev, int pin, int intline)
                                "for %d:%d INT%c\n", bus, dev, pin + 'A');
                }
 
                                "for %d:%d INT%c\n", bus, dev, pin + 'A');
                }
 
-               irq = ioapic_find_legacy_by_irq(intline,
+               irq = machintr_legacy_intr_find(intline,
                        INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
        }
 
                        INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
        }
 
index 2bfc13c..1ea3b1d 100644 (file)
@@ -85,6 +85,7 @@ static struct icu_irqmap {
        int                     im_type;        /* ICU_IMT_ */
        enum intr_trigger       im_trig;
        int                     im_msi_base;
        int                     im_type;        /* ICU_IMT_ */
        enum intr_trigger       im_trig;
        int                     im_msi_base;
+       uint32_t                im_flags;
 } icu_irqmaps[MAXCPU][IDT_HWI_VECTORS];
 
 static struct lwkt_token icu_irqmap_tok =
 } icu_irqmaps[MAXCPU][IDT_HWI_VECTORS];
 
 static struct lwkt_token icu_irqmap_tok =
@@ -102,6 +103,8 @@ static struct lwkt_token icu_irqmap_tok =
                                 (map)->im_type != ICU_IMT_SYSCALL && \
                                 (map)->im_type != ICU_IMT_SHADOW)
 
                                 (map)->im_type != ICU_IMT_SYSCALL && \
                                 (map)->im_type != ICU_IMT_SHADOW)
 
+#define ICU_IMF_CONF           0x1
+
 extern void    ICU_INTREN(int);
 extern void    ICU_INTRDIS(int);
 
 extern void    ICU_INTREN(int);
 extern void    ICU_INTRDIS(int);
 
@@ -115,6 +118,10 @@ static void        icu_abi_intr_teardown(int);
 static void    icu_abi_legacy_intr_config(int, enum intr_trigger,
                    enum intr_polarity);
 static int     icu_abi_legacy_intr_cpuid(int);
 static void    icu_abi_legacy_intr_config(int, enum intr_trigger,
                    enum intr_polarity);
 static int     icu_abi_legacy_intr_cpuid(int);
+static int     icu_abi_legacy_intr_find(int, enum intr_trigger,
+                   enum intr_polarity);
+static int     icu_abi_legacy_intr_find_bygsi(int, enum intr_trigger,
+                   enum intr_polarity);
 
 static int     icu_abi_msi_alloc(int [], int, int);
 static void    icu_abi_msi_release(const int [], int, int);
 
 static int     icu_abi_msi_alloc(int [], int, int);
 static void    icu_abi_msi_release(const int [], int, int);
@@ -143,6 +150,8 @@ struct machintr_abi MachIntrABI_ICU = {
 
        .legacy_intr_config = icu_abi_legacy_intr_config,
        .legacy_intr_cpuid = icu_abi_legacy_intr_cpuid,
 
        .legacy_intr_config = icu_abi_legacy_intr_config,
        .legacy_intr_cpuid = icu_abi_legacy_intr_cpuid,
+       .legacy_intr_find = icu_abi_legacy_intr_find,
+       .legacy_intr_find_bygsi = icu_abi_legacy_intr_find_bygsi,
 
        .msi_alloc      = icu_abi_msi_alloc,
        .msi_release    = icu_abi_msi_release,
 
        .msi_alloc      = icu_abi_msi_alloc,
        .msi_release    = icu_abi_msi_release,
@@ -370,6 +379,7 @@ icu_abi_legacy_intr_config(int irq, enum intr_trigger trig,
        KKASSERT(map->im_type == ICU_IMT_LEGACY);
 
        /* TODO: Check whether it is configured or not */
        KKASSERT(map->im_type == ICU_IMT_LEGACY);
 
        /* TODO: Check whether it is configured or not */
+       map->im_flags |= ICU_IMF_CONF;
 
        if (trig == map->im_trig)
                return;
 
        if (trig == map->im_trig)
                return;
@@ -671,3 +681,43 @@ icu_abi_msi_map(int intr, uint64_t *addr, uint32_t *data, int cpuid)
 
        lwkt_reltoken(&icu_irqmap_tok);
 }
 
        lwkt_reltoken(&icu_irqmap_tok);
 }
+
+static int
+icu_abi_legacy_intr_find(int irq, enum intr_trigger trig,
+    enum intr_polarity pola __unused)
+{
+       const struct icu_irqmap *map;
+
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
+
+       if (irq < 0 || irq >= ICU_HWI_VECTORS)
+               return -1;
+
+       map = &icu_irqmaps[0][irq];
+       if (map->im_type == ICU_IMT_LEGACY) {
+               if ((map->im_flags & ICU_IMF_CONF) &&
+                   trig != INTR_TRIGGER_CONFORM) {
+                       if (map->im_trig != trig)
+                               return -1;
+               }
+               return irq;
+       }
+       return -1;
+}
+
+static int
+icu_abi_legacy_intr_find_bygsi(int gsi, enum intr_trigger trig,
+    enum intr_polarity pola)
+{
+       /* GSI and IRQ has 1:1 mapping */
+       return icu_abi_legacy_intr_find(gsi, trig, pola);
+}
index 4af55a2..838bf56 100644 (file)
@@ -1057,13 +1057,13 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
 
        /* Finish initializing 8253 timer 0. */
        if (ioapic_enable) {
 
        /* Finish initializing 8253 timer 0. */
        if (ioapic_enable) {
-               irq = ioapic_find_legacy_by_irq(0, INTR_TRIGGER_EDGE,
+               irq = machintr_legacy_intr_find(0, INTR_TRIGGER_EDGE,
                        INTR_POLARITY_HIGH);
                if (irq < 0) {
 mixed_mode_setup:
                        error = ioapic_conf_legacy_extint(0);
                        if (!error) {
                        INTR_POLARITY_HIGH);
                if (irq < 0) {
 mixed_mode_setup:
                        error = ioapic_conf_legacy_extint(0);
                        if (!error) {
-                               irq = ioapic_find_legacy_by_irq(0,
+                               irq = machintr_legacy_intr_find(0,
                                    INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
                                if (irq < 0)
                                        error = ENOENT;
                                    INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
                                if (irq < 0)
                                        error = ENOENT;
index 92b7e57..367e70f 100644 (file)
@@ -494,6 +494,10 @@ static void        ioapic_abi_intr_teardown(int);
 static void    ioapic_abi_legacy_intr_config(int,
                    enum intr_trigger, enum intr_polarity);
 static int     ioapic_abi_legacy_intr_cpuid(int);
 static void    ioapic_abi_legacy_intr_config(int,
                    enum intr_trigger, enum intr_polarity);
 static int     ioapic_abi_legacy_intr_cpuid(int);
+static int     ioapic_abi_legacy_intr_find(int,
+                   enum intr_trigger, enum intr_polarity);
+static int     ioapic_abi_legacy_intr_find_bygsi(int,
+                   enum intr_trigger, enum intr_polarity);
 
 static int     ioapic_abi_msi_alloc(int [], int, int);
 static void    ioapic_abi_msi_release(const int [], int, int);
 
 static int     ioapic_abi_msi_alloc(int [], int, int);
 static void    ioapic_abi_msi_release(const int [], int, int);
@@ -524,6 +528,8 @@ struct machintr_abi MachIntrABI_IOAPIC = {
 
        .legacy_intr_config = ioapic_abi_legacy_intr_config,
        .legacy_intr_cpuid = ioapic_abi_legacy_intr_cpuid,
 
        .legacy_intr_config = ioapic_abi_legacy_intr_config,
        .legacy_intr_cpuid = ioapic_abi_legacy_intr_cpuid,
+       .legacy_intr_find = ioapic_abi_legacy_intr_find,
+       .legacy_intr_find_bygsi = ioapic_abi_legacy_intr_find_bygsi,
 
        .msi_alloc      = ioapic_abi_msi_alloc,
        .msi_release    = ioapic_abi_msi_release,
 
        .msi_alloc      = ioapic_abi_msi_alloc,
        .msi_release    = ioapic_abi_msi_release,
@@ -839,14 +845,22 @@ ioapic_fixup_legacy_irqmaps(void)
        }
 }
 
        }
 }
 
-int
-ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
+static int
+ioapic_abi_legacy_intr_find_bygsi(int gsi, enum intr_trigger trig,
     enum intr_polarity pola)
 {
        int cpu;
 
     enum intr_polarity pola)
 {
        int cpu;
 
-       KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL);
-       KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW);
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
 
        for (cpu = 0; cpu < ncpus; ++cpu) {
                int irq;
 
        for (cpu = 0; cpu < ncpus; ++cpu) {
                int irq;
@@ -858,7 +872,9 @@ ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
                        if (map->im_gsi == gsi) {
                                KKASSERT(map->im_type == IOAPIC_IMT_LEGACY);
 
                        if (map->im_gsi == gsi) {
                                KKASSERT(map->im_type == IOAPIC_IMT_LEGACY);
 
-                               if (map->im_flags & IOAPIC_IMF_CONF) {
+                               if ((map->im_flags & IOAPIC_IMF_CONF) &&
+                                   trig != INTR_TRIGGER_CONFORM &&
+                                   pola != INTR_POLARITY_CONFORM) {
                                        if (map->im_trig != trig ||
                                            map->im_pola != pola)
                                                return -1;
                                        if (map->im_trig != trig ||
                                            map->im_pola != pola)
                                                return -1;
@@ -870,14 +886,22 @@ ioapic_find_legacy_by_gsi(int gsi, enum intr_trigger trig,
        return -1;
 }
 
        return -1;
 }
 
-int
-ioapic_find_legacy_by_irq(int irq, enum intr_trigger trig,
+static int
+ioapic_abi_legacy_intr_find(int irq, enum intr_trigger trig,
     enum intr_polarity pola)
 {
        int cpu;
 
     enum intr_polarity pola)
 {
        int cpu;
 
-       KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL);
-       KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW);
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
 
        if (irq < 0 || irq >= ioapic_abi_legacy_irq_max)
                return -1;
 
        if (irq < 0 || irq >= ioapic_abi_legacy_irq_max)
                return -1;
@@ -886,7 +910,9 @@ ioapic_find_legacy_by_irq(int irq, enum intr_trigger trig,
                const struct ioapic_irqmap *map = &ioapic_irqmaps[cpu][irq];
 
                if (map->im_type == IOAPIC_IMT_LEGACY) {
                const struct ioapic_irqmap *map = &ioapic_irqmaps[cpu][irq];
 
                if (map->im_type == IOAPIC_IMT_LEGACY) {
-                       if (map->im_flags & IOAPIC_IMF_CONF) {
+                       if ((map->im_flags & IOAPIC_IMF_CONF) &&
+                           trig != INTR_TRIGGER_CONFORM &&
+                           pola != INTR_POLARITY_CONFORM) {
                                if (map->im_trig != trig ||
                                    map->im_pola != pola)
                                        return -1;
                                if (map->im_trig != trig ||
                                    map->im_pola != pola)
                                        return -1;
index ff0be4d..8cdf762 100644 (file)
@@ -69,7 +69,4 @@ void  ioapic_set_legacy_irqmap(int, int, enum intr_trigger,
            enum intr_polarity);
 void   ioapic_fixup_legacy_irqmaps(void);
 
            enum intr_polarity);
 void   ioapic_fixup_legacy_irqmaps(void);
 
-int    ioapic_find_legacy_by_gsi(int, enum intr_trigger, enum intr_polarity);
-int    ioapic_find_legacy_by_irq(int, enum intr_trigger, enum intr_polarity);
-
 #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */
 #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */
index 426b034..8b0c2cd 100644 (file)
@@ -85,6 +85,7 @@ static struct icu_irqmap {
        int                     im_type;        /* ICU_IMT_ */
        enum intr_trigger       im_trig;
        int                     im_msi_base;
        int                     im_type;        /* ICU_IMT_ */
        enum intr_trigger       im_trig;
        int                     im_msi_base;
+       uint32_t                im_flags;       /* ICU_IMF_ */
 } icu_irqmaps[MAXCPU][IDT_HWI_VECTORS];
 
 static struct lwkt_token icu_irqmap_tok =
 } icu_irqmaps[MAXCPU][IDT_HWI_VECTORS];
 
 static struct lwkt_token icu_irqmap_tok =
@@ -100,6 +101,8 @@ static struct lwkt_token icu_irqmap_tok =
 #define ICU_IMT_ISHWI(map)     ((map)->im_type != ICU_IMT_RESERVED && \
                                 (map)->im_type != ICU_IMT_SYSCALL)
 
 #define ICU_IMT_ISHWI(map)     ((map)->im_type != ICU_IMT_RESERVED && \
                                 (map)->im_type != ICU_IMT_SYSCALL)
 
+#define ICU_IMF_CONF           0x1
+
 extern void    ICU_INTREN(int);
 extern void    ICU_INTRDIS(int);
 
 extern void    ICU_INTREN(int);
 extern void    ICU_INTRDIS(int);
 
@@ -113,6 +116,10 @@ static void        icu_abi_intr_teardown(int);
 static void    icu_abi_legacy_intr_config(int, enum intr_trigger,
                    enum intr_polarity);
 static int     icu_abi_legacy_intr_cpuid(int);
 static void    icu_abi_legacy_intr_config(int, enum intr_trigger,
                    enum intr_polarity);
 static int     icu_abi_legacy_intr_cpuid(int);
+static int     icu_abi_legacy_intr_find(int, enum intr_trigger,
+                   enum intr_polarity);
+static int     icu_abi_legacy_intr_find_bygsi(int, enum intr_trigger,
+                   enum intr_polarity);
 
 static int     icu_abi_msi_alloc(int [], int, int);
 static void    icu_abi_msi_release(const int [], int, int);
 
 static int     icu_abi_msi_alloc(int [], int, int);
 static void    icu_abi_msi_release(const int [], int, int);
@@ -141,6 +148,8 @@ struct machintr_abi MachIntrABI_ICU = {
 
        .legacy_intr_config = icu_abi_legacy_intr_config,
        .legacy_intr_cpuid = icu_abi_legacy_intr_cpuid,
 
        .legacy_intr_config = icu_abi_legacy_intr_config,
        .legacy_intr_cpuid = icu_abi_legacy_intr_cpuid,
+       .legacy_intr_find = icu_abi_legacy_intr_find,
+       .legacy_intr_find_bygsi = icu_abi_legacy_intr_find_bygsi,
 
        .msi_alloc      = icu_abi_msi_alloc,
        .msi_release    = icu_abi_msi_release,
 
        .msi_alloc      = icu_abi_msi_alloc,
        .msi_release    = icu_abi_msi_release,
@@ -368,6 +377,7 @@ icu_abi_legacy_intr_config(int irq, enum intr_trigger trig,
        KKASSERT(map->im_type == ICU_IMT_LEGACY);
 
        /* TODO: Check whether it is configured or not */
        KKASSERT(map->im_type == ICU_IMT_LEGACY);
 
        /* TODO: Check whether it is configured or not */
+       map->im_flags |= ICU_IMF_CONF;
 
        if (trig == map->im_trig)
                return;
 
        if (trig == map->im_trig)
                return;
@@ -635,3 +645,43 @@ icu_abi_msi_map(int intr, uint64_t *addr, uint32_t *data, int cpuid)
 
        lwkt_reltoken(&icu_irqmap_tok);
 }
 
        lwkt_reltoken(&icu_irqmap_tok);
 }
+
+static int
+icu_abi_legacy_intr_find(int irq, enum intr_trigger trig,
+    enum intr_polarity pola __unused)
+{
+       const struct icu_irqmap *map;
+
+#ifdef INVARIANTS
+       if (trig == INTR_TRIGGER_CONFORM) {
+               KKASSERT(pola == INTR_POLARITY_CONFORM);
+       } else {
+               KKASSERT(trig == INTR_TRIGGER_EDGE ||
+                   trig == INTR_TRIGGER_LEVEL);
+               KKASSERT(pola == INTR_POLARITY_HIGH ||
+                   pola == INTR_POLARITY_LOW);
+       }
+#endif
+
+       if (irq < 0 || irq >= ICU_HWI_VECTORS)
+               return -1;
+
+       map = &icu_irqmaps[0][irq];
+       if (map->im_type == ICU_IMT_LEGACY) {
+               if ((map->im_flags & ICU_IMF_CONF) &&
+                   trig != INTR_TRIGGER_CONFORM) {
+                       if (map->im_trig != trig)
+                               return -1;
+               }
+               return irq;
+       }
+       return -1;
+}
+
+static int
+icu_abi_legacy_intr_find_bygsi(int gsi, enum intr_trigger trig,
+    enum intr_polarity pola)
+{
+       /* GSI and IRQ has 1:1 mapping */
+       return icu_abi_legacy_intr_find(gsi, trig, pola);
+}
index 13c5589..ed55c44 100644 (file)
@@ -1064,13 +1064,13 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
 
        /* Finish initializing 8254 timer 0. */
        if (ioapic_enable) {
 
        /* Finish initializing 8254 timer 0. */
        if (ioapic_enable) {
-               irq = ioapic_find_legacy_by_irq(0, INTR_TRIGGER_EDGE,
+               irq = machintr_legacy_intr_find(0, INTR_TRIGGER_EDGE,
                        INTR_POLARITY_HIGH);
                if (irq < 0) {
 mixed_mode_setup:
                        error = ioapic_conf_legacy_extint(0);
                        if (!error) {
                        INTR_POLARITY_HIGH);
                if (irq < 0) {
 mixed_mode_setup:
                        error = ioapic_conf_legacy_extint(0);
                        if (!error) {
-                               irq = ioapic_find_legacy_by_irq(0,
+                               irq = machintr_legacy_intr_find(0,
                                    INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
                                if (irq < 0)
                                        error = ENOENT;
                                    INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
                                if (irq < 0)
                                        error = ENOENT;
index 088bee6..30faeb8 100644 (file)
@@ -1441,7 +1441,7 @@ mptable_pci_int_route(int bus, int dev, int pin, int intline)
                gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
                        pci_int->mpci_ioapic_pin);
                if (gsi >= 0) {
                gsi = ioapic_gsi(pci_int->mpci_ioapic_idx,
                        pci_int->mpci_ioapic_pin);
                if (gsi >= 0) {
-                       irq = ioapic_find_legacy_by_gsi(gsi,
+                       irq = machintr_legacy_intr_find_bygsi(gsi,
                                INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
                }
        }
                                INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
                }
        }
@@ -1452,7 +1452,7 @@ mptable_pci_int_route(int bus, int dev, int pin, int intline)
                                "for %d:%d INT%c\n", bus, dev, pin + 'A');
                }
 
                                "for %d:%d INT%c\n", bus, dev, pin + 'A');
                }
 
-               irq = ioapic_find_legacy_by_irq(intline,
+               irq = machintr_legacy_intr_find(intline,
                        INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
        }
 
                        INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
        }
 
index f4807fc..17b09fc 100644 (file)
@@ -69,6 +69,10 @@ struct machintr_abi {
     void       (*legacy_intr_config)           /* config legacy intr */
                (int intr, enum intr_trigger trig, enum intr_polarity pola);
     int                (*legacy_intr_cpuid)(int intr); /* legacy intr target cpu */
     void       (*legacy_intr_config)           /* config legacy intr */
                (int intr, enum intr_trigger trig, enum intr_polarity pola);
     int                (*legacy_intr_cpuid)(int intr); /* legacy intr target cpu */
+    int                (*legacy_intr_find)             /* find legacy intr */
+               (int intr, enum intr_trigger trig, enum intr_polarity pola);
+    int                (*legacy_intr_find_bygsi)       /* find legacy intr by GSI */
+               (int gsi, enum intr_trigger trig, enum intr_polarity pola);
 
     int                (*msi_alloc)                    /* alloc count MSIs on cpu */
                (int intrs[], int count, int cpuid);
 
     int                (*msi_alloc)                    /* alloc count MSIs on cpu */
                (int intrs[], int count, int cpuid);
@@ -101,6 +105,11 @@ struct machintr_abi {
 #define machintr_legacy_intr_cpuid(intr) \
            MachIntrABI.legacy_intr_cpuid((intr))
 
 #define machintr_legacy_intr_cpuid(intr) \
            MachIntrABI.legacy_intr_cpuid((intr))
 
+#define machintr_legacy_intr_find(intr, trig, pola) \
+           MachIntrABI.legacy_intr_find((intr), (trig), (pola))
+#define machintr_legacy_intr_find_bygsi(gsi, trig, pola) \
+           MachIntrABI.legacy_intr_find_bygsi((gsi), (trig), (pola))
+
 extern struct machintr_abi MachIntrABI;
 
 #endif /* _KERNEL */
 extern struct machintr_abi MachIntrABI;
 
 #endif /* _KERNEL */