PPC MD bits for KSE. Runs test cases OK. Crippled to 1:1 mode for
the time being.
This commit is contained in:
parent
d424b73832
commit
6dabab5888
8
lib/libkse/arch/powerpc/Makefile.inc
Normal file
8
lib/libkse/arch/powerpc/Makefile.inc
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# XXX temporary
|
||||
CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= enter_uts.S context.S pthread_md.c
|
62
lib/libkse/arch/powerpc/include/atomic_ops.h
Normal file
62
lib/libkse/arch/powerpc/include/atomic_ops.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = 0; /* should be a better way to quieten cc1... */
|
||||
#ifdef __GNUC__
|
||||
__asm __volatile(
|
||||
"1: lwarx %0, 0, %4\n" /* load with reservation */
|
||||
" stwcx. %3, 0, %4\n" /* attempt to store val */
|
||||
" bne- 1b\n" /* interrupted? retry */
|
||||
" stw %0, %1\n" /* else, *dst -> *res */
|
||||
: "=&r" (tmp), "=m" (*res), "+m" (*dst)
|
||||
: "r" (val), "r" (dst)
|
||||
: "cc", "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
257
lib/libkse/arch/powerpc/include/pthread_md.h
Normal file
257
lib/libkse/arch/powerpc/include/pthread_md.h
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t);
|
||||
extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
extern int _ppc32_getcontext(mcontext_t *);
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %r2 points to a struct kcb.
|
||||
*/
|
||||
struct ppc32_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint32_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
long tcb_isfake;
|
||||
struct ppc32_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
/*
|
||||
* From the PowerPC32 TLS spec:
|
||||
*
|
||||
* "r2 is the thread pointer, and points 0x7000 past the end of the
|
||||
* thread control block." Or, 0x7008 past the start of the 8-byte tcb
|
||||
*/
|
||||
#define TP_OFFSET 0x7008
|
||||
register uint8_t *_tpr __asm("%r2");
|
||||
|
||||
#define _tcb ((struct tcb *)(_tpr - TP_OFFSET - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tpr = (uint8_t *)&tcb->tcb_tp + TP_OFFSET;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
|
||||
_ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size - 32);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
extern int _libkse_debug;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
|
||||
/*
|
||||
* A full context needs a system call to restore, so use
|
||||
* kse_switchin. Otherwise, the partial context can be
|
||||
* restored with _ppc32_setcontext
|
||||
*/
|
||||
if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
} else {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox)
|
||||
_ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_ppc32_setcontext(mc, 0, NULL);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
113
lib/libkse/arch/powerpc/powerpc/assym.c
Normal file
113
lib/libkse/arch/powerpc/powerpc/assym.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Used to generate mcontext_t offsets */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/assym.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ASSYM(_MC_VERSION, _MC_VERSION);
|
||||
ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE);
|
||||
ASSYM(_MC_FP_VALID, _MC_FP_VALID);
|
||||
|
||||
ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers));
|
||||
ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags));
|
||||
|
||||
ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0]));
|
||||
ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1]));
|
||||
ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2]));
|
||||
ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3]));
|
||||
ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4]));
|
||||
ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5]));
|
||||
ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6]));
|
||||
ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7]));
|
||||
ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8]));
|
||||
ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9]));
|
||||
ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10]));
|
||||
ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11]));
|
||||
ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12]));
|
||||
ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13]));
|
||||
ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14]));
|
||||
ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15]));
|
||||
ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16]));
|
||||
ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17]));
|
||||
ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18]));
|
||||
ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19]));
|
||||
ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20]));
|
||||
ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21]));
|
||||
ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22]));
|
||||
ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23]));
|
||||
ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24]));
|
||||
ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25]));
|
||||
ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26]));
|
||||
ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27]));
|
||||
ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28]));
|
||||
ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29]));
|
||||
ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30]));
|
||||
ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31]));
|
||||
ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32]));
|
||||
ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33]));
|
||||
ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34]));
|
||||
ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35]));
|
||||
|
||||
ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32]));
|
||||
ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0]));
|
||||
ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1]));
|
||||
ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2]));
|
||||
ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3]));
|
||||
ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4]));
|
||||
ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5]));
|
||||
ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6]));
|
||||
ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7]));
|
||||
ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8]));
|
||||
ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9]));
|
||||
ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10]));
|
||||
ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11]));
|
||||
ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12]));
|
||||
ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13]));
|
||||
ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14]));
|
||||
ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15]));
|
||||
ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16]));
|
||||
ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17]));
|
||||
ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18]));
|
||||
ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19]));
|
||||
ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20]));
|
||||
ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21]));
|
||||
ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22]));
|
||||
ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23]));
|
||||
ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24]));
|
||||
ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25]));
|
||||
ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26]));
|
||||
ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27]));
|
||||
ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28]));
|
||||
ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29]));
|
||||
ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30]));
|
||||
ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31]));
|
113
lib/libkse/arch/powerpc/powerpc/assym.s
Normal file
113
lib/libkse/arch/powerpc/powerpc/assym.s
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Struct offsets for version 0x1 of the mcontext struct.
|
||||
* Generated with
|
||||
* cc -c assym.c
|
||||
* ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s
|
||||
* hand-edit output
|
||||
*/
|
||||
#define _MC_VERSION 0x1
|
||||
#define _MC_VERSION_KSE 0xee
|
||||
#define _MC_FP_VALID 0x1
|
||||
|
||||
#define _MC_VERS 0x0
|
||||
#define _MC_FLAGS 0x4
|
||||
|
||||
#define _MC_R0 0x298
|
||||
#define _MC_R1 0x21c
|
||||
#define _MC_R2 0x220
|
||||
#define _MC_R3 0x224
|
||||
#define _MC_R4 0x228
|
||||
#define _MC_R5 0x22c
|
||||
#define _MC_R6 0x230
|
||||
#define _MC_R7 0x234
|
||||
#define _MC_R8 0x238
|
||||
#define _MC_R9 0x23c
|
||||
#define _MC_R10 0x240
|
||||
#define _MC_R11 0x244
|
||||
#define _MC_R12 0x248
|
||||
#define _MC_R13 0x24c
|
||||
#define _MC_R14 0x250
|
||||
#define _MC_R15 0x254
|
||||
#define _MC_R16 0x258
|
||||
#define _MC_R17 0x25c
|
||||
#define _MC_R18 0x260
|
||||
#define _MC_R19 0x264
|
||||
#define _MC_R20 0x268
|
||||
#define _MC_R21 0x26c
|
||||
#define _MC_R22 0x270
|
||||
#define _MC_R23 0x274
|
||||
#define _MC_R24 0x278
|
||||
#define _MC_R25 0x27c
|
||||
#define _MC_R26 0x280
|
||||
#define _MC_R27 0x284
|
||||
#define _MC_R28 0x288
|
||||
#define _MC_R29 0x28c
|
||||
#define _MC_R30 0x290
|
||||
#define _MC_R31 0x294
|
||||
#define _MC_LR 0x298
|
||||
#define _MC_CR 0x29c
|
||||
#define _MC_XER 0x2a0
|
||||
#define _MC_CTR 0x2a4
|
||||
|
||||
#define _MC_FPSCR 0x3c0
|
||||
#define _MC_F0 0x2c0
|
||||
#define _MC_F1 0x2c8
|
||||
#define _MC_F2 0x2d0
|
||||
#define _MC_F3 0x2d8
|
||||
#define _MC_F4 0x2e0
|
||||
#define _MC_F5 0x2e8
|
||||
#define _MC_F6 0x2f0
|
||||
#define _MC_F7 0x2f8
|
||||
#define _MC_F8 0x300
|
||||
#define _MC_F9 0x308
|
||||
#define _MC_F10 0x310
|
||||
#define _MC_F11 0x318
|
||||
#define _MC_F12 0x320
|
||||
#define _MC_F13 0x328
|
||||
#define _MC_F14 0x330
|
||||
#define _MC_F15 0x338
|
||||
#define _MC_F16 0x340
|
||||
#define _MC_F17 0x348
|
||||
#define _MC_F18 0x350
|
||||
#define _MC_F19 0x358
|
||||
#define _MC_F20 0x360
|
||||
#define _MC_F21 0x368
|
||||
#define _MC_F22 0x370
|
||||
#define _MC_F23 0x378
|
||||
#define _MC_F24 0x380
|
||||
#define _MC_F25 0x388
|
||||
#define _MC_F26 0x390
|
||||
#define _MC_F27 0x398
|
||||
#define _MC_F28 0x3a0
|
||||
#define _MC_F29 0x3a8
|
||||
#define _MC_F30 0x3b0
|
||||
#define _MC_F31 0x3b8
|
||||
|
151
lib/libkse/arch/powerpc/powerpc/context.S
Normal file
151
lib/libkse/arch/powerpc/powerpc/context.S
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
/*
|
||||
* int _ppc32_getcontext(mcontext_t *mcp)
|
||||
*
|
||||
* Save register state from a voluntary context switch.
|
||||
* Only volatile registers, and those needed to complete
|
||||
* a setcontext call, need to be saved.
|
||||
*
|
||||
* r1
|
||||
* r14-31
|
||||
* f14-31 XXX
|
||||
* lr
|
||||
*
|
||||
* Return 0 for this call, and set up the context so it will return
|
||||
* 1 when restored with _ppc32_setcontext().
|
||||
*
|
||||
* XXX XXX
|
||||
* Floating-point is a big issue. Since there's no way to determine
|
||||
* if the caller has used FP, all volatile register need to be saved.
|
||||
* If FP hasn't been used, this results in a lazy FP exception in
|
||||
* the kernel and from that point on FP is always switched in/out
|
||||
* for the thread, which may be a big performance drag for the system.
|
||||
* An alternative is to use a system call to get the context, which
|
||||
* will do the right thing for floating point, but will save all
|
||||
* registers rather than the caller-saved subset, and has the overhead
|
||||
* of a syscall.
|
||||
* Maybe another option would be to give a light-weight way for a
|
||||
* thread to determine if FP is in used: perhaps a syscall that
|
||||
* returns in the asm traphandler, or an OSX-style read-only page
|
||||
* with a flag to indicate FP state.
|
||||
*
|
||||
* For now, punt the issue ala Alpha 1:1 model and fix in the future.
|
||||
*/
|
||||
ENTRY(_ppc32_getcontext)
|
||||
stw %r1, _MC_R1(%r3)
|
||||
stw %r13, _MC_R13(%r3)
|
||||
stw %r14, _MC_R14(%r3)
|
||||
stw %r15, _MC_R15(%r3)
|
||||
stw %r16, _MC_R16(%r3)
|
||||
stw %r17, _MC_R17(%r3)
|
||||
stw %r18, _MC_R18(%r3)
|
||||
stw %r19, _MC_R19(%r3)
|
||||
stw %r20, _MC_R20(%r3)
|
||||
stw %r21, _MC_R21(%r3)
|
||||
stw %r22, _MC_R22(%r3)
|
||||
stw %r23, _MC_R23(%r3)
|
||||
stw %r24, _MC_R24(%r3)
|
||||
stw %r25, _MC_R25(%r3)
|
||||
stw %r26, _MC_R26(%r3)
|
||||
stw %r27, _MC_R27(%r3)
|
||||
stw %r28, _MC_R28(%r3)
|
||||
stw %r29, _MC_R28(%r3)
|
||||
stw %r30, _MC_R30(%r3)
|
||||
stw %r31, _MC_R31(%r3)
|
||||
mflr %r4
|
||||
stw %r4, _MC_LR(%r3)
|
||||
mfcr %r4
|
||||
stw %r4, _MC_CR(%r3)
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
li %r4, _MC_VERSION_KSE /* partial ucontext version */
|
||||
stw %r4, _MC_VERS(%r3)
|
||||
|
||||
/* Return 0 */
|
||||
li %r3, 0
|
||||
blr
|
||||
|
||||
/*
|
||||
* int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
|
||||
* intptr_t *loc);
|
||||
*
|
||||
* Should only be called for partial KSE contexts. The full context
|
||||
* case is handled by kse_switchin() in _thread_switch()
|
||||
*
|
||||
* Returns -1 on error and 1 for return from a saved context
|
||||
*/
|
||||
|
||||
ENTRY(_ppc32_setcontext)
|
||||
lwz %r6, _MC_VERS(%r3)
|
||||
cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */
|
||||
beq 1f
|
||||
li %r3, -1 /* invalid context type, return -1 */
|
||||
blr
|
||||
|
||||
1: /* partial format, callee-saved regs assumed */
|
||||
lwz %r1, _MC_R1(%r3)
|
||||
lwz %r13, _MC_R13(%r3)
|
||||
lwz %r14, _MC_R14(%r3)
|
||||
lwz %r15, _MC_R15(%r3)
|
||||
lwz %r16, _MC_R16(%r3)
|
||||
lwz %r17, _MC_R17(%r3)
|
||||
lwz %r18, _MC_R18(%r3)
|
||||
lwz %r19, _MC_R19(%r3)
|
||||
lwz %r20, _MC_R20(%r3)
|
||||
lwz %r21, _MC_R21(%r3)
|
||||
lwz %r22, _MC_R22(%r3)
|
||||
lwz %r23, _MC_R23(%r3)
|
||||
lwz %r24, _MC_R24(%r3)
|
||||
lwz %r25, _MC_R25(%r3)
|
||||
lwz %r26, _MC_R26(%r3)
|
||||
lwz %r27, _MC_R27(%r3)
|
||||
lwz %r28, _MC_R28(%r3)
|
||||
lwz %r29, _MC_R28(%r3)
|
||||
lwz %r30, _MC_R30(%r3)
|
||||
lwz %r31, _MC_R31(%r3)
|
||||
lwz %r6, _MC_LR(%r3)
|
||||
mtlr %r6
|
||||
lwz %r6, _MC_CR(%r3)
|
||||
mtcr %r6
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
/* if (loc != NULL) *loc = val */
|
||||
cmpwi %r5, 0
|
||||
beq 2f
|
||||
stw %r4, 0(%r5)
|
||||
|
||||
/* Return 1 */
|
||||
2: li %r3, 1
|
||||
blr
|
40
lib/libkse/arch/powerpc/powerpc/enter_uts.S
Normal file
40
lib/libkse/arch/powerpc/powerpc/enter_uts.S
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* long stacksz);
|
||||
*
|
||||
* Call (*uts)(km) on the requested stack. This function doesn't
|
||||
* return. The km parameter stays in %r3.
|
||||
*/
|
||||
ENTRY(_ppc32_enter_uts)
|
||||
add %r1,%r5,%r6 /* new stack = stack + stacksz */
|
||||
mtlr %r4 /* link register = uts */
|
||||
blrl /* (*uts)(km) */
|
76
lib/libkse/arch/powerpc/powerpc/pthread_md.c
Normal file
76
lib/libkse/arch/powerpc/powerpc/pthread_md.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
8
lib/libpthread/arch/powerpc/Makefile.inc
Normal file
8
lib/libpthread/arch/powerpc/Makefile.inc
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# XXX temporary
|
||||
CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= enter_uts.S context.S pthread_md.c
|
62
lib/libpthread/arch/powerpc/include/atomic_ops.h
Normal file
62
lib/libpthread/arch/powerpc/include/atomic_ops.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = 0; /* should be a better way to quieten cc1... */
|
||||
#ifdef __GNUC__
|
||||
__asm __volatile(
|
||||
"1: lwarx %0, 0, %4\n" /* load with reservation */
|
||||
" stwcx. %3, 0, %4\n" /* attempt to store val */
|
||||
" bne- 1b\n" /* interrupted? retry */
|
||||
" stw %0, %1\n" /* else, *dst -> *res */
|
||||
: "=&r" (tmp), "=m" (*res), "+m" (*dst)
|
||||
: "r" (val), "r" (dst)
|
||||
: "cc", "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
257
lib/libpthread/arch/powerpc/include/pthread_md.h
Normal file
257
lib/libpthread/arch/powerpc/include/pthread_md.h
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2004 by Peter Grehan. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
extern void _ppc32_enter_uts(struct kse_mailbox *, kse_func_t, void *, size_t);
|
||||
extern int _ppc32_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
extern int _ppc32_getcontext(mcontext_t *);
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _ppc32_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _ppc32_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %r2 points to a struct kcb.
|
||||
*/
|
||||
struct ppc32_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint32_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
long tcb_isfake;
|
||||
struct ppc32_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
/*
|
||||
* From the PowerPC32 TLS spec:
|
||||
*
|
||||
* "r2 is the thread pointer, and points 0x7000 past the end of the
|
||||
* thread control block." Or, 0x7008 past the start of the 8-byte tcb
|
||||
*/
|
||||
#define TP_OFFSET 0x7008
|
||||
register uint8_t *_tpr __asm("%r2");
|
||||
|
||||
#define _tcb ((struct tcb *)(_tpr - TP_OFFSET - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tpr = (uint8_t *)&tcb->tcb_tp + TP_OFFSET;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_ppc32_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tpr = (uint8_t *)&kcb->kcb_faketcb.tcb_tp + TP_OFFSET;
|
||||
_ppc32_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size - 32);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
extern int _libkse_debug;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
|
||||
/*
|
||||
* A full context needs a system call to restore, so use
|
||||
* kse_switchin. Otherwise, the partial context can be
|
||||
* restored with _ppc32_setcontext
|
||||
*/
|
||||
if (mc->mc_vers != _MC_VERSION_KSE && _libkse_debug != 0) {
|
||||
if (setmbox)
|
||||
kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX);
|
||||
else
|
||||
kse_switchin(&tcb->tcb_tmbx, 0);
|
||||
} else {
|
||||
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
|
||||
if (setmbox)
|
||||
_ppc32_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_ppc32_setcontext(mc, 0, NULL);
|
||||
}
|
||||
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
113
lib/libpthread/arch/powerpc/powerpc/assym.c
Normal file
113
lib/libpthread/arch/powerpc/powerpc/assym.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Used to generate mcontext_t offsets */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/assym.h>
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ASSYM(_MC_VERSION, _MC_VERSION);
|
||||
ASSYM(_MC_VERSION_KSE, _MC_VERSION_KSE);
|
||||
ASSYM(_MC_FP_VALID, _MC_FP_VALID);
|
||||
|
||||
ASSYM(_MC_VERS, offsetof(mcontext_t, mc_vers));
|
||||
ASSYM(_MC_FLAGS, offsetof(mcontext_t, mc_flags));
|
||||
|
||||
ASSYM(_MC_R0, offsetof(mcontext_t, mc_frame[0]));
|
||||
ASSYM(_MC_R1, offsetof(mcontext_t, mc_frame[1]));
|
||||
ASSYM(_MC_R2, offsetof(mcontext_t, mc_frame[2]));
|
||||
ASSYM(_MC_R3, offsetof(mcontext_t, mc_frame[3]));
|
||||
ASSYM(_MC_R4, offsetof(mcontext_t, mc_frame[4]));
|
||||
ASSYM(_MC_R5, offsetof(mcontext_t, mc_frame[5]));
|
||||
ASSYM(_MC_R6, offsetof(mcontext_t, mc_frame[6]));
|
||||
ASSYM(_MC_R7, offsetof(mcontext_t, mc_frame[7]));
|
||||
ASSYM(_MC_R8, offsetof(mcontext_t, mc_frame[8]));
|
||||
ASSYM(_MC_R9, offsetof(mcontext_t, mc_frame[9]));
|
||||
ASSYM(_MC_R10, offsetof(mcontext_t, mc_frame[10]));
|
||||
ASSYM(_MC_R11, offsetof(mcontext_t, mc_frame[11]));
|
||||
ASSYM(_MC_R12, offsetof(mcontext_t, mc_frame[12]));
|
||||
ASSYM(_MC_R13, offsetof(mcontext_t, mc_frame[13]));
|
||||
ASSYM(_MC_R14, offsetof(mcontext_t, mc_frame[14]));
|
||||
ASSYM(_MC_R15, offsetof(mcontext_t, mc_frame[15]));
|
||||
ASSYM(_MC_R16, offsetof(mcontext_t, mc_frame[16]));
|
||||
ASSYM(_MC_R17, offsetof(mcontext_t, mc_frame[17]));
|
||||
ASSYM(_MC_R18, offsetof(mcontext_t, mc_frame[18]));
|
||||
ASSYM(_MC_R19, offsetof(mcontext_t, mc_frame[19]));
|
||||
ASSYM(_MC_R20, offsetof(mcontext_t, mc_frame[20]));
|
||||
ASSYM(_MC_R21, offsetof(mcontext_t, mc_frame[21]));
|
||||
ASSYM(_MC_R22, offsetof(mcontext_t, mc_frame[22]));
|
||||
ASSYM(_MC_R23, offsetof(mcontext_t, mc_frame[23]));
|
||||
ASSYM(_MC_R24, offsetof(mcontext_t, mc_frame[24]));
|
||||
ASSYM(_MC_R25, offsetof(mcontext_t, mc_frame[25]));
|
||||
ASSYM(_MC_R26, offsetof(mcontext_t, mc_frame[26]));
|
||||
ASSYM(_MC_R27, offsetof(mcontext_t, mc_frame[27]));
|
||||
ASSYM(_MC_R28, offsetof(mcontext_t, mc_frame[28]));
|
||||
ASSYM(_MC_R29, offsetof(mcontext_t, mc_frame[29]));
|
||||
ASSYM(_MC_R30, offsetof(mcontext_t, mc_frame[30]));
|
||||
ASSYM(_MC_R31, offsetof(mcontext_t, mc_frame[31]));
|
||||
ASSYM(_MC_LR, offsetof(mcontext_t, mc_frame[32]));
|
||||
ASSYM(_MC_CR, offsetof(mcontext_t, mc_frame[33]));
|
||||
ASSYM(_MC_XER, offsetof(mcontext_t, mc_frame[34]));
|
||||
ASSYM(_MC_CTR, offsetof(mcontext_t, mc_frame[35]));
|
||||
|
||||
ASSYM(_MC_FPSCR, offsetof(mcontext_t, mc_fpreg[32]));
|
||||
ASSYM(_MC_F0, offsetof(mcontext_t, mc_fpreg[0]));
|
||||
ASSYM(_MC_F1, offsetof(mcontext_t, mc_fpreg[1]));
|
||||
ASSYM(_MC_F2, offsetof(mcontext_t, mc_fpreg[2]));
|
||||
ASSYM(_MC_F3, offsetof(mcontext_t, mc_fpreg[3]));
|
||||
ASSYM(_MC_F4, offsetof(mcontext_t, mc_fpreg[4]));
|
||||
ASSYM(_MC_F5, offsetof(mcontext_t, mc_fpreg[5]));
|
||||
ASSYM(_MC_F6, offsetof(mcontext_t, mc_fpreg[6]));
|
||||
ASSYM(_MC_F7, offsetof(mcontext_t, mc_fpreg[7]));
|
||||
ASSYM(_MC_F8, offsetof(mcontext_t, mc_fpreg[8]));
|
||||
ASSYM(_MC_F9, offsetof(mcontext_t, mc_fpreg[9]));
|
||||
ASSYM(_MC_F10, offsetof(mcontext_t, mc_fpreg[10]));
|
||||
ASSYM(_MC_F11, offsetof(mcontext_t, mc_fpreg[11]));
|
||||
ASSYM(_MC_F12, offsetof(mcontext_t, mc_fpreg[12]));
|
||||
ASSYM(_MC_F13, offsetof(mcontext_t, mc_fpreg[13]));
|
||||
ASSYM(_MC_F14, offsetof(mcontext_t, mc_fpreg[14]));
|
||||
ASSYM(_MC_F15, offsetof(mcontext_t, mc_fpreg[15]));
|
||||
ASSYM(_MC_F16, offsetof(mcontext_t, mc_fpreg[16]));
|
||||
ASSYM(_MC_F17, offsetof(mcontext_t, mc_fpreg[17]));
|
||||
ASSYM(_MC_F18, offsetof(mcontext_t, mc_fpreg[18]));
|
||||
ASSYM(_MC_F19, offsetof(mcontext_t, mc_fpreg[19]));
|
||||
ASSYM(_MC_F20, offsetof(mcontext_t, mc_fpreg[20]));
|
||||
ASSYM(_MC_F21, offsetof(mcontext_t, mc_fpreg[21]));
|
||||
ASSYM(_MC_F22, offsetof(mcontext_t, mc_fpreg[22]));
|
||||
ASSYM(_MC_F23, offsetof(mcontext_t, mc_fpreg[23]));
|
||||
ASSYM(_MC_F24, offsetof(mcontext_t, mc_fpreg[24]));
|
||||
ASSYM(_MC_F25, offsetof(mcontext_t, mc_fpreg[25]));
|
||||
ASSYM(_MC_F26, offsetof(mcontext_t, mc_fpreg[26]));
|
||||
ASSYM(_MC_F27, offsetof(mcontext_t, mc_fpreg[27]));
|
||||
ASSYM(_MC_F28, offsetof(mcontext_t, mc_fpreg[28]));
|
||||
ASSYM(_MC_F29, offsetof(mcontext_t, mc_fpreg[29]));
|
||||
ASSYM(_MC_F30, offsetof(mcontext_t, mc_fpreg[30]));
|
||||
ASSYM(_MC_F31, offsetof(mcontext_t, mc_fpreg[31]));
|
113
lib/libpthread/arch/powerpc/powerpc/assym.s
Normal file
113
lib/libpthread/arch/powerpc/powerpc/assym.s
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Struct offsets for version 0x1 of the mcontext struct.
|
||||
* Generated with
|
||||
* cc -c assym.c
|
||||
* ${SYSSRC}/kern/genassym.sh assym.o > assym_syms.s
|
||||
* hand-edit output
|
||||
*/
|
||||
#define _MC_VERSION 0x1
|
||||
#define _MC_VERSION_KSE 0xee
|
||||
#define _MC_FP_VALID 0x1
|
||||
|
||||
#define _MC_VERS 0x0
|
||||
#define _MC_FLAGS 0x4
|
||||
|
||||
#define _MC_R0 0x298
|
||||
#define _MC_R1 0x21c
|
||||
#define _MC_R2 0x220
|
||||
#define _MC_R3 0x224
|
||||
#define _MC_R4 0x228
|
||||
#define _MC_R5 0x22c
|
||||
#define _MC_R6 0x230
|
||||
#define _MC_R7 0x234
|
||||
#define _MC_R8 0x238
|
||||
#define _MC_R9 0x23c
|
||||
#define _MC_R10 0x240
|
||||
#define _MC_R11 0x244
|
||||
#define _MC_R12 0x248
|
||||
#define _MC_R13 0x24c
|
||||
#define _MC_R14 0x250
|
||||
#define _MC_R15 0x254
|
||||
#define _MC_R16 0x258
|
||||
#define _MC_R17 0x25c
|
||||
#define _MC_R18 0x260
|
||||
#define _MC_R19 0x264
|
||||
#define _MC_R20 0x268
|
||||
#define _MC_R21 0x26c
|
||||
#define _MC_R22 0x270
|
||||
#define _MC_R23 0x274
|
||||
#define _MC_R24 0x278
|
||||
#define _MC_R25 0x27c
|
||||
#define _MC_R26 0x280
|
||||
#define _MC_R27 0x284
|
||||
#define _MC_R28 0x288
|
||||
#define _MC_R29 0x28c
|
||||
#define _MC_R30 0x290
|
||||
#define _MC_R31 0x294
|
||||
#define _MC_LR 0x298
|
||||
#define _MC_CR 0x29c
|
||||
#define _MC_XER 0x2a0
|
||||
#define _MC_CTR 0x2a4
|
||||
|
||||
#define _MC_FPSCR 0x3c0
|
||||
#define _MC_F0 0x2c0
|
||||
#define _MC_F1 0x2c8
|
||||
#define _MC_F2 0x2d0
|
||||
#define _MC_F3 0x2d8
|
||||
#define _MC_F4 0x2e0
|
||||
#define _MC_F5 0x2e8
|
||||
#define _MC_F6 0x2f0
|
||||
#define _MC_F7 0x2f8
|
||||
#define _MC_F8 0x300
|
||||
#define _MC_F9 0x308
|
||||
#define _MC_F10 0x310
|
||||
#define _MC_F11 0x318
|
||||
#define _MC_F12 0x320
|
||||
#define _MC_F13 0x328
|
||||
#define _MC_F14 0x330
|
||||
#define _MC_F15 0x338
|
||||
#define _MC_F16 0x340
|
||||
#define _MC_F17 0x348
|
||||
#define _MC_F18 0x350
|
||||
#define _MC_F19 0x358
|
||||
#define _MC_F20 0x360
|
||||
#define _MC_F21 0x368
|
||||
#define _MC_F22 0x370
|
||||
#define _MC_F23 0x378
|
||||
#define _MC_F24 0x380
|
||||
#define _MC_F25 0x388
|
||||
#define _MC_F26 0x390
|
||||
#define _MC_F27 0x398
|
||||
#define _MC_F28 0x3a0
|
||||
#define _MC_F29 0x3a8
|
||||
#define _MC_F30 0x3b0
|
||||
#define _MC_F31 0x3b8
|
||||
|
151
lib/libpthread/arch/powerpc/powerpc/context.S
Normal file
151
lib/libpthread/arch/powerpc/powerpc/context.S
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
/*
|
||||
* int _ppc32_getcontext(mcontext_t *mcp)
|
||||
*
|
||||
* Save register state from a voluntary context switch.
|
||||
* Only volatile registers, and those needed to complete
|
||||
* a setcontext call, need to be saved.
|
||||
*
|
||||
* r1
|
||||
* r14-31
|
||||
* f14-31 XXX
|
||||
* lr
|
||||
*
|
||||
* Return 0 for this call, and set up the context so it will return
|
||||
* 1 when restored with _ppc32_setcontext().
|
||||
*
|
||||
* XXX XXX
|
||||
* Floating-point is a big issue. Since there's no way to determine
|
||||
* if the caller has used FP, all volatile register need to be saved.
|
||||
* If FP hasn't been used, this results in a lazy FP exception in
|
||||
* the kernel and from that point on FP is always switched in/out
|
||||
* for the thread, which may be a big performance drag for the system.
|
||||
* An alternative is to use a system call to get the context, which
|
||||
* will do the right thing for floating point, but will save all
|
||||
* registers rather than the caller-saved subset, and has the overhead
|
||||
* of a syscall.
|
||||
* Maybe another option would be to give a light-weight way for a
|
||||
* thread to determine if FP is in used: perhaps a syscall that
|
||||
* returns in the asm traphandler, or an OSX-style read-only page
|
||||
* with a flag to indicate FP state.
|
||||
*
|
||||
* For now, punt the issue ala Alpha 1:1 model and fix in the future.
|
||||
*/
|
||||
ENTRY(_ppc32_getcontext)
|
||||
stw %r1, _MC_R1(%r3)
|
||||
stw %r13, _MC_R13(%r3)
|
||||
stw %r14, _MC_R14(%r3)
|
||||
stw %r15, _MC_R15(%r3)
|
||||
stw %r16, _MC_R16(%r3)
|
||||
stw %r17, _MC_R17(%r3)
|
||||
stw %r18, _MC_R18(%r3)
|
||||
stw %r19, _MC_R19(%r3)
|
||||
stw %r20, _MC_R20(%r3)
|
||||
stw %r21, _MC_R21(%r3)
|
||||
stw %r22, _MC_R22(%r3)
|
||||
stw %r23, _MC_R23(%r3)
|
||||
stw %r24, _MC_R24(%r3)
|
||||
stw %r25, _MC_R25(%r3)
|
||||
stw %r26, _MC_R26(%r3)
|
||||
stw %r27, _MC_R27(%r3)
|
||||
stw %r28, _MC_R28(%r3)
|
||||
stw %r29, _MC_R28(%r3)
|
||||
stw %r30, _MC_R30(%r3)
|
||||
stw %r31, _MC_R31(%r3)
|
||||
mflr %r4
|
||||
stw %r4, _MC_LR(%r3)
|
||||
mfcr %r4
|
||||
stw %r4, _MC_CR(%r3)
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
li %r4, _MC_VERSION_KSE /* partial ucontext version */
|
||||
stw %r4, _MC_VERS(%r3)
|
||||
|
||||
/* Return 0 */
|
||||
li %r3, 0
|
||||
blr
|
||||
|
||||
/*
|
||||
* int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
|
||||
* intptr_t *loc);
|
||||
*
|
||||
* Should only be called for partial KSE contexts. The full context
|
||||
* case is handled by kse_switchin() in _thread_switch()
|
||||
*
|
||||
* Returns -1 on error and 1 for return from a saved context
|
||||
*/
|
||||
|
||||
ENTRY(_ppc32_setcontext)
|
||||
lwz %r6, _MC_VERS(%r3)
|
||||
cmpwi %r6, _MC_VERSION_KSE /* KSE partial context ? */
|
||||
beq 1f
|
||||
li %r3, -1 /* invalid context type, return -1 */
|
||||
blr
|
||||
|
||||
1: /* partial format, callee-saved regs assumed */
|
||||
lwz %r1, _MC_R1(%r3)
|
||||
lwz %r13, _MC_R13(%r3)
|
||||
lwz %r14, _MC_R14(%r3)
|
||||
lwz %r15, _MC_R15(%r3)
|
||||
lwz %r16, _MC_R16(%r3)
|
||||
lwz %r17, _MC_R17(%r3)
|
||||
lwz %r18, _MC_R18(%r3)
|
||||
lwz %r19, _MC_R19(%r3)
|
||||
lwz %r20, _MC_R20(%r3)
|
||||
lwz %r21, _MC_R21(%r3)
|
||||
lwz %r22, _MC_R22(%r3)
|
||||
lwz %r23, _MC_R23(%r3)
|
||||
lwz %r24, _MC_R24(%r3)
|
||||
lwz %r25, _MC_R25(%r3)
|
||||
lwz %r26, _MC_R26(%r3)
|
||||
lwz %r27, _MC_R27(%r3)
|
||||
lwz %r28, _MC_R28(%r3)
|
||||
lwz %r29, _MC_R28(%r3)
|
||||
lwz %r30, _MC_R30(%r3)
|
||||
lwz %r31, _MC_R31(%r3)
|
||||
lwz %r6, _MC_LR(%r3)
|
||||
mtlr %r6
|
||||
lwz %r6, _MC_CR(%r3)
|
||||
mtcr %r6
|
||||
|
||||
/* XXX f14-31 ? */
|
||||
|
||||
/* if (loc != NULL) *loc = val */
|
||||
cmpwi %r5, 0
|
||||
beq 2f
|
||||
stw %r4, 0(%r5)
|
||||
|
||||
/* Return 1 */
|
||||
2: li %r3, 1
|
||||
blr
|
40
lib/libpthread/arch/powerpc/powerpc/enter_uts.S
Normal file
40
lib/libpthread/arch/powerpc/powerpc/enter_uts.S
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Peter Grehan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* _ppc32_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* long stacksz);
|
||||
*
|
||||
* Call (*uts)(km) on the requested stack. This function doesn't
|
||||
* return. The km parameter stays in %r3.
|
||||
*/
|
||||
ENTRY(_ppc32_enter_uts)
|
||||
add %r1,%r5,%r6 /* new stack = stack + stacksz */
|
||||
mtlr %r4 /* link register = uts */
|
||||
blrl /* (*uts)(km) */
|
76
lib/libpthread/arch/powerpc/powerpc/pthread_md.c
Normal file
76
lib/libpthread/arch/powerpc/powerpc/pthread_md.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Neither the name of the author nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
Loading…
Reference in New Issue
Block a user