From a3dd9120071e6624f48839f678d71f5a6774c674 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sun, 6 Feb 2011 22:06:21 +0800 Subject: [PATCH] ioapic/icu: Add irqmap --- sys/platform/pc32/apic/ioapic_abi.c | 29 ++++++++++++++++++- sys/platform/pc32/apic/ioapic_abi.h | 2 ++ sys/platform/pc32/i386/machdep.c | 12 ++++++++ sys/platform/pc32/icu/icu_abi.c | 45 ++++++++++++++++++++++++++++- sys/platform/pc64/apic/ioapic_abi.c | 29 ++++++++++++++++++- sys/platform/pc64/apic/ioapic_abi.h | 2 ++ sys/platform/pc64/icu/icu_abi.c | 45 ++++++++++++++++++++++++++++- sys/platform/pc64/x86_64/machdep.c | 12 ++++++++ sys/sys/machintr.h | 1 + 9 files changed, 173 insertions(+), 4 deletions(-) diff --git a/sys/platform/pc32/apic/ioapic_abi.c b/sys/platform/pc32/apic/ioapic_abi.c index f2b963d95f..671b6d2261 100644 --- a/sys/platform/pc32/apic/ioapic_abi.c +++ b/sys/platform/pc32/apic/ioapic_abi.c @@ -449,6 +449,16 @@ static inthand_t *ioapic_intr[IOAPIC_HWI_VECTORS] = { &IDTVEC(ioapic_intr191) }; +static struct ioapic_irqmap { + int im_type; /* IOAPIC_IMT_ */ + enum intr_trigger im_trig; + int im_gsi; +} ioapic_irqmaps[MAX_HARDINTS]; /* XXX MAX_HARDINTS may not be correct */ + +#define IOAPIC_IMT_UNUSED 0 +#define IOAPIC_IMT_RESERVED 1 +#define IOAPIC_IMT_LINE 2 + extern void IOAPIC_INTREN(int); extern void IOAPIC_INTRDIS(int); @@ -459,6 +469,7 @@ static void ioapic_finalize(void); static void ioapic_cleanup(void); static void ioapic_setdefault(void); static void ioapic_stabilize(void); +static void ioapic_initmap(void); static int ioapic_imcr_present; @@ -472,7 +483,8 @@ struct machintr_abi MachIntrABI_IOAPIC = { .finalize = ioapic_finalize, .cleanup = ioapic_cleanup, .setdefault = ioapic_setdefault, - .stabilize = ioapic_stabilize + .stabilize = ioapic_stabilize, + .initmap = ioapic_initmap }; static int @@ -702,4 +714,19 @@ ioapic_setdefault(void) } } +/* XXX magic number */ +static void +ioapic_initmap(void) +{ + int i; + + for (i = 0; i < 16; ++i) { + struct ioapic_irqmap *map = &ioapic_irqmaps[i]; + + map->im_type = IOAPIC_IMT_LINE; + map->im_trig = INTR_TRIGGER_EDGE; + map->im_gsi = i; + } +} + #endif /* SMP */ diff --git a/sys/platform/pc32/apic/ioapic_abi.h b/sys/platform/pc32/apic/ioapic_abi.h index 0e6f843f56..0000189f4e 100644 --- a/sys/platform/pc32/apic/ioapic_abi.h +++ b/sys/platform/pc32/apic/ioapic_abi.h @@ -41,6 +41,8 @@ #ifndef _ARCH_APIC_IOAPIC_ABI_H_ #define _ARCH_APIC_IOAPIC_ABI_H_ +#ifdef SMP /* APIC_IO */ extern struct machintr_abi MachIntrABI_IOAPIC; +#endif #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */ diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index f5fb9e42b1..8834b2ac80 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -121,6 +121,7 @@ #include #include +#include #define PHYSMAP_ENTRIES 10 @@ -2073,6 +2074,17 @@ init386(int first) #endif rand_initialize(); + /* + * Initialize IRQ mapping + * + * NOTE: + * SHOULD be after elcr_probe() + */ + MachIntrABI_ICU.initmap(); +#ifdef SMP + MachIntrABI_IOAPIC.initmap(); +#endif + #ifdef DDB kdb_init(); if (boothowto & RB_KDB) diff --git a/sys/platform/pc32/icu/icu_abi.c b/sys/platform/pc32/icu/icu_abi.c index 81abb1e563..f063dd137b 100644 --- a/sys/platform/pc32/icu/icu_abi.c +++ b/sys/platform/pc32/icu/icu_abi.c @@ -55,6 +55,7 @@ #include #include +#include #include "icu.h" #include "icu_ipl.h" @@ -80,6 +81,15 @@ static inthand_t *icu_intr[ICU_HWI_VECTORS] = { &IDTVEC(icu_intr14), &IDTVEC(icu_intr15) }; +static struct icu_irqmap { + int im_type; /* ICU_IMT_ */ + enum intr_trigger im_trig; +} icu_irqmaps[MAX_HARDINTS]; /* XXX MAX_HARDINTS may not be correct */ + +#define ICU_IMT_UNUSED 0 /* KEEP THIS */ +#define ICU_IMT_RESERVED 1 +#define ICU_IMT_LINE 2 + extern void ICU_INTREN(int); extern void ICU_INTRDIS(int); @@ -90,6 +100,7 @@ static void icu_finalize(void); static void icu_cleanup(void); static void icu_setdefault(void); static void icu_stabilize(void); +static void icu_initmap(void); struct machintr_abi MachIntrABI_ICU = { MACHINTR_ICU, @@ -101,7 +112,8 @@ struct machintr_abi MachIntrABI_ICU = { .finalize = icu_finalize, .cleanup = icu_cleanup, .setdefault = icu_setdefault, - .stabilize = icu_stabilize + .stabilize = icu_stabilize, + .initmap = icu_initmap }; static int icu_imcr_present; @@ -263,3 +275,34 @@ icu_setdefault(void) SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); } } + +static void +icu_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 { + for (i = 0; i < ICU_HWI_VECTORS; ++i) { + switch (i) { + case 0: + case 1: + case 2: + case 8: + case 13: + icu_irqmaps[i].im_trig = INTR_TRIGGER_EDGE; + break; + + default: + icu_irqmaps[i].im_trig = INTR_TRIGGER_LEVEL; + break; + } + } + } +} diff --git a/sys/platform/pc64/apic/ioapic_abi.c b/sys/platform/pc64/apic/ioapic_abi.c index 7e35fd45bd..4987778484 100644 --- a/sys/platform/pc64/apic/ioapic_abi.c +++ b/sys/platform/pc64/apic/ioapic_abi.c @@ -449,6 +449,16 @@ static inthand_t *ioapic_intr[IOAPIC_HWI_VECTORS] = { &IDTVEC(ioapic_intr191) }; +static struct ioapic_irqmap { + int im_type; /* IOAPIC_IMT_ */ + enum intr_trigger im_trig; + int im_gsi; +} ioapic_irqmaps[MAX_HARDINTS]; /* XXX MAX_HARDINTS may not be correct */ + +#define IOAPIC_IMT_UNUSED 0 +#define IOAPIC_IMT_RESERVED 1 +#define IOAPIC_IMT_LINE 2 + extern void IOAPIC_INTREN(int); extern void IOAPIC_INTRDIS(int); @@ -459,6 +469,7 @@ static void ioapic_finalize(void); static void ioapic_cleanup(void); static void ioapic_setdefault(void); static void ioapic_stabilize(void); +static void ioapic_initmap(void); static int ioapic_imcr_present; @@ -472,7 +483,8 @@ struct machintr_abi MachIntrABI_IOAPIC = { .finalize = ioapic_finalize, .cleanup = ioapic_cleanup, .setdefault = ioapic_setdefault, - .stabilize = ioapic_stabilize + .stabilize = ioapic_stabilize, + .initmap = ioapic_initmap }; static int @@ -695,4 +707,19 @@ ioapic_setdefault(void) } } +/* XXX magic number */ +static void +ioapic_initmap(void) +{ + int i; + + for (i = 0; i < 16; ++i) { + struct ioapic_irqmap *map = &ioapic_irqmaps[i]; + + map->im_type = IOAPIC_IMT_LINE; + map->im_trig = INTR_TRIGGER_EDGE; + map->im_gsi = i; + } +} + #endif /* SMP */ diff --git a/sys/platform/pc64/apic/ioapic_abi.h b/sys/platform/pc64/apic/ioapic_abi.h index 0e6f843f56..0000189f4e 100644 --- a/sys/platform/pc64/apic/ioapic_abi.h +++ b/sys/platform/pc64/apic/ioapic_abi.h @@ -41,6 +41,8 @@ #ifndef _ARCH_APIC_IOAPIC_ABI_H_ #define _ARCH_APIC_IOAPIC_ABI_H_ +#ifdef SMP /* APIC_IO */ extern struct machintr_abi MachIntrABI_IOAPIC; +#endif #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */ diff --git a/sys/platform/pc64/icu/icu_abi.c b/sys/platform/pc64/icu/icu_abi.c index 849834af0e..6789b8e8db 100644 --- a/sys/platform/pc64/icu/icu_abi.c +++ b/sys/platform/pc64/icu/icu_abi.c @@ -55,6 +55,7 @@ #include #include +#include #include "icu.h" #include "icu_ipl.h" @@ -80,6 +81,15 @@ static inthand_t *icu_intr[ICU_HWI_VECTORS] = { &IDTVEC(icu_intr14), &IDTVEC(icu_intr15) }; +static struct icu_irqmap { + int im_type; /* ICU_IMT_ */ + enum intr_trigger im_trig; +} icu_irqmaps[MAX_HARDINTS]; /* XXX MAX_HARDINTS may not be correct */ + +#define ICU_IMT_UNUSED 0 /* KEEP THIS */ +#define ICU_IMT_RESERVED 1 +#define ICU_IMT_LINE 2 + extern void ICU_INTREN(int); extern void ICU_INTRDIS(int); @@ -90,6 +100,7 @@ static void icu_finalize(void); static void icu_cleanup(void); static void icu_setdefault(void); static void icu_stabilize(void); +static void icu_initmap(void); struct machintr_abi MachIntrABI_ICU = { MACHINTR_ICU, @@ -101,7 +112,8 @@ struct machintr_abi MachIntrABI_ICU = { .finalize = icu_finalize, .cleanup = icu_cleanup, .setdefault = icu_setdefault, - .stabilize = icu_stabilize + .stabilize = icu_stabilize, + .initmap = icu_initmap }; static int icu_imcr_present; @@ -263,3 +275,34 @@ icu_setdefault(void) SEL_KPL, 0); } } + +static void +icu_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 { + for (i = 0; i < ICU_HWI_VECTORS; ++i) { + switch (i) { + case 0: + case 1: + case 2: + case 8: + case 13: + icu_irqmaps[i].im_trig = INTR_TRIGGER_EDGE; + break; + + default: + icu_irqmaps[i].im_trig = INTR_TRIGGER_LEVEL; + break; + } + } + } +} diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index f0a4859217..bdd136f354 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -123,6 +123,7 @@ #include #include +#include #define PHYSMAP_ENTRIES 10 @@ -1858,6 +1859,17 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) #endif rand_initialize(); + /* + * Initialize IRQ mapping + * + * NOTE: + * SHOULD be after elcr_probe() + */ + MachIntrABI_ICU.initmap(); +#ifdef SMP + MachIntrABI_IOAPIC.initmap(); +#endif + #ifdef DDB kdb_init(); if (boothowto & RB_KDB) diff --git a/sys/sys/machintr.h b/sys/sys/machintr.h index 950e300a97..3655d63108 100644 --- a/sys/sys/machintr.h +++ b/sys/sys/machintr.h @@ -65,6 +65,7 @@ struct machintr_abi { void (*cleanup)(void); /* cleanup */ void (*setdefault)(void); /* set default vectors */ void (*stabilize)(void); /* stable before ints enabled */ + void (*initmap)(void); /* init irq mapping */ }; #define machintr_intren(intr) MachIntrABI.intren(intr) -- 2.41.0