summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-14 01:39:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-14 01:39:27 +0000
commitce1a9d7d9ebf3bc87c544d06542a3d30f604dca5 (patch)
tree7e1c263dc7b02602aa730654465bca583883d9dd
parentf8dfaf80bdc1a29fba2da8e1abc61a30da7ba6ab (diff)
MIPS64 SMP, compile only edition. Don't use yet ...
-rw-r--r--arch/mips64/kernel/Makefile4
-rw-r--r--arch/mips64/kernel/entry.S9
-rw-r--r--arch/mips64/kernel/setup.c4
-rw-r--r--arch/mips64/kernel/smp.c80
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c14
-rw-r--r--arch/mips64/tools/offset.c3
-rw-r--r--drivers/net/appletalk/.cvsignore2
-rw-r--r--include/asm-mips/cache.h8
-rw-r--r--include/asm-mips64/cache.h5
-rw-r--r--include/asm-mips64/hardirq.h59
-rw-r--r--include/asm-mips64/offset.h45
-rw-r--r--include/asm-mips64/processor.h12
-rw-r--r--include/asm-mips64/smp.h47
-rw-r--r--include/asm-mips64/spinlock.h5
-rw-r--r--include/asm-mips64/timex.h12
15 files changed, 256 insertions, 53 deletions
diff --git a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile
index 0f70cba13..8fb09b994 100644
--- a/arch/mips64/kernel/Makefile
+++ b/arch/mips64/kernel/Makefile
@@ -25,6 +25,10 @@ ifdef CONFIG_BINFMT_ELF32
O_OBJS += binfmt_elf32.o
endif
+ifdef CONFIG_SMP
+O_OBJS += smp.o
+endif
+
clean:
include $(TOPDIR)/Rules.make
diff --git a/arch/mips64/kernel/entry.S b/arch/mips64/kernel/entry.S
index b869ed96b..e591fd845 100644
--- a/arch/mips64/kernel/entry.S
+++ b/arch/mips64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.4 2000/01/17 23:32:46 ralf Exp $
+/* $Id: entry.S,v 1.5 2000/02/23 00:41:00 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -33,10 +33,11 @@ reschedule: jal schedule
FEXPORT(ret_from_sys_call)
FEXPORT(ret_from_irq)
-#ifdef __SMP__
-#error Barffff...
-#else
la t1, softirq_state
+#ifdef __SMP__
+ lwu t0, TASK_PROCESSOR($28)
+ dsll t0, t0, 5
+ daddu t1, t0
#endif
lw t0, 0 (t1)
lw t1, 4 (t1) # unused delay slot
diff --git a/arch/mips64/kernel/setup.c b/arch/mips64/kernel/setup.c
index 2a7d8a894..316ad7c29 100644
--- a/arch/mips64/kernel/setup.c
+++ b/arch/mips64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.7 2000/02/04 07:40:24 ralf Exp $
+/* $Id: setup.c,v 1.8 2000/03/02 02:36:50 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -40,7 +40,7 @@
#include <asm/sn/sn0/addrs.h>
#endif
-struct mips_cpuinfo boot_cpu_data;
+struct cpuinfo_mips boot_cpu_data;
#ifdef CONFIG_VT
struct screen_info screen_info;
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c
new file mode 100644
index 000000000..c0cd75e9a
--- /dev/null
+++ b/arch/mips64/kernel/smp.c
@@ -0,0 +1,80 @@
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include <asm/atomic.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
+/* The 'big kernel lock' */
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
+
+int smp_threads_ready = 0;
+
+void __init smp_boot_cpus(void)
+{
+}
+
+static atomic_t smp_commenced = ATOMIC_INIT(0);
+
+struct cpuinfo_mips cpu_data[NR_CPUS];
+
+int smp_num_cpus = 1; /* Number that came online. */
+
+void __init smp_commence(void)
+{
+ wmb();
+ atomic_set(&smp_commenced,1);
+}
+
+static void stop_this_cpu(void *dummy)
+{
+ /*
+ * Remove this CPU
+ */
+ for (;;);
+}
+
+void smp_send_stop(void)
+{
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_num_cpus = 1;
+}
+
+/*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+ * anything. Worst case is that we lose a reschedule ...
+ */
+void smp_send_reschedule(int cpu)
+{
+}
+
+int __cpu_number_map[NR_CPUS];
+int __cpu_logical_map[NR_CPUS];
+
+cycles_t cacheflush_time;
+
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+}
+
+/*
+ * Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <retry> If true, keep retrying until ready.
+ * <wait> If true, wait until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code.
+ *
+ * Does not return until remote CPUs are nearly ready to execute <func>
+ * or are or have executed.
+ */
+int
+smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
+{
+ /* XXX - kinda important ;-) */
+}
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index d7ddb8682..ae096d28f 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -1,4 +1,4 @@
-/* $Id: ip27-irq.c,v 1.7 2000/03/02 02:36:50 ralf Exp $
+/* $Id: ip27-irq.c,v 1.8 2000/03/07 15:45:29 ralf Exp $
*
* ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
*
@@ -8,7 +8,6 @@
#include <linux/init.h>
#include <linux/errno.h>
-#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
@@ -17,8 +16,8 @@
#include <linux/timex.h>
#include <linux/malloc.h>
#include <linux/random.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
@@ -52,6 +51,11 @@
irq_cpustat_t irq_stat [NR_CPUS];
+#ifdef CONFIG_SMP
+int global_irq_holder = NO_PROC_ID;
+spinlock_t global_irq_lock;
+#endif
+
extern asmlinkage void ip27_irq(void);
int (*irq_cannonicalize)(int irq);
@@ -105,7 +109,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- irq_enter(cpu);
+ irq_enter(cpu, irq);
kstat.irqs[cpu][irq]++;
action = *(irq + irq_action);
@@ -123,7 +127,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- irq_exit(cpu);
+ irq_exit(cpu, irq);
/* unmasking and bottom half handling is done magically for us. */
}
diff --git a/arch/mips64/tools/offset.c b/arch/mips64/tools/offset.c
index 4f8e28d09..a8833e216 100644
--- a/arch/mips64/tools/offset.c
+++ b/arch/mips64/tools/offset.c
@@ -1,4 +1,4 @@
-/* $Id: offset.c,v 1.5 1999/10/08 21:07:52 ralf Exp $
+/* $Id: offset.c,v 1.4 1999/12/04 03:59:01 ralf Exp $
*
* offset.c: Calculate pt_regs and task_struct offsets.
*
@@ -82,6 +82,7 @@ void output_task_defines(void)
offset("#define TASK_COUNTER ", struct task_struct, counter);
offset("#define TASK_PRIORITY ", struct task_struct, priority);
offset("#define TASK_MM ", struct task_struct, mm);
+ offset("#define TASK_PROCESSOR ", struct task_struct, processor);
size("#define TASK_STRUCT_SIZE ", struct task_struct);
linefeed;
}
diff --git a/drivers/net/appletalk/.cvsignore b/drivers/net/appletalk/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/drivers/net/appletalk/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 8def356dc..a6c80d31e 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -1,4 +1,4 @@
-/* $Id: cache.h,v 1.3 1999/10/09 00:01:42 ralf Exp $
+/* $Id: cache.h,v 1.4 2000/02/04 07:40:53 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -13,9 +13,11 @@
#include <linux/config.h>
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000)
-#define L1_CACHE_BYTES 16
+#define L1_CACHE_BYTES 16
#else
-#define L1_CACHE_BYTES 32 /* A guess */
+#define L1_CACHE_BYTES 32 /* A guess */
#endif
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+
#endif /* _ASM_CACHE_H */
diff --git a/include/asm-mips64/cache.h b/include/asm-mips64/cache.h
index 1327f2b1f..c05688a72 100644
--- a/include/asm-mips64/cache.h
+++ b/include/asm-mips64/cache.h
@@ -1,4 +1,4 @@
-/* $Id: cache.h,v 1.2 1999/10/09 00:01:43 ralf Exp $
+/* $Id: cache.h,v 1.3 2000/02/04 07:40:53 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -11,6 +11,7 @@
#define _ASM_CACHE_H
/* bytes per L1 cache line */
-#define L1_CACHE_BYTES 32 /* A guess */
+#define L1_CACHE_BYTES 32 /* A guess */
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
#endif /* _ASM_CACHE_H */
diff --git a/include/asm-mips64/hardirq.h b/include/asm-mips64/hardirq.h
index 29d780328..1c2d1e868 100644
--- a/include/asm-mips64/hardirq.h
+++ b/include/asm-mips64/hardirq.h
@@ -1,11 +1,11 @@
-/* $Id: hardirq.h,v 1.5 2000/03/02 02:37:13 ralf Exp $
+/* $Id: hardirq.h,v 1.6 2000/03/07 15:45:42 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1997 - 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_HARDIRQ_H
#define _ASM_HARDIRQ_H
@@ -40,14 +40,61 @@ extern irq_cpustat_t irq_stat [NR_CPUS];
#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)
#define hardirq_endlock(cpu) do { } while (0)
-#define irq_enter(cpu) (local_irq_count(cpu)++)
-#define irq_exit(cpu) (local_irq_count(cpu)--)
+#define irq_enter(cpu, irq) (local_irq_count(cpu)++)
+#define irq_exit(cpu, irq) (local_irq_count(cpu)--)
#define synchronize_irq() barrier();
#else
-#error No habla MIPS SMP
+#include <asm/atomic.h>
+#include <linux/spinlock.h>
+#include <asm/smp.h>
+
+extern int global_irq_holder;
+extern spinlock_t global_irq_lock;
+
+static inline int irqs_running (void)
+{
+ int i;
+
+ for (i = 0; i < smp_num_cpus; i++)
+ if (local_irq_count(i))
+ return 1;
+ return 0;
+}
+
+static inline void release_irqlock(int cpu)
+{
+ /* if we didn't own the irq lock, just ignore.. */
+ if (global_irq_holder == cpu) {
+ global_irq_holder = NO_PROC_ID;
+ spin_unlock(&global_irq_lock);
+ }
+}
+
+static inline int hardirq_trylock(int cpu)
+{
+ return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock);
+}
+
+#define hardirq_endlock(cpu) do { } while (0)
+
+static inline void irq_enter(int cpu, int irq)
+{
+ ++local_irq_count(cpu);
+
+ while (spin_is_locked(&global_irq_lock))
+ barrier();
+}
+
+static inline void irq_exit(int cpu, int irq)
+{
+ --local_irq_count(cpu);
+}
+
+extern void synchronize_irq(void);
#endif /* __SMP__ */
+
#endif /* _ASM_HARDIRQ_H */
diff --git a/include/asm-mips64/offset.h b/include/asm-mips64/offset.h
index b0d9e97c3..4a8c52982 100644
--- a/include/asm-mips64/offset.h
+++ b/include/asm-mips64/offset.h
@@ -52,30 +52,31 @@
#define TASK_COUNTER 56
#define TASK_PRIORITY 64
#define TASK_MM 80
-#define TASK_STRUCT_SIZE 1480
+#define TASK_PROCESSOR 100
+#define TASK_STRUCT_SIZE 1976
/* MIPS specific thread_struct offsets. */
-#define THREAD_REG16 896
-#define THREAD_REG17 904
-#define THREAD_REG18 912
-#define THREAD_REG19 920
-#define THREAD_REG20 928
-#define THREAD_REG21 936
-#define THREAD_REG22 944
-#define THREAD_REG23 952
-#define THREAD_REG29 960
-#define THREAD_REG30 968
-#define THREAD_REG31 976
-#define THREAD_STATUS 984
-#define THREAD_FPU 992
-#define THREAD_BVADDR 1256
-#define THREAD_BUADDR 1264
-#define THREAD_ECODE 1272
-#define THREAD_TRAPNO 1280
-#define THREAD_MFLAGS 1288
-#define THREAD_CURDS 1296
-#define THREAD_TRAMP 1304
-#define THREAD_OLDCTX 1312
+#define THREAD_REG16 1392
+#define THREAD_REG17 1400
+#define THREAD_REG18 1408
+#define THREAD_REG19 1416
+#define THREAD_REG20 1424
+#define THREAD_REG21 1432
+#define THREAD_REG22 1440
+#define THREAD_REG23 1448
+#define THREAD_REG29 1456
+#define THREAD_REG30 1464
+#define THREAD_REG31 1472
+#define THREAD_STATUS 1480
+#define THREAD_FPU 1488
+#define THREAD_BVADDR 1752
+#define THREAD_BUADDR 1760
+#define THREAD_ECODE 1768
+#define THREAD_TRAPNO 1776
+#define THREAD_MFLAGS 1784
+#define THREAD_CURDS 1792
+#define THREAD_TRAMP 1800
+#define THREAD_OLDCTX 1808
/* Linux mm_struct offsets. */
#define MM_USERS 32
diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
index f70258639..3bbbce9f5 100644
--- a/include/asm-mips64/processor.h
+++ b/include/asm-mips64/processor.h
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.9 2000/02/05 06:47:37 ralf Exp $
+/* $Id: processor.h,v 1.10 2000/02/24 00:13:20 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -24,13 +24,15 @@
#include <asm/reg.h>
#include <asm/system.h>
-struct mips_cpuinfo {
+struct cpuinfo_mips {
unsigned long udelay_val;
unsigned long *pgd_quick;
unsigned long *pmd_quick;
unsigned long *pte_quick;
unsigned long pgtable_cache_sz;
-};
+ unsigned long last_asn;
+ unsigned int irq_count, bh_count;
+} __attribute__((aligned(128)));
/*
* System setup and hardware flags..
@@ -42,11 +44,11 @@ extern char dedicated_iv_available; /* some embedded MIPS like Nevada */
extern char vce_available; /* Supports VCED / VCEI exceptions */
extern char mips4_available; /* CPU has MIPS IV ISA or better */
-extern struct mips_cpuinfo boot_cpu_data;
+extern struct cpuinfo_mips boot_cpu_data;
extern unsigned int vced_count, vcei_count;
#ifdef __SMP__
-extern struct mips_cpuinfo cpu_data[];
+extern struct cpuinfo_mips cpu_data[];
#define current_cpu_data cpu_data[smp_processor_id()]
#else
#define cpu_data &boot_cpu_data
diff --git a/include/asm-mips64/smp.h b/include/asm-mips64/smp.h
new file mode 100644
index 000000000..0370515a0
--- /dev/null
+++ b/include/asm-mips64/smp.h
@@ -0,0 +1,47 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#ifdef __SMP__
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+#if 0
+struct cpuinfo_mips { /* XXX */
+ unsigned long loops_per_sec;
+ unsigned long last_asn;
+ unsigned long *pgd_cache;
+ unsigned long *pte_cache;
+ unsigned long pgtable_cache_sz;
+ unsigned long ipi_count;
+ unsigned long irq_attempt[NR_IRQS];
+ unsigned long smp_local_irq_count;
+ unsigned long prof_multiplier;
+ unsigned long prof_counter;
+ int irq_count, bh_count;
+} __attribute__((aligned(64)));
+
+extern struct cpuinfo_mips cpu_data[NR_CPUS];
+#endif
+
+#define smp_processor_id() (current->processor)
+
+#define PROC_CHANGE_PENALTY 20
+
+/* Map from cpu id to sequential logical cpu number. This will only
+ not be idempotent when cpus failed to come on-line. */
+extern int __cpu_number_map[NR_CPUS];
+#define cpu_number_map(cpu) __cpu_number_map[cpu]
+
+/* The reverse map from sequential logical cpu number to cpu id. */
+extern int __cpu_logical_map[NR_CPUS];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+
+/* Good enough for toy^Wupto 64 CPU Origins. */
+extern unsigned long cpu_present_mask;
+
+#endif
+
+#define NO_PROC_ID (-1)
+
+#endif __ASM_SMP_H
diff --git a/include/asm-mips64/spinlock.h b/include/asm-mips64/spinlock.h
index 4651343e9..8787de4da 100644
--- a/include/asm-mips64/spinlock.h
+++ b/include/asm-mips64/spinlock.h
@@ -1,4 +1,4 @@
-/* $Id: spinlock.h,v 1.3 2000/01/23 21:15:52 ralf Exp $
+/* $Id: spinlock.h,v 1.4 2000/01/25 00:41:46 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -22,6 +22,9 @@ typedef struct {
#define spin_lock_init(x) do { (x)->lock = 0; } while(0);
+#define spin_is_locked(x) ((x)->lock != 0)
+#define spin_unlock_wait(x) ({ do { barrier(); } while ((x)->lock); })
+
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.
diff --git a/include/asm-mips64/timex.h b/include/asm-mips64/timex.h
index 2fcc2833c..1642f30be 100644
--- a/include/asm-mips64/timex.h
+++ b/include/asm-mips64/timex.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: timex.h,v 1.1 1999/08/18 23:37:53 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -33,7 +33,15 @@ extern cycles_t cacheflush_time;
static inline cycles_t get_cycles (void)
{
- return read_32bit_cp0_register(CP0_COUNT);
+ cycles_t val;
+
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "mfc0 %0, $9\n\t"
+ ".set reorder"
+ : "=r" (val));
+
+ return val;
}
#endif /* _ASM_TIMEX_H */