diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-01 01:54:46 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-01 01:54:46 +0000 |
commit | d49f62d0497bc81a70b1c2e01ddec71d8ea93c30 (patch) | |
tree | f44aa76d2fadd1356ebb9f13850b4b14e702010c | |
parent | 5e0a97c26457260b7a95383fae0fc2cf2f98237d (diff) |
Rudimentary sendintr() routine to send intrs to other cpus. This needs to
pull in defines from intr.h/intr_public.h. Also, need to store percpu
information regarding cpu slice # for cpu, hardware nasid and compact
node id.
-rw-r--r-- | arch/mips64/kernel/smp.c | 37 | ||||
-rw-r--r-- | include/asm-mips64/processor.h | 10 | ||||
-rw-r--r-- | include/asm-mips64/sn/arch.h | 6 | ||||
-rw-r--r-- | include/asm-mips64/sn/intr.h | 127 | ||||
-rw-r--r-- | include/asm-mips64/sn/intr_public.h | 59 |
5 files changed, 236 insertions, 3 deletions
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c index d72e97904..d4365c647 100644 --- a/arch/mips64/kernel/smp.c +++ b/arch/mips64/kernel/smp.c @@ -1,3 +1,4 @@ +#include <linux/config.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/threads.h> @@ -10,6 +11,42 @@ #include <asm/system.h> #include <asm/hardirq.h> +#ifdef CONFIG_SGI_IP27 + +#include <asm/sn/arch.h> +#include <asm/sn/intr.h> +#include <asm/sn/addrs.h> +#include <asm/sn/agent.h> + +#define DOACTION 0xab + +static void sendintr(int destid, unsigned char status) +{ + int level; + +#if (CPUS_PER_NODE == 2) + /* + * CPU slice A gets level CPU_ACTION_A + * CPU slice B gets level CPU_ACTION_B + */ + if (status == DOACTION) + level = CPU_ACTION_A + cputoslice(destid); + else /* DOTLBACTION */ + level = N_INTPEND_BITS + TLB_INTR_A + cputoslice(destid); + + /* + * Convert the compact hub number to the NASID to get the correct + * part of the address space. Then set the interrupt bit associated + * with the CPU we want to send the interrupt to. + */ + REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)), level); +#else + << Bomb! Must redefine this for more than 2 CPUS. >> +#endif +} + +#endif /* CONFIG_SGI_IP27 */ + /* The 'big kernel lock' */ spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; int smp_threads_ready = 0; /* Not used */ diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h index 7c7ae6d01..56692101b 100644 --- a/include/asm-mips64/processor.h +++ b/include/asm-mips64/processor.h @@ -19,11 +19,16 @@ #define current_text_addr() ({ __label__ _l; _l: &&_l;}) #if !defined (_LANGUAGE_ASSEMBLY) +#include <linux/config.h> #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/reg.h> #include <asm/system.h> +#if (defined(CONFIG_SGI_IP27) && defined(CONFIG_SMP)) +#include <asm/sn/types.h> +#endif + struct cpuinfo_mips { unsigned long udelay_val; unsigned long *pgd_quick; @@ -32,6 +37,11 @@ struct cpuinfo_mips { unsigned long pgtable_cache_sz; unsigned long last_asn; unsigned int irq_count, bh_count; +#if (defined(CONFIG_SGI_IP27) && defined(CONFIG_SMP)) + cnodeid_t p_nodeid; /* my node ID in compact-id-space */ + nasid_t p_nasid; /* my node ID in numa-as-id-space */ + unsigned char p_slice; /* Physical position on node board */ +#endif } __attribute__((aligned(128))); /* diff --git a/include/asm-mips64/sn/arch.h b/include/asm-mips64/sn/arch.h index c1c001ed5..5246b040c 100644 --- a/include/asm-mips64/sn/arch.h +++ b/include/asm-mips64/sn/arch.h @@ -27,11 +27,11 @@ typedef u64 nic_t; #define CNODE_NUM_CPUS(_cnode) (NODEPDA(_cnode)->node_num_cpus) #define CNODE_TO_CPU_BASE(_cnode) (NODEPDA(_cnode)->node_first_cpu) #define cputocnode(cpu) \ - (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_nodeid)) + (cpu_data[(cpu)].p_nodeid) #define cputonasid(cpu) \ - (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_nasid)) + (cpu_data[(cpu)].p_nasid) #define cputoslice(cpu) \ - (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_slice)) + (cpu_data[(cpu)].p_slice) #define makespnum(_nasid, _slice) \ (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice)) diff --git a/include/asm-mips64/sn/intr.h b/include/asm-mips64/sn/intr.h new file mode 100644 index 000000000..234a116b3 --- /dev/null +++ b/include/asm-mips64/sn/intr.h @@ -0,0 +1,127 @@ +/************************************************************************** + * * + * Copyright (C) 1992-1997, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#ifndef __SYS_SN_INTR_H__ +#define __SYS_SN_INTR_H__ + +/* Number of interrupt levels associated with each interrupt register. */ +#define N_INTPEND_BITS 64 + +#define INT_PEND0_BASELVL 0 +#define INT_PEND1_BASELVL 64 + +#define N_INTPENDJUNK_BITS 8 +#define INTPENDJUNK_CLRBIT 0x80 + +#include <asm/sn/intr_public.h> + +#if _LANGUAGE_C + +/* + * Macros to manipulate the interrupt register on the calling hub chip. + */ + +#define LOCAL_HUB_SEND_INTR(_level) LOCAL_HUB_S(PI_INT_PEND_MOD, \ + (0x100|(_level))) +#define REMOTE_HUB_SEND_INTR(_hub, _level) \ + REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (0x100|(_level))) + +/* + * When clearing the interrupt, make sure this clear does make it + * to the hub. Otherwise we could end up losing interrupts. + * We do an uncached load of the int_pend0 register to ensure this. + */ + +#define LOCAL_HUB_CLR_INTR(_level) \ + LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)), \ + LOCAL_HUB_L(PI_INT_PEND0) +#define REMOTE_HUB_CLR_INTR(_hub, _level) \ + REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)), \ + REMOTE_HUB_L((_hub), PI_INT_PEND0) + +#else /* LANGUAGE_ASSEMBLY */ + +#endif /* LANGUAGE_C */ + +/* + * Hard-coded interrupt levels: + */ + +/* + * L0 = SW1 + * L1 = SW2 + * L2 = INT_PEND0 + * L3 = INT_PEND1 + * L4 = RTC + * L5 = Profiling Timer + * L6 = Hub Errors + * L7 = Count/Compare (T5 counters) + */ + + +/* INT_PEND0 hard-coded bits. */ +#ifdef SABLE +#define SDISK_INTR 63 +#endif +#ifdef DEBUG_INTR_TSTAMP +/* hard coded interrupt level for interrupt latency test interrupt */ +#define CPU_INTRLAT_B 62 +#define CPU_INTRLAT_A 61 +#endif + +/* Hardcoded bits required by software. */ +#define MSC_MESG_INTR 9 +#define CPU_ACTION_B 8 +#define CPU_ACTION_A 7 + +/* These are determined by hardware: */ +#define CC_PEND_B 6 +#define CC_PEND_A 5 +#define UART_INTR 4 +#define PG_MIG_INTR 3 +#define GFX_INTR_B 2 +#define GFX_INTR_A 1 +#define RESERVED_INTR 0 + +/* INT_PEND1 hard-coded bits: */ +#define MSC_PANIC_INTR 63 +#define NI_ERROR_INTR 62 +#define MD_COR_ERR_INTR 61 +#define COR_ERR_INTR_B 60 +#define COR_ERR_INTR_A 59 +#define CLK_ERR_INTR 58 +#define IO_ERROR_INTR 57 /* set up by prom */ + +#define DEBUG_INTR_B 55 /* used by symmon to stop all cpus */ +#define DEBUG_INTR_A 54 + +#define BRIDGE_ERROR_INTR 53 /* Setup by PROM to catch Bridge Errors */ + +#define IP27_INTR_0 52 /* Reserved for PROM use */ +#define IP27_INTR_1 51 /* (do not use in Kernel) */ +#define IP27_INTR_2 50 +#define IP27_INTR_3 49 +#define IP27_INTR_4 48 +#define IP27_INTR_5 47 +#define IP27_INTR_6 46 +#define IP27_INTR_7 45 + +#define TLB_INTR_B 44 /* used for tlb flush random */ +#define TLB_INTR_A 43 + +#define LLP_PFAIL_INTR_B 42 /* see ml/SN/SN0/sysctlr.c */ +#define LLP_PFAIL_INTR_A 41 + +#define NI_BRDCAST_ERR_B 40 +#define NI_BRDCAST_ERR_A 39 + +#endif /* __SYS_SN_INTR_H__ */ diff --git a/include/asm-mips64/sn/intr_public.h b/include/asm-mips64/sn/intr_public.h new file mode 100644 index 000000000..63d3e6ebc --- /dev/null +++ b/include/asm-mips64/sn/intr_public.h @@ -0,0 +1,59 @@ +/************************************************************************** + * * + * Copyright (C) 1992-1997, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#ifndef __SYS_SN_INTR_PUBLIC_H__ +#define __SYS_SN_INTR_PUBLIC_H__ + + +/* REMEMBER: If you change these, the whole world needs to be recompiled. + * It would also require changing the hubspl.s code and SN0/intr.c + * Currently, the spl code has no support for multiple INTPEND1 masks. + */ + +#define N_INTPEND0_MASKS 1 +#define N_INTPEND1_MASKS 1 + +#define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1) +#define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1) + +#if _LANGUAGE_C +#include <asm/sn/arch.h> + +struct intr_vecblk_s; /* defined in asm/sn/intr.h */ + +/* + * The following are necessary to create the illusion of a CEL + * on the SN0 hub. We'll add more priority levels soon, but for + * now, any interrupt in a particular band effectively does an spl. + * These must be in the PDA since they're different for each processor. + * Users of this structure must hold the vector_lock in the appropriate vector + * block before modifying the mask arrays. There's only one vector block + * for each Hub so a lock in the PDA wouldn't be adequate. + */ +typedef struct hub_intmasks_s { + /* + * The masks are stored with the lowest-priority (most inclusive) + * in the lowest-numbered masks (i.e., 0, 1, 2...). + */ + /* INT_PEND0: */ + hubreg_t intpend0_masks[N_INTPEND0_MASKS]; + /* INT_PEND1: */ + hubreg_t intpend1_masks[N_INTPEND1_MASKS]; + /* INT_PEND0: */ + struct intr_vecblk_s *dispatch0; + /* INT_PEND1: */ + struct intr_vecblk_s *dispatch1; +} hub_intmasks_t; + +#endif /* _LANGUAGE_C */ +#endif /* __SYS_SN_INTR_PUBLIC_H__ */ + |