From: Sepherosa Ziehau Date: Tue, 13 Dec 2011 13:28:41 +0000 (+0800) Subject: i386/icu: Implement rman_setup MachIntrABI method X-Git-Tag: v3.0.0~401 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/14bd3265f42eb3f181ef473ce3ecab95bcea37f7 i386/icu: Implement rman_setup MachIntrABI method This merges b3cf468e65fcb31e33ab367c068eee119db92491 --- diff --git a/sys/platform/pc32/i386/nexus.c b/sys/platform/pc32/i386/nexus.c index 385ea50d1f..0ae3d48266 100644 --- a/sys/platform/pc32/i386/nexus.c +++ b/sys/platform/pc32/i386/nexus.c @@ -158,34 +158,14 @@ nexus_probe(device_t dev) for (cpuid = 0; cpuid < ncpus; ++cpuid) { struct rman *rm = &irq_rman[cpuid]; - /* - * IRQ's are on the mainboard on old systems, but on - * the ISA part of PCI->ISA bridges. There would be - * multiple sets of IRQs on multi-ISA-bus systems. - * PCI interrupts are routed to the ISA component, - * so in a way, PCI can be a partial child of an ISA - * bus(!). APIC interrupts are global though. In the - * non-APIC case, disallow the use of IRQ 2. - */ rm->rm_start = 0; + rm->rm_end = IDT_HWI_VECTORS - 1; rm->rm_type = RMAN_ARRAY; rm->rm_descr = "Interrupt request lines"; - /* - * XXX should use MachIntrABI.rman_setup - */ - if (ioapic_enable) { - rm->rm_end = IDT_HWI_VECTORS - 1; - if (rman_init(rm, cpuid)) - panic("nexus_probe rman_init"); - MachIntrABI.rman_setup(rm); - } else { - rm->rm_end = 15; - if (rman_init(rm, cpuid) || - rman_manage_region(rm, rm->rm_start, 1) || - rman_manage_region(rm, 3, rm->rm_end)) - panic("nexus_probe irq_rman"); - } + if (rman_init(rm, cpuid)) + panic("nexus_probe rman_init"); + MachIntrABI.rman_setup(rm); } /* diff --git a/sys/platform/pc32/icu/icu_abi.c b/sys/platform/pc32/icu/icu_abi.c index 254de9e5f5..3eb68e0b28 100644 --- a/sys/platform/pc32/icu/icu_abi.c +++ b/sys/platform/pc32/icu/icu_abi.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -84,13 +85,16 @@ static inthand_t *icu_intr[ICU_HWI_VECTORS] = { static struct icu_irqmap { int im_type; /* ICU_IMT_ */ enum intr_trigger im_trig; -} icu_irqmaps[IDT_HWI_VECTORS]; +} icu_irqmaps[MAXCPU][IDT_HWI_VECTORS]; #define ICU_IMT_UNUSED 0 /* KEEP THIS */ #define ICU_IMT_RESERVED 1 #define ICU_IMT_LINE 2 #define ICU_IMT_SYSCALL 3 +#define ICU_IMT_ISHWI(map) ((map)->im_type != ICU_IMT_RESERVED && \ + (map)->im_type != ICU_IMT_SYSCALL) + extern void ICU_INTREN(int); extern void ICU_INTRDIS(int); @@ -106,6 +110,7 @@ static void icu_abi_cleanup(void); static void icu_abi_setdefault(void); static void icu_abi_stabilize(void); static void icu_abi_initmap(void); +static void icu_abi_rman_setup(struct rman *); struct machintr_abi MachIntrABI_ICU = { MACHINTR_ICU, @@ -121,7 +126,8 @@ struct machintr_abi MachIntrABI_ICU = { .cleanup = icu_abi_cleanup, .setdefault = icu_abi_setdefault, .stabilize = icu_abi_stabilize, - .initmap = icu_abi_initmap + .initmap = icu_abi_initmap, + .rman_setup = icu_abi_rman_setup }; /* @@ -222,23 +228,41 @@ icu_abi_setdefault(void) static void icu_abi_initmap(void) { - int i; - - for (i = 0; i < ICU_HWI_VECTORS; ++i) - icu_irqmaps[i].im_type = ICU_IMT_LINE; - icu_irqmaps[ICU_IRQ_SLAVE].im_type = ICU_IMT_RESERVED; - - if (elcr_found) { - for (i = 0; i < ICU_HWI_VECTORS; ++i) - icu_irqmaps[i].im_trig = elcr_read_trigger(i); - } else { - /* - * NOTE: Trigger mode does not matter at all - */ - for (i = 0; i < ICU_HWI_VECTORS; ++i) - icu_irqmaps[i].im_trig = INTR_TRIGGER_EDGE; + int cpu; + + /* + * NOTE: ncpus is not ready yet + */ + for (cpu = 0; cpu < MAXCPU; ++cpu) { + int i; + + if (cpu != 0) { + for (i = 0; i < ICU_HWI_VECTORS; ++i) + icu_irqmaps[cpu][i].im_type = ICU_IMT_RESERVED; + } else { + for (i = 0; i < ICU_HWI_VECTORS; ++i) + icu_irqmaps[cpu][i].im_type = ICU_IMT_LINE; + icu_irqmaps[cpu][ICU_IRQ_SLAVE].im_type = + ICU_IMT_RESERVED; + + if (elcr_found) { + for (i = 0; i < ICU_HWI_VECTORS; ++i) { + icu_irqmaps[cpu][i].im_trig = + elcr_read_trigger(i); + } + } else { + /* + * NOTE: Trigger mode does not matter at all + */ + for (i = 0; i < ICU_HWI_VECTORS; ++i) { + icu_irqmaps[cpu][i].im_trig = + INTR_TRIGGER_EDGE; + } + } + } + icu_irqmaps[cpu][IDT_OFFSET_SYSCALL - IDT_OFFSET].im_type = + ICU_IMT_SYSCALL; } - icu_irqmaps[IDT_OFFSET_SYSCALL - IDT_OFFSET].im_type = ICU_IMT_SYSCALL; } static void @@ -250,7 +274,7 @@ icu_abi_intr_config(int irq, enum intr_trigger trig, KKASSERT(trig == INTR_TRIGGER_EDGE || trig == INTR_TRIGGER_LEVEL); KKASSERT(irq >= 0 && irq < IDT_HWI_VECTORS); - map = &icu_irqmaps[irq]; + map = &icu_irqmaps[0][irq]; KKASSERT(map->im_type == ICU_IMT_LINE); @@ -279,3 +303,49 @@ icu_abi_intr_cpuid(int irq __unused) { return 0; } + +static void +icu_abi_rman_setup(struct rman *rm) +{ + int start, end, i; + + KASSERT(rm->rm_cpuid >= 0 && rm->rm_cpuid < MAXCPU, + ("invalid rman cpuid %d", rm->rm_cpuid)); + + start = end = -1; + for (i = 0; i < IDT_HWI_VECTORS; ++i) { + const struct icu_irqmap *map = &icu_irqmaps[rm->rm_cpuid][i]; + + if (start < 0) { + if (ICU_IMT_ISHWI(map)) + start = end = i; + } else { + if (ICU_IMT_ISHWI(map)) { + end = i; + } else { + KKASSERT(end >= 0); + if (bootverbose) { + kprintf("ICU: rman cpu%d %d - %d\n", + rm->rm_cpuid, start, end); + } + if (rman_manage_region(rm, start, end)) { + panic("rman_manage_region" + "(cpu%d %d - %d)", rm->rm_cpuid, + start, end); + } + start = end = -1; + } + } + } + if (start >= 0) { + KKASSERT(end >= 0); + if (bootverbose) { + kprintf("ICU: rman cpu%d %d - %d\n", + rm->rm_cpuid, start, end); + } + if (rman_manage_region(rm, start, end)) { + panic("rman_manage_region(cpu%d %d - %d)", + rm->rm_cpuid, start, end); + } + } +}