about summary refs log tree commit diff
path: root/nptl/sysdeps/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/powerpc')
-rw-r--r--nptl/sysdeps/powerpc/Makefile21
-rw-r--r--nptl/sysdeps/powerpc/bits/atomic.h116
-rw-r--r--nptl/sysdeps/powerpc/pthread_spin_lock.c45
-rw-r--r--nptl/sysdeps/powerpc/pthread_spin_trylock.c43
-rw-r--r--nptl/sysdeps/powerpc/pthreaddef.h44
-rw-r--r--nptl/sysdeps/powerpc/tcb-offsets.sym13
-rw-r--r--nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c44
-rw-r--r--nptl/sysdeps/powerpc/tls.h152
8 files changed, 478 insertions, 0 deletions
diff --git a/nptl/sysdeps/powerpc/Makefile b/nptl/sysdeps/powerpc/Makefile
new file mode 100644
index 0000000000..3af2456003
--- /dev/null
+++ b/nptl/sysdeps/powerpc/Makefile
@@ -0,0 +1,21 @@
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/nptl/sysdeps/powerpc/bits/atomic.h b/nptl/sysdeps/powerpc/bits/atomic.h
new file mode 100644
index 0000000000..af6156389f
--- /dev/null
+++ b/nptl/sysdeps/powerpc/bits/atomic.h
@@ -0,0 +1,116 @@
+/* Atomic operations.  PowerPC version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \
+  (abort (), 0)
+
+#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \
+  (abort (), 0)
+
+#ifdef UP
+#define __ARCH_ACQ_INSTR	""
+#define __ARCH_REL_INSTR	""
+#else
+#define __ARCH_ACQ_INSTR	"isync"
+#define __ARCH_REL_INSTR	"sync"
+#endif
+
+/*
+ * XXX At present these have both acquire and release semantics.
+ * Ultimately we should do separate _acq and _rel versions.
+ */
+
+/*
+ * XXX this may not work properly on 64-bit if the register
+ * containing oldval has the high half non-zero for some reason.
+ */
+#define __arch_compare_and_exchange_32_acq(mem, newval, oldval)	\
+({								\
+  unsigned int __tmp;						\
+  __asm __volatile (__ARCH_REL_INSTR "\n"			\
+		    "1:	lwarx	%0,0,%1\n"			\
+		    "	subf.	%0,%2,%0\n"			\
+		    "	bne	2f\n"				\
+		    "	stwcx.	%3,0,%1\n"			\
+		    "	bne-	1b\n"				\
+		    "2:	" __ARCH_ACQ_INSTR			\
+		    : "=&r" (__tmp)				\
+		    : "r" (mem), "r" (oldval), "r" (newval)	\
+		    : "cr0", "memory");				\
+  __tmp != 0;							\
+})
+
+#ifdef __powerpc64__
+#define __arch_compare_and_exchange_64_acq(mem, newval, oldval)	\
+({								\
+  unsigned long	__tmp;						\
+  __asm __volatile (__ARCH_REL_INSTR "\n"			\
+		    "1:	ldarx	%0,0,%1\n"			\
+		    "	subf.	%0,%2,%0\n"			\
+		    "	bne	2f\n"				\
+		    "	stdcx.	%3,0,%1\n"			\
+		    "	bne-	1b\n"				\
+		    "2:	" __ARCH_ACQ_INSTR			\
+		    : "=&r" (__tmp)				\
+		    : "r" (mem), "r" (oldval), "r" (newval)	\
+		    : "cr0", "memory");				\
+  __tmp != 0;							\
+})
+
+#else /* powerpc32 */
+#define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \
+  (abort (), 0)
+#endif
+
+#define atomic_full_barrier()	__asm ("sync" ::: "memory")
+#ifdef __powerpc64__
+#define atomic_read_barrier()	__asm ("lwsync" ::: "memory")
+#else
+#define atomic_read_barrier()	__asm ("sync" ::: "memory")
+#endif
+#define atomic_write_barrier()	__asm ("eieio" ::: "memory")
diff --git a/nptl/sysdeps/powerpc/pthread_spin_lock.c b/nptl/sysdeps/powerpc/pthread_spin_lock.c
new file mode 100644
index 0000000000..e2293fda10
--- /dev/null
+++ b/nptl/sysdeps/powerpc/pthread_spin_lock.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+
+int
+pthread_spin_lock (lock)
+     pthread_spinlock_t *lock;
+{
+  unsigned int __tmp;
+
+  asm volatile (
+       "1:	lwarx	%0,0,%1\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne-	2f\n"
+       "	stwcx.	%2,0,%1\n"
+       "	bne-	2f\n"
+       "	isync\n"
+       "	.subsection 1\n"
+       "2:	lwzx	%0,0,%1\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne	2b\n"
+       "	b	1b\n"
+       "	.previous"
+       : "=&r" (__tmp)
+       : "r" (lock), "r" (1)
+       : "cr0", "memory");
+  return 0;
+}
diff --git a/nptl/sysdeps/powerpc/pthread_spin_trylock.c b/nptl/sysdeps/powerpc/pthread_spin_trylock.c
new file mode 100644
index 0000000000..d8e1dbcc81
--- /dev/null
+++ b/nptl/sysdeps/powerpc/pthread_spin_trylock.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (lock)
+     pthread_spinlock_t *lock;
+{
+  unsigned int old;
+  int err = EBUSY;
+
+  asm ("1:	lwarx	%0,0,%2\n"
+       "	cmpwi	0,%0,0\n"
+       "	bne	2f\n"
+       "	stwcx.	%3,0,%2\n"
+       "	bne-	1b\n"
+       "	li	%1,0\n"
+       "	isync\n"
+       "2:	"
+       : "=&r" (old), "=&r" (err)
+       : "r" (lock), "r" (1), "1" (err)
+       : "cr0", "memory");
+
+  return err;
+}
diff --git a/nptl/sysdeps/powerpc/pthreaddef.h b/nptl/sysdeps/powerpc/pthreaddef.h
new file mode 100644
index 0000000000..b28d0bedd7
--- /dev/null
+++ b/nptl/sysdeps/powerpc/pthreaddef.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(4 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  The ABI requires 16
+   bytes (for both 32-bit and 64-bit PowerPC).  */
+#define STACK_ALIGN		16
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK	4096
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT		16
+
+/* The signal used for asynchronous cancelation.  */
+#define SIGCANCEL		__SIGRTMIN
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME	__builtin_frame_address (0)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+
+/* While there is no such syscall.  */
+#define __exit_thread_inline(val) \
+  INLINE_SYSCALL (exit, 1, (val))
diff --git a/nptl/sysdeps/powerpc/tcb-offsets.sym b/nptl/sysdeps/powerpc/tcb-offsets.sym
new file mode 100644
index 0000000000..d6b7560b8e
--- /dev/null
+++ b/nptl/sysdeps/powerpc/tcb-offsets.sym
@@ -0,0 +1,13 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+# undef __thread_register
+# define __thread_register	((void *) 0)
+# define thread_offsetof(mem)	((void *) &THREAD_SELF->mem - (void *) 0)
+
+#if TLS_MULTIPLE_THREADS_IN_TCB
+MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
+#endif
diff --git a/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c b/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c
new file mode 100644
index 0000000000..d1a93681a3
--- /dev/null
+++ b/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c
@@ -0,0 +1,44 @@
+/* Which thread is running on an LWP?  PowerPC version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "thread_dbP.h"
+#include <tls.h>
+
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
+{
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  prgregset_t regs;
+  if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+    return TD_ERR;
+
+  th->th_unique = ((void *) regs[PT_THREAD_POINTER]
+		   - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE);
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+
+  return TD_OK;
+}
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
new file mode 100644
index 0000000000..04d76a6e6e
--- /dev/null
+++ b/nptl/sysdeps/powerpc/tls.h
@@ -0,0 +1,152 @@
+/* Definition for thread-local data handling.  NPTL/PowerPC version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H	1
+
+# include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* We require TLS support in the tools.  */
+#ifndef HAVE_TLS_SUPPORT
+# error "TLS support is required."
+#endif
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP	1
+
+/* For 32-bit, we use the multiple_threads field in the pthread struct */
+#ifndef __powerpc64__
+# define TLS_MULTIPLE_THREADS_IN_TCB	1
+#endif
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+/* This layout is actually wholly private and not affected by the ABI.
+   Nor does it overlap the pthread data structure, so we need nothing
+   extra here at all.  */
+typedef struct
+{
+  dtv_t *dtv;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN	__alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE		sizeof (tcbhead_t)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN		__alignof__ (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE	sizeof (struct pthread)
+
+/* XXX if __alignof__ (struct pthread) > __alignof (tcbhead_t)
+   we could be in trouble.  -- paulus */
+
+# ifndef __powerpc64__
+/* Register r2 (tp) is reserved by the ABI as "thread pointer". */
+register void *__thread_register __asm__ ("r2");
+#  define PT_THREAD_POINTER PT_R2
+# else
+/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
+register void *__thread_register __asm__ ("r13");
+#  define PT_THREAD_POINTER PT_R13
+# endif
+
+/* The following assumes that TP (R2 or R13) points to the end of the
+   TCB + 0x7000 (per the ABI).  This implies that TCB address is
+   TP-(TLS_TCB_SIZE + 0x7000).  As we define TLS_DTV_AT_TP we can
+   assume that the pthread struct is allocated immediately ahead of the
+   TCB.  This implies that the pthread_descr address is
+   TP-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000).  */
+# define TLS_TCB_OFFSET	0x7000
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp)	(((tcbhead_t *) (tcbp))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+    (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET + TLS_TCB_SIZE, NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET - TLS_TCB_SIZE))->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+    ((struct pthread *) (__thread_register \
+			 - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE))
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) \
+    ((void)(descr), (THREAD_SELF)->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+    ((void)(descr), (THREAD_SELF)->member = (value))
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+    ((void)(descr), (THREAD_SELF)->member[idx] = (value))
+
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */