Date: Fri, 27 Dec 2002 17:32:36 -0800 (PST) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 22825 for review Message-ID: <200212280132.gBS1WakY007301@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22825 Change 22825 by marcel@marcel_nfs on 2002/12/27 17:31:54 o Move ia64_sapics and ia64_sapic_count from interrupt.c to sapic.c. o Remove ia64_add_sapic(). Adding a sapic to the array is done in sapic_create directly now. o Update the interrupt counter as early as possible to help diagnose interrupt problems. o Create a new sysctl "hw.apic" that shows the RTEs for all (x)APICs in the system. This may be combined with interrupt counters as an alternative interface for vmstat -i. It may also go away... In ia64_enable(), we have a serious problem. We use the IRQ to determine the trigger mode and polarity. We assume that the first 16 IRQs are identity mapped onto the the dual-PIC IRQs used by legacy systems to support 8259 compatibility mode. Those interrupts are hardcoded to be edge sensitive and active high. All other (higher) IRQs are assumed (and hardcode) to be level sensitive active low. The latter is not true. On the HP rx2600 the ACPI based sio(4) devices are edge triggered active high and have vectors 66 and 67. DANGER, WILL ROBINSON: this change hardcodes the trigger mode and polarity for 3 interrupt vectors to be edge sensitive active high. Do not use this code unless you know it cannot harm. The kludge committed to get a serial console on the HP box in the cluster until we have figured where and how we can get information about interrupts and specificly about trigger mode and polarity. Affected files ... .. //depot/projects/ia64/sys/ia64/ia64/interrupt.c#18 edit .. //depot/projects/ia64/sys/ia64/ia64/sapic.c#15 edit Differences ... ==== //depot/projects/ia64/sys/ia64/ia64/interrupt.c#18 (text+ko) ==== @@ -206,11 +206,12 @@ volatile long *cntp; /* interrupt counter */ }; -static struct sapic *ia64_sapics[16]; /* XXX make this resizable */ -static int ia64_sapic_count; static struct mtx ia64_intrs_lock; static struct ia64_intr *ia64_intrs[256]; +extern struct sapic *ia64_sapics[]; +extern int ia64_sapic_count; + static void ithds_init(void *dummy) { @@ -219,13 +220,6 @@ } SYSINIT(ithds_init, SI_SUB_INTR, SI_ORDER_SECOND, ithds_init, NULL); -void -ia64_add_sapic(struct sapic *sa) -{ - - ia64_sapics[ia64_sapic_count++] = sa; -} - static void ia64_enable(int vector) { @@ -234,14 +228,11 @@ irq = vector - IA64_HARDWARE_IRQ_BASE; for (i = 0; i < ia64_sapic_count; i++) { struct sapic *sa = ia64_sapics[i]; - if (irq >= sa->sa_base && irq <= sa->sa_limit) - sapic_enable(sa, irq - sa->sa_base, vector, - (irq < 16 - ? SAPIC_TRIGGER_EDGE - : SAPIC_TRIGGER_LEVEL), - (irq < 16 - ? SAPIC_POLARITY_HIGH - : SAPIC_POLARITY_LOW)); + if (irq < sa->sa_base || irq > sa->sa_limit) + continue; + sapic_enable(sa, irq - sa->sa_base, vector, + (irq < 16) ? SAPIC_TRIGGER_EDGE : SAPIC_TRIGGER_LEVEL, + (irq < 16) ? SAPIC_POLARITY_HIGH : SAPIC_POLARITY_LOW); } } @@ -338,6 +329,9 @@ if (i == NULL) return; /* no ithread for this vector */ + if (i->cntp) + atomic_add_long(i->cntp, 1); + ithd = i->ithd; KASSERT(ithd != NULL, ("interrupt vector without a thread")); @@ -348,9 +342,6 @@ if (TAILQ_EMPTY(&ithd->it_handlers)) return; - if (i->cntp) - atomic_add_long(i->cntp, 1); - /* * Handle a fast interrupt if there is no actual thread for this * interrupt by calling the handler directly without Giant. Note ==== //depot/projects/ia64/sys/ia64/ia64/sapic.c#15 (text+ko) ==== @@ -36,9 +36,18 @@ #include <machine/sapicreg.h> #include <sys/bus.h> #include <machine/intr.h> +#include <sys/sysctl.h> static MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices"); +static int sysctl_hw_apic(SYSCTL_HANDLER_ARGS); + +SYSCTL_OID(_hw, OID_AUTO, apic, CTLTYPE_STRING|CTLFLAG_RD, + NULL, 0, sysctl_hw_apic, "A", "(x)APIC redirection table entries"); + +struct sapic *ia64_sapics[16]; /* XXX make this resizable */ +int ia64_sapic_count; + struct sapic_rte { u_int64_t rte_vector :8; u_int64_t rte_delivery_mode :3; @@ -75,11 +84,8 @@ ia64_mf(); } -#ifdef DDB - static void -sapic_read_rte(struct sapic *sa, int which, - struct sapic_rte *rte) +sapic_read_rte(struct sapic *sa, int which, struct sapic_rte *rte) { u_int32_t *p = (u_int32_t *) rte; register_t c; @@ -90,8 +96,6 @@ intr_restore(c); } -#endif - static void sapic_write_rte(struct sapic *sa, int which, struct sapic_rte *rte) @@ -122,7 +126,7 @@ max = (sapic_read(sa, SAPIC_VERSION) >> 16) & 0xff; sa->sa_limit = base + max; - ia64_add_sapic(sa); + ia64_sapics[ia64_sapic_count++] = sa; return sa; } @@ -137,8 +141,13 @@ bzero(&rte, sizeof(rte)); rte.rte_destination_id = (lid >> 24) & 255; rte.rte_destination_eid = (lid >> 16) & 255; - rte.rte_trigger_mode = trigger_mode; - rte.rte_polarity = polarity; + if (vector == 66 || vector == 67 || vector == 68) { + rte.rte_trigger_mode = SAPIC_TRIGGER_EDGE; + rte.rte_polarity = SAPIC_POLARITY_HIGH; + } else { + rte.rte_trigger_mode = trigger_mode; + rte.rte_polarity = polarity; + } rte.rte_delivery_mode = SAPIC_DELMODE_LOWPRI; rte.rte_vector = vector; sapic_write_rte(sa, input, &rte); @@ -153,6 +162,46 @@ ia64_mf(); } +static int +sysctl_hw_apic(SYSCTL_HANDLER_ARGS) +{ + char buf[80]; + struct sapic_rte rte; + struct sapic *sa; + int apic, count, error, index, len; + + len = sprintf(buf, "\n APIC Idx: Id,EId : RTE\n"); + error = SYSCTL_OUT(req, buf, len); + if (error) + return (error); + + for (apic = 0; apic < ia64_sapic_count; apic++) { + sa = ia64_sapics[apic]; + count = sa->sa_limit - sa->sa_base + 1; + for (index = 0; index < count; index++) { + sapic_read_rte(sa, index, &rte); + if (rte.rte_mask != 0) + continue; + len = sprintf(buf, + " 0x%02x %3d: (%02x,%02x): %3d %d %d %s %s %s %s %s\n", + sa->sa_id, index, + rte.rte_destination_id, rte.rte_destination_eid, + rte.rte_vector, rte.rte_delivery_mode, + rte.rte_destination_mode, + rte.rte_delivery_status ? "DS" : " ", + rte.rte_polarity ? "low-active " : "high-active", + rte.rte_rirr ? "RIRR" : " ", + rte.rte_trigger_mode ? "level" : "edge ", + rte.rte_flushen ? "F" : " "); + error = SYSCTL_OUT(req, buf, len); + if (error) + return (error); + } + } + + return (0); +} + #ifdef DDB #include <ddb/ddb.h> To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212280132.gBS1WakY007301>