diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc_r/arch/sparc64/_atomic_lock.c | 48 | ||||
-rw-r--r-- | lib/libc_r/arch/sparc64/uthread_machdep.c | 45 | ||||
-rw-r--r-- | lib/libc_r/arch/sparc64/uthread_machdep.h | 7 | ||||
-rw-r--r-- | lib/libc_r/arch/sparc64/uthread_machdep_asm.S | 39 | ||||
-rw-r--r-- | lib/libpthread/arch/sparc64/_atomic_lock.c | 48 | ||||
-rw-r--r-- | lib/libpthread/arch/sparc64/uthread_machdep.c | 45 | ||||
-rw-r--r-- | lib/libpthread/arch/sparc64/uthread_machdep.h | 7 | ||||
-rw-r--r-- | lib/libpthread/arch/sparc64/uthread_machdep_asm.S | 39 |
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 + |