if (info == NULL)
TAILQ_INSERT_HEAD(&ioapic_conf.ioc_list, ninfo, io_link);
}
+
+void
+ioapic_intsrc(int irq, int gsi)
+{
+ KKASSERT(irq < 16);
+ if (ioapic_conf.ioc_intsrc[irq] != -1 &&
+ ioapic_conf.ioc_intsrc[irq] != gsi) {
+ kprintf("IOAPIC: warning intsrc irq %d, gsi %d -> gsi %d\n",
+ irq, ioapic_conf.ioc_intsrc[irq], gsi);
+ }
+ ioapic_conf.ioc_intsrc[irq] = gsi;
+}
mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
{
struct mptable_ioapic_int_cbarg *arg = xarg;
+ const struct mptable_ioapic *ioapic;
const struct mptable_bus *bus;
const struct INTENTRY *ent;
if (bus == NULL)
return 0;
- /* XXX rough estimation */
- if (ent->src_bus_irq != ent->dst_apic_int) {
- if (bootverbose) {
- kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
- ent->src_bus_irq, ent->dst_apic_int);
+ TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+ if (ioapic->mio_apic_id == ent->dst_apic_id)
+ break;
+ }
+ if (ioapic == NULL) {
+ kprintf("MPTABLE: warning ISA int dst apic id %d "
+ "does not exist\n", ent->dst_apic_id);
+ return 0;
+ }
+
+ if (!ioapic_use_old) {
+ int gsi;
+
+ if (ent->dst_apic_int >= ioapic->mio_npin) {
+ panic("mptable_ioapic_enumerate: invalid I/O APIC "
+ "pin %d, should be < %d",
+ ent->dst_apic_int, ioapic->mio_npin);
+ }
+ gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
+
+ if (ent->src_bus_irq != gsi) {
+ if (bootverbose) {
+ kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+ ent->src_bus_irq, gsi);
+ }
+ ioapic_intsrc(ent->src_bus_irq, gsi);
+ }
+ } else {
+ /* XXX rough estimation */
+ if (ent->src_bus_irq != ent->dst_apic_int) {
+ if (bootverbose) {
+ kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+ ent->src_bus_irq, ent->dst_apic_int);
+ }
}
}
return 0;
if (mptable_use_default) {
if (bootverbose)
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
return;
}
if (TAILQ_EMPTY(&bus_info.mbi_list)) {
if (bootverbose)
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
} else {
struct mptable_ioapic_int_cbarg arg;
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
"(no int)\n");
}
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
}
}
const struct acpi_madt_intsrc *intsrc_ent;
intsrc_ent = (const struct acpi_madt_intsrc *)ent;
- if (intsrc_ent->mint_src == intsrc_ent->mint_gsi)
+ if (intsrc_ent->mint_src == intsrc_ent->mint_gsi ||
+ intsrc_ent->mint_bus != MADT_INT_BUS_ISA)
return 0;
MADT_VPRINTF("INTSRC irq %d -> gsi %u\n",
intsrc_ent->mint_src, intsrc_ent->mint_gsi);
+ ioapic_intsrc(intsrc_ent->mint_src, intsrc_ent->mint_gsi);
} else if (ent->me_type == MADT_ENT_IOAPIC) {
const struct acpi_madt_ioapic *ioapic_ent;
void ioapic_config(void);
void ioapic_enumerator_register(struct ioapic_enumerator *);
void ioapic_add(void *, int, int);
+void ioapic_intsrc(int, int);
extern int apic_io_enable;
extern int ioapic_use_old;
if (info == NULL)
TAILQ_INSERT_HEAD(&ioapic_conf.ioc_list, ninfo, io_link);
}
+
+void
+ioapic_intsrc(int irq, int gsi)
+{
+ KKASSERT(irq < 16);
+ if (ioapic_conf.ioc_intsrc[irq] != -1 &&
+ ioapic_conf.ioc_intsrc[irq] != gsi) {
+ kprintf("IOAPIC: warning intsrc irq %d, gsi %d -> gsi %d\n",
+ irq, ioapic_conf.ioc_intsrc[irq], gsi);
+ }
+ ioapic_conf.ioc_intsrc[irq] = gsi;
+}
void ioapic_config(void);
void ioapic_enumerator_register(struct ioapic_enumerator *);
void ioapic_add(void *, int, int);
+void ioapic_intsrc(int, int);
#if defined(READY)
void clr_io_apic_mask24 (int, u_int32_t);
mptable_ioapic_int_callback(void *xarg, const void *pos, int type)
{
struct mptable_ioapic_int_cbarg *arg = xarg;
+ const struct mptable_ioapic *ioapic;
const struct mptable_bus *bus;
const struct INTENTRY *ent;
if (bus == NULL)
return 0;
- /* XXX rough estimation */
- if (ent->src_bus_irq != ent->dst_apic_int) {
- if (bootverbose) {
- kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
- ent->src_bus_irq, ent->dst_apic_int);
+ TAILQ_FOREACH(ioapic, &mptable_ioapic_list, mio_link) {
+ if (ioapic->mio_apic_id == ent->dst_apic_id)
+ break;
+ }
+ if (ioapic == NULL) {
+ kprintf("MPTABLE: warning ISA int dst apic id %d "
+ "does not exist\n", ent->dst_apic_id);
+ return 0;
+ }
+
+ if (!ioapic_use_old) {
+ int gsi;
+
+ if (ent->dst_apic_int >= ioapic->mio_npin) {
+ panic("mptable_ioapic_enumerate: invalid I/O APIC "
+ "pin %d, should be < %d",
+ ent->dst_apic_int, ioapic->mio_npin);
+ }
+ gsi = ioapic->mio_gsi_base + ent->dst_apic_int;
+
+ if (ent->src_bus_irq != gsi) {
+ if (bootverbose) {
+ kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+ ent->src_bus_irq, gsi);
+ }
+ ioapic_intsrc(ent->src_bus_irq, gsi);
+ }
+ } else {
+ /* XXX rough estimation */
+ if (ent->src_bus_irq != ent->dst_apic_int) {
+ if (bootverbose) {
+ kprintf("MPTABLE: INTSRC irq %d -> GSI %d\n",
+ ent->src_bus_irq, ent->dst_apic_int);
+ }
}
}
return 0;
if (mptable_use_default) {
if (bootverbose)
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (default)\n");
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
return;
}
if (TAILQ_EMPTY(&bus_info.mbi_list)) {
if (bootverbose)
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 (no bus)\n");
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
} else {
struct mptable_ioapic_int_cbarg arg;
kprintf("MPTABLE: INTSRC irq 0 -> GSI 2 "
"(no int)\n");
}
- /* TODO default intsrc */
+ ioapic_intsrc(0, 2);
}
}
const struct acpi_madt_intsrc *intsrc_ent;
intsrc_ent = (const struct acpi_madt_intsrc *)ent;
- if (intsrc_ent->mint_src == intsrc_ent->mint_gsi)
+ if (intsrc_ent->mint_src == intsrc_ent->mint_gsi ||
+ intsrc_ent->mint_bus != MADT_INT_BUS_ISA)
return 0;
MADT_VPRINTF("INTSRC irq %d -> gsi %u\n",
intsrc_ent->mint_src, intsrc_ent->mint_gsi);
+ ioapic_intsrc(intsrc_ent->mint_src, intsrc_ent->mint_gsi);
} else if (ent->me_type == MADT_ENT_IOAPIC) {
const struct acpi_madt_ioapic *ioapic_ent;