summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libc_r/arch/sparc64/_atomic_lock.c48
-rw-r--r--lib/libc_r/arch/sparc64/uthread_machdep.c45
-rw-r--r--lib/libc_r/arch/sparc64/uthread_machdep.h7
-rw-r--r--lib/libc_r/arch/sparc64/uthread_machdep_asm.S39
-rw-r--r--lib/libpthread/arch/sparc64/_atomic_lock.c48
-rw-r--r--lib/libpthread/arch/sparc64/uthread_machdep.c45
-rw-r--r--lib/libpthread/arch/sparc64/uthread_machdep.h7
-rw-r--r--lib/libpthread/arch/sparc64/uthread_machdep_asm.S39
8 files changed, 278 insertions, 0 deletions
diff --git a/lib/libc_r/arch/sparc64/_atomic_lock.c b/lib/libc_r/arch/sparc64/_atomic_lock.c
new file mode 100644
index 00000000000..f14f9f51ba0
--- /dev/null
+++ b/lib/libc_r/arch/sparc64/_atomic_lock.c
@@ -0,0 +1,48 @@
+/* $OpenBSD: _atomic_lock.c,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/*
+ * Atomic lock for sparc
+ */
+
+#include "spinlock.h"
+
+int
+_atomic_lock(volatile _spinlock_lock_t * lock)
+{
+ _spinlock_lock_t old;
+
+ /*
+ * " ldstub [address], reg_rd
+ *
+ * The atomic load-store instructions copy a byte from memory
+ * into r[rd]m then rewrite the addressed byte in memory to all
+ * ones [_SPINLOCK_LOCKED]. The operation is performed
+ * atomically, that is, without allowing intervening interrupts
+ * or deferred traps. In a multiprocessor system, two or more
+ * processors executing atomic load-store unsigned byte [...]
+ * addressing the same byte [...] simultaneously are guaranteed
+ * to execute them in an undefined, but serial order."
+ * - p101, The SPARC Architecure Manual (version 8) Prentice-Hall
+ *
+ * "LDSTUB loads a byte value from memory to a register and writes
+ * the value FF_16 into the addressed byte atomically. LDSTUB
+ * is the classic test-and-set instruction. Like SWAP, it has
+ * a consensus number of two and so cannot resolve more than
+ * two contending processes in a wait-free fashion."
+ * - p129, The SPARC Architecture Manual (version 9) Prentice-Hall
+ * (See also section J.6 (spinlocks))
+ *
+ * (No change to the condition codes are documented.)
+ */
+ __asm__("ldstub %0,%1"
+ : "=m" (*lock), "=r" (old)
+ : "0" (*lock));
+
+ return (old == _SPINLOCK_LOCKED);
+}
+
+int
+_atomic_is_locked(volatile _spinlock_lock_t * lock)
+{
+
+ return (*lock == _SPINLOCK_LOCKED);
+}
diff --git a/lib/libc_r/arch/sparc64/uthread_machdep.c b/lib/libc_r/arch/sparc64/uthread_machdep.c
new file mode 100644
index 00000000000..eaea79af8d3
--- /dev/null
+++ b/lib/libc_r/arch/sparc64/uthread_machdep.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: uthread_machdep.c,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+
+/*
+ * Machine-dependent thread state functions for OpenBSD/sparc.
+ */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/param.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Given a stack and an entry function, initialise a state
+ * structure that can be later switched to.
+ */
+void
+_thread_machdep_init(statep, base, len, entry)
+ struct _machdep_state* statep;
+ void *base;
+ int len;
+ void (*entry)(void);
+{
+ struct frame64 *f;
+
+ /* Locate the initial frame, aligned at the top of the stack */
+ f = (struct frame64 *)(((int)base + len - sizeof *f) & ~ALIGNBYTES);
+
+ f->fr_fp = (struct frame64 *)-1; /* purposefully misaligned */
+ f->fr_pc = -1; /* for gdb */
+ statep->fp = (int)f;
+ statep->pc = -8 + (int)entry;
+}
+
+void
+_thread_machdep_save_float_state(statep)
+ struct _machdep_state* statep;
+{
+}
+
+void
+_thread_machdep_restore_float_state(statep)
+ struct _machdep_state* statep;
+{
+}
diff --git a/lib/libc_r/arch/sparc64/uthread_machdep.h b/lib/libc_r/arch/sparc64/uthread_machdep.h
new file mode 100644
index 00000000000..6014cf53f03
--- /dev/null
+++ b/lib/libc_r/arch/sparc64/uthread_machdep.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: uthread_machdep.h,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/* David Leonard, <d@csee.uq.edu.au>. Public domain. */
+
+struct _machdep_state {
+ int fp; /* frame pointer */
+ int pc; /* program counter */
+};
diff --git a/lib/libc_r/arch/sparc64/uthread_machdep_asm.S b/lib/libc_r/arch/sparc64/uthread_machdep_asm.S
new file mode 100644
index 00000000000..aef33143968
--- /dev/null
+++ b/lib/libc_r/arch/sparc64/uthread_machdep_asm.S
@@ -0,0 +1,39 @@
+/* $OpenBSD: uthread_machdep_asm.S,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/* David Leonard <d@csee.uq.edu.au>. Public domain. */
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+
+/*
+ * Switch stacks.
+ * On sparc this also means we switch register windows.
+ */
+
+#ifdef __sparcv9__
+#define flushw .word 0x81580000
+#else
+#define flushw t T_FLUSHWIN
+#endif
+
+#define SA(x) (((x)+15)&(~0x1f))
+#define MINFRAME ((16+1+6)*8)
+
+/* void _thread_switch(int newstate[2], int savestate[2], int flags); */
+ENTRY(_thread_machdep_switch)
+
+ /* new window */
+ save %sp, -SA(MINFRAME), %sp
+
+ /* flush all windows (except current one) into memory frames */
+ flushw
+
+ /* switch the stack pointer and return address */
+ st %fp, [%i1 + 0]
+ st %i7, [%i1 + 4]
+ ld [%i0 + 0], %fp
+ ld [%i0 + 4], %i7
+
+ /* return to saved window at new %fp */
+ ret
+ restore
+
diff --git a/lib/libpthread/arch/sparc64/_atomic_lock.c b/lib/libpthread/arch/sparc64/_atomic_lock.c
new file mode 100644
index 00000000000..f14f9f51ba0
--- /dev/null
+++ b/lib/libpthread/arch/sparc64/_atomic_lock.c
@@ -0,0 +1,48 @@
+/* $OpenBSD: _atomic_lock.c,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/*
+ * Atomic lock for sparc
+ */
+
+#include "spinlock.h"
+
+int
+_atomic_lock(volatile _spinlock_lock_t * lock)
+{
+ _spinlock_lock_t old;
+
+ /*
+ * " ldstub [address], reg_rd
+ *
+ * The atomic load-store instructions copy a byte from memory
+ * into r[rd]m then rewrite the addressed byte in memory to all
+ * ones [_SPINLOCK_LOCKED]. The operation is performed
+ * atomically, that is, without allowing intervening interrupts
+ * or deferred traps. In a multiprocessor system, two or more
+ * processors executing atomic load-store unsigned byte [...]
+ * addressing the same byte [...] simultaneously are guaranteed
+ * to execute them in an undefined, but serial order."
+ * - p101, The SPARC Architecure Manual (version 8) Prentice-Hall
+ *
+ * "LDSTUB loads a byte value from memory to a register and writes
+ * the value FF_16 into the addressed byte atomically. LDSTUB
+ * is the classic test-and-set instruction. Like SWAP, it has
+ * a consensus number of two and so cannot resolve more than
+ * two contending processes in a wait-free fashion."
+ * - p129, The SPARC Architecture Manual (version 9) Prentice-Hall
+ * (See also section J.6 (spinlocks))
+ *
+ * (No change to the condition codes are documented.)
+ */
+ __asm__("ldstub %0,%1"
+ : "=m" (*lock), "=r" (old)
+ : "0" (*lock));
+
+ return (old == _SPINLOCK_LOCKED);
+}
+
+int
+_atomic_is_locked(volatile _spinlock_lock_t * lock)
+{
+
+ return (*lock == _SPINLOCK_LOCKED);
+}
diff --git a/lib/libpthread/arch/sparc64/uthread_machdep.c b/lib/libpthread/arch/sparc64/uthread_machdep.c
new file mode 100644
index 00000000000..eaea79af8d3
--- /dev/null
+++ b/lib/libpthread/arch/sparc64/uthread_machdep.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: uthread_machdep.c,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+
+/*
+ * Machine-dependent thread state functions for OpenBSD/sparc.
+ */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/param.h>
+#include <pthread.h>
+#include "pthread_private.h"
+
+/*
+ * Given a stack and an entry function, initialise a state
+ * structure that can be later switched to.
+ */
+void
+_thread_machdep_init(statep, base, len, entry)
+ struct _machdep_state* statep;
+ void *base;
+ int len;
+ void (*entry)(void);
+{
+ struct frame64 *f;
+
+ /* Locate the initial frame, aligned at the top of the stack */
+ f = (struct frame64 *)(((int)base + len - sizeof *f) & ~ALIGNBYTES);
+
+ f->fr_fp = (struct frame64 *)-1; /* purposefully misaligned */
+ f->fr_pc = -1; /* for gdb */
+ statep->fp = (int)f;
+ statep->pc = -8 + (int)entry;
+}
+
+void
+_thread_machdep_save_float_state(statep)
+ struct _machdep_state* statep;
+{
+}
+
+void
+_thread_machdep_restore_float_state(statep)
+ struct _machdep_state* statep;
+{
+}
diff --git a/lib/libpthread/arch/sparc64/uthread_machdep.h b/lib/libpthread/arch/sparc64/uthread_machdep.h
new file mode 100644
index 00000000000..6014cf53f03
--- /dev/null
+++ b/lib/libpthread/arch/sparc64/uthread_machdep.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: uthread_machdep.h,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/* David Leonard, <d@csee.uq.edu.au>. Public domain. */
+
+struct _machdep_state {
+ int fp; /* frame pointer */
+ int pc; /* program counter */
+};
diff --git a/lib/libpthread/arch/sparc64/uthread_machdep_asm.S b/lib/libpthread/arch/sparc64/uthread_machdep_asm.S
new file mode 100644
index 00000000000..aef33143968
--- /dev/null
+++ b/lib/libpthread/arch/sparc64/uthread_machdep_asm.S
@@ -0,0 +1,39 @@
+/* $OpenBSD: uthread_machdep_asm.S,v 1.1 2001/09/10 20:00:14 jason Exp $ */
+/* David Leonard <d@csee.uq.edu.au>. Public domain. */
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+
+/*
+ * Switch stacks.
+ * On sparc this also means we switch register windows.
+ */
+
+#ifdef __sparcv9__
+#define flushw .word 0x81580000
+#else
+#define flushw t T_FLUSHWIN
+#endif
+
+#define SA(x) (((x)+15)&(~0x1f))
+#define MINFRAME ((16+1+6)*8)
+
+/* void _thread_switch(int newstate[2], int savestate[2], int flags); */
+ENTRY(_thread_machdep_switch)
+
+ /* new window */
+ save %sp, -SA(MINFRAME), %sp
+
+ /* flush all windows (except current one) into memory frames */
+ flushw
+
+ /* switch the stack pointer and return address */
+ st %fp, [%i1 + 0]
+ st %i7, [%i1 + 4]
+ ld [%i0 + 0], %fp
+ ld [%i0 + 4], %i7
+
+ /* return to saved window at new %fp */
+ ret
+ restore
+