diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:18:26 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:18:26 +0000 |
commit | c7c4310f7fc1485925d800628bf50b3aeab535ef (patch) | |
tree | b12aa4be0e8fb82aaaea97fb475e793e8a347c49 /arch/sparc64 | |
parent | 1ffd1d069ca4c5ffe16fea6175dab1b9bbb15820 (diff) |
Merge with Linux 2.4.0-test3-pre8. Linus has accepted most of what
I've sent him, so we're very close to full integration of the MIPS
port into his sources.
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/config.in | 1 | ||||
-rw-r--r-- | arch/sparc64/defconfig | 7 | ||||
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 40 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 2 | ||||
-rw-r--r-- | arch/sparc64/lib/Makefile | 5 | ||||
-rw-r--r-- | arch/sparc64/lib/dec_and_lock.S | 61 | ||||
-rw-r--r-- | arch/sparc64/mm/ultra.S | 20 | ||||
-rw-r--r-- | arch/sparc64/solaris/fs.c | 1 |
9 files changed, 130 insertions, 9 deletions
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 5cd76d3af..eede4683d 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -27,6 +27,7 @@ define_bool CONFIG_VT_CONSOLE y bool 'Symmetric multi-processing support' CONFIG_SMP # Global things across all Sun machines. +define_bool CONFIG_HAVE_DEC_LOCK y define_bool CONFIG_ISA n define_bool CONFIG_PCMCIA n define_bool CONFIG_SBUS y diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 6612852e4..3cf68e2b5 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -20,6 +20,7 @@ CONFIG_KMOD=y CONFIG_VT=y CONFIG_VT_CONSOLE=y # CONFIG_SMP is not set +CONFIG_HAVE_DEC_LOCK=y # CONFIG_ISA is not set # CONFIG_PCMCIA is not set CONFIG_SBUS=y @@ -155,12 +156,8 @@ CONFIG_INET=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y CONFIG_IPV6=m # CONFIG_IPV6_EUI64 is not set # CONFIG_KHTTPD is not set diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 446072933..b066b8b96 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -325,7 +325,7 @@ beyond_if: current->thread.flags |= SPARC_FLAG_32BIT; } start_thread32(regs, ex.a_entry, current->mm->start_stack); - if (current->flags & PF_PTRACED) + if (current->ptrace & PT_PTRACED) send_sig(SIGTRAP, current, 0); return 0; } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 2ef0d1004..40b12eb6a 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -386,6 +386,46 @@ void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2) } } +struct call_data_struct { + void (*func) (void *info); + void *info; + atomic_t finished; + int wait; +}; + +extern unsigned long xcall_call_function; + +int smp_call_function(void (*func)(void *info), void *info, + int nonatomic, int wait) +{ + struct call_data_struct data; + int cpus = smp_num_cpus - 1; + + if (!cpus) + return 0; + + data.func = func; + data.info = info; + atomic_set(&data.finished, 0); + data.wait = wait; + + smp_cross_call(&xcall_call_function, + 0, (u64) &data, 0); + if (wait) { + while (atomic_read(&data.finished) != cpus) + barrier(); + } + + return 0; +} + +void smp_call_function_client(struct call_data_struct *call_data) +{ + call_data->func(call_data->info); + if (call_data->wait) + atomic_inc(&call_data->finished); +} + extern unsigned long xcall_flush_tlb_page; extern unsigned long xcall_flush_tlb_mm; extern unsigned long xcall_flush_tlb_range; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 8b917e303..5d2dd2985 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -279,7 +279,7 @@ char * getname32(const char *filename) char *tmp, *result; result = ERR_PTR(-ENOMEM); - tmp = (char *)__get_free_page(GFP_KERNEL); + tmp = __getname(); if (tmp) { int retval = do_getname32(filename, tmp); diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index 548ef0ac4..6c2d54e04 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile @@ -1,5 +1,5 @@ # $Id: Makefile,v 1.22 2000/03/31 04:06:23 davem Exp $ -# Makefile for Sparc library files.. +# Makefile for Sparc64 library files.. # CFLAGS := $(CFLAGS) @@ -7,7 +7,8 @@ CFLAGS := $(CFLAGS) OBJS = PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \ memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \ VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \ - VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o + VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \ + dec_and_lock.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S new file mode 100644 index 000000000..dca825a7f --- /dev/null +++ b/arch/sparc64/lib/dec_and_lock.S @@ -0,0 +1,61 @@ +/* $Id$ + * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" + * using cas and ldstub instructions. + * + * Copyright (C) 2000 David S. Miller (davem@redhat.com) + */ + + .text + .align 64 + + /* CAS basically works like this: + * + * void CAS(MEM, REG1, REG2) + * { + * START_ATOMIC(); + * if (*(MEM) == REG1) { + * TMP = *(MEM); + * *(MEM) = REG2; + * REG2 = TMP; + * } + * END_ATOMIC(); + * } + * + * All non-contention cases are handled in 2 I-cache + * lines which is 1 L2 cache line. + */ + + .globl atomic_dec_and_lock +atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */ +loop1: lduw [%o0], %g5 + subcc %g5, 1, %g7 + be,pn %icc, to_zero + nop +nzero: cas [%o0], %g5, %g7 + cmp %g5, %g7 + bne,pn %icc, loop1 + mov 0, %g1 + +out: retl + mov %g1, %o0 +to_zero:ldstub [%o1], %g3 + brnz,pn %g3, spin_on_lock + membar #StoreLoad | #StoreStore +loop2: cas [%o0], %g5, %g7 /* ASSERT(g7 == 0) */ + brnz,pt %g7, out + mov 1, %g1 + + lduw [%o0], %g5 + subcc %g5, 1, %g7 + be,pn %icc, loop2 + nop + membar #StoreStore | #LoadStore + stb %g0, [%o1] + b,pt %xcc, nzero + nop + +spin_on_lock: + ldub [%o1], %g3 + brnz,pt %g3, spin_on_lock + membar #LoadLoad + b,a,pt %xcc, to_zero diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 90cc898ff..e954b24c8 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -432,4 +432,24 @@ xcall_flush_cache_all: nop flush %g6 retry + + .globl xcall_call_function +xcall_call_function: + mov TLB_TAG_ACCESS, %g5 ! wheee... + stxa %g1, [%g5] ASI_IMMU ! save call_data here for a bit + membar #Sync + rdpr %pstate, %g2 + wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate + mov TLB_TAG_ACCESS, %g2 + ldxa [%g2] ASI_IMMU, %g5 + rdpr %pil, %g2 + wrpr %g0, 15, %pil + sethi %hi(109f), %g7 + b,pt %xcc, etrap_irq +109: or %g7, %lo(109b), %g7 + call smp_call_function_client + mov %l5, %o0 + b,pt %xcc, rtrap + clr %l6 + #endif /* CONFIG_SMP */ diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 5be9c5d49..8200c831f 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c @@ -9,6 +9,7 @@ #include <linux/types.h> #include <linux/sched.h> +#include <linux/malloc.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/file.h> |