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);
.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,
}
}
-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;
- 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;
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;
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;
- 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;
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;
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_ */
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);
}
}
"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);
}
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 =
(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);
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);
.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,
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;
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);
+}
/* 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) {
- irq = ioapic_find_legacy_by_irq(0,
+ irq = machintr_legacy_intr_find(0,
INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
if (irq < 0)
error = ENOENT;
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);
.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,
}
}
-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;
- 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;
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;
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;
- 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;
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;
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_ */
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 =
#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);
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);
.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,
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;
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);
+}
/* 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) {
- irq = ioapic_find_legacy_by_irq(0,
+ irq = machintr_legacy_intr_find(0,
INTR_TRIGGER_EDGE, INTR_POLARITY_HIGH);
if (irq < 0)
error = ENOENT;
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);
}
}
"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);
}
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);
#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 */