summaryrefslogtreecommitdiffstats
path: root/arch/sparc/lib
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
commitdb7d4daea91e105e3859cf461d7e53b9b77454b2 (patch)
tree9bb65b95440af09e8aca63abe56970dd3360cc57 /arch/sparc/lib
parent9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff)
Merge with Linux 2.2.8.
Diffstat (limited to 'arch/sparc/lib')
-rw-r--r--arch/sparc/lib/Makefile7
-rw-r--r--arch/sparc/lib/atomic.S14
-rw-r--r--arch/sparc/lib/bitops.S85
-rw-r--r--arch/sparc/lib/debuglocks.c36
-rw-r--r--arch/sparc/lib/irqlock.S65
-rw-r--r--arch/sparc/lib/lshrdi3.S29
6 files changed, 88 insertions, 148 deletions
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 0670ff273..d5b475480 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -1,11 +1,11 @@
-# $Id: Makefile,v 1.26 1998/07/26 03:02:43 davem Exp $
+# $Id: Makefile,v 1.28 1999/03/21 06:37:44 davem Exp $
# Makefile for Sparc library files..
#
OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \
strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \
strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \
- copy_user.o locks.o atomic.o bitops.o debuglocks.o
+ copy_user.o locks.o atomic.o bitops.o debuglocks.o lshrdi3.o
ifdef CONFIG_SMP
OBJS += irqlock.o
@@ -89,6 +89,9 @@ urem.o: urem.S
ashrdi3.o: ashrdi3.S
$(CC) -D__ASSEMBLY__ -c -o ashrdi3.o ashrdi3.S
+lshrdi3.o: lshrdi3.S
+ $(CC) -D__ASSEMBLY__ -c -o lshrdi3.o lshrdi3.S
+
dep:
include $(TOPDIR)/Rules.make
diff --git a/arch/sparc/lib/atomic.S b/arch/sparc/lib/atomic.S
index 4e4aa0646..c57e61574 100644
--- a/arch/sparc/lib/atomic.S
+++ b/arch/sparc/lib/atomic.S
@@ -44,6 +44,7 @@ ___xchg32_sun4md:
.globl ___atomic_add
___atomic_add:
rd %psr, %g3 ! Keep the code small, old way was stupid
+ nop; nop; nop; ! Let the bits set
or %g3, PSR_PIL, %g7 ! Disable interrupts
wr %g7, 0x0, %psr ! Set %psr
nop; nop; nop; ! Let the bits set
@@ -51,12 +52,16 @@ ___atomic_add:
1: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
orcc %g7, 0x0, %g0 ! Did we get it?
bne 1b ! Nope...
-#endif
ld [%g1], %g7 ! Load locked atomic_t
sra %g7, 8, %g7 ! Get signed 24-bit integer
add %g7, %g2, %g2 ! Add in argument
sll %g2, 8, %g7 ! Transpose back to atomic_t
st %g7, [%g1] ! Clever: This releases the lock as well.
+#else
+ ld [%g1], %g7 ! Load locked atomic_t
+ add %g7, %g2, %g2 ! Add in argument
+ st %g2, [%g1] ! Store it back
+#endif
wr %g3, 0x0, %psr ! Restore original PSR_PIL
nop; nop; nop; ! Let the bits set
jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
@@ -65,6 +70,7 @@ ___atomic_add:
.globl ___atomic_sub
___atomic_sub:
rd %psr, %g3 ! Keep the code small, old way was stupid
+ nop; nop; nop; ! Let the bits set
or %g3, PSR_PIL, %g7 ! Disable interrupts
wr %g7, 0x0, %psr ! Set %psr
nop; nop; nop; ! Let the bits set
@@ -72,12 +78,16 @@ ___atomic_sub:
1: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
orcc %g7, 0x0, %g0 ! Did we get it?
bne 1b ! Nope...
-#endif
ld [%g1], %g7 ! Load locked atomic_t
sra %g7, 8, %g7 ! Get signed 24-bit integer
sub %g7, %g2, %g2 ! Subtract argument
sll %g2, 8, %g7 ! Transpose back to atomic_t
st %g7, [%g1] ! Clever: This releases the lock as well
+#else
+ ld [%g1], %g7 ! Load locked atomic_t
+ sub %g7, %g2, %g2 ! Subtract argument
+ st %g2, [%g1] ! Store it back
+#endif
wr %g3, 0x0, %psr ! Restore original PSR_PIL
nop; nop; nop; ! Let the bits set
jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
index 253c358fe..ea9ed5a6c 100644
--- a/arch/sparc/lib/bitops.S
+++ b/arch/sparc/lib/bitops.S
@@ -20,12 +20,10 @@
.globl ___set_bit
___set_bit:
rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
+ nop; nop; nop;
+ or %g3, PSR_PIL, %g5
+ wr %g5, 0x0, %psr
nop; nop; nop
-1:
#ifdef __SMP__
set C_LABEL(bitops_spinlock), %g5
2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
@@ -38,17 +36,12 @@ ___set_bit:
#ifdef __SMP__
st %g5, [%g1]
set C_LABEL(bitops_spinlock), %g5
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g0, [%g5]
+ stb %g0, [%g5]
#else
- andcc %g3, PSR_PIL, %g0
- bne 1f
- st %g5, [%g1]
+ st %g5, [%g1]
#endif
wr %g3, 0x0, %psr
nop; nop; nop
-1:
jmpl %o7, %g0
mov %g4, %o7
@@ -56,12 +49,10 @@ ___set_bit:
.globl ___clear_bit
___clear_bit:
rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
nop; nop; nop
-1:
+ or %g3, PSR_PIL, %g5
+ wr %g5, 0x0, %psr
+ nop; nop; nop
#ifdef __SMP__
set C_LABEL(bitops_spinlock), %g5
2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
@@ -74,17 +65,12 @@ ___clear_bit:
#ifdef __SMP__
st %g5, [%g1]
set C_LABEL(bitops_spinlock), %g5
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g0, [%g5]
+ stb %g0, [%g5]
#else
- andcc %g3, PSR_PIL, %g0
- bne 1f
- st %g5, [%g1]
+ st %g5, [%g1]
#endif
wr %g3, 0x0, %psr
nop; nop; nop
-1:
jmpl %o7, %g0
mov %g4, %o7
@@ -92,12 +78,10 @@ ___clear_bit:
.globl ___change_bit
___change_bit:
rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
nop; nop; nop
-1:
+ or %g3, PSR_PIL, %g5
+ wr %g5, 0x0, %psr
+ nop; nop; nop
#ifdef __SMP__
set C_LABEL(bitops_spinlock), %g5
2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
@@ -110,17 +94,12 @@ ___change_bit:
#ifdef __SMP__
st %g5, [%g1]
set C_LABEL(bitops_spinlock), %g5
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g0, [%g5]
+ stb %g0, [%g5]
#else
- andcc %g3, PSR_PIL, %g0
- bne 1f
- st %g5, [%g1]
+ st %g5, [%g1]
#endif
wr %g3, 0x0, %psr
nop; nop; nop
-1:
jmpl %o7, %g0
mov %g4, %o7
@@ -128,12 +107,10 @@ ___change_bit:
.globl ___set_le_bit
___set_le_bit:
rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
nop; nop; nop
-1:
+ or %g3, PSR_PIL, %g5
+ wr %g5, 0x0, %psr
+ nop; nop; nop
#ifdef __SMP__
set C_LABEL(bitops_spinlock), %g5
2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
@@ -146,29 +123,22 @@ ___set_le_bit:
#ifdef __SMP__
stb %g5, [%g1]
set C_LABEL(bitops_spinlock), %g5
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g0, [%g5]
+ stb %g0, [%g5]
#else
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g5, [%g1]
+ stb %g5, [%g1]
#endif
wr %g3, 0x0, %psr
nop; nop; nop
-1:
jmpl %o7, %g0
mov %g4, %o7
.globl ___clear_le_bit
___clear_le_bit:
rd %psr, %g3
- andcc %g3, PSR_PIL, %g0
- bne 1f
- nop
- wr %g3, PSR_PIL, %psr
nop; nop; nop
-1:
+ or %g3, PSR_PIL, %g5
+ wr %g5, 0x0, %psr
+ nop; nop; nop
#ifdef __SMP__
set C_LABEL(bitops_spinlock), %g5
2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP.
@@ -181,16 +151,11 @@ ___clear_le_bit:
#ifdef __SMP__
stb %g5, [%g1]
set C_LABEL(bitops_spinlock), %g5
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g0, [%g5]
+ stb %g0, [%g5]
#else
- andcc %g3, PSR_PIL, %g0
- bne 1f
- stb %g5, [%g1]
+ stb %g5, [%g1]
#endif
wr %g3, 0x0, %psr
nop; nop; nop
-1:
jmpl %o7, %g0
mov %g4, %o7
diff --git a/arch/sparc/lib/debuglocks.c b/arch/sparc/lib/debuglocks.c
index 8f0941ebf..62313e4ae 100644
--- a/arch/sparc/lib/debuglocks.c
+++ b/arch/sparc/lib/debuglocks.c
@@ -1,12 +1,13 @@
-/* $Id: debuglocks.c,v 1.5 1998/10/14 09:19:04 jj Exp $
+/* $Id: debuglocks.c,v 1.7 1999/04/21 02:26:58 anton Exp $
* debuglocks.c: Debugging versions of SMP locking primitives.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au)
*/
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/tasks.h> /* For NR_CPUS */
#include <asm/psr.h>
#include <asm/system.h>
#include <asm/spinlock.h>
@@ -28,29 +29,33 @@
static inline void show(char *str, spinlock_t *lock, unsigned long caller)
{
int cpu = smp_processor_id();
+ extern spinlock_t console_lock;
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n",str,
- lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
+ if (lock != &console_lock)
+ printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n",str,
+ lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
}
static inline void show_read(char *str, rwlock_t *lock, unsigned long caller)
{
int cpu = smp_processor_id();
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n",str,
+ printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n", str,
lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
}
static inline void show_write(char *str, rwlock_t *lock, unsigned long caller)
{
int cpu = smp_processor_id();
+ int i;
+
+ printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)", str,
+ lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
+
+ for(i = 0; i < NR_CPUS; i++)
+ printk(" reader[i]=%08lx", lock->reader_pc[i]);
- printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx) reader[0]=%08lx reader[1]=%08lx reader[2]=%08lx reader[3]=%08lx\n",
- str, lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3,
- lock->reader_pc[0],
- lock->reader_pc[1],
- lock->reader_pc[2],
- lock->reader_pc[3]);
+ printk("\n");
}
#undef INIT_STUCK
@@ -103,9 +108,6 @@ void _do_spin_unlock(spinlock_t *lock)
lock->lock = 0;
}
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
void _do_read_lock(rwlock_t *rw, char *str)
{
unsigned long caller;
@@ -133,9 +135,6 @@ wlock_again:
rw->lock++;
}
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
void _do_read_unlock(rwlock_t *rw, char *str)
{
unsigned long caller;
@@ -163,9 +162,6 @@ wlock_again:
rw->lock -= 0x1ff;
}
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
void _do_write_lock(rwlock_t *rw, char *str)
{
unsigned long caller;
diff --git a/arch/sparc/lib/irqlock.S b/arch/sparc/lib/irqlock.S
index 23194e723..4c41e9825 100644
--- a/arch/sparc/lib/irqlock.S
+++ b/arch/sparc/lib/irqlock.S
@@ -1,4 +1,4 @@
-/* $Id: irqlock.S,v 1.4 1997/05/01 02:26:54 davem Exp $
+/* $Id: irqlock.S,v 1.5 1999/04/20 13:22:37 anton Exp $
* irqlock.S: High performance IRQ global locking and interrupt entry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -10,69 +10,6 @@
.text
.align 4
- /* This is incredibly insane... */
- .globl ___irq_enter
-___irq_enter:
- sethi %hi(local_irq_count), %g2
- sll %g1, 2, %g1
- or %g2, %lo(local_irq_count), %g2
- ld [%g2 + %g1], %g3
- sethi %hi(global_irq_count), %g5
- add %g3, 1, %g3
- or %g5, %lo(global_irq_count), %g5
- st %g3, [%g2 + %g1]
-1:
- ldstub [%g5 + 3], %g2
- orcc %g2, 0x0, %g0
- bne 1b
- ld [%g5], %g3
- sra %g3, 8, %g3
- add %g3, 1, %g3
- sll %g3, 8, %g3
- st %g3, [%g5]
- sethi %hi(global_irq_lock), %g1
- ldub [%g1 + %lo(global_irq_lock)], %g2
-1:
- orcc %g2, 0x0, %g0
- bne,a 1b
- ldub [%g1 + %lo(global_irq_lock)], %g2
-___irq_enter_out:
- jmpl %o7, %g0
- mov %g4, %o7
-
- .globl ___irq_exit
-___irq_exit:
- rd %psr, %g3
- sethi %hi(global_irq_count), %g1
- or %g3, PSR_PIL, %g3
- or %g1, %lo(global_irq_count), %g1
- wr %g3, 0x0, %psr
- sethi %hi(local_irq_count), %g2
- sll %g7, 2, %g7
- or %g2, %lo(local_irq_count), %g2
- ld [%g2 + %g7], %g3
-1:
- ldstub [%g1 + 3], %g5
- orcc %g5, 0x0, %g0
- bne 1b
- ld [%g1], %g5
- sra %g5, 8, %g5
- sub %g5, 1, %g5
- sll %g5, 8, %g5
- st %g5, [%g1]
- sub %g3, 1, %g3
- sethi %hi(global_irq_holder), %g1
- st %g3, [%g2 + %g7]
- srl %g7, 2, %g7
- ldub [%g1 + %lo(global_irq_holder)], %g5
- cmp %g5, %g7
- bne ___irq_enter_out
- mov NO_PROC_ID, %g2
- stb %g2, [%g1 + %lo(global_irq_holder)]
- sethi %hi(global_irq_lock), %g5
- b ___irq_enter_out
- stb %g0, [%g5 + %lo(global_irq_lock)]
-
/* Weird calling conventions... %g7=flags, %g4=%prev_o7
* Very clever for the __global_sti case, the inline which
* gets us here clears %g7 and it just works.
diff --git a/arch/sparc/lib/lshrdi3.S b/arch/sparc/lib/lshrdi3.S
new file mode 100644
index 000000000..f5300a1c8
--- /dev/null
+++ b/arch/sparc/lib/lshrdi3.S
@@ -0,0 +1,29 @@
+/* $Id: lshrdi3.S,v 1.1 1999/03/21 06:37:45 davem Exp $ */
+
+#include <asm/cprefix.h>
+
+ .globl C_LABEL(__lshrdi3)
+C_LABEL(__lshrdi3):
+ cmp %o2, 0
+ be 3f
+ mov 0x20, %g2
+
+ sub %g2, %o2, %g2
+ cmp %g2, 0
+ bg 1f
+ srl %o0, %o2, %o4
+
+ clr %o4
+ neg %g2
+ b 2f
+ srl %o0, %g2, %o5
+1:
+ sll %o0, %g2, %g3
+ srl %o1, %o2, %g2
+ or %g2, %g3, %o5
+2:
+ mov %o4, %o0
+ mov %o5, %o1
+3:
+ retl
+ nop