Skip site navigation (1)Skip section navigation (2)
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>