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
- Lines: 317
- Date:
2003-06-13 07:51:30.000000000 -0700
- Orig file:
linux-2.4.20/arch/ia64/sn/io/sn2/ml_SN_intr.c
- Orig date:
2002-08-02 17:39:43.000000000 -0700
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)