From 929c940f129e9d8a4c01475290abd850b8e696e5 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 18 Mar 2011 13:59:50 +0800 Subject: [PATCH] ioapic/abi: Save IRQ to GSI mapping --- sys/platform/pc32/apic/ioapic_abi.c | 46 +++++++++++++++++++++++++++++ sys/platform/pc32/apic/ioapic_abi.h | 10 ++++++- sys/platform/pc32/apic/mpapic.c | 3 +- sys/platform/pc64/apic/ioapic_abi.c | 46 +++++++++++++++++++++++++++++ sys/platform/pc64/apic/ioapic_abi.h | 10 ++++++- sys/platform/pc64/apic/mpapic.c | 3 +- 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/sys/platform/pc32/apic/ioapic_abi.c b/sys/platform/pc32/apic/ioapic_abi.c index 8aa26a0e81..ef6f42ad88 100644 --- a/sys/platform/pc32/apic/ioapic_abi.c +++ b/sys/platform/pc32/apic/ioapic_abi.c @@ -56,6 +56,7 @@ #include +#include #include #ifdef SMP /* APIC-IO */ @@ -728,4 +729,49 @@ ioapic_initmap(void) ioapic_irqmaps[IOAPIC_HWI_SYSCALL].im_type = IOAPIC_IMT_SYSCALL; } +void +ioapic_abi_set_irqmap(int irq, int gsi, enum intr_trigger trig, + enum intr_polarity pola) +{ + struct apic_intmapinfo *info; + struct ioapic_irqmap *map; + void *ioaddr; + int pin; + + KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL); + KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW); + KKASSERT((trig == INTR_TRIGGER_EDGE && pola == INTR_POLARITY_HIGH) || + (trig == INTR_TRIGGER_LEVEL && pola == INTR_POLARITY_LOW)); + + KKASSERT(irq >= 0 && irq < IOAPIC_HWI_VECTORS); + map = &ioapic_irqmaps[irq]; + + KKASSERT(map->im_type == IOAPIC_IMT_UNUSED); + map->im_type = IOAPIC_IMT_LINE; + + map->im_gsi = gsi; + map->im_trig = trig; + map->im_pola = pola; + + if (bootverbose) { + kprintf("IOAPIC: irq %d -> gsi %d %c\n", irq, map->im_gsi, + trig == INTR_TRIGGER_LEVEL ? 'L' : 'E'); + } + + pin = ioapic_gsi_pin(gsi); + ioaddr = ioapic_gsi_ioaddr(gsi); + + info = &int_to_apicintpin[irq]; + + info->ioapic = 0; /* XXX unused */ + info->int_pin = pin; + info->apic_address = ioaddr; + info->redirindex = IOAPIC_REDTBL + (2 * pin); + info->flags = IOAPIC_IM_FLAG_MASKED; + if (trig == INTR_TRIGGER_LEVEL) + info->flags |= IOAPIC_IM_FLAG_LEVEL; + + /* TODO setup pin */ +} + #endif /* SMP */ diff --git a/sys/platform/pc32/apic/ioapic_abi.h b/sys/platform/pc32/apic/ioapic_abi.h index 0000189f4e..b43c46e239 100644 --- a/sys/platform/pc32/apic/ioapic_abi.h +++ b/sys/platform/pc32/apic/ioapic_abi.h @@ -41,8 +41,16 @@ #ifndef _ARCH_APIC_IOAPIC_ABI_H_ #define _ARCH_APIC_IOAPIC_ABI_H_ +#ifndef _SYS_BUS_H_ +#include +#endif + #ifdef SMP /* APIC_IO */ + extern struct machintr_abi MachIntrABI_IOAPIC; -#endif + +void ioapic_abi_set_irqmap(int, int, enum intr_trigger, enum intr_polarity); + +#endif /* SMP */ #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */ diff --git a/sys/platform/pc32/apic/mpapic.c b/sys/platform/pc32/apic/mpapic.c index 708bf85717..c4e9e40778 100644 --- a/sys/platform/pc32/apic/mpapic.c +++ b/sys/platform/pc32/apic/mpapic.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -1263,9 +1264,7 @@ ioapic_gsi_setup(int gsi) irq = gsi; } -#if 0 ioapic_abi_set_irqmap(irq, gsi, trig, pola); -#endif } void * diff --git a/sys/platform/pc64/apic/ioapic_abi.c b/sys/platform/pc64/apic/ioapic_abi.c index 3d807122c3..532a4ac532 100644 --- a/sys/platform/pc64/apic/ioapic_abi.c +++ b/sys/platform/pc64/apic/ioapic_abi.c @@ -56,6 +56,7 @@ #include +#include #include #ifdef SMP /* APIC-IO */ @@ -721,4 +722,49 @@ ioapic_initmap(void) ioapic_irqmaps[IOAPIC_HWI_SYSCALL].im_type = IOAPIC_IMT_SYSCALL; } +void +ioapic_abi_set_irqmap(int irq, int gsi, enum intr_trigger trig, + enum intr_polarity pola) +{ + struct apic_intmapinfo *info; + struct ioapic_irqmap *map; + void *ioaddr; + int pin; + + KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL); + KKASSERT(pola == INTR_POLARITY_HIGH || pola == INTR_POLARITY_LOW); + KKASSERT((trig == INTR_TRIGGER_EDGE && pola == INTR_POLARITY_HIGH) || + (trig == INTR_TRIGGER_LEVEL && pola == INTR_POLARITY_LOW)); + + KKASSERT(irq >= 0 && irq < IOAPIC_HWI_VECTORS); + map = &ioapic_irqmaps[irq]; + + KKASSERT(map->im_type == IOAPIC_IMT_UNUSED); + map->im_type = IOAPIC_IMT_LINE; + + map->im_gsi = gsi; + map->im_trig = trig; + map->im_pola = pola; + + if (bootverbose) { + kprintf("IOAPIC: irq %d -> gsi %d %c\n", irq, map->im_gsi, + trig == INTR_TRIGGER_LEVEL ? 'L' : 'E'); + } + + pin = ioapic_gsi_pin(gsi); + ioaddr = ioapic_gsi_ioaddr(gsi); + + info = &int_to_apicintpin[irq]; + + info->ioapic = 0; /* XXX unused */ + info->int_pin = pin; + info->apic_address = ioaddr; + info->redirindex = IOAPIC_REDTBL + (2 * pin); + info->flags = IOAPIC_IM_FLAG_MASKED; + if (trig == INTR_TRIGGER_LEVEL) + info->flags |= IOAPIC_IM_FLAG_LEVEL; + + /* TODO setup pin */ +} + #endif /* SMP */ diff --git a/sys/platform/pc64/apic/ioapic_abi.h b/sys/platform/pc64/apic/ioapic_abi.h index 0000189f4e..b43c46e239 100644 --- a/sys/platform/pc64/apic/ioapic_abi.h +++ b/sys/platform/pc64/apic/ioapic_abi.h @@ -41,8 +41,16 @@ #ifndef _ARCH_APIC_IOAPIC_ABI_H_ #define _ARCH_APIC_IOAPIC_ABI_H_ +#ifndef _SYS_BUS_H_ +#include +#endif + #ifdef SMP /* APIC_IO */ + extern struct machintr_abi MachIntrABI_IOAPIC; -#endif + +void ioapic_abi_set_irqmap(int, int, enum intr_trigger, enum intr_polarity); + +#endif /* SMP */ #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */ diff --git a/sys/platform/pc64/apic/mpapic.c b/sys/platform/pc64/apic/mpapic.c index cfef0ac9eb..c2033e0d27 100644 --- a/sys/platform/pc64/apic/mpapic.c +++ b/sys/platform/pc64/apic/mpapic.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1325,9 +1326,7 @@ ioapic_gsi_setup(int gsi) irq = gsi; } -#if 0 ioapic_abi_set_irqmap(irq, gsi, trig, pola); -#endif } void * -- 2.41.0