summaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-10 23:18:26 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-10 23:18:26 +0000
commitc7c4310f7fc1485925d800628bf50b3aeab535ef (patch)
treeb12aa4be0e8fb82aaaea97fb475e793e8a347c49 /arch/sparc64
parent1ffd1d069ca4c5ffe16fea6175dab1b9bbb15820 (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.in1
-rw-r--r--arch/sparc64/defconfig7
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c2
-rw-r--r--arch/sparc64/kernel/smp.c40
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c2
-rw-r--r--arch/sparc64/lib/Makefile5
-rw-r--r--arch/sparc64/lib/dec_and_lock.S61
-rw-r--r--arch/sparc64/mm/ultra.S20
-rw-r--r--arch/sparc64/solaris/fs.c1
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>