summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-08 09:19:47 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-08 09:19:47 +0000
commit2090b3a3b3e6da74543ccf265684f89ae04893dc (patch)
tree13e5ab30012a6e97f1b7ac474930042724b4b310 /arch
parente93a5a86c71e4ff677161a883202e2e0336ce55f (diff)
New code to install and enable interrupt handlers for intercpu intrs.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/sgi-ip27/ip27-init.c13
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c65
2 files changed, 70 insertions, 8 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c
index b7f34c2bf..67d05a025 100644
--- a/arch/mips64/sgi-ip27/ip27-init.c
+++ b/arch/mips64/sgi-ip27/ip27-init.c
@@ -314,18 +314,19 @@ cpuid_t getcpuid(void)
void per_cpu_init(void)
{
static int is_slave = 0;
-
-#if 0
cpuid_t cpu = getcpuid();
-#endif
cnodeid_t cnode = get_compact_nodeid();
#if 0
intr_init();
#endif
set_cp0_status(ST0_IM, 0);
- cpu_time_init();
per_hub_init(cnode);
+ cpu_time_init();
+ install_cpuintr(cpu);
+#if 0
+ install_tlbintr(cpu);
+#endif
if (is_slave) {
set_cp0_status(ST0_BEV, 0);
if (mips4_available)
@@ -333,10 +334,6 @@ void per_cpu_init(void)
set_cp0_status(ST0_KX|ST0_SX|ST0_UX, ST0_KX|ST0_SX|ST0_UX);
set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1);
}
-#if 0
- install_cpuintr(cpu);
- install_tlbintr(cpu);
-#endif
if (is_slave == 0)
is_slave = 1;
}
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 765020578..db6575395 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -33,6 +33,8 @@
#include <asm/sn/sn0/hub.h>
#include <asm/sn/sn0/ip27.h>
#include <asm/sn/arch.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/intr_public.h>
/*
* Linux has a controller-independent x86 interrupt architecture.
@@ -602,3 +604,66 @@ void __global_restore_flags(unsigned long flags)
}
#endif /* CONFIG_SMP */
+
+hub_intmasks_t per_hub_intmasks[MAX_COMPACT_NODES];
+
+/*
+ * Get values that vary depending on which CPU and bit we're operating on.
+ */
+static hub_intmasks_t *intr_get_ptrs(cpuid_t cpu, int bit, int *new_bit,
+ hubreg_t **intpend_masks, int *ip)
+{
+ hub_intmasks_t *hub_intmasks;
+
+ hub_intmasks = &per_hub_intmasks[cputocnode(cpu)];
+ if (bit < N_INTPEND_BITS) {
+ *intpend_masks = hub_intmasks->intpend0_masks;
+ *ip = 0;
+ *new_bit = bit;
+ } else {
+ *intpend_masks = hub_intmasks->intpend1_masks;
+ *ip = 1;
+ *new_bit = bit - N_INTPEND_BITS;
+ }
+ return hub_intmasks;
+}
+
+int intr_connect_level(cpuid_t cpu, int bit)
+{
+ int ip;
+ int slice = cputoslice(cpu);
+ volatile hubreg_t *mask_reg;
+ hubreg_t *intpend_masks;
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+ (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+
+ /* Make sure it's not already pending when we connect it. */
+ REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS);
+
+ intpend_masks[0] |= (1ULL << (u64)bit);
+
+ if (ip == 0) {
+ mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+ PI_INT_MASK_OFFSET * slice);
+ } else {
+ mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+ PI_INT_MASK_OFFSET * slice);
+ }
+ HUB_S(mask_reg, intpend_masks[0]);
+ return(0);
+}
+
+void install_cpuintr(cpuid_t cpu)
+{
+ int intr_bit = CPU_ACTION_A + cputoslice(cpu);
+
+ intr_connect_level(cpu, intr_bit);
+}
+
+void install_tlbintr(cpuid_t cpu)
+{
+ int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
+
+ intr_connect_level(cpu, intr_bit);
+}