patch-2.4.21 linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c

Next file: linux-2.4.21/arch/ia64/sn/io/sn2/ml_iograph.c
Previous file: linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_init.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ia64/sn/io/sn2/ml_SN_intr.c linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c
@@ -36,6 +36,7 @@
 #include <asm/sn/pci/pcibr_private.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn2/shub_mmr_t.h>
+#include <asm/sn/sn2/shubio.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
 
@@ -44,6 +45,26 @@
 extern nasid_t master_nasid;
 
 //  Initialize some shub registers for interrupts, both IO and error.
+//  
+
+#ifdef BRINGUP2
+static long vec1_opt, ii0_opt;
+static int __init set_vec1_opt(char *str)
+{
+        vec1_opt = 1;
+        return 1;
+}
+
+static int __init set_ii0_opt(char *str)
+{
+        ii0_opt = 1;
+        return 1;
+}
+
+__setup("vec1", set_vec1_opt);
+__setup("ii0", set_ii0_opt);
+#endif
+
 
 void
 intr_init_vecblk( nodepda_t *npda,
@@ -51,24 +72,15 @@
 		int sn)
 {
 	int 			nasid = cnodeid_to_nasid(node);
-	nasid_t			console_nasid;
 	sh_ii_int0_config_u_t	ii_int_config;
 	cpuid_t			cpu;
 	cpuid_t			cpu0, cpu1;
 	nodepda_t		*lnodepda;
 	sh_ii_int0_enable_u_t	ii_int_enable;
-	sh_local_int0_config_u_t	local_int_config;
-	sh_local_int0_enable_u_t	local_int_enable;
-	sh_fsb_system_agent_config_u_t	fsb_system_agent;
 	sh_int_node_id_config_u_t	node_id_config;
-	int is_console;
+	extern void sn_init_cpei_timer(void);
+	static int timer_added = 0;
 
-	console_nasid = get_console_nasid();
-	if (console_nasid < 0) {
-		console_nasid = master_nasid;
-	}
-
-	is_console = nasid == console_nasid;
 
 	if (is_headless_node(node) ) {
 		int cnode;
@@ -95,13 +107,15 @@
 	}
 
 	// Get the physical id's of the cpu's on this node.
-	cpu0 = id_eid_to_cpu_physical_id(nasid, 0);
-	cpu1 = id_eid_to_cpu_physical_id(nasid, 1);
+	cpu0 = nasid_slice_to_cpu_physical_id(nasid, 0);
+	cpu1 = nasid_slice_to_cpu_physical_id(nasid, 2);
 
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
 
+
 	// The II_INT_CONFIG register for cpu 0.
+	ii_int_config.sh_ii_int0_config_regval = 0;
 	ii_int_config.sh_ii_int0_config_s.type = 0;
 	ii_int_config.sh_ii_int0_config_s.agt = 0;
 	ii_int_config.sh_ii_int0_config_s.pid = cpu0;
@@ -110,7 +124,9 @@
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_CONFIG),
 		ii_int_config.sh_ii_int0_config_regval);
 
+
 	// The II_INT_CONFIG register for cpu 1.
+	ii_int_config.sh_ii_int0_config_regval = 0;
 	ii_int_config.sh_ii_int0_config_s.type = 0;
 	ii_int_config.sh_ii_int0_config_s.agt = 0;
 	ii_int_config.sh_ii_int0_config_s.pid = cpu1;
@@ -119,101 +135,28 @@
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_CONFIG),
 		ii_int_config.sh_ii_int0_config_regval);
 
+
 	// Enable interrupts for II_INT0 and 1.
+	ii_int_enable.sh_ii_int0_enable_regval = 0;
 	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
+#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC)
+	/* Dont enable any ints from II. We will poll for interrupts. */
+	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0;
+
+	/* Enable IPIs. We use them ONLY for send INITs to hung cpus */
+	*(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1;
+#endif
 
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
 		ii_int_enable.sh_ii_int0_enable_regval);
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_ENABLE),
 		ii_int_enable.sh_ii_int0_enable_regval);
 
-	// init error regs
-	// LOCAL_INT0 is for the UART only.
-
-	local_int_config.sh_local_int0_config_s.type = 0;
-	local_int_config.sh_local_int0_config_s.agt = 0;
-	local_int_config.sh_local_int0_config_s.pid = cpu;
-	local_int_config.sh_local_int0_config_s.base = 0;
-	local_int_config.sh_local_int0_config_s.idx = SGI_UART_VECTOR;
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_CONFIG),
-		local_int_config.sh_local_int0_config_regval);
-
-	// LOCAL_INT1 is for all hardware errors.
-	// It will send a BERR, which will result in an MCA.
-	local_int_config.sh_local_int0_config_s.idx = 0;
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
-		local_int_config.sh_local_int0_config_regval);
-
-	// Clear the LOCAL_INT_ENABLE register.
-	local_int_enable.sh_local_int0_enable_regval = 0;
-
-	if (is_console) {
-		// Enable the UART interrupt.  Only applies to the console nasid.
-		local_int_enable.sh_local_int0_enable_s.uart_int = 1;
-
-		HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_ENABLE),
-			local_int_enable.sh_local_int0_enable_regval);
-	}
-
-	// Enable all the error interrupts.
-	local_int_enable.sh_local_int0_enable_s.uart_int = 0;
-	local_int_enable.sh_local_int0_enable_s.pi_hw_int = 1;
-	local_int_enable.sh_local_int0_enable_s.md_hw_int = 1;
-	local_int_enable.sh_local_int0_enable_s.xn_hw_int = 1;
-	local_int_enable.sh_local_int0_enable_s.lb_hw_int = 1;
-	local_int_enable.sh_local_int0_enable_s.ii_hw_int = 1;
-	local_int_enable.sh_local_int0_enable_s.pi_uce_int = 1;
-	local_int_enable.sh_local_int0_enable_s.md_uce_int = 1;
-	local_int_enable.sh_local_int0_enable_s.xn_uce_int = 1;
-	local_int_enable.sh_local_int0_enable_s.system_shutdown_int = 1;
-	local_int_enable.sh_local_int0_enable_s.l1_nmi_int = 1;
-	local_int_enable.sh_local_int0_enable_s.stop_clock = 1;
-
-
-	// Send BERR, rather than an interrupt, for shub errors.
-	local_int_config.sh_local_int0_config_s.agt = 1;
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
-		local_int_config.sh_local_int0_config_regval);
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_ENABLE),
-		local_int_enable.sh_local_int0_enable_regval);
-
-	// Make sure BERR is enabled.
-	fsb_system_agent.sh_fsb_system_agent_config_regval = 
-		HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG) );
-	fsb_system_agent.sh_fsb_system_agent_config_s.berr_assert_en = 1;
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG),
-		fsb_system_agent.sh_fsb_system_agent_config_regval);
-
-	// Set LOCAL_INT2 to field CEs
-
-	local_int_enable.sh_local_int0_enable_regval = 0;
-
-	local_int_config.sh_local_int0_config_s.agt = 0;
-	local_int_config.sh_local_int0_config_s.idx = SGI_SHUB_ERROR_VECTOR;
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_CONFIG),
-		local_int_config.sh_local_int0_config_regval);
-
-	local_int_enable.sh_local_int0_enable_s.pi_ce_int = 1;
-	local_int_enable.sh_local_int0_enable_s.md_ce_int = 1;
-	local_int_enable.sh_local_int0_enable_s.xn_ce_int = 1;
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_ENABLE),
-		local_int_enable.sh_local_int0_enable_regval);
-
-	// Make sure all the rest of the LOCAL_INT regs are disabled.
-	local_int_enable.sh_local_int0_enable_regval = 0;
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT3_ENABLE),
-		local_int_enable.sh_local_int0_enable_regval);
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT4_ENABLE),
-		local_int_enable.sh_local_int0_enable_regval);
-
-	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
-		local_int_enable.sh_local_int0_enable_regval);
 
+	if (!timer_added) { // can only init the timer once.
+		timer_added = 1;
+		sn_init_cpei_timer();
+	}
 }
 
 // (Un)Reserve an irq on this cpu.
@@ -225,12 +168,17 @@
 {
 	int i;
 	irqpda_t	*irqs = irqpdaindr[cpu];
+	static int	nextvec=IA64_SN2_FIRST_DEVICE_VECTOR;
 
 	if (reserve) {
 		if (bit < 0) {
-			for (i = IA64_SN2_FIRST_DEVICE_VECTOR; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+			for (i = nextvec; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
 				if (irqs->irq_flags[i] == 0) {
 					bit = i;
+#ifdef BRINGUP2
+					if (vec1_opt)
+						nextvec = i+1;
+#endif
 					break;
 				}
 			}
@@ -343,6 +291,10 @@
 		if (min_count > intrs) {
 			min_count = intrs;
 			best_cpu = cpu;
+#ifdef BRINGUP2
+			if (ii0_opt)
+				break;
+#endif
 		}
 	}
 	return best_cpu;
@@ -393,31 +345,40 @@
 		int *resp_bit)
 {
 	cpuid_t		cpuid;
-	cnodeid_t	candidate = -1;
+	cpuid_t		candidate = CPU_NONE;
+	cnodeid_t	candidate_node;
 	devfs_handle_t	pconn_vhdl;
 	pcibr_soft_t	pcibr_soft;
+	int 		bit;
 
 /* SN2 + pcibr addressing limitation */
 /* Due to this limitation, all interrupts from a given bridge must go to the name node.*/
+/* The interrupt must also be targetted for the same processor. */
 /* This limitation does not exist on PIC. */
+/* But, the processor limitation will stay.  The limitation will be similar to */
+/* the bedrock/xbridge limit regarding PI's */
 
 	if ( (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
 		( (pcibr_soft = pcibr_soft_get(pconn_vhdl) ) != NULL) ) {
 			if (pcibr_soft->bsi_err_intr) {
-				candidate = cpuid_to_cnodeid( ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid);
+				candidate =  ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid;
 			}
 	}
 
-	if (candidate >= 0) {
-		// The node was chosen already when we assigned the error interrupt.
-		cpuid = intr_bit_reserve_test(CPU_NONE,
-						0,
-						candidate,
-						req_bit,
-						0,
-						owner_dev,
-						name,
-						resp_bit);
+
+	if (candidate != CPU_NONE) {
+		// The cpu was chosen already when we assigned the error interrupt.
+		bit = intr_reserve_level(candidate, 
+					req_bit, 
+					resflags, 
+					owner_dev, 
+					name);
+		if (bit < 0) {
+			cpuid = CPU_NONE;
+		} else {
+			cpuid = candidate;
+			*resp_bit = bit;
+		}
 	} else {
 		// Need to choose one.  Try the controlling c-brick first.
 		cpuid = intr_bit_reserve_test(CPU_NONE,
@@ -434,10 +395,9 @@
 		return cpuid;
 	}
 
-	if (candidate >= 0) {
-		printk("Cannot target interrupt to target node (%d).\n",candidate);
-		return CPU_NONE;
-	} else {
+	if (candidate  != CPU_NONE) {
+		printk("Cannot target interrupt to target node (%ld).\n",candidate);
+		return CPU_NONE; } else {
 		printk("Cannot target interrupt to closest node (%d) 0x%p\n",
 			master_node_get(dev), (void *)owner_dev);
 	}
@@ -448,11 +408,11 @@
 	{
 		static cnodeid_t last_node = -1;
 		if (last_node >= numnodes) last_node = 0;
-		for (candidate = last_node + 1; candidate != last_node; candidate++) {
-			if (candidate == numnodes) candidate = 0;
+		for (candidate_node = last_node + 1; candidate_node != last_node; candidate_node++) {
+			if (candidate_node == numnodes) candidate_node = 0;
 			cpuid = intr_bit_reserve_test(CPU_NONE,
 							0,
-							candidate,
+							candidate_node,
 							req_bit,
 							0,
 							owner_dev,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)