diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-14 01:39:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-14 01:39:27 +0000 |
commit | ce1a9d7d9ebf3bc87c544d06542a3d30f604dca5 (patch) | |
tree | 7e1c263dc7b02602aa730654465bca583883d9dd | |
parent | f8dfaf80bdc1a29fba2da8e1abc61a30da7ba6ab (diff) |
MIPS64 SMP, compile only edition. Don't use yet ...
-rw-r--r-- | arch/mips64/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/mips64/kernel/entry.S | 9 | ||||
-rw-r--r-- | arch/mips64/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/mips64/kernel/smp.c | 80 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-irq.c | 14 | ||||
-rw-r--r-- | arch/mips64/tools/offset.c | 3 | ||||
-rw-r--r-- | drivers/net/appletalk/.cvsignore | 2 | ||||
-rw-r--r-- | include/asm-mips/cache.h | 8 | ||||
-rw-r--r-- | include/asm-mips64/cache.h | 5 | ||||
-rw-r--r-- | include/asm-mips64/hardirq.h | 59 | ||||
-rw-r--r-- | include/asm-mips64/offset.h | 45 | ||||
-rw-r--r-- | include/asm-mips64/processor.h | 12 | ||||
-rw-r--r-- | include/asm-mips64/smp.h | 47 | ||||
-rw-r--r-- | include/asm-mips64/spinlock.h | 5 | ||||
-rw-r--r-- | include/asm-mips64/timex.h | 12 |
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 */ |