diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-08 09:19:47 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-08 09:19:47 +0000 |
commit | 2090b3a3b3e6da74543ccf265684f89ae04893dc (patch) | |
tree | 13e5ab30012a6e97f1b7ac474930042724b4b310 /arch | |
parent | e93a5a86c71e4ff677161a883202e2e0336ce55f (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.c | 13 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-irq.c | 65 |
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); +} |