Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Sep 2003 01:52:09 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 37862 for review
Message-ID:  <200309100852.h8A8q9jG071961@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=37862

Change 37862 by marcel@marcel_nfs on 2003/09/10 01:51:57

	Change the sapic code to allow us to implement bus_config_intr().
	It works like this. When we find an I/O APIC in the MADT, we
	create a structure for it. At that time we initialize all RTEs.
	Interrupts will be masked by default and trigger mode and polarity
	are defined as before. We implement sapic_config_intr() by reading
	the RTE from the SAPIC, update the trigger mode and polarity and
	write the modified RTE back. Now when we enable an interrupt, we
	can always be sure that the SAPIC has the correct defaults and we
	only have to update the vector, set the delivery mode and unmask
	the interrupt.
	
	This compiles, but hasn't been runtime tested. I'm a bit uneasy
	with masking all interrupts but I'll notice soon enough if that
	works or not.
	
	With this commit, the interrupt hack has been gone, because
	ia64_enable() has been gone completely.
	
	/me looks at the time and knows who's going to be late tomorrow.

Affected files ...

.. //depot/projects/ia64/sys/ia64/ia64/interrupt.c#32 edit
.. //depot/projects/ia64/sys/ia64/ia64/nexus.c#6 edit
.. //depot/projects/ia64/sys/ia64/ia64/sapic.c#21 edit
.. //depot/projects/ia64/sys/ia64/include/sapicvar.h#5 edit

Differences ...

==== //depot/projects/ia64/sys/ia64/ia64/interrupt.c#32 (text+ko) ====

@@ -259,31 +259,6 @@
 SYSINIT(ithds_init, SI_SUB_INTR, SI_ORDER_SECOND, ithds_init, NULL);
 
 static void
-ia64_enable(int vector)
-{
-	int irq, i;
-
-	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)
-			continue;
-		/*
-		 * KLUDGE: Not all interrupts higher or equal to 16 are
-		 * active low and level sensitive. We don't know yet how
-		 * to check for this, so we hardcode the 2 cases we have
-		 * wrong explicitly. This kludge is specific to the HP
-		 * rx2600...
-		 */
-		sapic_enable(sa, irq - sa->sa_base, vector,
-		    ((irq < 16 || vector == 66 || vector == 67)
-			? SAPIC_TRIGGER_EDGE : SAPIC_TRIGGER_LEVEL),
-		    ((irq < 16 || vector == 66 || vector == 67)
-			? SAPIC_POLARITY_HIGH : SAPIC_POLARITY_LOW));
-	}
-}
-
-static void
 ia64_send_eoi(int vector)
 {
 	int irq, i;
@@ -350,8 +325,7 @@
 	if (errcode)
 		return errcode;
 
-	ia64_enable(vector);
-	return 0;
+	return (sapic_enable(irq, vector));
 }
 
 int

==== //depot/projects/ia64/sys/ia64/ia64/nexus.c#6 (text+ko) ====

@@ -49,15 +49,16 @@
 #include <machine/bus.h>
 #include <sys/rman.h>
 #include <sys/interrupt.h>
-#include <machine/intr.h>
 
-#include <machine/vmparam.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
-#include <machine/pmap.h>
 
+#include <machine/intr.h>
 #include <machine/nexusvar.h>
+#include <machine/pmap.h>
 #include <machine/resource.h>
+#include <machine/sapicvar.h>
+#include <machine/vmparam.h>
 
 #include <isa/isareg.h>
 #include <sys/rtprio.h>
@@ -543,8 +544,7 @@
     enum intr_polarity pol)
 {
 
-	printf("XXX: %s: irq=%d, trig=%d, pol=%d\n", __func__, irq, trig, pol);
-	return (EINVAL);
+	return (sapic_config_intr(irq, trig, pol));
 }
 
 #if 0

==== //depot/projects/ia64/sys/ia64/ia64/sapic.c#21 (text+ko) ====

@@ -32,12 +32,13 @@
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
-#include <machine/sapicvar.h>
-#include <machine/sapicreg.h>
 #include <sys/bus.h>
+#include <sys/sysctl.h>
+
 #include <machine/intr.h>
 #include <machine/pal.h>
-#include <sys/sysctl.h>
+#include <machine/sapicreg.h>
+#include <machine/sapicvar.h>
 
 static MALLOC_DEFINE(M_SAPIC, "sapic", "I/O SAPIC devices");
 
@@ -100,8 +101,7 @@
 }
 
 static void
-sapic_write_rte(struct sapic *sa, int which,
-		struct sapic_rte *rte)
+sapic_write_rte(struct sapic *sa, int which, struct sapic_rte *rte)
 {
 	u_int32_t *p = (u_int32_t *) rte;
 	register_t c;
@@ -112,11 +112,44 @@
 	intr_restore(c);
 }
 
+int
+sapic_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol)
+{
+	struct sapic_rte rte;
+	struct sapic *sa;
+	int i;
+
+	for (i = 0; i < ia64_sapic_count; i++) {
+		sa = ia64_sapics[i];
+		if (irq < sa->sa_base || irq > sa->sa_limit)
+			continue;
+
+		sapic_read_rte(sa, irq - sa->sa_base, &rte);
+		if (trig != INTR_TRIGGER_CONFORM)
+			rte.rte_trigger_mode = (trig == INTR_TRIGGER_EDGE) ?
+			    SAPIC_TRIGGER_EDGE : SAPIC_TRIGGER_LEVEL;
+		else
+			rte.rte_trigger_mode = (irq < 16) ?
+			    SAPIC_TRIGGER_EDGE : SAPIC_TRIGGER_LEVEL;
+		if (pol != INTR_POLARITY_CONFORM)
+			rte.rte_polarity = (pol == INTR_POLARITY_HIGH) ?
+			    SAPIC_POLARITY_HIGH : SAPIC_POLARITY_LOW;
+		else
+			rte.rte_polarity = (irq < 16) ? SAPIC_POLARITY_HIGH :
+			    SAPIC_POLARITY_LOW;
+		sapic_write_rte(sa, irq - sa->sa_base, &rte);
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
 struct sapic *
 sapic_create(int id, int base, u_int64_t address)
 {
+	struct sapic_rte rte;
 	struct sapic *sa;
-	int max;
+	int i, max;
 
 	sa = malloc(sizeof(struct sapic), M_SAPIC, M_NOWAIT);
 	if (!sa)
@@ -131,24 +164,47 @@
 
 	ia64_sapics[ia64_sapic_count++] = sa;
 
-	return sa;
+	/*
+	 * Initialize all RTEs with a default trigger mode and polarity.
+	 * This may be changed later by calling sapic_config_intr(). We
+	 * mask all interrupts by default.
+	 */
+	bzero(&rte, sizeof(rte));
+	rte.rte_mask = 1;
+	for (i = base; i <= sa->sa_limit; i++) {
+		rte.rte_trigger_mode = (i < 16) ? SAPIC_TRIGGER_EDGE :
+		    SAPIC_TRIGGER_LEVEL;
+		rte.rte_polarity = (i < 16) ? SAPIC_POLARITY_HIGH :
+		    SAPIC_POLARITY_LOW;
+		sapic_write_rte(sa, i - base, &rte);
+	}
+
+	return (sa);
 }
 
-void
-sapic_enable(struct sapic *sa, int input, int vector,
-	     int trigger_mode, int polarity)
+int
+sapic_enable(int irq, int vector)
 {
 	struct sapic_rte rte;
-	u_int64_t lid = ia64_get_lid();
+	struct sapic *sa;
+	uint64_t lid = ia64_get_lid();
+	int i;
+
+	for (i = 0; i < ia64_sapic_count; i++) {
+		sa = ia64_sapics[i];
+		if (irq < sa->sa_base || irq > sa->sa_limit)
+			continue;
 
-	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;
-	rte.rte_delivery_mode = SAPIC_DELMODE_LOWPRI;
-	rte.rte_vector = vector;
-	sapic_write_rte(sa, input, &rte);
+		sapic_read_rte(sa, irq - sa->sa_base, &rte);
+		rte.rte_destination_id = (lid >> 24) & 255;
+		rte.rte_destination_eid = (lid >> 16) & 255;
+		rte.rte_delivery_mode = SAPIC_DELMODE_LOWPRI;
+		rte.rte_vector = vector;
+		rte.rte_mask = 0;
+		sapic_write_rte(sa, irq - sa->sa_base, &rte);
+		return (0);
+	}
+	return (ENOENT);
 }
 
 void

==== //depot/projects/ia64/sys/ia64/include/sapicvar.h#5 (text+ko) ====

@@ -49,12 +49,12 @@
 #define SAPIC_DELMODE_INIT	5
 #define SAPIC_DELMODE_EXTINT	7
 
-struct sapic	*sapic_create(int id, int base, u_int64_t address);
-void		sapic_enable(struct sapic *sa, int input, int vector,
-			     int trigger_mode, int polarity);
-void		sapic_eoi(struct sapic *sa, int vector);
+int	sapic_config_intr(int irq, enum intr_trigger, enum intr_polarity);
+struct sapic *sapic_create(int id, int base, uint64_t address);
+int	sapic_enable(int irq, int vector);
+void	sapic_eoi(struct sapic *sa, int vector);
 #ifdef DDB
-void		sapic_print(struct sapic *sa, int input);
+void	sapic_print(struct sapic *sa, int input);
 #endif
 
 #endif /* ! _MACHINE_SAPICVAR_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200309100852.h8A8q9jG071961>