summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-01 01:54:46 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-01 01:54:46 +0000
commitd49f62d0497bc81a70b1c2e01ddec71d8ea93c30 (patch)
treef44aa76d2fadd1356ebb9f13850b4b14e702010c
parent5e0a97c26457260b7a95383fae0fc2cf2f98237d (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.c37
-rw-r--r--include/asm-mips64/processor.h10
-rw-r--r--include/asm-mips64/sn/arch.h6
-rw-r--r--include/asm-mips64/sn/intr.h127
-rw-r--r--include/asm-mips64/sn/intr_public.h59
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__ */
+